示例#1
0
  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);
  }