package mikera.vectorz.util; import java.util.Arrays; import java.util.List; import mikera.util.Rand; import mikera.vectorz.Tools; public class IntArrays { public static final int[] EMPTY_INT_ARRAY=new int[0]; public static int[] of(int... ints) { return ints; } public static int[] create(Object o) { if (o instanceof List<?>) { return create((List<?>)o); } else if (o instanceof int[]) { return ((int[]) o).clone(); } else if (o instanceof double[]) { return create((double[]) o); } else if (o instanceof Iterable<?>) { return create(Tools.toList((Iterable<?>) o)); } throw new IllegalArgumentException("Can't convert to int[]: "+o); } public static int[] create(double[] ls) { int n=ls.length; int[] r=new int[n]; for (int i=0; i<n; i++) { r[i]=Tools.toInt(ls[i]); } return r; } public static int[] create(List<?> ls) { int n=ls.size(); int[] r=new int[n]; for (int i=0; i<n; i++) { r[i]=Tools.toInt(ls.get(i)); } return r; } public static int[] removeIndex(int[] data, int index) { int len=data.length; int[] result=new int[len-1]; System.arraycopy(data, 0, result, 0, index); System.arraycopy(data, index+1, result, index, len-index-1); return result; } public static int[] reverse(int[] data) { int n = data.length; int[] result=new int[n]; for (int i=0; i<n; i++) { result[n-1-i]=data[i]; } return result; } public static int[] consArray(int a, int[] as) { int len=as.length; int[] nas=new int[len+1]; nas[0]=a; System.arraycopy(as, 0, nas, 1, len); return nas; } public static int[] tailArray(int[] as) { int len=as.length-1; int[] nas=new int[len]; System.arraycopy(as, 1, nas, 0, len); return nas; } public static long[] copyIntsToLongs(int[] src, long[] dst) { for (int i=0; i<src.length; i++) { dst[i]=src[i]; } return dst; } public static double[] copyIntsToDoubles(int[] src, int srcOffset, double[] dst, int dstOffset, int length) { for (int i=0; i<length; i++) { dst[dstOffset+i]=src[srcOffset+i]; } return dst; } public static long[] copyIntsToLongs(int[] src) { long[] dst=new long[src.length]; return copyIntsToLongs(src,dst); } public static long arrayProduct(int[] vs) { long r=1; for (int x:vs) { r*=x; } return r; } public static long arrayProduct(int[] vs, int from, int to) { long r=1; for (int i=from; i<to; i++) { r*=vs[i]; } return r; } /** * Computes the standard packed array strides for a given shape. * @param shape * @return */ public static final int[] calcStrides(int[] shape) { int dimensions=shape.length; int[] stride=new int[dimensions]; int st=1; for (int j=dimensions-1; j>=0; j--) { stride[j]=st; st*=shape[j]; } return stride; } /** * Tests if two int array scontain equal values. * @param as * @param bs * @return */ public static boolean equals(int[] as, int[] bs) { if (as==bs) return true; int n=as.length; if (n!=bs.length) return false; for (int i=0; i<n; i++) { if (as[i]!=bs[i]) return false; } return true; } /** * Creates a randomised int[] array, each element in the range [0..max) * where max is the corresponding element in the shape array * * @param shape * @return */ public static int[] rand(int[] shape) { int n=shape.length; int[] result=new int[n]; for (int i=0; i<n; i++) { result[i]=Rand.r(shape[i]); } return result; } public static int[] rand(int[] shape, java.util.Random r) { int n=shape.length; int[] result=new int[n]; for (int i=0; i<n; i++) { result[i]=r.nextInt(shape[i]); } return result; } public static int dotProduct(int[] xs, int[] ys) { int result=0; int n=xs.length; if (ys.length!=n) throw new IllegalArgumentException("Different array sizes"); for (int i=0; i<n; i++) { result+=xs[i]*ys[i]; } return result; } /** * Finds the position of a value in a sorted index, or -1 if before the array. */ public static final int indexLookup(int[] data, int i) { if (i<data[0]) return -1; int min=0; int max=data.length-1; while (min<max) { int mid=(min+max+1)>>1; int mi=data[mid]; if (i==mi) return mid; if (i<mi) { max=mid-1; } else { min=mid; } } return min; } public static int indexPosition(int[] data, int x) { return indexPosition(data,x,0,data.length); } public static int indexPosition(int[] data, int x, int min, int max) { if ((max-min)>20) { return indexPositionBig(data,x,0,max); } else { return indexPositionSmall(data,x, 0, max); } } private static int indexPositionBig(int[] data, int x, int min, int max) { int lx=data[min]; int hx=data[max-1]; if (x<=lx) { if (x==lx) return min; return -1; } if (x>=hx) { if (x==hx) return max-1; return -1; } while ((min+10)<max) { int mid=min+((max-min)*(x-lx))/((hx-lx)*2); // best estimate of position int mx=data[mid]; if (x==mx) return mid; if (x<mx) { max=mid; hx=mx; } else { min=mid+1; lx=mx; } } return indexPositionSmall(data, x,min,max); } private static int indexPositionSmall(int[] data, int x, int min, int max) { while (min<max) { int mid=(min+max)>>1; // bisect interval int mx=data[mid]; if (x==mx) return mid; if (x<mx) { max=mid; } else { min=mid+1; } } return -1; } public static int[] decrementAll(int[] xs) { int len=xs.length; int[] rs=new int[len]; for (int i=0; i<len; i++) { rs[i]=xs[i]-1; } return rs; } public static int[] incrementAll(int[] xs) { int len=xs.length; int[] rs=new int[len]; for (int i=0; i<len; i++) { rs[i]=xs[i]+1; } return rs; } public static void swap(int[] inds, int a, int b) { int temp = inds[a]; inds[a] = inds[b]; inds[b] = temp; } public static final int[] copyOf(int[] data) { return Arrays.copyOf(data, data.length); } public static boolean isZero(int[] as) { for (int i=0; i<as.length; i++) { if (as[i]!=0) return false; } return true; } public static int[] insert(int[] data, int position, int value) { int len=data.length; int[] nas=new int[len+1]; System.arraycopy(data, 0, nas, 0, position); nas[position]=value; System.arraycopy(data, position, nas, position+1, len-position); return nas; } private static int countMatches(int[] xs, int[] ys) { int res=0; int xi=0; int yi=0; while ((xi<xs.length)&&(yi<ys.length)) { int x=xs[xi]; int y=ys[yi]; if (x==y) { res++; xi++; yi++; } else if (x<y) { xi++; } else { yi++; } } return res; } public static int[] mergeSorted(int[] xs, int[] ys) { int xl=xs.length; if (xl==0) return ys.clone(); int yl=ys.length; if (yl==0) return xs.clone(); int ms = countMatches(xs,ys); int[] rs=new int[xl+yl-ms]; int xi=0; int yi=0; for (int i=0; i<rs.length; i++) { int x=(xi<xl)?xs[xi]:Integer.MAX_VALUE; int y=(yi<yl)?ys[yi]:Integer.MAX_VALUE; if (x==y) { rs[i]=x; xi++; yi++; } else if (x<y) { rs[i]=x; xi++; } else { rs[i]=y; yi++; } } return rs; } public static int[] intersectSorted(int[] xs, int[] ys) { int xl=xs.length; if (xl==0) return EMPTY_INT_ARRAY; int yl=ys.length; if (yl==0) return EMPTY_INT_ARRAY; int ms = countMatches(xs,ys); int[] rs=new int[ms]; int xi=0; int yi=0; for (int i=0; i<rs.length; i++) { int x=xs[xi]; int y=ys[yi]; while (x!=y) { if (x<y) { xi++; x=xs[xi]; } else { yi++; y=ys[yi]; } } rs[i]=x; xi++; yi++; } return rs; } public static boolean validIndex(int[] as, int[] shape) { if (as.length!=shape.length) return false; for (int i=0; i<shape.length; i++) { int a=as[i]; if ((a<0)||(a>=shape[i])) return false; } return true; } public static int[] select(int[] source, int... inds) { int n=inds.length; int[] r=new int[n]; for (int i=0; i<n; i++) { r[i]=source[inds[i]]; } return r; } public static void add(int[] as, int v) { for (int i=0; i<as.length; i++) { as[i]+=v; } } }