/** * <p> * The condition p = 2 number of a matrix is used to measure the sensitivity of the linear * system <b>Ax=b</b>. A value near one indicates that it is a well conditioned matrix.<br> * <br> * κ<sub>2</sub> = ||A||<sub>2</sub>||A<sup>-1</sup>||<sub>2</sub> * </p> * <p> * This is also known as the spectral condition number. * </p> * * @param A The matrix. * @return The condition number. */ public static double conditionP2(DMatrixRMaj A) { SingularValueDecomposition_F64 <DMatrixRMaj> svd = DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, false, true); svd.decompose(A); double[] singularValues = svd.getSingularValues(); int n = SingularOps_DDRM.rank(svd, UtilEjml.TEST_F64); if (n == 0) { return(0); } double smallest = double.MaxValue; double largest = double.MinValue; foreach (double s in singularValues) { if (s < smallest) { smallest = s; } if (s > largest) { largest = s; } } return(largest / smallest); }
/** * 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); }
/** * <p> * Computes the induced p = 2 matrix norm, which is the largest singular value. * </p> * * @param A Matrix. Not modified. * @return The norm. */ public static double inducedP2(DMatrixRMaj A) { SingularValueDecomposition_F64 <DMatrixRMaj> svd = DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, false, true); if (!svd.decompose(A)) { throw new InvalidOperationException("Decomposition failed"); } double[] singularValues = svd.getSingularValues(); // the largest singular value is the induced p2 norm return(UtilEjml.max(singularValues, 0, singularValues.Length)); }
/** * Computes the nullity of a matrix using the specified tolerance. * * @param A Matrix whose rank is to be calculated. Not modified. * @param threshold The numerical threshold used to determine a singular value. * @return The matrix's nullity. */ public static int nullity(DMatrixRMaj A, double threshold) { SingularValueDecomposition_F64 <DMatrixRMaj> svd = DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, false, true); if (svd.inputModified()) { A = (DMatrixRMaj)A.copy(); } if (!svd.decompose(A)) { throw new InvalidOperationException("Decomposition failed"); } return(SingularOps_DDRM.nullity(svd, threshold)); }
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); } }
/** * Creates a new solver targeted at the specified matrix size. * * @param maxRows The expected largest matrix it might have to process. Can be larger. * @param maxCols The expected largest matrix it might have to process. Can be larger. */ public SolvePseudoInverseSvd_DDRM(int maxRows, int maxCols) { svd = DecompositionFactory_DDRM.svd(maxRows, maxCols, true, true, true); }