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

water.util.ArrayUtils Maven / Gradle / Ivy

package water.util;

import water.MemoryManager;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.Random;

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[] 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;
  }

  // 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= 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) {
    if(n <= 0) return null;
    double[] result = new double[n];
    Random random = getRNG(seed);

    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;
  }

  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;
  }

  // sparse sortedMerge (ids and vals)
  public static void sortedMerge(int[] aIds, double [] aVals, int[] bIds, double [] bVals, int [] resIds, double [] resVals) {
    int i = 0, j = 0;
    for(int k = 0; k < resIds.length; ++k){
      if(i == aIds.length){
        System.arraycopy(bIds,j,resIds,k,resIds.length-k);
        System.arraycopy(bVals,j,resVals,k,resVals.length-k);
        j = bIds.length;
        break;
      }
      if(j == bIds.length) {
        System.arraycopy(aIds,i,resIds,k,resIds.length-k);
        System.arraycopy(aVals,i,resVals,k,resVals.length-k);
        i = aIds.length;
        break;
      }
      if(aIds[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;
  }

  /**
   * 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, 50);
  }
  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 void subtract (double [] a, double [] b, double [] c) {
    for(int i = 0; i < a.length; ++i)
      c[i] = a[i] - b[i];
  }

  /** 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 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;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy