/**
   * Will only ever be accessed by a single thread. Rechecks the target update time again in case a
   * second write thread was blocking the current one. {@link #lastUpdateRun} gets set to a negative
   * value to specify that this method is currently running.
   */
  public void doUpdate() {

    // Check whether entry is required.
    if (!state.get().checkNeedsUpdate(forceUpdateInterval)) {
      return;
    }

    // Prevent recursion!
    // ------------------
    // To prevent another call from entering this block it's
    // necessary to set active
    if (!active.compareAndSet(false, true)) {
      return;
    }

    try {
      final Set<String> ids = sessions.keySet();
      log.info("Synchronizing session cache. Count = " + ids.size());
      final StopWatch sw = new Slf4JStopWatch();
      for (String id : ids) {
        reload(id);
      }

      sw.stop("omero.sessions.synchronization");
      log.info(String.format("Synchronization took %s ms.", sw.getElapsedTime()));

    } catch (Exception e) {
      log.error("Error synchronizing cache", e);
    } finally {
      active.set(false);
    }
  }
 /**
  * matrix test
  *
  * @throws Exception exception
  */
 public void testMatrix() throws Exception {
   ChatMessage msg = constructMessage();
   int count = 100000;
   // hot swap
   for (int i = 0; i < 10000; i++) {
     hessian(msg);
     jackson(msg);
     jackson2(msg);
     msgpack(msg);
   }
   System.out.println(count + " loop:");
   StopWatch stopWatch = new StopWatch();
   stopWatch.start("hessian");
   for (int i = 0; i < count; i++) {
     hessian(msg);
   }
   stopWatch.stop("hessian");
   System.out.println(stopWatch.getTag() + ":" + stopWatch.getElapsedTime());
   stopWatch.start("jackson");
   for (int i = 0; i < count; i++) {
     jackson(msg);
   }
   stopWatch.stop("jackson");
   System.out.println(stopWatch.getTag() + ":" + stopWatch.getElapsedTime());
   stopWatch.start("msgpack");
   for (int i = 0; i < count; i++) {
     msgpack(msg);
   }
   stopWatch.stop("msgpack");
   System.out.println(stopWatch.getTag() + ":" + stopWatch.getElapsedTime());
   stopWatch.start("jackson2");
   for (int i = 0; i < count; i++) {
     jackson2(msg);
   }
   stopWatch.stop("jackson2");
   System.out.println(stopWatch.getTag() + ":" + stopWatch.getElapsedTime());
 }
示例#3
0
  public static void main(String[] args) throws LPException {

    final int rows = 40;
    final int cols = rows;

    logger.trace("Start Unwrapping");
    logger.info("Simulate Data");
    SimulateData simulateData = new SimulateData(rows, cols);
    simulateData.peaks();

    DoubleMatrix Phi = simulateData.getSimulatedData();
    DoubleMatrix Psi = UnwrapUtils.wrapDoubleMatrix(Phi);

    StopWatch clockFull = new StopWatch();
    clockFull.start();

    Unwrapper unwrapper = new Unwrapper(Psi);
    unwrapper.unwrap();

    clockFull.stop();
    logger.info("Total processing time {} [sec]", (double) (clockFull.getElapsedTime()) / 1000);
  }
