All Downloads are FREE. Search and download functionalities are using the official Maven repository.

water.util.ArrayUtils Maven / Gradle / Ivy

There is a newer version: 3.8.2.9
Show newest version
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