예제 #1
0
        /**
         * <p>
         * Solves for x in the following equation:<br>
         * <br>
         * A*x = b
         * </p>
         *
         * <p>
         * If the system could not be solved then false is returned.  If it returns true
         * that just means the algorithm finished operating, but the results could still be bad
         * because 'A' is singular or nearly singular.
         * </p>
         *
         * <p>
         * If repeat calls to solve are being made then one should consider using {@link LinearSolverFactory_DSCC}
         * instead.
         * </p>
         *
         * <p>
         * It is ok for 'b' and 'x' to be the same matrix.
         * </p>
         *
         * @param a (Input) A matrix that is m by n. Not modified.
         * @param b (Input) A matrix that is n by k. Not modified.
         * @param x (Output) A matrix that is m by k. Modified.
         *
         * @return true if it could invert the matrix false if it could not.
         */
        public static bool solve(DMatrixSparseCSC a,
                                 DMatrixRMaj b,
                                 DMatrixRMaj x)
        {
            LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver;

            if (a.numRows > a.numCols)
            {
                solver = LinearSolverFactory_DSCC.qr(FillReducing.NONE); // todo specify a filling that makes sense
            }
            else
            {
                solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE);
            }

            // Ensure that the input isn't modified
            if (solver.modifiesA())
            {
                a = (DMatrixSparseCSC)a.copy();
            }

            if (solver.modifiesB())
            {
                b = (DMatrixRMaj)b.copy();
            }

            // decompose then solve the matrix
            if (!solver.setA(a))
            {
                return(false);
            }

            solver.solve(b, x);
            return(true);
        }
