Пример #1
0
  @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();
 }