/** * Computes a basis (the principal components) from the most dominant eigenvectors. * * @param numComponents Number of vectors it will use to describe the data. Typically much * smaller than the number of elements in the input vector. */ public void computeBasis(int numComponents) { if (numComponents > A.getNumCols()) { throw new ArgumentException("More components requested that the data's length."); } if (sampleIndex != A.getNumRows()) { throw new ArgumentException("Not all the data has been added"); } if (numComponents > sampleIndex) { throw new ArgumentException("More data needed to compute the desired number of components"); } this.numComponents = numComponents; // compute the mean of all the samples for (int i = 0; i < A.getNumRows(); i++) { for (int j = 0; j < mean.Length; j++) { mean[j] += A.get(i, j); } } for (int j = 0; j < mean.Length; j++) { mean[j] /= A.getNumRows(); } // subtract the mean from the original data for (int i = 0; i < A.getNumRows(); i++) { for (int j = 0; j < mean.Length; j++) { A.set(i, j, A.get(i, j) - mean[j]); } } // Compute SVD and save time by not computing U SingularValueDecomposition <DMatrixRMaj> svd = DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, true, false); if (!svd.decompose(A)) { throw new InvalidOperationException("SVD failed"); } V_t = svd.getV(null, true); DMatrixRMaj W = svd.getW(null); // Singular values are in an arbitrary order initially SingularOps_DDRM.descendingOrder(null, false, W, V_t, true); // strip off unneeded components and find the basis V_t.reshape(numComponents, mean.Length, true); }
/** * The nullity of the decomposed matrix. * * @see SingularOps_DDRM#nullity(SingularValueDecomposition_F64, double) * * @return The matrix's nullity */ public int nullity() { if (is64) { return(SingularOps_DDRM.nullity((SingularValueDecomposition_F64 <DMatrixRMaj>)svd, 10.0 * UtilEjml.EPS)); } else { return(SingularOps_FDRM.nullity((SingularValueDecomposition_F32 <FMatrixRMaj>)svd, 5.0f * UtilEjml.F_EPS)); } }
/** * Returns the rank of the decomposed matrix. * * @see SingularOps_DDRM#rank(SingularValueDecomposition_F64, double) * * @return The matrix's rank */ public int rank() { if (is64) { return(SingularOps_DDRM.rank((SingularValueDecomposition_F64 <DMatrixRMaj>)svd, tol)); } else { return(SingularOps_FDRM.rank((SingularValueDecomposition_F32 <FMatrixRMaj>)svd, (float)tol)); } }
public /**/ double quality() { if (is64) { var m = mat as DMatrixRMaj; var um = U.getMatrix() as DMatrixRMaj; var wm = W.getMatrix() as DMatrixRMaj; var vmt = V.transpose().getMatrix() as DMatrixRMaj; return(DecompositionFactory_DDRM.quality(m, um, wm, vmt)); } else { var m = mat as FMatrixRMaj; var um = U.getMatrix() as FMatrixRMaj; var wm = W.getMatrix() as FMatrixRMaj; var vmt = V.transpose().getMatrix() as FMatrixRMaj; return(DecompositionFactory_FDRM.quality(m, um, wm, vmt)); } } /** * Computes the null space from an SVD. For more information see {@link SingularOps_DDRM#nullSpace}. * @return Null space vector. */ public SimpleMatrix <T> nullSpace() { // TODO take advantage of the singular values being ordered already if (is64) { var ns = SingularOps_DDRM.nullSpace((SingularValueDecomposition_F64 <DMatrixRMaj>)svd, null, tol); return(SimpleMatrix <T> .wrap(ns as T)); } else { var ns = SingularOps_FDRM.nullSpace((SingularValueDecomposition_F32 <FMatrixRMaj>)svd, null, (float)tol); return(SimpleMatrix <T> .wrap(ns as T)); } }
public SimpleSVD(Matrix mat, bool compact) { this.mat = mat; this.is64 = mat is DMatrixRMaj; if (is64) { DMatrixRMaj m = (DMatrixRMaj)mat; svd = (SingularValueDecomposition <T>)DecompositionFactory_DDRM.svd(m.numRows, m.numCols, true, true, compact); } else { FMatrixRMaj m = (FMatrixRMaj)mat; svd = (SingularValueDecomposition <T>)DecompositionFactory_FDRM.svd(m.numRows, m.numCols, true, true, compact); } if (!svd.decompose((T)mat)) { throw new InvalidOperationException("Decomposition failed"); } U = SimpleMatrix <T> .wrap(svd.getU(null, false)); W = SimpleMatrix <T> .wrap(svd.getW(null)); V = SimpleMatrix <T> .wrap(svd.getV(null, false)); // order singular values from largest to smallest if (is64) { var um = U.getMatrix() as DMatrixRMaj; var wm = W.getMatrix() as DMatrixRMaj; var vm = V.getMatrix() as DMatrixRMaj; SingularOps_DDRM.descendingOrder(um, false, wm, vm, false); tol = SingularOps_DDRM.singularThreshold((SingularValueDecomposition_F64 <DMatrixRMaj>)svd); } else { var um = U.getMatrix() as FMatrixRMaj; var wm = W.getMatrix() as FMatrixRMaj; var vm = V.getMatrix() as FMatrixRMaj; SingularOps_FDRM.descendingOrder(um, false, wm, vm, false); tol = SingularOps_FDRM.singularThreshold((SingularValueDecomposition_F32 <FMatrixRMaj>)svd); } }