/** * Extracts the nullity of a matrix using a preexisting decomposition and default threshold. * * @param svd A precomputed decomposition. Not modified. * @return The nullity of the decomposed matrix. * @see #singularThreshold(SingularValueDecomposition_F64) */ public static int nullity <T>(SingularValueDecomposition_F64 <T> svd) where T : Matrix { double threshold = singularThreshold(svd); return(nullity(svd, threshold)); }
/** * <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); }
public static double singularThreshold <T>(SingularValueDecomposition_F64 <T> svd, double tolerance) where T : Matrix { double[] w = svd.getSingularValues(); int N = svd.numberOfSingularValues(); return(singularThreshold(w, N, tolerance)); }
/** * <p> * Returns the null-space from the singular value decomposition. The null space is a set of non-zero vectors that * when multiplied by the original matrix return zero. * </p> * * <p> * The null space is found by extracting the columns in V that are associated singular values less than * or equal to the threshold. In some situations a non-compact SVD is required. * </p> * * @param svd A precomputed decomposition. Not modified. * @param nullSpace Storage for null space. Will be reshaped as needed. Modified. * @param tol Threshold for selecting singular values. Try UtilEjml.EPS. * @return The null space. */ public static DMatrixRMaj nullSpace(SingularValueDecomposition_F64 <DMatrixRMaj> svd, DMatrixRMaj nullSpace, double tol) { int N = svd.numberOfSingularValues(); double[] s = svd.getSingularValues(); DMatrixRMaj V = svd.getV(null, true); if (V.numRows != svd.numCols()) { throw new ArgumentException( "Can't compute the null space using a compact SVD for a matrix of this size."); } // first determine the size of the null space int numVectors = svd.numCols() - N; for (int i = 0; i < N; i++) { if (s[i] <= tol) { numVectors++; } } // declare output data if (nullSpace == null) { nullSpace = new DMatrixRMaj(numVectors, svd.numCols()); } else { nullSpace.reshape(numVectors, svd.numCols()); } // now extract the vectors int count = 0; for (int i = 0; i < N; i++) { if (s[i] <= tol) { CommonOps_DDRM.extract(V, i, i + 1, 0, V.numCols, nullSpace, count++, 0); } } for (int i = N; i < svd.numCols(); i++) { CommonOps_DDRM.extract(V, i, i + 1, 0, V.numCols, nullSpace, count++, 0); } CommonOps_DDRM.transpose(nullSpace); return(nullSpace); }
/** * <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)); }
/** * Extracts the rank of a matrix using a preexisting decomposition. * * @see #singularThreshold(SingularValueDecomposition_F64) * * @param svd A precomputed decomposition. Not modified. * @param threshold Tolerance used to determine of a singular value is singular. * @return The rank of the decomposed matrix. */ public static int rank(SingularValueDecomposition_F64 <DMatrixRMaj> svd, double threshold) { int numRank = 0; double[] w = svd.getSingularValues(); int N = svd.numberOfSingularValues(); for (int j = 0; j < N; j++) { if (w[j] > threshold) { numRank++; } } return(numRank); }
/** * Extracts the nullity of a matrix using a preexisting decomposition. * * @see #singularThreshold(SingularValueDecomposition_F64) * * @param svd A precomputed decomposition. Not modified. * @param threshold Tolerance used to determine of a singular value is singular. * @return The nullity of the decomposed matrix. */ public static int nullity(SingularValueDecomposition_F64 <DMatrixRMaj> svd, double threshold) { int ret = 0; double[] w = svd.getSingularValues(); int N = svd.numberOfSingularValues(); int numCol = svd.numCols(); for (int j = 0; j < N; j++) { if (w[j] <= threshold) { ret++; } } return(ret + numCol - N); }
/** * Returns a reasonable threshold for singular values.<br><br> * * tol = max (size (A)) * largest sigma * eps; * * @param svd A precomputed decomposition. Not modified. * @return threshold for singular values */ public static double singularThreshold(SingularValueDecomposition_F64 <DMatrixRMaj> svd) { double largest = 0; double[] w = svd.getSingularValues(); int N = svd.numberOfSingularValues(); for (int j = 0; j < N; j++) { if (w[j] > largest) { largest = w[j]; } } int M = Math.Max(svd.numCols(), svd.numRows()); return(M * largest * UtilEjml.EPS); }
/** * Returns a reasonable threshold for singular values.<br><br> * * tol = max (size (A)) * largest sigma * eps; * * @param svd A precomputed decomposition. Not modified. * @return threshold for singular values */ public static double singularThreshold <T>(SingularValueDecomposition_F64 <T> svd) where T : Matrix { return(singularThreshold(svd, UtilEjml.EPS)); }
/** * <p> * The vector associated will the smallest singular value is returned as the null space * of the decomposed system. A right null space is returned if 'isRight' is set to true, * and a left null space if false. * </p> * * @param svd A precomputed decomposition. Not modified. * @param isRight true for right null space and false for left null space. Right is more commonly used. * @param nullVector Optional storage for a vector for the null space. Modified. * @return Vector in V associated with smallest singular value.. */ public static DMatrixRMaj nullVector(SingularValueDecomposition_F64 <DMatrixRMaj> svd, bool isRight, DMatrixRMaj nullVector) { int N = svd.numberOfSingularValues(); double[] s = svd.getSingularValues(); DMatrixRMaj A = isRight ? svd.getV(null, true) : svd.getU(null, false); if (isRight) { if (A.numRows != svd.numCols()) { throw new ArgumentException("Can't compute the null space using a compact SVD for a matrix of this size."); } if (nullVector == null) { nullVector = new DMatrixRMaj(svd.numCols(), 1); } else { nullVector.reshape(svd.numCols(), 1); } } else { if (A.numCols != svd.numRows()) { throw new ArgumentException("Can't compute the null space using a compact SVD for a matrix of this size."); } if (nullVector == null) { nullVector = new DMatrixRMaj(svd.numRows(), 1); } else { nullVector.reshape(svd.numRows(), 1); } } int smallestIndex = -1; if (isRight && svd.numCols() > svd.numRows()) { smallestIndex = svd.numCols() - 1; } else if (!isRight && svd.numCols() < svd.numRows()) { smallestIndex = svd.numRows() - 1; } else { // find the smallest singular value double smallestValue = Double.MaxValue; for (int i = 0; i < N; i++) { if (s[i] < smallestValue) { smallestValue = s[i]; smallestIndex = i; } } } // extract the null space if (isRight) { SpecializedOps_DDRM.subvector(A, smallestIndex, 0, A.numRows, true, 0, nullVector); } else { SpecializedOps_DDRM.subvector(A, 0, smallestIndex, A.numRows, false, 0, nullVector); } return(nullVector); }
/** * 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); }
/** * Extracts the nullity of a matrix using a preexisting decomposition and default threshold. * * @see #singularThreshold(SingularValueDecomposition_F64) * * @param svd A precomputed decomposition. Not modified. * @return The nullity of the decomposed matrix. */ public static int nullity(SingularValueDecomposition_F64 <DMatrixRMaj> svd) { double threshold = singularThreshold(svd); return(nullity(svd, threshold)); }
public SafeSvd_DDRM(SingularValueDecomposition_F64 <DMatrixRMaj> alg) { this.alg = alg; }