예제 #2
0
        /**
         * <p>
         * Checks to see if the matrix is positive semidefinite:
         * </p>
         * <p>
         * x<sup>T</sup> A x &ge; 0<br>
         * for all x where x is a non-zero vector and A is a symmetric matrix.
         * </p>
         *
         * @param A square symmetric matrix. Not modified.
         *
         * @return True if it is positive semidefinite and false if it is not.
         */
        public static bool isPositiveSemidefinite(DMatrixRMaj A)
        {
            if (!isSquare(A))
            {
                return(false);
            }

            EigenDecomposition_F64 <DMatrixRMaj> eig = DecompositionFactory_DDRM.eig(A.numCols, false);

            if (eig.inputModified())
            {
                A = (DMatrixRMaj)A.copy();
            }
            eig.decompose(A);

            for (int i = 0; i < A.numRows; i++)
            {
                Complex_F64 v = eig.getEigenvalue(i);

                if (v.getReal() < 0)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        /**
         * Computes the QR decomposition of the provided matrix.
         *
         * @param A Matrix which is to be decomposed.  Not modified.
         */
        public void decompose(DMatrixRMaj A)
        {
            Equation.Equation eq = new Equation.Equation();

            this.QR = (DMatrixRMaj)A.copy();

            int N = Math.Min(A.numCols, A.numRows);

            gammas = new double[A.numCols];

            for (int i = 0; i < N; i++)
            {
                // update temporary variables
                eq.alias(QR.numRows - i, "Ni", QR, "QR", i, "i");

                // Place the column that should be zeroed into v
                eq.process("v=QR(i:,i)");
                eq.process("maxV=max(abs(v))");

                // Note that v is lazily created above.  Need direct access to it, which is done below.
                DMatrixRMaj v = eq.lookupMatrix("v");

                double maxV = eq.lookupDouble("maxV");
                if (maxV > 0 && v.getNumElements() > 1)
                {
                    // normalize to reduce overflow issues
                    eq.process("v=v/maxV");

                    // compute the magnitude of the vector
                    double tau = NormOps_DDRM.normF(v);

                    if (v.get(0) < 0)
                    {
                        tau *= -1.0;
                    }

                    eq.alias(tau, "tau");
                    eq.process("u_0 = v(0,0)+tau");
                    eq.process("gamma = u_0/tau");
                    eq.process("v=v/u_0");
                    eq.process("v(0,0)=1");
                    eq.process("QR(i:,i:) = (eye(Ni) - gamma*v*v')*QR(i:,i:)");
                    eq.process("QR(i:,i) = v");
                    eq.process("QR(i,i) = -1*tau*maxV");

                    // save gamma for recomputing Q later on
                    gammas[i] = eq.lookupDouble("gamma");
                }
            }
        }
        /**
         * <p>
         * Checks to see if the matrix is positive definite.
         * </p>
         * <p>
         * x<sup>T</sup> A x &gt; 0<br>
         * for all x where x is a non-zero vector and A is a symmetric matrix.
         * </p>
         *
         * @param A square symmetric matrix. Not modified.
         * @return True if it is positive definite and false if it is not.
         */
        public static bool isPositiveDefinite(DMatrixRMaj A)
        {
            if (!isSquare(A))
            {
                return(false);
            }

            CholeskyDecompositionInner_DDRM chol = new CholeskyDecompositionInner_DDRM(true);

            if (chol.inputModified())
            {
                A = A.copy();
            }

            return(chol.decompose(A));
        }
        /**
         * Creates a random distribution with the specified mean and covariance.  The references
         * to the variables are not saved, their value are copied.
         *
         * @param rand Used to create the random numbers for the draw. Reference is saved.
         * @param cov The covariance of the distribution.  Not modified.
         */
        public CovarianceRandomDraw_DDRM(IMersenneTwister rand, DMatrixRMaj cov)
        {
            r = new DMatrixRMaj(cov.numRows, 1);
            CholeskyDecompositionInner_DDRM cholesky = new CholeskyDecompositionInner_DDRM(true);

            if (cholesky.inputModified())
            {
                cov = (DMatrixRMaj)cov.copy();
            }
            if (!cholesky.decompose(cov))
            {
                throw new InvalidOperationException("Decomposition failed!");
            }

            A         = cholesky.getT();
            this.rand = rand;
        }
예제 #6
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(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));
        }
        /**
         * Checks to see if the rows of the provided matrix are linearly independent.
         *
         * @param A Matrix whose rows are being tested for linear independence.
         * @return true if linearly independent and false otherwise.
         */
        public static bool isRowsLinearIndependent(DMatrixRMaj A)
        {
            // LU decomposition
            LUDecomposition <DMatrixRMaj> lu = DecompositionFactory_DDRM.lu(A.numRows, A.numCols);

            if (lu.inputModified())
            {
                A = A.copy();
            }

            if (!lu.decompose(A))
            {
                throw new SystemException("Decompositon failed?");
            }

            // if they are linearly independent it should not be singular
            return(!lu.isSingular());
        }
        /**
         * Creates a random distribution with the specified mean and covariance.  The references
         * to the variables are not saved, their value are copied.
         *
         * @param rand Used to create the random numbers for the draw. Reference is saved.
         * @param cov The covariance of the distribution.  Not modified.
         */
        public CovarianceRandomDraw_DDRM(Random rand, DMatrixRMaj cov)
        {
            r = new DMatrixRMaj(cov.numRows, 1);
            CholeskyDecompositionInner_DDRM cholesky = new CholeskyDecompositionInner_DDRM(true);

            if (cholesky.inputModified())
            {
                cov = cov.copy();
            }
            if (!cholesky.decompose(cov))
            {
                throw new SystemException("Decomposition failed!");
            }

            A = cholesky.getT();
            //this.rand = rand;
            this.rand = new Java.Util.Random();
        }
예제 #9
0
        public override object Clone()
        {
            CMAESSpecies myobj = (CMAESSpecies)(base.Clone());

            // clone the distribution and other variables here
            myobj.c        = c.copy();
            myobj.b        = b.copy();
            myobj.d        = d.copy();
            myobj.bd       = (DMatrixRMaj)bd.copy();
            myobj.sbd      = (DMatrixRMaj)sbd.copy();
            myobj.invsqrtC = invsqrtC.copy();

            myobj.xmean = xmean.copy();
            myobj.ps    = ps.copy();
            myobj.pc    = pc.copy();

            return(myobj);
        }
