private static void applyLhs( final float w1, final float[][][] wp, final float[][][] p2, final float[][][] p3, final float[][][] x, final float[][][] y) { final int n3 = x.length; Parallel.loop( 1, n3, 2, new Parallel.LoopInt() { // i3 = 1, 3, 5, ... public void compute(int i3) { applyLhsSlice3(i3, w1, wp, p2, p3, x, y); } }); Parallel.loop( 2, n3, 2, new Parallel.LoopInt() { // i3 = 2, 4, 6, ... public void compute(int i3) { applyLhsSlice3(i3, w1, wp, p2, p3, x, y); } }); }
public static void normalizeErrors( float[][][][] e, final float ignoreMin, final float ignoreMax) { 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 && ei > ignoreMin) emin = ei; if (ei > emax && ei < ignoreMax) 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); }
/** * Applies the shifts {@code u} to the trace {@code g}. * * @param sf the sampling that {@code g} is being warped to. * @param u the shifts to apply to {@code g}. * @param sg the sampling of {@code g}. * @param g the trace to be warped. * @return the warped image. */ public static float[][][] applyShifts( Sampling sf, final float[][][] u, Sampling sg, final float[][][] g) { final int n1 = u[0][0].length; final int n2 = u[0].length; final int n3 = u.length; final int ng = g[0][0].length; final double dg = sg.getDelta(); final double df = sf.getDelta(); final double fg = sg.getDelta(); final double ff = sf.getDelta(); final float[][][] hf = new float[n3][n2][n1]; final SincInterp si = new SincInterp(); int n23 = n3 * n2; Parallel.loop( n23, new Parallel.LoopInt() { public void compute(int i23) { int i2 = i23 % n2; int i3 = i23 / n2; double v = ff; for (int i1 = 0; i1 < n1; i1++, v = ff + i1 * df) { hf[i3][i2][i1] = si.interpolate(ng, dg, fg, g[i3][i2], (float) v + u[i3][i2][i1]); } } }); return hf; }
public float[][][][] flattenWithShifts( final Sampling s1, final float[][][] r, final float[][][] f) { cleanShifts(r); final int n3 = r.length; final int n2 = r[0].length; final int n1 = r[0][0].length; // Compute u1(x1,x2,x3). final double f1 = s1.getFirst(); final double d1 = s1.getDelta(); final float[][][] u1 = r; for (int i3 = 0; i3 < n3; ++i3) { for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { float x1i = (float) (f1 + i1 * d1); u1[i3][i2][i1] = (float) (x1i + r[i3][i2][i1] * d1); } } } // Compute x1(u1,u2). final float[][][] x1 = new float[n3][n2][n1]; final InverseInterpolator ii = new InverseInterpolator(s1, s1); Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) ii.invert(u1[i3][i2], x1[i3][i2]); } }); final SincInterpolator si = new SincInterpolator(); final float[][][] g = new float[n3][n2][n1]; Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) si.interpolate(n1, d1, f1, f[i3][i2], n1, x1[i3][i2], g[i3][i2]); } }); return new float[][][][] {g, u1}; }
private static void smooth2(final float sigma, final float[][][] s, final float[][][] x) { final int n3 = x.length; Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { float[][] s3 = (s != null) ? s[i3] : null; float[][] x3 = x[i3]; smooth2(sigma, s3, x3); } }); }
private void removeAverage(final float[][][] x) { final int n1 = x[0][0].length; Parallel.loop( 1, n1, 2, new Parallel.LoopInt() { // i1 = 1, 3, 5, ... public void compute(int i1) { removeAverage(i1, x); } }); Parallel.loop( 2, n1, 2, new Parallel.LoopInt() { // i1 = 2, 4, 6, ... public void compute(int i1) { removeAverage(i1, x); } }); }
/** * Gets mappings computed from specified slopes and planarities. * * @param s1 sampling of 1st dimension. * @param s2 sampling of 2nd dimension. * @param p2 array of slopes of image features. * @param ep array of planarities of image features. */ public Mappings getMappingsFromSlopes( Sampling s1, Sampling s2, Sampling s3, float[][][] p2, float[][][] p3, float[][][] ep) { // Sampling parameters. final int n1 = s1.getCount(); final int n2 = s2.getCount(); final int n3 = s3.getCount(); float d1 = (float) s1.getDelta(); float d2 = (float) s2.getDelta(); float d3 = (float) s3.getDelta(); float f1 = (float) s1.getFirst(); // If necessary, convert units for slopes to samples per sample. if (d1 != d2) p2 = mul(d2 / d1, p2); if (d1 != d3) p3 = mul(d3 / d1, p3); // Compute shifts r(x1,x2,x3), in samples. float[][][] b = new float[n3][n2][n1]; // right-hand side float[][][] r = new float[n3][n2][n1]; // shifts, in samples VecArrayFloat3 vb = new VecArrayFloat3(b); VecArrayFloat3 vr = new VecArrayFloat3(r); Smoother3 smoother3 = new Smoother3(n1, n2, n3, _sigma1, _sigma2, _sigma3, ep); A3 a3 = new A3(smoother3, _weight1, ep, p2, p3); CgSolver cs = new CgSolver(_small, _niter); makeRhs(ep, p2, p3, b); smoother3.applyTranspose(b); cs.solve(a3, vb, vr); smoother3.apply(r); cleanShifts(r); // Compute u1(x1,x2,x3). final float[][][] u1 = r; for (int i3 = 0; i3 < n3; ++i3) { for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { float x1i = f1 + i1 * d1; u1[i3][i2][i1] = x1i + r[i3][i2][i1] * d1; } } } // Compute x1(u1,u2). final float[][][] x1 = b; final InverseInterpolator ii = new InverseInterpolator(s1, s1); Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) ii.invert(u1[i3][i2], x1[i3][i2]); } }); return new Mappings(s1, s2, s3, u1, x1); }
public static float[][] compositeShifts( final Sampling sf, final float[][] u1, final float[][] u2) { int n2 = u1.length; final float[][] uc = new float[n2][]; Parallel.loop( n2, new Parallel.LoopInt() { public void compute(int i2) { uc[i2] = compositeShifts(sf, u1[i2], u2[i2]); } }); return uc; }
@Deprecated public static float[][][] transposeLag23(final float[][][] e) { final int nl = e[0][0].length; final int n1 = e[0].length; final int n2 = e.length; final float[][][] t = new float[n1][n2][nl]; Parallel.loop( n1, new Parallel.LoopInt() { public void compute(int i1) { for (int i2 = 0; i2 < n2; ++i2) t[i1][i2] = e[i2][i1]; } }); return t; }
@Deprecated public static float[][][] transposeLag12(final float[][][] e) { final int nl = e[0][0].length; final int n1 = e[0].length; final int n2 = e.length; final float[][][] t = new float[n2][nl][n1]; Parallel.loop( n2, new Parallel.LoopInt() { public void compute(int i2) { for (int il = 0; il < nl; ++il) for (int i1 = 0; i1 < n1; ++i1) t[i2][il][i1] = e[i2][i1][il]; } }); return t; }
// Smoothing for dimension 3. private static void smooth3(final float sigma, final float[][][] s, final float[][][] x) { final int n2 = x[0].length; final int n3 = x.length; Parallel.loop( n2, new Parallel.LoopInt() { public void compute(int i2) { float[][] s2 = (s != null) ? new float[n3][] : null; float[][] x2 = new float[n3][]; for (int i3 = 0; i3 < n3; ++i3) { if (s != null) s2[i3] = s[i3][i2]; x2[i3] = x[i3][i2]; } smooth2(sigma, s2, x2); } }); }
private float[][][] apply(final float[][][] ux, final float[][][] f) { final int n1 = s1.getCount(); final int n2 = s2.getCount(); final int n3 = s3.getCount(); final double d1 = s1.getDelta(); final double f1 = s1.getFirst(); final SincInterpolator si = new SincInterpolator(); final float[][][] g = new float[n3][n2][n1]; Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) si.interpolate(n1, d1, f1, f[i3][i2], n1, ux[i3][i2], g[i3][i2]); } }); return g; }
public static void normalize(float[][] f, final float nmin, final float nmax) { final int n1 = f[0].length; final int n2 = f.length; final float[][] ff = f; final float vmin = min(f); final float vmax = max(f); final float range = vmax - vmin; final float nrange = nmax - nmin; Parallel.loop( n2, new Parallel.LoopInt() { public void compute(int i2) { for (int i1 = 0; i1 < n1; ++i1) { float vi = ff[i2][i1]; ff[i2][i1] = nrange * (vi - vmin) / range + nmin; } } }); }
/** * Computes the NRMS value of the warped PS trace {@code h} and the PP trace {@code f}. The NRMS * value is the RMS of the difference between {@code f} and {@code h} divided by the average RMS * of {@code f} and {@code h}. * * @param n1Max the length of {@code f} and {@code h} to use for this computation. * @param f the PP traces. * @param h the warped PS traces. * @return the NRMS value, this measure is between 0.0 and 2.0. */ public static float computeNrms(final int n1Max, final float[][][] f, final float[][][] h) { int n1f = f[0][0].length; int n1h = h[0][0].length; Check.argument(n1Max <= n1f, "n1Max<=n1f"); Check.argument(n1Max <= n1h, "n1Max<=n1h"); final int n3 = f.length; final int n2 = f[0].length; final int n23 = n2 * n3; float scale = 1.0f / (n1Max * n23); float[] rms = Parallel.reduce( n23, new Parallel.ReduceInt<float[]>() { @Override public float[] compute(int i23) { int i2 = i23 % n2; int i3 = i23 / n2; float[] fhdSq = new float[3]; for (int i1 = 0; i1 < n1Max; i1++) { float fv = f[i3][i2][i1]; float hv = h[i3][i2][i1]; fhdSq[0] += fv * fv; fhdSq[1] += hv * hv; fhdSq[2] += (hv - fv) * (hv - fv); } return fhdSq; } @Override public float[] combine(float[] fhdSq1, float[] fhdSq2) { float[] rms = new float[3]; rms[0] = fhdSq1[0] + fhdSq2[0]; rms[1] = fhdSq1[1] + fhdSq2[1]; rms[2] = fhdSq1[2] + fhdSq2[2]; return rms; } }); float frms = sqrt(rms[0] * scale); float hrms = sqrt(rms[1] * scale); float drms = sqrt(rms[2] * scale); float nrms = (2.0f * drms) / (frms + hrms); return nrms; }
/** * Shifts and scales alignment errors to be in range [0,1]. * * @param emin minimum alignment error before normalizing. * @param emax maximum alignment error before normalizing. * @param e input/output array of alignment errors. */ private static void shiftAndScale(float emin, float emax, float[][][] e) { // System.out.println("shiftAndScale: emin="+emin+" emax="+emax); final int nl = e[0][0].length; final int n1 = e[0].length; final int n2 = e.length; final float eshift = emin; final float escale = (emax > emin) ? 1.0f / (emax - emin) : 1.0f; final float[][][] ef = e; Parallel.loop( n2, new Parallel.LoopInt() { public void compute(int i2) { for (int i1 = 0; i1 < n1; ++i1) { for (int il = 0; il < nl; ++il) { ef[i2][i1][il] = (ef[i2][i1][il] - eshift) * escale; } } } }); }
public float[][][] findScreenPoints( final float smin, final float[][][] ss, final float[][][] u1, final float[][][] u2, final float[][][] u3) { final int n3 = ss.length; final int n2 = ss[0].length; final int n1 = ss[0][0].length; final Sampling s1 = new Sampling(n1); final Sampling s2 = new Sampling(n2); final Sampling s3 = new Sampling(n3); final float[][][] mk = new float[n3][n2][n1]; final SincInterpolator si = new SincInterpolator(); si.setExtrapolation(SincInterpolator.Extrapolation.CONSTANT); Parallel.loop( 1, n3 - 1, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 1; i2 < n2 - 1; ++i2) { for (int i1 = 1; i1 < n1 - 1; ++i1) { float sxi = ss[i3][i2][i1]; float u1i = u1[i3][i2][i1] * 2f; float u2i = u2[i3][i2][i1] * 2f; float u3i = u3[i3][i2][i1] * 2f; float x1m = i1 - u1i; float x2m = i2 - u2i; float x3m = i3 - u3i; float x1p = i1 + u1i; float x2p = i2 + u2i; float x3p = i3 + u3i; float sxm = si.interpolate(s1, s2, s3, ss, x1m, x2m, x3m); float sxp = si.interpolate(s1, s2, s3, ss, x1p, x2p, x3p); if (sxi > sxm && sxi > sxp && sxi > smin) mk[i3][i2][i1] = sxi; } } } }); return mk; }
public float[][][] scalarField(final int n1, final int n2, final int n3, FaultCell[] fc) { final int d2 = 10; final int d3 = 10; final int d1 = 20; final float v = -1.f; float sigmaNor = 4.0f; float sigmaPhi = 6.0f; float sigmaTheta = 20.0f; final float sw = 1.0f / (sigmaNor * sigmaNor); final float sv = 1.0f / (sigmaPhi * sigmaPhi); final float su = 1.0f / (sigmaTheta * sigmaTheta); int nc = fc.length; final float[] wp = new float[nc]; final float[][] xf = new float[3][nc]; final float[][] xs = new float[nc][6]; final float[][] ws = new float[nc][6]; final float[][] us = new float[nc][6]; final float[][] vs = new float[nc][6]; setKdTreePoints(fc, xf, xs, ws, us, vs, wp); final int[] bs1 = setBounds(n1, xf[0]); final int[] bs2 = setBounds(n2, xf[1]); final int[] bs3 = setBounds(n3, xf[2]); final KdTree kt = new KdTree(xf); final float[][][] sf = fillfloat(v, n1, n2, n3); Parallel.loop( bs3[0], bs3[1], 1, new Parallel.LoopInt() { public void compute(int i3) { float[] xmin = new float[3]; float[] xmax = new float[3]; System.out.println("i3=" + i3); for (int i2 = bs2[0]; i2 < bs2[1]; ++i2) { for (int i1 = bs1[0]; i1 < bs1[1]; ++i1) { float[] y = new float[] {i1, i2, i3}; int ne = kt.findNearest(y); float x1 = xf[0][ne]; float x2 = xf[1][ne]; float x3 = xf[2][ne]; float dd = distance(new float[] {x1, x2, x3}, y); if (dd > 16.0f) { continue; } getRange(d1, d2, d3, i1, i2, i3, n1, n2, n3, xmin, xmax); int[] id = kt.findInRange(xmin, xmax); int nd = id.length; if (nd < 50) { continue; } sf[i3][i2][i1] = 0.0f; float wps = 0.0f; for (int ik = 0; ik < nd; ++ik) { int ip = id[ik]; float wpi = pow(wp[ip], 8.0f); float w1s = ws[ip][0]; float w2s = ws[ip][1]; float w3s = ws[ip][2]; float w12 = ws[ip][3]; float w13 = ws[ip][4]; float w23 = ws[ip][5]; float u1s = us[ip][0]; float u2s = us[ip][1]; float u3s = us[ip][2]; float u12 = us[ip][3]; float u13 = us[ip][4]; float u23 = us[ip][5]; float v1s = vs[ip][0]; float v2s = vs[ip][1]; float v3s = vs[ip][2]; float v12 = vs[ip][3]; float v13 = vs[ip][4]; float v23 = vs[ip][5]; float x1m = i1 - xs[ip][0]; float x2m = i2 - xs[ip][1]; float x3m = i3 - xs[ip][2]; float x1p = i1 - xs[ip][3]; float x2p = i2 - xs[ip][4]; float x3p = i3 - xs[ip][5]; float x1sm = x1m * x1m; float x2sm = x2m * x2m; float x3sm = x3m * x3m; float x12m = x1m * x2m; float x13m = x1m * x3m; float x23m = x2m * x3m; float x1sp = x1p * x1p; float x2sp = x2p * x2p; float x3sp = x3p * x3p; float x12p = x1p * x2p; float x13p = x1p * x3p; float x23p = x2p * x3p; float g11m = w1s * x1sm + w12 * x12m + w13 * x13m; float g12m = u1s * x1sm + u12 * x12m + u13 * x13m; float g13m = v1s * x1sm + v12 * x12m + v13 * x13m; float g21m = w12 * x12m + w2s * x2sm + w23 * x23m; float g22m = u12 * x12m + u2s * x2sm + u23 * x23m; float g23m = v12 * x12m + v2s * x2sm + v23 * x23m; float g31m = w13 * x13m + w23 * x23m + w3s * x3sm; float g32m = u13 * x13m + u23 * x23m + u3s * x3sm; float g33m = v13 * x13m + v23 * x23m + v3s * x3sm; float g11p = w1s * x1sp + w12 * x12p + w13 * x13p; float g12p = u1s * x1sp + u12 * x12p + u13 * x13p; float g13p = v1s * x1sp + v12 * x12p + v13 * x13p; float g21p = w12 * x12p + w2s * x2sp + w23 * x23p; float g22p = u12 * x12p + u2s * x2sp + u23 * x23p; float g23p = v12 * x12p + v2s * x2sp + v23 * x23p; float g31p = w13 * x13p + w23 * x23p + w3s * x3sp; float g32p = u13 * x13p + u23 * x23p + u3s * x3sp; float g33p = v13 * x13p + v23 * x23p + v3s * x3sp; float gssm = (g11m + g21m + g31m) * sw + (g12m + g22m + g32m) * su + (g13m + g23m + g33m) * sv; float gssp = (g11p + g21p + g31p) * sw + (g12p + g22p + g32p) * su + (g13p + g23p + g33p) * sv; sf[i3][i2][i1] += (exp(-gssp) - exp(-gssm)) * wpi; wps += wpi; } sf[i3][i2][i1] /= wps; } } } }); return sf; }
public float[][][] scalarFieldM( final int n1, final int n2, final int n3, final FaultCell[] fc, final float[][][] fp, final float[][][] ft) { final int d2 = 10; final int d3 = 10; final int d1 = 10; // final float v = -1.f; final float v = 0.0f; float sigmaNor = 4.0f; float sigmaPhi = 10.0f; float sigmaTheta = 20.0f; final float sw = 1.0f / (sigmaNor * sigmaNor); final float sv = 1.0f / (sigmaPhi * sigmaPhi); final float su = 1.0f / (sigmaTheta * sigmaTheta); int nc = fc.length; final float[] wp = new float[nc]; final float[][] xf = new float[3][nc]; final float[][] xs = new float[nc][3]; final float[][] ws = new float[nc][6]; final float[][] us = new float[nc][6]; final float[][] vs = new float[nc][6]; setKdTreePointsM(fc, xf, xs, ws, us, vs, wp); final int[] bs1 = setBounds(n1, xf[0]); final int[] bs2 = setBounds(n2, xf[1]); final int[] bs3 = setBounds(n3, xf[2]); final KdTree kt = new KdTree(xf); final float[][][] sf = fillfloat(v, n1, n2, n3); final float[][][] fpp = copy(fp); final float[][][] ftp = copy(ft); Parallel.loop( bs3[0], bs3[1], 1, new Parallel.LoopInt() { public void compute(int i3) { float[] xmin = new float[3]; float[] xmax = new float[3]; System.out.println("i3=" + i3); for (int i2 = bs2[0]; i2 < bs2[1]; ++i2) { for (int i1 = bs1[0]; i1 < bs1[1]; ++i1) { float[] y = new float[] {i1, i2, i3}; int ne = kt.findNearest(y); float x1 = xf[0][ne]; float x2 = xf[1][ne]; float x3 = xf[2][ne]; float dd = distance(new float[] {x1, x2, x3}, y); if (dd > 50.0f) { continue; } getRange(d1, d2, d3, i1, i2, i3, n1, n2, n3, xmin, xmax); int[] id = kt.findInRange(xmin, xmax); int nd = id.length; if (nd < 1) { continue; } sf[i3][i2][i1] = 0.0f; float wps = 0.0f; float fpa = 0.0f; float fta = 0.0f; float fps = 0.0f; float fts = 0.0f; for (int ik = 0; ik < nd; ++ik) { int ip = id[ik]; float wpi = pow(wp[ip], 8.0f); float w1s = ws[ip][0]; float w2s = ws[ip][1]; float w3s = ws[ip][2]; float w12 = ws[ip][3]; float w13 = ws[ip][4]; float w23 = ws[ip][5]; float u1s = us[ip][0]; float u2s = us[ip][1]; float u3s = us[ip][2]; float u12 = us[ip][3]; float u13 = us[ip][4]; float u23 = us[ip][5]; float v1s = vs[ip][0]; float v2s = vs[ip][1]; float v3s = vs[ip][2]; float v12 = vs[ip][3]; float v13 = vs[ip][4]; float v23 = vs[ip][5]; float dx1 = i1 - xs[ip][0]; float dx2 = i2 - xs[ip][1]; float dx3 = i3 - xs[ip][2]; float d11 = dx1 * dx1; float d12 = dx1 * dx2; float d13 = dx1 * dx3; float d22 = dx2 * dx2; float d23 = dx2 * dx3; float d33 = dx3 * dx3; float g11 = w1s * d11 + w12 * d12 + w13 * d13; float g12 = u1s * d11 + u12 * d12 + u13 * d13; float g13 = v1s * d11 + v12 * d12 + v13 * d13; float g21 = w12 * d12 + w2s * d22 + w23 * d23; float g22 = u12 * d12 + u2s * d22 + u23 * d23; float g23 = v12 * d12 + v2s * d22 + v23 * d23; float g31 = w13 * d13 + w23 * d23 + w3s * d33; float g32 = u13 * d13 + u23 * d23 + u3s * d33; float g33 = v13 * d13 + v23 * d23 + v3s * d33; float gss = 0.0f; gss += (g11 + g21 + g31) * sw; gss += (g12 + g22 + g32) * su; gss += (g13 + g23 + g33) * sv; float sfi = exp(-gss) * wpi; sf[i3][i2][i1] += sfi; int j1 = fc[ip].i1; int j2 = fc[ip].i2; int j3 = fc[ip].i3; int k1 = fc[ne].i1; int k2 = fc[ne].i2; int k3 = fc[ne].i3; float fpr = fpp[k3][k2][k1]; float fpi = fpp[j3][j2][j1]; if (abs(fpr - fpi) <= 30) { fps += sfi; fpa += fpp[j3][j2][j1] * sfi; } fts += sfi; fta += ftp[j3][j2][j1] * sfi; wps += wpi; } ft[i3][i2][i1] = fta / fts; fp[i3][i2][i1] = fpa / fps; sf[i3][i2][i1] /= wps; } } } }); return sf; }