示例#4
0
  private void costantiniUnwrap() throws LPException {

    final int ny = wrappedPhase.rows - 1; // start from Zero!
    final int nx = wrappedPhase.columns - 1; // start from Zero!

    if (wrappedPhase.isVector()) throw new IllegalArgumentException("Input must be 2D array");
    if (wrappedPhase.rows < 2 || wrappedPhase.columns < 2)
      throw new IllegalArgumentException("Size of input must be larger than 2");

    // Default weight
    DoubleMatrix w1 = DoubleMatrix.ones(ny + 1, 1);
    w1.put(0, 0.5);
    w1.put(w1.length - 1, 0.5);
    DoubleMatrix w2 = DoubleMatrix.ones(1, nx + 1);
    w2.put(0, 0.5);
    w2.put(w2.length - 1, 0.5);
    DoubleMatrix weight = w1.mmul(w2);

    DoubleMatrix i, j, I_J, IP1_J, I_JP1;
    DoubleMatrix Psi1, Psi2;
    DoubleMatrix[] ROWS;

    // Compute partial derivative Psi1, eqt (1,3)
    i = intRangeDoubleMatrix(0, ny - 1);
    j = intRangeDoubleMatrix(0, nx);
    ROWS = grid2D(i, j);
    I_J = JblasUtils.sub2ind(wrappedPhase.rows, ROWS[0], ROWS[1]);
    IP1_J = JblasUtils.sub2ind(wrappedPhase.rows, ROWS[0].add(1), ROWS[1]);
    Psi1 =
        JblasUtils.getMatrixFromIdx(wrappedPhase, IP1_J)
            .sub(JblasUtils.getMatrixFromIdx(wrappedPhase, I_J));
    Psi1 = UnwrapUtils.wrapDoubleMatrix(Psi1);

    // Compute partial derivative Psi2, eqt (2,4)
    i = intRangeDoubleMatrix(0, ny);
    j = intRangeDoubleMatrix(0, nx - 1);
    ROWS = grid2D(i, j);
    I_J = JblasUtils.sub2ind(wrappedPhase.rows, ROWS[0], ROWS[1]);
    I_JP1 = JblasUtils.sub2ind(wrappedPhase.rows, ROWS[0], ROWS[1].add(1));
    Psi2 =
        JblasUtils.getMatrixFromIdx(wrappedPhase, I_JP1)
            .sub(JblasUtils.getMatrixFromIdx(wrappedPhase, I_J));
    Psi2 = UnwrapUtils.wrapDoubleMatrix(Psi2);

    // Compute beq
    DoubleMatrix beq = DoubleMatrix.zeros(ny, nx);
    i = intRangeDoubleMatrix(0, ny - 1);
    j = intRangeDoubleMatrix(0, nx - 1);
    ROWS = grid2D(i, j);
    I_J = JblasUtils.sub2ind(Psi1.rows, ROWS[0], ROWS[1]);
    I_JP1 = JblasUtils.sub2ind(Psi1.rows, ROWS[0], ROWS[1].add(1));
    beq.addi(JblasUtils.getMatrixFromIdx(Psi1, I_JP1).sub(JblasUtils.getMatrixFromIdx(Psi1, I_J)));
    I_J = JblasUtils.sub2ind(Psi2.rows, ROWS[0], ROWS[1]);
    I_JP1 = JblasUtils.sub2ind(Psi2.rows, ROWS[0].add(1), ROWS[1]);
    beq.subi(JblasUtils.getMatrixFromIdx(Psi2, I_JP1).sub(JblasUtils.getMatrixFromIdx(Psi2, I_J)));
    beq.muli(-1 / (2 * Constants._PI));
    for (int k = 0; k < beq.length; k++) {
      beq.put(k, Math.round(beq.get(k)));
    }
    beq.reshape(beq.length, 1);

    logger.debug("Constraint matrix");
    i = intRangeDoubleMatrix(0, ny - 1);
    j = intRangeDoubleMatrix(0, nx - 1);
    ROWS = grid2D(i, j);
    DoubleMatrix ROW_I_J = JblasUtils.sub2ind(i.length, ROWS[0], ROWS[1]);
    int nS0 = nx * ny;

    // Use by S1p, S1m
    DoubleMatrix[] COLS;
    COLS = grid2D(i, j);
    DoubleMatrix COL_IJ_1 = JblasUtils.sub2ind(i.length, COLS[0], COLS[1]);
    COLS = grid2D(i, j.add(1));
    DoubleMatrix COL_I_JP1 = JblasUtils.sub2ind(i.length, COLS[0], COLS[1]);
    int nS1 = (nx + 1) * (ny);

    // SOAPBinding.Use by S2p, S2m
    COLS = grid2D(i, j);
    DoubleMatrix COL_IJ_2 = JblasUtils.sub2ind(i.length + 1, COLS[0], COLS[1]);
    COLS = grid2D(i.add(1), j);
    DoubleMatrix COL_IP1_J = JblasUtils.sub2ind(i.length + 1, COLS[0], COLS[1]);
    int nS2 = nx * (ny + 1);

    // Equality constraint matrix (Aeq)
    /*
        S1p = + sparse(ROW_I_J, COL_I_JP1,1,nS0,nS1) ...
              - sparse(ROW_I_J, COL_IJ_1,1,nS0,nS1);
        S1m = -S1p;

        S2p = - sparse(ROW_I_J, COL_IP1_J,1,nS0,nS2) ...
              + sparse(ROW_I_J, COL_IJ_2,1,nS0,nS2);
        S2m = -S2p;
    */

    // ToDo: Aeq matrix should be sparse from it's initialization, look into JblasMatrix factory for
    // howto
    // ...otherwise even a data set of eg 40x40 pixels will exhaust heap:
    // ...    dimension of Aeq (equality constraints) matrix for 30x30 input is 1521x6240 matrix
    // ...    dimension of Aeq (                    ) matrix for 50x50 input is 2401x9800
    // ...    dimension of Aeq (                    ) matrix for 512x512 input is 261121x1046528
    DoubleMatrix S1p =
        JblasUtils.setUpMatrixFromIdx(nS0, nS1, ROW_I_J, COL_I_JP1)
            .sub(JblasUtils.setUpMatrixFromIdx(nS0, nS1, ROW_I_J, COL_IJ_1));
    DoubleMatrix S1m = S1p.neg();

    DoubleMatrix S2p =
        JblasUtils.setUpMatrixFromIdx(nS0, nS2, ROW_I_J, COL_IP1_J)
            .neg()
            .add(JblasUtils.setUpMatrixFromIdx(nS0, nS2, ROW_I_J, COL_IJ_2));
    DoubleMatrix S2m = S2p.neg();

    DoubleMatrix Aeq =
        concatHorizontally(concatHorizontally(S1p, S1m), concatHorizontally(S2p, S2m));

    final int nObs = Aeq.columns;
    final int nUnkn = Aeq.rows;

    DoubleMatrix c1 = JblasUtils.getMatrixFromRange(0, ny, 0, weight.columns, weight);
    DoubleMatrix c2 = JblasUtils.getMatrixFromRange(0, weight.rows, 0, nx, weight);

    c1.reshape(c1.length, 1);
    c2.reshape(c2.length, 1);

    DoubleMatrix cost =
        DoubleMatrix.concatVertically(
            DoubleMatrix.concatVertically(c1, c1), DoubleMatrix.concatVertically(c2, c2));

    logger.debug("Minimum network flow resolution");

    StopWatch clockLP = new StopWatch();
    LinearProgram lp = new LinearProgram(cost.data);
    lp.setMinProblem(true);

    boolean[] integerBool = new boolean[nObs];
    double[] lowerBound = new double[nObs];
    double[] upperBound = new double[nObs];

    for (int k = 0; k < nUnkn; k++) {
      lp.addConstraint(new LinearEqualsConstraint(Aeq.getRow(k).toArray(), beq.get(k), "cost"));
    }

    for (int k = 0; k < nObs; k++) {
      integerBool[k] = true;
      lowerBound[k] = 0;
      upperBound[k] = 99999;
    }

    // setup bounds and integer nature
    lp.setIsinteger(integerBool);
    lp.setUpperbound(upperBound);
    lp.setLowerbound(lowerBound);
    LinearProgramSolver solver = SolverFactory.newDefault();

    //        double[] solution;
    //        solution = solver.solve(lp);
    DoubleMatrix solution = new DoubleMatrix(solver.solve(lp));

    clockLP.stop();
    logger.debug("Total GLPK time: {} [sec]", (double) (clockLP.getElapsedTime()) / 1000);

    // Displatch the LP solution
    int offset;

    int[] idx1p = JblasUtils.intRangeIntArray(0, nS1 - 1);
    DoubleMatrix x1p = solution.get(idx1p);
    x1p.reshape(ny, nx + 1);
    offset = idx1p[nS1 - 1] + 1;

    int[] idx1m = JblasUtils.intRangeIntArray(offset, offset + nS1 - 1);
    DoubleMatrix x1m = solution.get(idx1m);
    x1m.reshape(ny, nx + 1);
    offset = idx1m[idx1m.length - 1] + 1;

    int[] idx2p = JblasUtils.intRangeIntArray(offset, offset + nS2 - 1);
    DoubleMatrix x2p = solution.get(idx2p);
    x2p.reshape(ny + 1, nx);
    offset = idx2p[idx2p.length - 1] + 1;

    int[] idx2m = JblasUtils.intRangeIntArray(offset, offset + nS2 - 1);
    DoubleMatrix x2m = solution.get(idx2m);
    x2m.reshape(ny + 1, nx);

    // Compute the derivative jumps, eqt (20,21)
    DoubleMatrix k1 = x1p.sub(x1m);
    DoubleMatrix k2 = x2p.sub(x2m);

    // (?) Round to integer solution
    if (roundK == true) {
      for (int idx = 0; idx < k1.length; idx++) {
        k1.put(idx, FastMath.floor(k1.get(idx)));
      }
      for (int idx = 0; idx < k2.length; idx++) {
        k2.put(idx, FastMath.floor(k2.get(idx)));
      }
    }

    // Sum the jumps with the wrapped partial derivatives, eqt (10,11)
    k1.reshape(ny, nx + 1);
    k2.reshape(ny + 1, nx);
    k1.addi(Psi1.div(Constants._TWO_PI));
    k2.addi(Psi2.div(Constants._TWO_PI));

    // Integrate the partial derivatives, eqt (6)
    // cumsum() method in JblasTester -> see cumsum_demo() in JblasTester.cumsum_demo()
    DoubleMatrix k2_temp = DoubleMatrix.concatHorizontally(DoubleMatrix.zeros(1), k2.getRow(0));
    k2_temp = JblasUtils.cumsum(k2_temp, 1);
    DoubleMatrix k = DoubleMatrix.concatVertically(k2_temp, k1);
    k = JblasUtils.cumsum(k, 1);

    // Unwrap - final solution
    unwrappedPhase = k.mul(Constants._TWO_PI);
  }
