public static Matrix averageColumnVector(Matrix... matrices) { int columns = matrices[0].getColumnDimension(); if (matrices[0].getRowDimension() != 1) throw new IllegalArgumentException(); // double[] avg = new double[columns]; Matrix avg = new Matrix(1, columns); for (Matrix m : matrices) { avg.plusEquals(m); } avg.timesEquals(1.0 / matrices.length); return avg; }
/** * Update the covariance Matrix of the weight posterior distribution (SIGMA) along with its * cholesky factor: * * <p>SIGMA = (A + beta * PHI^t * PHI)^{-1} * * <p>SIGMA_chol with SIGMA_chol * SIGMA_chol^t = SIGMA */ protected void updateSIGMA() { Matrix SIGMA_inv = PHI_t.times(PHI_t.transpose()); SIGMA_inv.timesEquals(beta); SIGMA_inv.plusEquals(A); /** Update the factor ... */ SECholeskyDecomposition CD = new SECholeskyDecomposition(SIGMA_inv.getArray()); Matrix U = CD.getPTR().times(CD.getL()); SIGMA_chol = U.inverse(); /** Update SIGMA */ SIGMA = (SIGMA_chol.transpose()).times(SIGMA_chol); }
/** * Update the mean of the weight posterior distribution (mu): * * <p>mu = beta * SIGMA * PHI^t * t */ protected void updateMu() { mu = SIGMA.times(PHI_t.times(new Matrix(t))); mu.timesEquals(beta); }
@Override public final void process(final Spot spot) { if (img.numDimensions() == 3) { // 3D case final SpotNeighborhood<T> neighborhood = new SpotNeighborhood<T>(spot, img); final SpotNeighborhoodCursor<T> cursor = neighborhood.cursor(); double x, y, z; double x2, y2, z2; double mass, totalmass = 0; double Ixx = 0, Iyy = 0, Izz = 0, Ixy = 0, Ixz = 0, Iyz = 0; final double[] position = new double[img.numDimensions()]; while (cursor.hasNext()) { cursor.fwd(); mass = cursor.get().getRealDouble(); cursor.getRelativePosition(position); x = position[0]; y = position[1]; z = position[2]; totalmass += mass; x2 = x * x; y2 = y * y; z2 = z * z; Ixx += mass * (y2 + z2); Iyy += mass * (x2 + z2); Izz += mass * (x2 + y2); Ixy -= mass * x * y; Ixz -= mass * x * z; Iyz -= mass * y * z; } final Matrix mat = new Matrix(new double[][] {{Ixx, Ixy, Ixz}, {Ixy, Iyy, Iyz}, {Ixz, Iyz, Izz}}); mat.timesEquals(1 / totalmass); final EigenvalueDecomposition eigdec = mat.eig(); final double[] eigenvalues = eigdec.getRealEigenvalues(); final Matrix eigenvectors = eigdec.getV(); final double I1 = eigenvalues[0]; final double I2 = eigenvalues[1]; final double I3 = eigenvalues[2]; final double a = Math.sqrt(2.5 * (I2 + I3 - I1)); final double b = Math.sqrt(2.5 * (I3 + I1 - I2)); final double c = Math.sqrt(2.5 * (I1 + I2 - I3)); final double[] semiaxes = new double[] {a, b, c}; // Sort semi-axes by ascendent order and get the sorting index final double[] semiaxes_ordered = semiaxes.clone(); Arrays.sort(semiaxes_ordered); final int[] order = new int[3]; for (int i = 0; i < semiaxes_ordered.length; i++) for (int j = 0; j < semiaxes.length; j++) if (semiaxes_ordered[i] == semiaxes[j]) order[i] = j; // Get the sorted eigenvalues final double[][] uvectors = new double[3][3]; for (int i = 0; i < eigenvalues.length; i++) { uvectors[i][0] = eigenvectors.get(0, order[i]); uvectors[i][1] = eigenvectors.get(1, order[i]); uvectors[i][2] = eigenvectors.get(2, order[i]); } // Store in the Spot object double theta, phi; for (int i = 0; i < uvectors.length; i++) { theta = Math.acos( uvectors[i][2] / Math.sqrt( uvectors[i][0] * uvectors[i][0] + uvectors[i][1] * uvectors[i][1] + uvectors[i][2] * uvectors[i][2])); phi = Math.atan2(uvectors[i][1], uvectors[i][0]); if (phi < -Math.PI / 2) phi += Math.PI; // For an ellipsoid we care only for the // angles in [-pi/2 , pi/2] if (phi > Math.PI / 2) phi -= Math.PI; // Store in descending order spot.putFeature(featurelist_sa[i], semiaxes_ordered[i]); spot.putFeature(featurelist_phi[i], phi); spot.putFeature(featurelist_theta[i], theta); } // Store the Spot morphology (needs to be outside the above loop) spot.putFeature(MORPHOLOGY, estimateMorphology(semiaxes_ordered)); } else if (img.numDimensions() == 2) { // 2D case final SpotNeighborhood<T> neighborhood = new SpotNeighborhood<T>(spot, img); final SpotNeighborhoodCursor<T> cursor = neighborhood.cursor(); double x, y; double x2, y2; double mass, totalmass = 0; double Ixx = 0, Iyy = 0, Ixy = 0; final double[] position = new double[img.numDimensions()]; while (cursor.hasNext()) { cursor.fwd(); mass = cursor.get().getRealDouble(); cursor.getRelativePosition(position); x = position[0]; y = position[1]; totalmass += mass; x2 = x * x; y2 = y * y; Ixx += mass * (y2); Iyy += mass * (x2); Ixy -= mass * x * y; } final Matrix mat = new Matrix(new double[][] {{Ixx, Ixy}, {Ixy, Iyy}}); mat.timesEquals(1 / totalmass); final EigenvalueDecomposition eigdec = mat.eig(); final double[] eigenvalues = eigdec.getRealEigenvalues(); final Matrix eigenvectors = eigdec.getV(); final double I1 = eigenvalues[0]; final double I2 = eigenvalues[1]; final double a = Math.sqrt(4 * I1); final double b = Math.sqrt(4 * I2); final double[] semiaxes = new double[] {a, b}; // Sort semi-axes by ascendent order and get the sorting index final double[] semiaxes_ordered = semiaxes.clone(); Arrays.sort(semiaxes_ordered); final int[] order = new int[2]; for (int i = 0; i < semiaxes_ordered.length; i++) for (int j = 0; j < semiaxes.length; j++) if (semiaxes_ordered[i] == semiaxes[j]) order[i] = j; // Get the sorted eigenvalues final double[][] uvectors = new double[2][2]; for (int i = 0; i < eigenvalues.length; i++) { uvectors[i][0] = eigenvectors.get(0, order[i]); uvectors[i][1] = eigenvectors.get(1, order[i]); } // Store in the Spot object double theta, phi; for (int i = 0; i < uvectors.length; i++) { theta = 0; phi = Math.atan2(uvectors[i][1], uvectors[i][0]); if (phi < -Math.PI / 2) phi += Math.PI; // For an ellipsoid we care only for the // angles in [-pi/2 , pi/2] if (phi > Math.PI / 2) phi -= Math.PI; // Store in descending order spot.putFeature(featurelist_sa[i], semiaxes_ordered[i]); spot.putFeature(featurelist_phi[i], phi); spot.putFeature(featurelist_theta[i], theta); } spot.putFeature(featurelist_sa[2], Double.valueOf(0)); spot.putFeature(featurelist_phi[2], Double.valueOf(0)); spot.putFeature(featurelist_theta[2], Double.valueOf(0)); // Store the Spot morphology (needs to be outside the above loop) spot.putFeature(MORPHOLOGY, estimateMorphology(semiaxes_ordered)); } }
/** * Get mean covariance matrix C2 for given pixel. * * @param x X coordinate of the given pixel. * @param y Y coordinate of the given pixel. * @param halfWindowSizeX The sliding window width /2 * @param halfWindowSizeY The sliding window height /2 * @param sourceImageWidth Source image width. * @param sourceImageHeight Source image height. * @param sourceProductType The source product type. * @param sourceTiles The source tiles for all bands. * @param dataBuffers Source tile data buffers. * @param Cr The real part of the mean covariance matrix. * @param Ci The imaginary part of the mean covariance matrix. */ public static void getMeanCovarianceMatrixC2( final int x, final int y, final int halfWindowSizeX, final int halfWindowSizeY, final int sourceImageWidth, final int sourceImageHeight, final PolBandUtils.MATRIX sourceProductType, final Tile[] sourceTiles, final ProductData[] dataBuffers, final double[][] Cr, final double[][] Ci) { final double[][] tempCr = new double[2][2]; final double[][] tempCi = new double[2][2]; final int xSt = Math.max(x - halfWindowSizeX, 0); final int xEd = Math.min(x + halfWindowSizeX, sourceImageWidth - 1); final int ySt = Math.max(y - halfWindowSizeY, 0); final int yEd = Math.min(y + halfWindowSizeY, sourceImageHeight - 1); final int num = (yEd - ySt + 1) * (xEd - xSt + 1); final TileIndex srcIndex = new TileIndex(sourceTiles[0]); final Matrix CrMat = new Matrix(2, 2); final Matrix CiMat = new Matrix(2, 2); if (sourceProductType == PolBandUtils.MATRIX.C2) { for (int yy = ySt; yy <= yEd; ++yy) { srcIndex.calculateStride(yy); for (int xx = xSt; xx <= xEd; ++xx) { getCovarianceMatrixC2(srcIndex.getIndex(xx), dataBuffers, tempCr, tempCi); CrMat.plusEquals(new Matrix(tempCr)); CiMat.plusEquals(new Matrix(tempCi)); } } } else if (sourceProductType == PolBandUtils.MATRIX.LCHCP || sourceProductType == PolBandUtils.MATRIX.RCHCP || sourceProductType == PolBandUtils.MATRIX.DUAL_HH_HV || sourceProductType == PolBandUtils.MATRIX.DUAL_VH_VV || sourceProductType == PolBandUtils.MATRIX.DUAL_HH_VV) { final double[] tempKr = new double[2]; final double[] tempKi = new double[2]; for (int yy = ySt; yy <= yEd; ++yy) { srcIndex.calculateStride(yy); for (int xx = xSt; xx <= xEd; ++xx) { getScatterVector(srcIndex.getIndex(xx), dataBuffers, tempKr, tempKi); computeCovarianceMatrixC2(tempKr, tempKi, tempCr, tempCi); CrMat.plusEquals(new Matrix(tempCr)); CiMat.plusEquals(new Matrix(tempCi)); } } } else { throw new OperatorException("getMeanCovarianceMatrixC2 not implemented for raw dual pol"); } CrMat.timesEquals(1.0 / num); CiMat.timesEquals(1.0 / num); for (int i = 0; i < 2; i++) { Cr[i][0] = CrMat.get(i, 0); Ci[i][0] = CiMat.get(i, 0); Cr[i][1] = CrMat.get(i, 1); Ci[i][1] = CiMat.get(i, 1); } }