public static double quality(DMatrixRMaj orig, DMatrixRMaj U, DMatrixRMaj W, DMatrixRMaj Vt)
        {
            // foundA = U*W*Vt
            DMatrixRMaj UW = new DMatrixRMaj(U.numRows, W.numCols);

            CommonOps_DDRM.mult(U, W, UW);
            DMatrixRMaj foundA = new DMatrixRMaj(UW.numRows, Vt.numCols);

            CommonOps_DDRM.mult(UW, Vt, foundA);

            double normA = NormOps_DDRM.normF(foundA);

            return(SpecializedOps_DDRM.diffNormF(orig, foundA) / normA);
        }
        /**
         * <p>
         * Creates a reflector from the provided vector.<br>
         * <br>
         * Q = I - &gamma; u u<sup>T</sup><br>
         * &gamma; = 2/||u||<sup>2</sup>
         * </p>
         *
         * <p>
         * In practice {@link VectorVectorMult_DDRM#householder(double, DMatrixD1, DMatrixD1, DMatrixD1)}  multHouseholder}
         * should be used for performance reasons since there is no need to calculate Q explicitly.
         * </p>
         *
         * @param u A vector. Not modified.
         * @return An orthogonal reflector.
         */
        public static DMatrixRMaj createReflector(DMatrix1Row u)
        {
            if (!MatrixFeatures_DDRM.isVector(u))
            {
                throw new ArgumentException("u must be a vector");
            }

            double norm  = NormOps_DDRM.fastNormF(u);
            double gamma = -2.0 / (norm * norm);

            DMatrixRMaj Q = CommonOps_DDRM.identity(u.NumElements);

            CommonOps_DDRM.multAddTransB(gamma, u, u, Q);

            return(Q);
        }
示例#3
0
        /**
         * <p>
         * Creates a randomly generated set of orthonormal vectors.  At most it can generate the same
         * number of vectors as the dimension of the vectors.
         * </p>
         *
         * <p>
         * This is done by creatingJava.Util.Random vectors then ensuring that they are orthogonal
         * to all the ones previously created with reflectors.
         * </p>
         *
         * <p>
         * NOTE: This employs a brute force O(N<sup>3</sup>) algorithm.
         * </p>
         *
         * @param dimen dimension of the space which the vectors will span.
         * @param numVectors How many vectors it should generate.
         * @param rand Used to createJava.Util.Random vectors.
         * @return Array of NJava.Util.Random orthogonal vectors of unit Count().
         */
        // is there a faster algorithm out there? This one is a bit sluggish
        public static DMatrixRMaj[] span(int dimen, int numVectors, Java.Util.Random rand)
        {
            if (dimen < numVectors)
            {
                throw new ArgumentException("The number of vectors must be less than or equal to the dimension");
            }

            DMatrixRMaj[] u = new DMatrixRMaj[numVectors];

            u[0] = RandomMatrices_DDRM.rectangle(dimen, 1, -1, 1, rand);
            NormOps_DDRM.normalizeF(u[0]);

            for (int i = 1; i < numVectors; i++)
            {
                //            System.out.println(" i = "+i);
                DMatrixRMaj a = new DMatrixRMaj(dimen, 1);
                DMatrixRMaj r = RandomMatrices_DDRM.rectangle(dimen, 1, -1, 1, rand);

                for (int j = 0; j < i; j++)
                {
                    // find a vector that is normal to vector j
                    // u[i] = (1/2)*(r + Q[j]*r)
                    a.setTo(r);
                    VectorVectorMult_DDRM.householder(-2.0, u[j], r, a);
                    CommonOps_DDRM.add(r, a, a);
                    CommonOps_DDRM.scale(0.5, a);

                    //                UtilEjml.print(a);

                    DMatrixRMaj t = a;
                    a = r;
                    r = t;

                    // normalize it so it doesn't get too small
                    double val = NormOps_DDRM.normF(r);
                    if (val == 0 || Double.IsNaN(val) || Double.IsInfinity(val))
                    {
                        throw new SystemException("Failed sanity check");
                    }
                    CommonOps_DDRM.divide(r, val);
                }

                u[i] = r;
            }

            return(u);
        }
        /**
         * <p>
         * Computes the F norm of the difference between the two Matrices:<br>
         * <br>
         * Sqrt{&sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> ( a<sub>ij</sub> - b<sub>ij</sub>)<sup>2</sup>}
         * </p>
         * <p>
         * This is often used as a cost function.
         * </p>
         *
         * @param a m by n matrix. Not modified.
         * @param b m by n matrix. Not modified.
         * @return The F normal of the difference matrix.
         * @see NormOps_DDRM#fastNormF
         */
        public static double diffNormF(DMatrixD1 a, DMatrixD1 b)
        {
            if (a.numRows != b.numRows || a.numCols != b.numCols)
            {
                throw new ArgumentException("Both matrices must have the same shape.");
            }

            int size = a.NumElements;

            DMatrixRMaj diff = new DMatrixRMaj(size, 1);

            for (int i = 0; i < size; i++)
            {
                diff.set(i, b.get(i) - a.get(i));
            }
            return(NormOps_DDRM.normF(diff));
        }
示例#5
0
 public double normF(Matrix A)
 {
     return(NormOps_DDRM.normF((DMatrixRMaj)A));
 }