示例#5
0
文件: CPM.java 项目: fpl/s1tbx
  private void estimateCPM() {

    logger.info("Start EJML Estimation");

    numIterations = 0;
    boolean estimationDone = false;

    DenseMatrix64F eL_hat = null;
    DenseMatrix64F eP_hat = null;
    DenseMatrix64F rhsL = null;
    DenseMatrix64F rhsP = null;

    // normalize master coordinates for stability -- only master!
    TDoubleArrayList yMasterNorm = new TDoubleArrayList();
    TDoubleArrayList xMasterNorm = new TDoubleArrayList();
    for (int i = 0; i < yMaster.size(); i++) {
      yMasterNorm.add(PolyUtils.normalize2(yMaster.getQuick(i), normWin.linelo, normWin.linehi));
      xMasterNorm.add(PolyUtils.normalize2(xMaster.getQuick(i), normWin.pixlo, normWin.pixhi));
    }

    // helper variables
    int winL;
    int winP;
    int maxWSum_idx = 0;

    while (!estimationDone) {

      String codeBlockMessage = "LS ESTIMATION PROCEDURE";
      StopWatch stopWatch = new StopWatch();
      StopWatch clock = new StopWatch();
      clock.start();
      stopWatch.setTag(codeBlockMessage);
      stopWatch.start();

      logger.info("Start iteration: {}" + numIterations);

      /** Remove identified outlier from previous estimation */
      if (numIterations != 0) {
        logger.info(
            "Removing observation {}, idxList {},  from observation vector."
                + index.getQuick(maxWSum_idx)
                + maxWSum_idx);
        index.removeAt(maxWSum_idx);
        yMasterNorm.removeAt(maxWSum_idx);
        xMasterNorm.removeAt(maxWSum_idx);
        yOffset.removeAt(maxWSum_idx);
        xOffset.removeAt(maxWSum_idx);

        // only for outlier removal
        yMaster.removeAt(maxWSum_idx);
        xMaster.removeAt(maxWSum_idx);
        ySlave.removeAt(maxWSum_idx);
        xSlave.removeAt(maxWSum_idx);
        coherence.removeAt(maxWSum_idx);

        // also take care of slave pins
        slaveGCPList.remove(maxWSum_idx);

        //                if (demRefinement) {
        //                    ySlaveGeometry.removeAt(maxWSum_idx);
        //                    xSlaveGeometry.removeAt(maxWSum_idx);
        //                }

      }

      /** Check redundancy */
      numObservations = index.size(); // Number of points > threshold
      if (numObservations < numUnknowns) {
        logger.severe(
            "coregpm: Number of windows > threshold is smaller than parameters solved for.");
        throw new ArithmeticException(
            "coregpm: Number of windows > threshold is smaller than parameters solved for.");
      }

      // work with normalized values
      DenseMatrix64F A =
          new DenseMatrix64F(
              SystemOfEquations.constructDesignMatrix_loop(
                  yMasterNorm.toArray(), xMasterNorm.toArray(), cpmDegree));

      logger.info("TIME FOR SETUP of SYSTEM : {}" + stopWatch.lap("setup"));

      RowD1Matrix64F Qy_1; // vector
      double meanValue;
      switch (cpmWeight) {
        case "linear":
          logger.info("Using sqrt(coherence) as weights");
          Qy_1 = DenseMatrix64F.wrap(numObservations, 1, coherence.toArray());
          // Normalize weights to avoid influence on estimated var.factor
          logger.info("Normalizing covariance matrix for LS estimation");
          meanValue = CommonOps.elementSum(Qy_1) / numObservations;
          CommonOps.divide(meanValue, Qy_1); // normalize vector
          break;
        case "quadratic":
          logger.info("Using coherence as weights.");
          Qy_1 = DenseMatrix64F.wrap(numObservations, 1, coherence.toArray());
          CommonOps.elementMult(Qy_1, Qy_1);
          // Normalize weights to avoid influence on estimated var.factor
          meanValue = CommonOps.elementSum(Qy_1) / numObservations;
          logger.info("Normalizing covariance matrix for LS estimation.");
          CommonOps.divide(meanValue, Qy_1); // normalize vector
          break;
        case "bamler":
          // TODO: see Bamler papers IGARSS 2000 and 2004
          logger.warning("Bamler weighting method NOT IMPLEMENTED, falling back to None.");
          Qy_1 = onesEJML(numObservations);
          break;
        case "none":
          logger.info("No weighting.");
          Qy_1 = onesEJML(numObservations);
          break;
        default:
          Qy_1 = onesEJML(numObservations);
          break;
      }

      logger.info("TIME FOR SETUP of VC diag matrix: {}" + stopWatch.lap("diag VC matrix"));

      /** tempMatrix_1 matrices */
      final DenseMatrix64F yL_matrix = DenseMatrix64F.wrap(numObservations, 1, yOffset.toArray());
      final DenseMatrix64F yP_matrix = DenseMatrix64F.wrap(numObservations, 1, xOffset.toArray());
      logger.info("TIME FOR SETUP of TEMP MATRICES: {}" + stopWatch.lap("Temp matrices"));

      /** normal matrix */
      final DenseMatrix64F N =
          new DenseMatrix64F(numUnknowns, numUnknowns); // = A_transpose.mmul(Qy_1_diag.mmul(A));

      /*
                  // fork/join parallel implementation
                  RowD1Matrix64F result = A.copy();
                  DiagXMat dd = new DiagXMat(Qy_1, A, 0, A.numRows, result);
                  ForkJoinPool pool = new ForkJoinPool();
                  pool.invoke(dd);
                  CommonOps.multAddTransA(A, dd.result, N);
      */

      CommonOps.multAddTransA(A, diagxmat(Qy_1, A), N);
      DenseMatrix64F Qx_hat = N.copy();

      logger.info("TIME FOR SETUP of NORMAL MATRIX: {}" + stopWatch.lap("Normal matrix"));

      /** right hand sides */
      // azimuth
      rhsL = new DenseMatrix64F(numUnknowns, 1); // A_transpose.mmul(Qy_1_diag.mmul(yL_matrix));
      CommonOps.multAddTransA(1d, A, diagxmat(Qy_1, yL_matrix), rhsL);
      // range
      rhsP = new DenseMatrix64F(numUnknowns, 1); // A_transpose.mmul(Qy_1_diag.mmul(yP_matrix));
      CommonOps.multAddTransA(1d, A, diagxmat(Qy_1, yP_matrix), rhsP);
      logger.info("TIME FOR SETUP of RightHand Side: {}" + stopWatch.lap("Right-hand-side"));

      LinearSolver<DenseMatrix64F> solver = LinearSolverFactory.leastSquares(100, 100);
      /** compute solution */
      if (!solver.setA(Qx_hat)) {
        throw new IllegalArgumentException("Singular Matrix");
      }
      solver.solve(rhsL, rhsL);
      solver.solve(rhsP, rhsP);
      logger.info("TIME FOR SOLVING of System: {}" + stopWatch.lap("Solving System"));

      /** inverting of Qx_hat for stability check */
      solver.invert(Qx_hat);

      logger.info("TIME FOR INVERSION OF N: {}" + stopWatch.lap("Inversion of N"));

      /** test inversion and check stability: max(abs([N*inv(N) - E)) ?= 0 */
      DenseMatrix64F tempMatrix_1 = new DenseMatrix64F(N.numRows, N.numCols);
      CommonOps.mult(N, Qx_hat, tempMatrix_1);
      CommonOps.subEquals(
          tempMatrix_1, CommonOps.identity(tempMatrix_1.numRows, tempMatrix_1.numCols));
      double maxDeviation = CommonOps.elementMaxAbs(tempMatrix_1);
      if (maxDeviation > .01) {
        logger.severe(
            "COREGPM: maximum deviation N*inv(N) from unity = {}. This is larger than 0.01"
                + maxDeviation);
        throw new IllegalStateException("COREGPM: maximum deviation N*inv(N) from unity)");
      } else if (maxDeviation > .001) {
        logger.warning(
            "COREGPM: maximum deviation N*inv(N) from unity = {}. This is between 0.01 and 0.001"
                + maxDeviation);
      }
      logger.info("TIME FOR STABILITY CHECK: {}" + stopWatch.lap("Stability Check"));

      logger.info("Coeffs in Azimuth direction: {}" + rhsL.toString());
      logger.info("Coeffs in Range direction: {}" + rhsP.toString());
      logger.info("Max Deviation: {}" + maxDeviation);
      logger.info("System Quality: {}" + solver.quality());

      /** some other stuff if the scale is okay */
      DenseMatrix64F Qe_hat = new DenseMatrix64F(numObservations, numObservations);
      DenseMatrix64F tempMatrix_2 = new DenseMatrix64F(numObservations, numUnknowns);

      CommonOps.mult(A, Qx_hat, tempMatrix_2);
      CommonOps.multTransB(-1, tempMatrix_2, A, Qe_hat);
      scaleInputDiag(Qe_hat, Qy_1);

      // solution: Azimuth
      DenseMatrix64F yL_hat = new DenseMatrix64F(numObservations, 1);
      eL_hat = new DenseMatrix64F(numObservations, 1);
      CommonOps.mult(A, rhsL, yL_hat);
      CommonOps.sub(yL_matrix, yL_hat, eL_hat);

      // solution: Range
      DenseMatrix64F yP_hat = new DenseMatrix64F(numObservations, 1);
      eP_hat = new DenseMatrix64F(numObservations, 1);
      CommonOps.mult(A, rhsP, yP_hat);
      CommonOps.sub(yP_matrix, yP_hat, eP_hat);

      logger.info("TIME FOR DATA preparation for TESTING: {}" + stopWatch.lap("Testing Setup"));

      /** overal model test (variance factor) */
      double overAllModelTest_L = 0;
      double overAllModelTest_P = 0;

      for (int i = 0; i < numObservations; i++) {
        overAllModelTest_L += FastMath.pow(eL_hat.get(i), 2) * Qy_1.get(i);
        overAllModelTest_P += FastMath.pow(eP_hat.get(i), 2) * Qy_1.get(i);
      }

      overAllModelTest_L =
          (overAllModelTest_L / FastMath.pow(SIGMA_L, 2)) / (numObservations - numUnknowns);
      overAllModelTest_P =
          (overAllModelTest_P / FastMath.pow(SIGMA_P, 2)) / (numObservations - numUnknowns);

      logger.info("Overall Model Test Lines: {}" + overAllModelTest_L);
      logger.info("Overall Model Test Pixels: {}" + overAllModelTest_P);

      logger.info("TIME FOR OMT: {}" + stopWatch.lap("OMT"));

      /** ---------------------- DATASNOPING ----------------------------------- * */
      /** Assumed Qy diag */

      /** initialize */
      DenseMatrix64F wTest_L = new DenseMatrix64F(numObservations, 1);
      DenseMatrix64F wTest_P = new DenseMatrix64F(numObservations, 1);

      for (int i = 0; i < numObservations; i++) {
        wTest_L.set(i, eL_hat.get(i) / (Math.sqrt(Qe_hat.get(i, i)) * SIGMA_L));
        wTest_P.set(i, eP_hat.get(i) / (Math.sqrt(Qe_hat.get(i, i)) * SIGMA_P));
      }

      /** find maxima's */
      // azimuth
      winL = absArgmax(wTest_L);
      double maxWinL = Math.abs(wTest_L.get(winL));
      logger.info(
          "maximum wtest statistic azimuth = {} for window number: {} "
              + maxWinL
              + index.getQuick(winL));

      // range
      winP = absArgmax(wTest_P);
      double maxWinP = Math.abs(wTest_P.get(winP));
      logger.info(
          "maximum wtest statistic range = {} for window number: {} "
              + maxWinP
              + index.getQuick(winP));

      /** use summed wTest in Azimuth and Range direction for outlier detection */
      DenseMatrix64F wTestSum = new DenseMatrix64F(numObservations);
      for (int i = 0; i < numObservations; i++) {
        wTestSum.set(i, FastMath.pow(wTest_L.get(i), 2) + FastMath.pow(wTest_P.get(i), 2));
      }

      maxWSum_idx = absArgmax(wTest_P);
      double maxWSum = wTest_P.get(winP);
      logger.info(
          "Detected outlier: summed sqr.wtest = {}; observation: {}"
              + maxWSum
              + index.getQuick(maxWSum_idx));

      /** Test if we are estimationDone yet */
      // check on number of observations
      if (numObservations <= numUnknowns) {
        logger.warning("NO redundancy!  Exiting iterations.");
        estimationDone = true; // cannot remove more than this
      }

      // check on test k_alpha
      if (Math.max(maxWinL, maxWinP) <= criticalValue) {
        // all tests accepted?
        logger.info("All outlier tests accepted! (final solution computed)");
        estimationDone = true;
      }

      if (numIterations >= maxIterations) {
        logger.info("max. number of iterations reached (exiting loop).");
        estimationDone = true; // we reached max. (or no max_iter specified)
      }

      /** Only warn if last iteration has been estimationDone */
      if (estimationDone) {
        if (overAllModelTest_L > 10) {
          logger.warning(
              "COREGPM: Overall Model Test, Lines = {} is larger than 10. (Suggest model or a priori sigma not correct.)"
                  + overAllModelTest_L);
        }
        if (overAllModelTest_P > 10) {
          logger.warning(
              "COREGPM: Overall Model Test, Pixels = {} is larger than 10. (Suggest model or a priori sigma not correct.)"
                  + overAllModelTest_P);
        }

        /** if a priori sigma is correct, max wtest should be something like 1.96 */
        if (Math.max(maxWinL, maxWinP) > 200.0) {
          logger.warning(
              "Recommendation: remove window number: {} and re-run step COREGPM.  max. wtest is: {}."
                  + index.get(winL)
                  + Math.max(maxWinL, maxWinP));
        }
      }

      logger.info("TIME FOR wTestStatistics: {}" + stopWatch.lap("WTEST"));
      logger.info("Total Estimation TIME: {}" + clock.getElapsedTime());

      numIterations++; // update counter here!
    } // only warn when iterating

    yError = eL_hat.getData();
    xError = eP_hat.getData();

    yCoef = rhsL.getData();
    xCoef = rhsP.getData();
  }