예제 #1
0
  public int rank(double effectiveZero) {

    DenseMatrix svdDude;

    if (this instanceof DenseMatrix) {
      svdDude = (DenseMatrix) this;
    } else {
      svdDude = new DenseMatrix(this);
    }

    SingularValueDecomposition svd = SingularValueDecompositionMTJ.create(svdDude);

    return svd.effectiveRank(effectiveZero);
  }
  /**
   * Test of learn method, of class gov.sandia.cognition.learning.pca.PrincipalComponentsAnalysis.
   *
   * <p>The example data is based on: http://www.kernel-machines.org/code/kpca_toy.m
   */
  public void testPCALearn() {
    System.out.println("PCA.learn");

    int num = random.nextInt(100) + 10;
    ArrayList<Vector> data = new ArrayList<Vector>(num);
    final double r1 = random.nextDouble();
    final double r2 = r1 / random.nextDouble();
    for (int i = 0; i < num; i++) {
      data.add(VectorFactory.getDefault().createUniformRandom(INPUT_DIM, r1, r2, random));
    }

    Vector mean = MultivariateStatisticsUtil.computeMean(data);

    DenseMatrix X = DenseMatrixFactoryMTJ.INSTANCE.createMatrix(INPUT_DIM, num);
    for (int n = 0; n < num; n++) {
      X.setColumn(n, data.get(n).minus(mean));
    }

    final ArrayList<Vector> dataCopy = ObjectUtil.cloneSmartElementsAsArrayList(data);

    long startsvd = System.currentTimeMillis();
    SingularValueDecomposition svd = SingularValueDecompositionMTJ.create(X);
    long stopsvd = System.currentTimeMillis();

    long start = System.currentTimeMillis();
    PrincipalComponentsAnalysis instance = this.createPCAInstance();
    PrincipalComponentsAnalysisFunction f = instance.learn(data);
    long stop = System.currentTimeMillis();

    assertEquals(dataCopy, data);

    System.out.println("Uhat:\n" + f.getDimensionReducer().getDiscriminant().transpose());
    System.out.println("U:\n" + svd.getU());

    System.out.println("Time taken: SVD = " + (stopsvd - startsvd) + ", PCA = " + (stop - start));

    // Make sure the PCA algorithm subtracted off the sample mean
    if (mean.equals(f.getMean(), 1e-5) == false) {
      assertEquals(mean, f.getMean());
    }

    assertEquals(OUTPUT_DIM, instance.getNumComponents());
    assertEquals(instance.getNumComponents(), f.getOutputDimensionality());
    assertEquals(INPUT_DIM, f.getInputDimensionality());

    if (mean.equals(f.getMean(), 1e-5) == false) {
      assertEquals(mean, f.getMean());
    }

    double absnorm = 0.0;
    int nc = instance.getNumComponents() * INPUT_DIM;
    for (int i = 0; i < instance.getNumComponents(); i++) {
      Vector uihat = f.getDimensionReducer().getDiscriminant().getRow(i);
      for (int j = 0; j < i; j++) {
        Vector ujhat = f.getDimensionReducer().getDiscriminant().getRow(j);
        assertEquals(
            "Dot product between " + i + " and " + j + " is too large!",
            0.0,
            uihat.dotProduct(ujhat),
            1e-2);
      }
      assertEquals(1.0, uihat.norm2(), 1e-5);
      Vector ui = svd.getU().getColumn(i);
      absnorm += Math.min(ui.minus(uihat).norm2(), ui.minus(uihat.scale(-1)).norm2());
    }
    absnorm /= nc;

    System.out.println("U 1-norm: " + absnorm);
    assertEquals(0.0, absnorm, 1e-1);
  }