public void model( final SLCImage master, final SLCImage slave, Orbit masterOrbit, Orbit slaveOrbit) throws Exception { if (!masterOrbit.isInterpolated()) { logger.debug("Baseline cannot be computed, master orbit not initialized."); throw new Exception("Baseline.model_parameters: master orbit not initialized"); } else if (!slaveOrbit.isInterpolated()) { logger.debug("Baseline cannot be computed, slave orbit not initialized."); throw new Exception("Baseline.model_parameters: slave orbit not initialized"); } if (isInitialized) { logger.warn("baseline already isInitialized??? (returning)"); return; } masterWavelength = master.getRadarWavelength(); // Model r = nearRange + drange_dp*p -- p starts at 1 nearRange = master.pix2range(1.0); drange_dp = master.pix2range(2.0) - master.pix2range(1.0); nearRange -= drange_dp; // -- p starts at 1 // Set min/maxima for normalization linMin = master.currentWindow.linelo; // also used during polyval... linMax = master.currentWindow.linehi; pixMin = master.currentWindow.pixlo; pixMax = master.currentWindow.pixhi; hMin = 0.0; hMax = 5000.0; // Loop counters and sampling int cnt = 0; // matrix index final double deltaPixels = master.currentWindow.pixels() / N_POINTS_RNG; final double deltaLines = master.currentWindow.lines() / N_POINTS_AZI; final double deltaHeight = (hMax - hMin) / N_HEIGHTS; // Declare matrices for modeling Bperp // Note: for stability of normalmatrix, fill aMatrix with normalized line, etc. // perpendicular baseline DoubleMatrix bPerpMatrix = new DoubleMatrix(N_POINTS_AZI * N_POINTS_RNG * N_HEIGHTS, 1); // parallel baseline DoubleMatrix bParMatrix = new DoubleMatrix(N_POINTS_AZI * N_POINTS_RNG * N_HEIGHTS, 1); // viewing angle DoubleMatrix thetaMatrix = new DoubleMatrix(N_POINTS_AZI * N_POINTS_RNG * N_HEIGHTS, 1); // incidence angle DoubleMatrix thetaIncMatrix = new DoubleMatrix(N_POINTS_AZI * N_POINTS_RNG * N_HEIGHTS, 1); // design matrix DoubleMatrix aMatrix = new DoubleMatrix(N_POINTS_AZI * N_POINTS_RNG * N_HEIGHTS, numCoeffs); // Loop over heights(k), lines(i), pixels(j) to estimate baseline // height levels for (long k = 0; k < N_HEIGHTS; ++k) { final double height = hMin + k * deltaHeight; // azimuth direction for (long i = 0; i < N_POINTS_AZI; ++i) { final double line = master.currentWindow.linelo + i * deltaLines; Point pointOnEllips; // point, returned by lp2xyz double sTazi, sTrange; // Azimuth time for this line final double mTazi = master.line2ta(line); // xyz for master satellite from time final Point pointOnMasterOrb = masterOrbit.getXYZ(mTazi); // Continue looping in range direction for (long j = 0; j < N_POINTS_RNG; ++j) { final double pixel = master.currentWindow.pixlo + j * deltaPixels; // ______ Range time for this pixel ______ // final double m_trange = master.pix2tr(pixel); pointOnEllips = masterOrbit.lph2xyz(line, pixel, height, master); // Compute xyz for slave satellite from pointOnEllips Point pointTime = slaveOrbit.xyz2t(pointOnEllips, slave); sTazi = pointTime.y; sTrange = pointTime.x; // Slave position final Point pointOnSlaveOrb = slaveOrbit.getXYZ(sTazi); // Compute angle between near parallel orbits final Point velOnMasterOrb = masterOrbit.getXYZDot(mTazi); final Point velOnSlaveOrb = slaveOrbit.getXYZDot(sTazi); final double angleOrbits = velOnMasterOrb.angle(velOnSlaveOrb); logger.debug( "Angle between orbits master-slave (at l,p= " + line + "," + pixel + ") = " + rad2deg(angleOrbits) + " [deg]"); // Note: convergence assumed constant! orbitConvergence = angleOrbits; // final heading = angle(velOnMasterOrb,[1 0 0]) //? // orbitHeading = 0.0; // not yet used // The baseline parameters, derived from the positions (x,y,z) // alpha is angle counterclockwize(b, plane with normal=rho1=rho2) // theta is angle counterclockwize(rho1 = pointOnMasterOrb, r1 = pointOnMasterOrb - // pointOnEllips, r2 = pointOnSlaveOrb - pointOnEllips) // construct helper class BaselineComponents baselineComponents = new BaselineComponents().invoke(); compute_B_Bpar_Bperp_Theta( baselineComponents, pointOnEllips, pointOnMasterOrb, pointOnSlaveOrb); final double b = baselineComponents.getB(); final double bPar = baselineComponents.getBpar(); final double bPerp = baselineComponents.getBperp(); final double theta = baselineComponents.getTheta(); final double thetaInc = computeIncAngle(pointOnMasterOrb, pointOnEllips); // [rad]!!! // Modelling of bPerp(l,p) = a00 + a10*l + a01*p bPerpMatrix.put(cnt, 0, bPerp); bParMatrix.put(cnt, 0, bPar); thetaMatrix.put(cnt, 0, theta); thetaIncMatrix.put(cnt, 0, thetaInc); // --- b(l,p,h) = a000 + // a100*l + a010*p + a001*h + // a110*l*p + a101*l*h + a011*p*h + // a200*l^2 + a020*p^2 + a002*h^2 aMatrix.put(cnt, 0, 1.0); aMatrix.put(cnt, 1, normalize2(line, linMin, linMax)); aMatrix.put(cnt, 2, normalize2(pixel, pixMin, pixMax)); aMatrix.put(cnt, 3, normalize2(height, hMin, hMax)); aMatrix.put(cnt, 4, normalize2(line, linMin, linMax) * normalize2(pixel, pixMin, pixMax)); aMatrix.put(cnt, 5, normalize2(line, linMin, linMax) * normalize2(height, hMin, hMax)); aMatrix.put(cnt, 6, normalize2(pixel, pixMin, pixMax) * normalize2(height, hMin, hMax)); aMatrix.put(cnt, 7, sqr(normalize2(line, linMin, linMax))); aMatrix.put(cnt, 8, sqr(normalize2(pixel, pixMin, pixMax))); aMatrix.put(cnt, 9, sqr(normalize2(height, hMin, hMax))); cnt++; // b/alpha representation of baseline final double alpha = (bPar == 0 && bPerp == 0) ? Double.NaN : theta - Math.atan2(bPar, bPerp); // sign ok atan2 // horizontal/vertical representation of baseline final double bH = b * Math.cos(alpha); // sign ok final double bV = b * Math.sin(alpha); // sign ok // TODO: check sign of infinity!!! // Height ambiguity: [h] = -lambda/4pi * (r1sin(theta)/bPerp) * phi==2pi final double hAmbiguity = (bPerp == 0) ? Double.POSITIVE_INFINITY : -master.getRadarWavelength() * (pointOnMasterOrb.min(pointOnEllips)).norm() * Math.sin(theta) / (2.0 * bPerp); // Some extra info if in DEBUG unwrapMode logger.debug( "The baseline parameters for (l,p,h) = " + line + ", " + pixel + ", " + height); logger.debug("\talpha (deg), BASELINE: \t" + rad2deg(alpha) + " \t" + b); logger.debug("\tbPar, bPerp: \t" + bPar + " \t" + bPerp); logger.debug("\tbH, bV: \t" + bH + " \t" + bV); logger.debug("\tHeight ambiguity: \t" + hAmbiguity); logger.debug("\ttheta (deg): \t" + rad2deg(theta)); logger.debug("\tthetaInc (deg): \t" + rad2deg(thetaInc)); logger.debug("\tpointOnMasterOrb (x,y,z) = " + pointOnMasterOrb.toString()); logger.debug("\tpointOnSlaveOrb (x,y,z) = " + pointOnSlaveOrb.toString()); logger.debug("\tpointOnEllips (x,y,z) = " + pointOnEllips.toString()); } // loop pixels } // loop lines } // loop heights // Model all Baselines as 2d polynomial of degree 1 DoubleMatrix nMatrix = matTxmat(aMatrix, aMatrix); DoubleMatrix rhsBperp = matTxmat(aMatrix, bPerpMatrix); DoubleMatrix rhsBpar = matTxmat(aMatrix, bParMatrix); DoubleMatrix rhsTheta = matTxmat(aMatrix, thetaMatrix); DoubleMatrix rhsThetaInc = matTxmat(aMatrix, thetaIncMatrix); // DoubleMatrix Qx_hat = nMatrix; final DoubleMatrix Qx_hat = LinearAlgebraUtils.invertChol(Decompose.cholesky(nMatrix).transpose()); // TODO: refactor to _internal_ cholesky decomposition // choles(Qx_hat); // Cholesky factorisation normalmatrix // solvechol(Qx_hat,rhsBperp); // Solution Bperp coefficients in rhsB // solvechol(Qx_hat,rhsBpar); // Solution Theta coefficients in rhsTheta // solvechol(Qx_hat,rhsTheta); // Solution Theta coefficients in rhsTheta // solvechol(Qx_hat,rhsThetaInc); // Solution Theta_inc coefficients in rhsThetaInc // invertchol(Qx_hat); // Covariance matrix of normalized unknowns rhsBperp = Solve.solvePositive(nMatrix, rhsBperp); rhsBpar = Solve.solvePositive(nMatrix, rhsBpar); rhsTheta = Solve.solvePositive(nMatrix, rhsTheta); rhsThetaInc = Solve.solvePositive(nMatrix, rhsThetaInc); // Info on inversion, normalization is ok______ final DoubleMatrix yHatBperp = aMatrix.mmul(rhsBperp); final DoubleMatrix eHatBperp = bPerpMatrix.sub(yHatBperp); // DoubleMatrix Qe_hat = Qy - Qy_hat; // DoubleMatrix y_hatT = aMatrix * rhsTheta; // DoubleMatrix e_hatT = thetaMatrix - y_hatT; // Copy estimated coefficients to private fields bperpCoeffs = rhsBperp; bparCoeffs = rhsBpar; thetaCoeffs = rhsTheta; thetaIncCoeffs = rhsThetaInc; // Test inverse -- repair matrix!!! for (int i = 0; i < Qx_hat.rows; i++) { for (int j = 0; j < i; j++) { Qx_hat.put(j, i, Qx_hat.get(i, j)); } } final double maxDev = abs(nMatrix.mmul(Qx_hat).sub(DoubleMatrix.eye(Qx_hat.rows))).max(); logger.debug("BASELINE: max(abs(nMatrix*inv(nMatrix)-I)) = " + maxDev); if (maxDev > .01) { logger.warn( "BASELINE: max. deviation nMatrix*inv(nMatrix) from unity = " + maxDev + ". This is larger than .01: do not use this!"); } else if (maxDev > .001) { logger.warn( "BASELINE: max. deviation nMatrix*inv(nMatrix) from unity = " + maxDev + ". This is between 0.01 and 0.001 (maybe not use it)"); } // Output solution and give max error // --- B(l,p,h) = a000 + // a100*l + a010*p + a001*h + // a110*l*p + a101*l*h + a011*p*h + // a200*l^2 + a020*p^2 + a002*h^2 logger.debug("--------------------"); logger.debug("Result of modeling: Bperp(l,p) = a000 + a100*l + a010*p + a001*h + "); logger.debug(" a110*l*p + a101*l*h + a011*p*h + a200*l^2 + a020*p^2 + a002*h^2"); logger.debug("l,p,h in normalized coordinates [-2:2]."); logger.debug("Bperp_a000 = " + rhsBperp.get(0, 0)); logger.debug("Bperp_a100 = " + rhsBperp.get(1, 0)); logger.debug("Bperp_a010 = " + rhsBperp.get(2, 0)); logger.debug("Bperp_a001 = " + rhsBperp.get(3, 0)); logger.debug("Bperp_a110 = " + rhsBperp.get(4, 0)); logger.debug("Bperp_a101 = " + rhsBperp.get(5, 0)); logger.debug("Bperp_a011 = " + rhsBperp.get(6, 0)); logger.debug("Bperp_a200 = " + rhsBperp.get(7, 0)); logger.debug("Bperp_a020 = " + rhsBperp.get(8, 0)); logger.debug("Bperp_a002 = " + rhsBperp.get(9, 0)); double maxerr = (abs(eHatBperp)).max(); if (maxerr > 2.00) // { logger.warn("Max. error bperp modeling at 3D datapoints: " + maxerr + "m"); } else { logger.info("Max. error bperp modeling at 3D datapoints: " + maxerr + "m"); } logger.debug("--------------------"); logger.debug("Range: r(p) = r0 + dr*p"); logger.debug("l and p in un-normalized, absolute, coordinates (1:nMatrix)."); final double range1 = master.pix2range(1.0); final double range5000 = master.pix2range(5000.0); final double drange = (range5000 - range1) / 5000.0; logger.debug("range = " + (range1 - drange) + " + " + drange + "*p"); // orbit initialized isInitialized = true; }
public static void main(String[] args) { DoubleMatrix A = readJamaMatrixFromFile(".\\src\\test\\resources\\10_10_A"); DoubleMatrix B = readJamaMatrixFromFile(".\\src\\test\\resources\\10_10_B"); Long start = System.currentTimeMillis(); DoubleMatrix result = A.mmul(B); Long end = System.currentTimeMillis(); Long time = end - start; System.out.println("Time for JBLAS multiply 10x10 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\100_100_M1"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\100_100_M2"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 100x100 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\200_200_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\200_200_B"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 200x200 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\300_300_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\300_300_B"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 300x300 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\500_500_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\500_500_B"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 500x500 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\1000_1000_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\1000_1000_B"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 1000x1000 is: " + time); // Matrix Multiply x2 A = readJamaMatrixFromFile(".\\src\\test\\resources\\2_2_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\2_2_B"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 2x2 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\4_4_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\4_4_B"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 4x4 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\8_8_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\8_8_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 8x8 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\16_16_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\16_16_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 16x16 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\32_32_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\32_32_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 32x32 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\64_64_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\64_64_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 64x64 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\128_128_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\128_128_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 128x128 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\256_256_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\256_256_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 256x256 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\512_512_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\512_512_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 512x512 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\1024_1024_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\1024_1024_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 1024x1024 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\2048_2048_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\2048_2048_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 2048x2048 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\4096_4096_A"); B = readJamaMatrixFromFile(".\\src\\test\\resources\\4096_4096_A"); start = System.currentTimeMillis(); result = A.mmul(B); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS multiply 4096x4096 is: " + time); // LU Decomp A = readJamaMatrixFromFile(".\\src\\test\\resources\\2_2_A"); Decompose lucalc = new Decompose(); start = System.currentTimeMillis(); Decompose.LUDecomposition<DoubleMatrix> resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 2x2 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\4_4_A"); // Decompose lucalc = new Decompose(); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 4x4 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\8_8_A"); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 8x8 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\16_16_A"); // Decompose lucalc = new Decompose(); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 16x16 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\32_32_A"); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 32x32 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\64_64_A"); // Decompose lucalc = new Decompose(); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 64x64 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\128_128_A"); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 128x128 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\256_256_A"); // Decompose lucalc = new Decompose(); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 256x256 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\512_512_A"); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 512x512 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\1024_1024_A"); // Decompose lucalc = new Decompose(); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 1024x1024 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\2048_2048_A"); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 2048x2048 is: " + time); A = readJamaMatrixFromFile(".\\src\\test\\resources\\4096_4096_A"); start = System.currentTimeMillis(); resultLu = lucalc.lu(A); end = System.currentTimeMillis(); time = end - start; System.out.println("Time for JBLAS LU 4096x4096 is: " + time); }