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