Example #1
0
        /**
         * <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>
         * &kappa;<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 float conditionP2(FMatrixRMaj A)
        {
            SingularValueDecomposition_F32 <FMatrixRMaj> svd =
                DecompositionFactory_FDRM.svd(A.numRows, A.numCols, false, false, true);

            svd.decompose(A);

            float[] singularValues = svd.getSingularValues();

            int n = SingularOps_FDRM.rank(svd, UtilEjml.TEST_F32);

            if (n == 0)
            {
                return(0);
            }

            float smallest = float.MaxValue;
            float largest  = float.MinValue;

            foreach (float s in singularValues)
            {
                if (s < smallest)
                {
                    smallest = s;
                }
                if (s > largest)
                {
                    largest = s;
                }
            }

            return(largest / smallest);
        }
Example #2
0
        /**
         * <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.F_EPS.
         * @return The null space.
         */
        public static FMatrixRMaj nullSpace(SingularValueDecomposition_F32 <FMatrixRMaj> svd,
                                            FMatrixRMaj nullSpace, float tol)
        {
            int N = svd.numberOfSingularValues();

            float[] s = svd.getSingularValues();

            FMatrixRMaj 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 FMatrixRMaj(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_FDRM.extract(V, i, i + 1, 0, V.numCols, nullSpace, count++, 0);
                }
            }
            for (int i = N; i < svd.numCols(); i++)
            {
                CommonOps_FDRM.extract(V, i, i + 1, 0, V.numCols, nullSpace, count++, 0);
            }

            CommonOps_FDRM.transpose(nullSpace);

            return(nullSpace);
        }
Example #3
0
        /**
         * <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 float inducedP2(FMatrixRMaj A)
        {
            SingularValueDecomposition_F32 <FMatrixRMaj> svd =
                DecompositionFactory_FDRM.svd(A.numRows, A.numCols, false, false, true);

            if (!svd.decompose(A))
            {
                throw new InvalidOperationException("Decomposition failed");
            }

            float[] singularValues = svd.getSingularValues();

            // the largest singular value is the induced p2 norm
            return(UtilEjml.max(singularValues, 0, singularValues.Length));
        }
Example #4
0
        /**
         * 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(FMatrixRMaj A, float threshold)
        {
            SingularValueDecomposition_F32 <FMatrixRMaj> svd =
                DecompositionFactory_FDRM.svd(A.numRows, A.numCols, false, false, true);

            if (svd.inputModified())
            {
                A = (FMatrixRMaj)A.copy();
            }

            if (!svd.decompose(A))
            {
                throw new InvalidOperationException("Decomposition failed");
            }

            return(SingularOps_FDRM.nullity(svd, threshold));
        }
Example #5
0
        /**
         * Extracts the rank of a matrix using a preexisting decomposition.
         *
         * @see #singularThreshold(SingularValueDecomposition_F32)
         *
         * @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_F32 <FMatrixRMaj> svd, float threshold)
        {
            int numRank = 0;

            float[] w = svd.getSingularValues();

            int N = svd.numberOfSingularValues();

            for (int j = 0; j < N; j++)
            {
                if (w[j] > threshold)
                {
                    numRank++;
                }
            }

            return(numRank);
        }
Example #6
0
        /**
         * Extracts the nullity of a matrix using a preexisting decomposition.
         *
         * @see #singularThreshold(SingularValueDecomposition_F32)
         *
         * @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_F32 <FMatrixRMaj> svd, float threshold)
        {
            int ret = 0;

            float[] 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);
        }
Example #7
0
        /**
         * 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 float singularThreshold(SingularValueDecomposition_F32 <FMatrixRMaj> svd)
        {
            float largest = 0;

            float[] 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.F_EPS);
        }
Example #8
0
 public SafeSvd_FDRM(SingularValueDecomposition_F32 <FMatrixRMaj> alg)
 {
     this.alg = alg;
 }
 /**
  * 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_FDRM(int maxRows, int maxCols)
 {
     svd = DecompositionFactory_FDRM.svd(maxRows, maxCols, true, true, true);
 }
Example #10
0
        /**
         * Extracts the nullity of a matrix using a preexisting decomposition and default threshold.
         *
         * @see #singularThreshold(SingularValueDecomposition_F32)
         *
         * @param svd A precomputed decomposition.  Not modified.
         * @return The nullity of the decomposed matrix.
         */
        public static int nullity(SingularValueDecomposition_F32 <FMatrixRMaj> svd)
        {
            float threshold = singularThreshold(svd);

            return(nullity(svd, threshold));
        }
Example #11
0
        /**
         * <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 FMatrixRMaj nullVector(SingularValueDecomposition_F32 <FMatrixRMaj> svd,
                                             bool isRight,
                                             FMatrixRMaj nullVector)
        {
            int N = svd.numberOfSingularValues();

            float[] s = svd.getSingularValues();

            FMatrixRMaj 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 FMatrixRMaj(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 FMatrixRMaj(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
                float smallestValue = float.MaxValue;

                for (int i = 0; i < N; i++)
                {
                    if (s[i] < smallestValue)
                    {
                        smallestValue = s[i];
                        smallestIndex = i;
                    }
                }
            }

            // extract the null space
            if (isRight)
            {
                SpecializedOps_FDRM.subvector(A, smallestIndex, 0, A.numRows, true, 0, nullVector);
            }
            else
            {
                SpecializedOps_FDRM.subvector(A, 0, smallestIndex, A.numRows, false, 0, nullVector);
            }

            return(nullVector);
        }