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); }