예제 #10
0
        public void setup(DMatrixRMaj A)
        {
            if (A.numRows != A.numCols)
            {
                throw new InvalidOperationException("Must be square");
            }

            if (N != A.numRows)
            {
                N = A.numRows;

                this.A = (DMatrixRMaj)A.copy();
                u      = new DMatrixRMaj(A.numRows, 1);

                _temp        = new DMatrixRMaj(A.numRows, 1);
                numStepsFind = new int[A.numRows];
            }
            else
            {
                this.A.set(A);
                UtilEjml.memset(numStepsFind, 0, numStepsFind.Length);
            }

            // zero all the off numbers that should be zero for a hessenberg matrix
            for (int i = 2; i < N; i++)
            {
                for (int j = 0; j < i - 1; j++)
                {
                    this.A.set(i, j, 0);
                }
            }

            eigenvalues = new Complex_F64[A.numRows];
            for (int i = 0; i < eigenvalues.Length; i++)
            {
                eigenvalues[i] = new Complex_F64();
            }

            numEigen        = 0;
            lastExceptional = 0;
            numExceptional  = 0;
            steps           = 0;
        }
예제 #11
0
        private List <DMatrixRMaj> createSimulatedMeas(DMatrixRMaj x)
        {
            List <DMatrixRMaj> ret = new List <DMatrixRMaj>();

            DMatrixRMaj F = createF(T);
            DMatrixRMaj H = createH();

//        UtilEjml.print(F);
//        UtilEjml.print(H);

            DMatrixRMaj x_next = new DMatrixRMaj(x);
            DMatrixRMaj z      = new DMatrixRMaj(H.numRows, 1);

            for (int i = 0; i < MAX_STEPS; i++)
            {
                CommonOps_DDRM.mult(F, x, x_next);
                CommonOps_DDRM.mult(H, x_next, z);
                ret.Add((DMatrixRMaj)z.copy());
                x.set(x_next);
            }

            return(ret);
        }
예제 #12
0
        /**
         * Computes the QR decomposition of the provided matrix.
         *
         * @param A Matrix which is to be decomposed.  Not modified.
         */
        public void decompose(DMatrixRMaj A)
        {
            this.QR = (DMatrixRMaj)A.copy();

            int N = Math.Min(A.numCols, A.numRows);

            gammas = new double[A.numCols];

            DMatrixRMaj A_small = new DMatrixRMaj(A.numRows, A.numCols);
            DMatrixRMaj A_mod   = new DMatrixRMaj(A.numRows, A.numCols);
            DMatrixRMaj v       = new DMatrixRMaj(A.numRows, 1);
            DMatrixRMaj Q_k     = new DMatrixRMaj(A.numRows, A.numRows);

            for (int i = 0; i < N; i++)
            {
                // reshape temporary variables
                A_small.reshape(QR.numRows - i, QR.numCols - i, false);
                A_mod.reshape(A_small.numRows, A_small.numCols, false);
                v.reshape(A_small.numRows, 1, false);
                Q_k.reshape(v.getNumElements(), v.getNumElements(), false);

                // use extract matrix to get the column that is to be zeroed
                CommonOps_DDRM.extract(QR, i, QR.numRows, i, i + 1, v, 0, 0);

                double max = CommonOps_DDRM.elementMaxAbs(v);

                if (max > 0 && v.getNumElements() > 1)
                {
                    // normalize to reduce overflow issues
                    CommonOps_DDRM.divide(v, max);

                    // compute the magnitude of the vector
                    double tau = NormOps_DDRM.normF(v);

                    if (v.get(0) < 0)
                    {
                        tau *= -1.0;
                    }

                    double u_0   = v.get(0) + tau;
                    double gamma = u_0 / tau;

                    CommonOps_DDRM.divide(v, u_0);
                    v.set(0, 1.0);

                    // extract the submatrix of A which is being operated on
                    CommonOps_DDRM.extract(QR, i, QR.numRows, i, QR.numCols, A_small, 0, 0);

                    // A = (I - &gamma;*u*u<sup>T</sup>)A
                    CommonOps_DDRM.setIdentity(Q_k);
                    CommonOps_DDRM.multAddTransB(-gamma, v, v, Q_k);
                    CommonOps_DDRM.mult(Q_k, A_small, A_mod);

                    // save the results
                    CommonOps_DDRM.insert(A_mod, QR, i, i);
                    CommonOps_DDRM.insert(v, QR, i, i);
                    QR.unsafe_set(i, i, -tau * max);

                    // save gamma for recomputing Q later on
                    gammas[i] = gamma;
                }
            }
        }