
water.util.ArrayUtils Maven / Gradle / Ivy
package water.util;
import water.DKV;
import water.Futures;
import water.Key;
import water.MemoryManager;
import water.fvec.*;
import java.text.DecimalFormat;
import java.util.*;
import static water.util.RandomUtils.getRNG;
/* Bulk Array Utilities */
public class ArrayUtils {
// Sum elements of an array
public static long sum(final long[] from) {
long result = 0;
for (long d: from) result += d;
return result;
}
public static int sum(final int[] from) {
int result = 0;
for( int d : from ) result += d;
return result;
}
public static float sum(final float[] from) {
float result = 0;
for (float d: from) result += d;
return result;
}
public static double sum(final double[] from) {
double result = 0;
for (double d: from) result += d;
return result;
}
public static float[] reduceMin(float[] a, float[] b) {
for (int i=0; i= 0?x[i]:-x[i];
return sum;
}
public static double linfnorm(double [] x, boolean skipLast){
double res = Double.NEGATIVE_INFINITY;
int last = x.length -(skipLast?1:0);
for(int i = 0; i < last; ++i) {
if(x[i] > res) res = x[i];
if(-x[i] > res) res = -x[i];
}
return res;
}
public static double l2norm(double[] x) { return Math.sqrt(l2norm2(x)); }
public static double l2norm(double [] x, boolean skipLast){
return Math.sqrt(l2norm2(x, skipLast));
}
public static double l2norm(double[] x, double[] y) { return Math.sqrt(l2norm2(x,y)); }
public static double l2norm(double[][] x, double[][] y) { return Math.sqrt(l2norm2(x,y)); }
// Add arrays, element-by-element
public static byte[] add(byte[] a, byte[] b) {
for(int i = 0; i < a.length; i++ ) a[i] += b[i];
return a;
}
public static int[] add(int[] a, int[] b) {
for(int i = 0; i < a.length; i++ ) a[i] += b[i];
return a;
}
public static int[][] add(int[][] a, int[][] b) {
for(int i = 0; i < a.length; i++ ) add(a[i],b[i]);
return a;
}
public static long[] add(long[] a, long[] b) {
if( b==null ) return a;
for(int i = 0; i < a.length; i++ ) a[i] += b[i];
return a;
}
public static long[][] add(long[][] a, long[][] b) {
for(int i = 0; i < a.length; i++ ) add(a[i],b[i]);
return a;
}
public static long[][][] add(long[][][] a, long[][][] b) {
for(int i = 0; i < a.length; i++ ) add(a[i],b[i]);
return a;
}
public static float[] add(float[] a, float[] b) {
if( b==null ) return a;
for(int i = 0; i < a.length; i++ ) a[i] += b[i];
return a;
}
public static float[][] add(float[][] a, float[][] b) {
for(int i = 0; i < a.length; i++ ) add(a[i],b[i]);
return a;
}
public static boolean[] or(boolean[] a, boolean[] b) {
if (b==null)return a;
for (int i = 0; i < a.length; i++) a[i] |= b[i];
return a;
}
public static double[][] deepClone(double [][] ary){
double [][] res = ary.clone();
for(int i = 0 ; i < res.length; ++i)
res[i] = ary[i].clone();
return res;
}
public static double[] add(double[] a, double[] b) {
if( a==null ) return b;
for(int i = 0; i < a.length; i++ ) a[i] += b[i];
return a;
}
public static double[] add(double[] a, double b) {
for(int i = 0; i < a.length; i++ ) a[i] += b;
return a;
}
public static double[] wadd(double[] a, double[] b, double w) {
if( a==null ) return b;
for(int i = 0; i < a.length; i++ )
a[i] += w*b[i];
return a;
}
public static double[] wadd(double[] a, double[] b, double [] c, double w) {
if( a==null ) return b;
for(int i = 0; i < a.length; i++ )
c[i] = a[i] + w*b[i];
return c;
}
// a <- b + c
public static double[] add(double[] a, double[] b, double [] c) {
for(int i = 0; i < a.length; i++ )
a[i] = b[i] + c[i];
return a;
}
public static double[][] add(double[][] a, double[][] b) {
for(int i = 0; i < a.length; i++ ) a[i] = add(a[i], b[i]);
return a;
}
public static double[][][] add(double[][][] a, double[][][] b) {
for(int i = 0; i < a.length; i++ ) a[i] = add(a[i],b[i]);
return a;
}
public static double avg(double[] nums) {
double sum = 0;
for(double n: nums) sum+=n;
return sum/nums.length;
}
public static double avg(long[] nums) {
long sum = 0;
for(long n: nums) sum+=n;
return sum/nums.length;
}
public static long[] add(long[] nums, long a) {
for (int i=0;i T[] subarray(T[] a, int off, int len) {
return Arrays.copyOfRange(a,off,off+len);
}
/** Returns the index of the largest value in the array.
* In case of a tie, an the index is selected randomly.
*/
public static int maxIndex(int[] from, Random rand) {
assert rand != null;
int result = 0;
int maxCount = 0; // count of maximal element for a 1 item reservoir sample
for( int i = 1; i < from.length; ++i ) {
if( from[i] > from[result] ) {
result = i;
maxCount = 1;
} else if( from[i] == from[result] ) {
if( rand.nextInt(++maxCount) == 0 ) result = i;
}
}
return result;
}
public static int maxIndex(float[] from, Random rand) {
assert rand != null;
int result = 0;
int maxCount = 0; // count of maximal element for a 1 item reservoir sample
for( int i = 1; i < from.length; ++i ) {
if( from[i] > from[result] ) {
result = i;
maxCount = 1;
} else if( from[i] == from[result] ) {
if( rand.nextInt(++maxCount) == 0 ) result = i;
}
}
return result;
}
public static int maxIndex(double[] from, Random rand) {
assert rand != null;
int result = 0;
int maxCount = 0; // count of maximal element for a 1 item reservoir sample
for( int i = 1; i < from.length; ++i ) {
if( from[i] > from[result] ) {
result = i;
maxCount = 1;
} else if( from[i] == from[result] ) {
if( rand.nextInt(++maxCount) == 0 ) result = i;
}
}
return result;
}
public static int maxIndex(int[] from) {
int result = 0;
for (int i = 1; ifrom[result]) result = i;
return result;
}
public static int maxIndex(long[] from) {
int result = 0;
for (int i = 1; ifrom[result]) result = i;
return result;
}
public static int maxIndex(double[] from) {
int result = 0;
for (int i = 1; ifrom[result]) result = i;
return result;
}
public static int minIndex(int[] from) {
int result = 0;
for (int i = 1; iresult) result = ary[i];
return result;
}
public static float maxValue(float[] ary) {
return maxValue(ary,0,ary.length);
}
public static float maxValue(float[] ary, int from, int to) {
float result = ary[from];
for (int i = from+1; iresult) result = ary[i];
return result;
}
public static float minValue(float[] from) {
float result = from[0];
for (int i = 1; iresult) result = from[i];
return result;
}
public static long maxValue(int[] from) {
int result = from[0];
for (int i = 1; iresult) result = from[i];
return result;
}
public static long minValue(long[] from) {
long result = from[0];
for (int i = 1; i int find(T[] ts, T elem) {return find(ts,elem,0);}
// Find an element with linear search & return it's index, or -1
public static int find(T[] ts, T elem, int off) {
for (int i = off; i < ts.length; i++)
if (elem == ts[i] || elem.equals(ts[i]))
return i;
return -1;
}
public static int find(long[] ls, long elem) {
for(int i=0; i= 0 ? 1 : 2);
max_width = Math.max(dStr.length() + prefix, max_width);
}
}
for( double[] line : arr ) {
for( int c = 0; c < line.length; ++c ) {
double d = line[c];
String dStr = dformat.format(d);
if( dStr.indexOf('.') == -1 ) dStr += ".0";
for( int x = dStr.indexOf('.'); x < ilengths[c] + 1; ++x )
sb.append(' ');
sb.append(dStr);
if( dStr.indexOf('.') == -1 ) sb.append('.');
for( int i = dStr.length() - Math.max(0, dStr.indexOf('.')); i <= 5; ++i )
sb.append('0');
}
sb.append("\n");
}
return sb.toString();
}
public static int[] unpackInts(long... longs) {
int len = 2*longs.length;
int result[] = new int[len];
int i = 0;
for (long l : longs) {
result[i++] = (int) (l & 0xffffffffL);
result[i++] = (int) (l>>32);
}
return result;
}
private static void swap(long[] a, int i, int change) {
long helper = a[i];
a[i] = a[change];
a[change] = helper;
}
private static void swap(int[] a, int i, int change) {
int helper = a[i];
a[i] = a[change];
a[change] = helper;
}
/**
* Extract a shuffled array of integers
* @param a input array
* @param n number of elements to extract
* @param result array to store the results into (will be of size n)
* @param seed random number seed
* @param startIndex offset into a
* @return result
*/
public static int[] shuffleArray(int[] a, int n, int result[], long seed, int startIndex) {
if (n<=0) return result;
Random random = getRNG(seed);
if (result == null || result.length != n)
result = new int[n];
result[0] = a[startIndex];
for (int i = 1; i < n; i++) {
int j = random.nextInt(i+1);
if (j!=i) result[i] = result[j];
result[j] = a[startIndex+i];
}
for (int i = 0; i < n; ++i)
assert(ArrayUtils.contains(result, a[startIndex+i]));
return result;
}
public static void shuffleArray(int[] a, Random rng) {
int n = a.length;
for (int i = 0; i < n; i++) {
int change = i + rng.nextInt(n - i);
swap(a, i, change);
}
}
// Generate a n by m array of random numbers drawn from the standard normal distribution
public static double[][] gaussianArray(int n, int m) { return gaussianArray(n, m, System.currentTimeMillis()); }
public static double[][] gaussianArray(int n, int m, long seed) {
if(n <= 0 || m <= 0) return null;
double[][] result = new double[n][m];
Random random = getRNG(seed);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++)
result[i][j] = random.nextGaussian();
}
return result;
}
public static double[] gaussianVector(int n) { return gaussianVector(n, System.currentTimeMillis()); }
public static double[] gaussianVector(int n, long seed) { return gaussianVector(n, getRNG(seed)); }
public static double[] gaussianVector(int n, Random random) {
if(n <= 0) return null;
double[] result = new double[n];
for(int i = 0; i < n; i++)
result[i] = random.nextGaussian();
return result;
}
/** Returns number of strings which represents a number. */
public static int numInts(String... a) {
int cnt = 0;
for(String s : a) if (isInt(s)) cnt++;
return cnt;
}
public static boolean isInt(String s) {
int i = s.charAt(0)=='-' ? 1 : 0;
for(; i T[] join(T[] a, T[] b) {
T[] res = Arrays.copyOf(a, a.length+b.length);
System.arraycopy(b, 0, res, a.length, b.length);
return res;
}
public static final boolean hasNaNsOrInfs(double [] ary){
for(double d:ary)
if(Double.isNaN(d) || Double.isInfinite(d))
return true;
return false;
}
public static final boolean hasNaNs(double [] ary){
for(double d:ary)
if(Double.isNaN(d))
return true;
return false;
}
public static final boolean hasNaNsOrInfs(float [] ary){
for(float d:ary)
if(Double.isNaN(d) || Double.isInfinite(d))
return true;
return false;
}
/** Generates sequence (start, stop) of integers: (start, start+1, ...., stop-1) */
static public int[] seq(int start, int stop) {
assert start T[] append(T[] a, T... b) {
if( a==null ) return b;
T[] tmp = Arrays.copyOf(a,a.length+b.length);
System.arraycopy(b,0,tmp,a.length,b.length);
return tmp;
}
public static int[] append(int[] a, int b) {
if( a==null || a.length == 0) return new int[]{b};
int[] tmp = Arrays.copyOf(a,a.length+1);
tmp[a.length] = b;
return tmp;
}
static public String[] prepend(String[] ary, String s) {
if (ary==null) return new String[] { s };
String[] nary = new String[ary.length+1];
nary[0] = s;
System.arraycopy(ary,0,nary,1,ary.length);
return nary;
}
static public T[] copyAndFillOf(T[] original, int newLength, T padding) {
if(newLength < 0) throw new NegativeArraySizeException("The array size is negative.");
T[] newArray = Arrays.copyOf(original, newLength);
if(original.length < newLength) {
System.arraycopy(original, 0, newArray, 0, original.length);
Arrays.fill(newArray, original.length, newArray.length, padding);
} else
System.arraycopy(original, 0, newArray, 0, newLength);
return newArray;
}
static public double[] copyAndFillOf(double[] original, int newLength, double padding) {
if(newLength < 0) throw new NegativeArraySizeException("The array size is negative.");
double[] newArray = new double[newLength];
if(original.length < newLength) {
System.arraycopy(original, 0, newArray, 0, original.length);
Arrays.fill(newArray, original.length, newArray.length, padding);
} else
System.arraycopy(original, 0, newArray, 0, newLength);
return newArray;
}
static public long[] copyAndFillOf(long[] original, int newLength, long padding) {
if(newLength < 0) throw new NegativeArraySizeException("The array size is negative.");
long[] newArray = new long[newLength];
if(original.length < newLength) {
System.arraycopy(original, 0, newArray, 0, original.length);
Arrays.fill(newArray, original.length, newArray.length, padding);
} else
System.arraycopy(original, 0, newArray, 0, newLength);
return newArray;
}
static public double[] copyFromIntArray(int[] a) {
double[] da = new double[a.length];
for(int i=0;i bIds[j]) {
resIds[k] = bIds[j];
resVals[k] = bVals[j];
++j;
} else {
resIds[k] = aIds[i];
resVals[k] = aVals[i];
++i;
}
}
assert i == aIds.length && j == bIds.length;
}
public static String[] select(String[] ary, int[] idxs) {
String [] res = new String[idxs.length];
for(int i = 0; i < res.length; ++i)
res[i] = ary[idxs[i]];
return res;
}
public static double[] select(double[] ary, int[] idxs) {
double [] res = MemoryManager.malloc8d(idxs.length);
for(int i = 0; i < res.length; ++i)
res[i] = ary[idxs[i]];
return res;
}
public static double [] expandAndScatter(double [] ary, int N, int [] ids) {
assert ary.length == ids.length;
double [] res = MemoryManager.malloc8d(N);
for(int i = 0; i < ids.length; ++i) res[ids[i]] = ary[i];
return res;
}
/**
* Sort an integer array of indices based on values
* Updates indices in place, keeps values the same
* @param idxs indices
* @param values values
*/
public static void sort(final int[] idxs, final double[] values) {
sort(idxs, values, 500);
}
public static void sort(final int[] idxs, final double[] values, int cutoff) {
if (idxs.length < cutoff) {
//hand-rolled insertion sort
for (int i = 0; i < idxs.length; i++) {
for (int j = i; j > 0 && values[idxs[j - 1]] > values[idxs[j]]; j--) {
int tmp = idxs[j];
idxs[j] = idxs[j - 1];
idxs[j - 1] = tmp;
}
}
} else {
Integer[] d = new Integer[idxs.length];
for (int i = 0; i < idxs.length; ++i) d[i] = idxs[i];
// Arrays.parallelSort(d, new Comparator() {
Arrays.sort(d, new Comparator() {
@Override
public int compare(Integer x, Integer y) {
return values[x] < values[y] ? -1 : (values[x] > values[y] ? 1 : 0);
}
});
for (int i = 0; i < idxs.length; ++i) idxs[i] = d[i];
}
}
public static double [] subtract (double [] a, double [] b) {
double [] c = MemoryManager.malloc8d(a.length);
subtract(a,b,c);
return c;
}
public static double[] subtract (double [] a, double [] b, double [] c) {
for(int i = 0; i < a.length; ++i)
c[i] = a[i] - b[i];
return c;
}
/** Flatenize given array.
*
* Example: [[1,2], [3,null], [4]] -> [1,2,3,null,4]
* @param arr array of arrays
* @param any type
* @return flattened array, if input was null return null, if input was empty return null
*/
public static T[] flat(T[][] arr) {
if (arr == null) return null;
if (arr.length == 0) return null;
int tlen = 0;
for (T[] t : arr) tlen += t.length;
T[] result = Arrays.copyOf(arr[0], tlen);
int j = arr[0].length;
for (int i = 1; i < arr.length; i++) {
System.arraycopy(arr[i], 0, result, j, arr[i].length);
j += arr[i].length;
}
return result;
}
public static double [][] convertTo2DMatrix(double [] x, int N) {
assert x.length % N == 0;
int len = x.length/N;
double [][] res = new double[len][];
for(int i = 0; i < len; ++i) {
res[i] = MemoryManager.malloc8d(N);
System.arraycopy(x,i*N,res[i],0,N);
}
return res;
}
public static double[] flat(double[][] arr) {
if (arr == null) return null;
if (arr.length == 0) return null;
int tlen = 0;
for (double[] t : arr) tlen += t.length;
double[] result = Arrays.copyOf(arr[0], tlen);
int j = arr[0].length;
for (int i = 1; i < arr.length; i++) {
System.arraycopy(arr[i], 0, result, j, arr[i].length);
j += arr[i].length;
}
return result;
}
public static Object[][] zip(Object[] a, Object[] b) {
if (a.length != b.length) throw new IllegalArgumentException("Cannot zip arrays of different lenghts!");
Object[][] result = new Object[a.length][2];
for (int i = 0; i < a.length; i++) {
result[i][0] = a[i];
result[i][1] = b[i];
}
return result;
}
public static int crossProductSize(Map hyperSpace) {
int size = 1;
for (Map.Entry entry : hyperSpace.entrySet()) {
V[] value = entry.getValue();
size *= value != null ? value.length : 1;
}
return size;
}
public static Integer[] interval(Integer start, Integer end) {
return interval(start, end, 1);
}
public static Integer[] interval(Integer start, Integer end, Integer step) {
int len = 1 + (end - start) / step; // Include both ends of interval
Integer[] result = new Integer[len];
for(int i = 0, value = start; i < len; i++, value += step) {
result[i] = value;
}
return result;
}
public static Float[] interval(Float start, Float end, Float step) {
int len = 1 + (int)((end - start) / step); // Include both ends of interval
Float[] result = new Float[len];
Float value = start;
for(int i = 0; i < len; i++, value = start + i*step) {
result[i] = value;
}
return result;
}
public static Double[] interval(Double start, Double end, Double step) {
int len = 1 + (int)((end - start) / step); // Include both ends of interval
Double[] result = new Double[len];
Double value = start;
for(int i = 0; i < len; i++, value = start + i*step) {
result[i] = value;
}
return result;
}
public static String [] remove(String [] ary, String s) {
if(s == null)return ary;
int cnt = 0;
int idx = find(ary,s);
while(idx > 0) {
++cnt;
idx = find(ary,s,++idx);
}
if(cnt == 0)return ary;
String [] res = new String[ary.length-cnt];
int j = 0;
for(String x:ary)
if(!x.equals(s))
res[j++] = x;
return res;
}
/** Create a new frame based on given row data.
* @param key Key for the frame
* @param names names of frame columns
* @param rows data given in the form of rows
* @return new frame which contains columns named according given names and including given data */
public static Frame frame(Key key, String[] names, double[]... rows) {
assert names == null || names.length == rows[0].length;
Futures fs = new Futures();
Vec[] vecs = new Vec[rows[0].length];
Key keys[] = Vec.VectorGroup.VG_LEN1.addVecs(vecs.length);
int rowLayout = -1;
for( int c = 0; c < vecs.length; c++ ) {
AppendableVec vec = new AppendableVec(keys[c], Vec.T_NUM);
NewChunk chunk = new NewChunk(vec, 0);
for (double[] row : rows) chunk.addNum(row[c]);
chunk.close(0, fs);
if( rowLayout== -1) rowLayout = vec.compute_rowLayout();
vecs[c] = vec.close(rowLayout,fs);
}
fs.blockForPending();
Frame fr = new Frame(key, names, vecs);
if( key != null ) DKV.put(key, fr);
return fr;
}
public static Frame frame(double[]... rows) { return frame(null, rows); }
public static Frame frame(String[] names, double[]... rows) { return frame(Key.make(), names, rows); }
public static Frame frame(String name, Vec vec) { Frame f = new Frame(); f.add(name, vec); return f; }
/**
* Remove b from a, both a,b are assumed to be sorted.
*/
public static int[] removeSorted(int [] a, int [] b) {
int [] indeces = new int[b.length];
indeces[0] = Arrays.binarySearch(a,0,a.length,b[0]);
if(indeces[0] < 0)
throw new NoSuchElementException("value " + b[0] + " not found in the first array.");
for(int i = 1; i < b.length; ++i) {
indeces[i] = Arrays.binarySearch(a,indeces[i-1],a.length,b[i]);
if(indeces[i] < 0)
throw new NoSuchElementException("value " + b[i] + " not found in the first array.");
}
return removeIds(a,indeces);
}
public static int[] removeIds(int[] x, int[] ids) {
int [] res = new int[x.length-ids.length];
int j = 0;
for(int i = 0; i < x.length; ++i)
if(j == ids.length || i != ids[j]) res[i-j] = x[i]; else ++j;
return res;
}
public static double[] removeIds(double[] x, int[] ids) {
double [] res = new double[x.length-ids.length];
int j = 0;
for(int i = 0; i < x.length; ++i)
if(j == ids.length || i != ids[j]) res[i-j] = x[i]; else ++j;
return res;
}
public static boolean hasNzs(double[] x) {
if(x == null)
return false;
for(double d:x)
if(d != 0) return true;
return false;
}
public static int countNonzeros(double[] beta) {
int res = 0;
for(double d:beta)
if(d != 0)++res;
return res;
}
public static long[] subtract(long n, long[] nums) {
for (int i=0; i T[] remove( T[] ary, int id) {
if(id == ary.length-1) return Arrays.copyOf(ary,id);
if(id == 0) return Arrays.copyOfRange(ary,id,ary.length);
return append(Arrays.copyOf(ary,id), Arrays.copyOfRange(ary,id,ary.length));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy