/** * Performs a reduce <code>for (int i=begin; i<end; ++i)</code>. * @param begin the begin index for the loop; must be less than end. * @param end the end index (not included) for the loop. * @param body the loop body. * @return the computed value. */ public static <V> V reduce(int begin, int end, ReduceInt<V> body) { return reduce(begin,end,1,1,body); }
/** * Performs a reduce <code>for (int i=0; i<end; ++i)</code>. * @param end the end index (not included) for the loop. * @param body the loop body. * @return the computed value. */ public static <V> V reduce(int end, ReduceInt<V> body) { return reduce(0,end,1,1,body); }
/** * Performs a reduce <code>for (int i=begin; i<end; i+=step)</code>. * @param begin the begin index for the loop; must be less than end. * @param end the end index (not included) for the loop. * @param step the index increment; must be positive. * @param body the loop body. * @return the computed value. */ public static <V> V reduce( int begin, int end, int step, ReduceInt<V> body) { return reduce(begin,end,step,1,body); }
private static float sumP(final float[][][] a) { int n = a.length; return reduce(n,new ReduceInt<Float>() { public Float compute(int i) { return sumP(a[i]); // nested parallelism } public Float combine(Float s1, Float s2) { return s1+s2; } }); }
private float sumP(int begin, int end, int step, int chunk, final float[] a) { //trace("begin="+begin+" end="+end+" step="+step+" chunk="+chunk); return reduce(begin,end,step,chunk,new ReduceInt<Float>() { public Float compute(int i) { return a[i]; } public Float combine(Float s1, Float s2) { return s1+s2; } }); }
/** * Returns normalized 1D alignment errors for 2D images. * The number of lags nl = 1+shiftMax-shiftMin. Lag indices * il = 0, 1, 2, ..., nl-1 correspond to integer shifts in * [shiftMin,shiftMax]. * @param f array[n2][n1] for the image f[i2][i1]. * @param g array[n2][n1] for the image g[i2][i1]. * @return array[n1][nl] of alignment errors. */ public float[][] computeErrors1(float[][] f, float[][] g) { final float[][] ff = f; final float[][] gf = g; final int nl = 1+_lmax-_lmin; final int n1 = f[0].length; final int n2 = f.length; float[][] e = Parallel.reduce(n2,new Parallel.ReduceInt<float[][]>() { public float[][] compute(int i2) { float[][] e = new float[n1][nl]; computeErrors(ff[i2],gf[i2],e); return e; } public float[][] combine(float[][] ea, float[][] eb) { return add(ea,eb); }}); normalizeErrors(e); return e; }
/** * Normalizes alignment errors to be in range [0,1]. * @param e input/output array of alignment errors. */ public static void normalizeErrors(float[][][] e) { final float[][][] ef = e; int n2 = e.length; MinMax mm = Parallel.reduce(n2,new Parallel.ReduceInt<MinMax>() { public MinMax compute(int i2) { int nl = ef[i2][0].length; int n1 = ef[i2].length; float emin = Float.MAX_VALUE; float emax = -Float.MAX_VALUE; for (int i1=0; i1<n1; ++i1) { for (int il=0; il<nl; ++il) { float ei = ef[i2][i1][il]; if (ei<emin) emin = ei; if (ei>emax) emax = ei; } } return new MinMax(emin,emax); } public MinMax combine(MinMax mm1, MinMax mm2) { return new MinMax(min(mm1.emin,mm2.emin),max(mm1.emax,mm2.emax)); }}); shiftAndScale(mm.emin,mm.emax,e); }
private static void normalizeErrors(float[][][][] e) { final int nl = e[0][0][0].length; final int n1 = e[0][0].length; final int n2 = e[0].length; final int n3 = e.length; final float[][][][] ef = e; MinMax mm = Parallel.reduce(n3,new Parallel.ReduceInt<MinMax>() { public MinMax compute(int i3) { float emin = Float.MAX_VALUE; float emax = -Float.MAX_VALUE; for (int i2=0; i2<n2; ++i2) { for (int i1=0; i1<n1; ++i1) { for (int il=0; il<nl; ++il) { float ei = ef[i3][i2][i1][il]; if (ei<emin) emin = ei; if (ei>emax) emax = ei; } } } return new MinMax(emin,emax); } public MinMax combine(MinMax mm1, MinMax mm2) { return new MinMax(min(mm1.emin,mm2.emin),max(mm1.emax,mm2.emax)); }}); shiftAndScale(mm.emin,mm.emax,e); } private static void shiftAndScale(float emin, float emax, float[][][][] e) {
/** * Returns normalized 1D alignment errors for 3D images. * The number of lags nl = 1+shiftMax-shiftMin. Lag indices * il = 0, 1, 2, ..., nl-1 correspond to integer shifts in * [shiftMin,shiftMax]. * @param f array[n3][n2][n1] for the image f[i3][i2][i1]. * @param g array[n3][n2][n1] for the image g[i3][i2][i1]. * @return array[n1][nl] of alignment errors. */ public float[][] computeErrors1(float[][][] f, float[][][] g) { final float[][][] ff = f; final float[][][] gf = g; final int nl = 1+_lmax-_lmin; final int n1 = f[0][0].length; final int n2 = f[0].length; final int n3 = f.length; float[][] e = Parallel.reduce(n2*n3,new Parallel.ReduceInt<float[][]>() { public float[][] compute(int i23) { int i2 = i23%n2; int i3 = i23/n2; float[][] e = new float[n1][nl]; computeErrors(ff[i3][i2],gf[i3][i2],e); return e; } public float[][] combine(float[][] ea, float[][] eb) { return add(ea,eb); }}); normalizeErrors(e); return e; }
private static float sumP(final float[][] a) { int n = a.length; int chunk = max(1,10000/a[0].length); return reduce(0,n,1,chunk,new ReduceInt<Float>() { public Float compute(int i) { return sum(a[i]); } public Float combine(Float s1, Float s2) { return s1+s2; } }); } private static float sumP(final float[][][] a) {