@Test public void testInclinedPlane() throws IOException { DoubleMatrix1D normal = new DenseDoubleMatrix1D(3); normal.assign(new double[] {.0, .0, 1.0}); InclinedPlane3D inclinedPlane = new InclinedPlane3D(); inclinedPlane.setRandomGenerator(new MersenneTwister(123456789)); inclinedPlane.setNormal(normal); inclinedPlane.setBounds(new Rectangle(-5, -5, 10, 10)); inclinedPlane.setNoiseStd(0.5); DoubleMatrix2D data = inclinedPlane.generate(10); SVDPCA pca = new SVDPCA(data); System.out.println("Eigenvalues:"); System.out.println(pca.getEigenvalues()); System.out.println("Eigenvectors:"); System.out.println(pca.getEigenvectors()); System.out.println("Meanvector:"); System.out.println(pca.getMean()); // Recalculate the input from a truncated SVD, first calculate the mean DoubleMatrix1D mean = new SparseDoubleMatrix1D(3); for (int i = 0; i < data.rows(); ++i) { mean.assign(data.viewRow(i), Functions.plus); } mean.assign(Functions.div(data.rows())); // Truncate the SVD and calculate the coefficient matrix DenseDoubleMatrix2D coefficients = new DenseDoubleMatrix2D(data.rows(), 2); DoubleMatrix2D centeredInput = data.copy(); for (int i = 0; i < data.rows(); ++i) { centeredInput.viewRow(i).assign(mean, Functions.minus); } centeredInput.zMult( pca.getEigenvectors().viewPart(0, 0, 2, 3), coefficients, 1, 0, false, true); // Reconstruct the data from the lower dimensional information DoubleMatrix2D reconstruction = data.copy(); for (int i = 0; i < reconstruction.rows(); ++i) { reconstruction.viewRow(i).assign(mean); } coefficients.zMult( pca.getEigenvectors().viewPart(0, 0, 2, 3), reconstruction, 1, 1, false, false); // Output to file (can be read by GNU Plot) String fileName = "inclined-plane-svd-pca.dat"; String packagePath = this.getClass().getPackage().getName().replaceAll("\\.", "/"); File outputFile = new File("src/test/resources/" + packagePath + "/" + fileName); PrintWriter writer = new PrintWriter(outputFile); writer.write(data.toString()); writer.close(); }
/** * Returns the best cut of a graph w.r.t. the degree of dissimilarity between points of different * partitions and the degree of similarity between points of the same partition. * * @param W the weight matrix of the graph * @return an array of two elements, each of these contains the points of a partition */ protected static int[][] bestCut(DoubleMatrix2D W) { int n = W.columns(); // Builds the diagonal matrices D and D^(-1/2) (represented as their diagonals) DoubleMatrix1D d = DoubleFactory1D.dense.make(n); DoubleMatrix1D d_minus_1_2 = DoubleFactory1D.dense.make(n); for (int i = 0; i < n; i++) { double d_i = W.viewRow(i).zSum(); d.set(i, d_i); d_minus_1_2.set(i, 1 / Math.sqrt(d_i)); } DoubleMatrix2D D = DoubleFactory2D.sparse.diagonal(d); // System.out.println("DoubleMatrix2D :\n"+D.toString()); DoubleMatrix2D X = D.copy(); // System.out.println("DoubleMatrix2D copy :\n"+X.toString()); // X = D^(-1/2) * (D - W) * D^(-1/2) X.assign(W, Functions.minus); // System.out.println("DoubleMatrix2D X: (D-W) :\n"+X.toString()); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) X.set(i, j, X.get(i, j) * d_minus_1_2.get(i) * d_minus_1_2.get(j)); // Computes the eigenvalues and the eigenvectors of X EigenvalueDecomposition e = new EigenvalueDecomposition(X); DoubleMatrix1D lambda = e.getRealEigenvalues(); // Selects the eigenvector z_2 associated with the second smallest eigenvalue // Creates a map that contains the pairs <index, eigenvalue> AbstractIntDoubleMap map = new OpenIntDoubleHashMap(n); for (int i = 0; i < n; i++) map.put(i, Math.abs(lambda.get(i))); IntArrayList list = new IntArrayList(); // Sorts the map on the value map.keysSortedByValue(list); // Gets the index of the second smallest element int i_2 = list.get(1); // y_2 = D^(-1/2) * z_2 DoubleMatrix1D y_2 = e.getV().viewColumn(i_2).copy(); y_2.assign(d_minus_1_2, Functions.mult); // Creates a map that contains the pairs <i, y_2[i]> map.clear(); for (int i = 0; i < n; i++) map.put(i, y_2.get(i)); // Sorts the map on the value map.keysSortedByValue(list); // Search the element in the map previuosly ordered that minimizes the cut // of the partition double best_cut = Double.POSITIVE_INFINITY; int[][] partition = new int[2][]; // The array v contains all the elements of the graph ordered by their // projection on vector y_2 int[] v = list.elements(); // For each admissible splitting point i for (int i = 1; i < n; i++) { // The array a contains all the elements that have a projection on vector // y_2 less or equal to the one of i-th element // The array b contains the remaining elements int[] a = new int[i]; int[] b = new int[n - i]; System.arraycopy(v, 0, a, 0, i); System.arraycopy(v, i, b, 0, n - i); double cut = Ncut(W, a, b, v); if (cut < best_cut) { best_cut = cut; partition[0] = a; partition[1] = b; } } // System.out.println("Partition:"); // UtilsJS.printMatrix(partition); return partition; }
public final DoubleMatrix2D getData() { return data2.copy(); }