예제 #1
0
        /**
         * Creates a new random symmetric matrix that will have the specified real eigenvalues.
         *
         * @param num Dimension of the resulting matrix.
         * @param rand Random number generator.
         * @param eigenvalues Set of real eigenvalues that the matrix will have.
         * @return A random matrix with the specified eigenvalues.
         */
        public static FMatrixRMaj symmetricWithEigenvalues(int num, IMersenneTwister rand, float[] eigenvalues)
        {
            FMatrixRMaj V = RandomMatrices_FDRM.orthogonal(num, num, rand);
            FMatrixRMaj D = CommonOps_FDRM.diag(eigenvalues);

            FMatrixRMaj temp = new FMatrixRMaj(num, num);

            CommonOps_FDRM.mult(V, D, temp);
            CommonOps_FDRM.multTransB(temp, V, D);

            return(D);
        }
예제 #2
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 creating 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 create random vectors.
         * @return Array of N random orthogonal vectors of unit length.
         */
        // is there a faster algorithm out there? This one is a bit sluggish
        public static FMatrixRMaj[] span(int dimen, int numVectors, IMersenneTwister rand)
        {
            if (dimen < numVectors)
            {
                throw new ArgumentException("The number of vectors must be less than or equal to the dimension");
            }

            FMatrixRMaj[] u = new FMatrixRMaj[numVectors];

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

            for (int i = 1; i < numVectors; i++)
            {
//            Console.WriteLine(" i = "+i);
                FMatrixRMaj a = new FMatrixRMaj(dimen, 1);
                FMatrixRMaj r = null;

                for (int j = 0; j < i; j++)
                {
//                Console.WriteLine("j = "+j);
                    if (j == 0)
                    {
                        r = RandomMatrices_FDRM.rectangle(dimen, 1, -1, 1, rand);
                    }

                    // find a vector that is normal to vector j
                    // u[i] = (1/2)*(r + Q[j]*r)
                    a.set(r);
                    VectorVectorMult_FDRM.householder(-2.0f, u[j], r, a);
                    CommonOps_FDRM.add(r, a, a);
                    CommonOps_FDRM.scale(0.5f, a);

//                UtilEjml.print(a);

                    FMatrixRMaj t = a;
                    a = r;
                    r = t;

                    // normalize it so it doesn't get too small
                    float val = NormOps_FDRM.normF(r);
                    if (val == 0 || float.IsNaN(val) || float.IsInfinity(val))
                    {
                        throw new InvalidOperationException("Failed sanity check");
                    }
                    CommonOps_FDRM.divide(r, val);
                }

                u[i] = r;
            }

            return(u);
        }
예제 #3
0
        /**
         * <p>
         * Creates a random matrix which will have the provided singular values.  The length of sv
         * is assumed to be the rank of the matrix.  This can be useful for testing purposes when one
         * needs to ensure that a matrix is not singular but randomly generated.
         * </p>
         *
         * @param numRows Number of rows in generated matrix.
         * @param numCols NUmber of columns in generated matrix.
         * @param rand Random number generator.
         * @param sv Singular values of the matrix.
         * @return A new matrix with the specified singular values.
         */
        public static FMatrixRMaj singleValues(int numRows, int numCols,
                                               IMersenneTwister rand, float[] sv)
        {
            FMatrixRMaj U = RandomMatrices_FDRM.orthogonal(numRows, numRows, rand);
            FMatrixRMaj V = RandomMatrices_FDRM.orthogonal(numCols, numCols, rand);

            FMatrixRMaj S = new FMatrixRMaj(numRows, numCols);

            int min = Math.Min(numRows, numCols);

            min = Math.Min(min, sv.Length);

            for (int i = 0; i < min; i++)
            {
                S.set(i, i, sv[i]);
            }

            FMatrixRMaj tmp = new FMatrixRMaj(numRows, numCols);

            CommonOps_FDRM.mult(U, S, tmp);
            CommonOps_FDRM.multTransB(tmp, V, S);

            return(S);
        }