private void calculatePCs() { // square values in the distance matrix, then double center them DoubleMatrix dm = SquaredDoubleMatrixFromDistanceMatrix(); int n = dm.numberOfRows(); // double center the matrix for (int r = 0; r < n; r++) { double mean = dm.rowSum(r) / n; for (int c = 0; c < n; c++) { dm.set(r, c, dm.get(r, c) - mean); } } for (int c = 0; c < n; c++) { double mean = dm.columnSum(c) / n; for (int r = 0; r < n; r++) { dm.set(r, c, dm.get(r, c) - mean); } } // finally multiply by -1/2 dm.scalarMultEquals(-0.5); // get an eigenvalue decomposition eigenDecomp = dm.getEigenvalueDecomposition(); // calculate PC's for positive eigenvalues numberOfPositiveEigenvalues = 0; double[] eval = eigenDecomp.getEigenvalues(); for (int i = 0; i < n; i++) if (eval[i] > tol) numberOfPositiveEigenvalues++; eigenVectors = eigenDecomp.getEigenvectors(); // determine the sort order int nEigenvalues = eval.length; eigenSort = IntStream.range(0, nEigenvalues) .boxed() .sorted( (a, b) -> { if (eval[a] > eval[b]) return -1; if (eval[a] < eval[b]) return 1; return 0; }) .mapToInt(I -> I.intValue()) .toArray(); eigenVectors.column(280); }
public double[] getPrincipalCoordinate(int index) { if (index > numberOfPositiveEigenvalues - 1) return null; double eval = Math.sqrt(eigenDecomp.getEigenvalue(eigenSort[index])); int ntaxa = myDistanceMatrix.numberOfTaxa(); double[] pc = new double[ntaxa]; for (int i = 0; i < ntaxa; i++) pc[i] = eigenVectors.get(i, eigenSort[index]) * eval; return pc; }
public double getEigenvalue(int index) { return eigenDecomp.getEigenvalue(eigenSort[index]); }