예제 #1
0
        /**
         * Computes the d and H parameters.  Where d is the average error gradient and
         * H is an approximation of the hessian.
         */
        private void computeDandH(DMatrixRMaj param, DMatrixRMaj x, DMatrixRMaj y)
        {
            func.compute(param, x, tempDH);
            CommonOps_DDRM.subtractEquals(tempDH, y);

            computeNumericalJacobian(param, x, jacobian);

            int numParam = param.getNumElements();
            int length   = x.getNumElements();

            // d = average{ (f(x_i;p) - y_i) * jacobian(:,i) }
            for (int i = 0; i < numParam; i++)
            {
                double total = 0;
                for (int j = 0; j < length; j++)
                {
                    total += tempDH.get(j, 0) * jacobian.get(i, j);
                }
                d.set(i, 0, total / length);
            }

            // compute the approximation of the hessian
            CommonOps_DDRM.multTransB(jacobian, jacobian, H);
            CommonOps_DDRM.scale(1.0 / length, H);
        }
예제 #2
0
        //@Override
        public void update(DMatrixRMaj z, DMatrixRMaj R)
        {
            // y = z - H x
            CommonOps_DDRM.mult(H, x, y);
            CommonOps_DDRM.subtract(z, y, y);

            // S = H P H' + R
            CommonOps_DDRM.mult(H, P, c);
            CommonOps_DDRM.multTransB(c, H, S);
            CommonOps_DDRM.addEquals(S, R);

            // K = PH'S^(-1)
            if (!solver.setA(S))
            {
                throw new InvalidOperationException("Invert failed");
            }
            solver.invert(S_inv);
            CommonOps_DDRM.multTransA(H, S_inv, d);
            CommonOps_DDRM.mult(P, d, K);

            // x = x + Ky
            CommonOps_DDRM.mult(K, y, a);
            CommonOps_DDRM.addEquals(x, a);

            // P = (I-kH)P = P - (KH)P = P-K(HP)
            CommonOps_DDRM.mult(H, P, c);
            CommonOps_DDRM.mult(K, c, b);
            CommonOps_DDRM.subtractEquals(P, b);
        }
예제 #3
0
        //@Override
        public void predict()
        {
            // x = F x
            CommonOps_DDRM.mult(F, x, a);
            x.set(a);

            // P = F P F' + Q
            CommonOps_DDRM.mult(F, P, b);
            CommonOps_DDRM.multTransB(b, F, P);
            CommonOps_DDRM.addEquals(P, Q);
        }
예제 #4
0
        /**
         * Creates a newJava.Util.Random symmetric matrix that will have the specified real eigenvalues.
         *
         * @param num Dimension of the resulting matrix.
         * @param randJava.Util.Random number generator.
         * @param eigenvalues Set of real eigenvalues that the matrix will have.
         * @return AJava.Util.Random matrix with the specified eigenvalues.
         */
        public static DMatrixRMaj symmetricWithEigenvalues(int num, Java.Util.Random rand, double[] eigenvalues)
        {
            DMatrixRMaj V = RandomMatrices_DDRM.orthogonal(num, num, rand);
            DMatrixRMaj D = CommonOps_DDRM.diag(eigenvalues);

            DMatrixRMaj temp = new DMatrixRMaj(num, num);

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

            return(D);
        }
예제 #5
0
        /**
         * Creates aJava.Util.Random symmetric positive definite matrix.
         *
         * @param width The width of the square matrix it returns.
         * @param randJava.Util.Random number generator used to make the matrix.
         * @return TheJava.Util.Random symmetric  positive definite matrix.
         */
        public static DMatrixRMaj symmetricPosDef(int width, Java.Util.Random rand)
        {
            // This is not formally proven to work.  It just seems to work.
            DMatrixRMaj a = new DMatrixRMaj(width, 1);
            DMatrixRMaj b = new DMatrixRMaj(width, width);

            for (int i = 0; i < width; i++)
            {
                a.set(i, 0, rand.NextDouble());
            }

            CommonOps_DDRM.multTransB(a, a, b);

            for (int i = 0; i < width; i++)
            {
                b.add(i, i, 1);
            }

            return(b);
        }
예제 #6
0
        /**
         * <p>
         * Creates aJava.Util.Random matrix which will have the provided singular values.  The Count() 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 randJava.Util.Random number generator.
         * @param sv Singular values of the matrix.
         * @return A new matrix with the specified singular values.
         */
        public static DMatrixRMaj singular(int numRows, int numCols,
                                           Java.Util.Random rand, double[] sv)
        {
            DMatrixRMaj U, V, S;

            // speed it up in compact format
            if (numRows > numCols)
            {
                U = RandomMatrices_DDRM.orthogonal(numRows, numCols, rand);
                V = RandomMatrices_DDRM.orthogonal(numCols, numCols, rand);
                S = new DMatrixRMaj(numCols, numCols);
            }
            else
            {
                U = RandomMatrices_DDRM.orthogonal(numRows, numRows, rand);
                V = RandomMatrices_DDRM.orthogonal(numCols, numCols, rand);
                S = new DMatrixRMaj(numRows, numCols);
            }

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

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

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

            DMatrixRMaj tmp = new DMatrixRMaj(numRows, numCols);

            CommonOps_DDRM.mult(U, S, tmp);
            S.reshape(numRows, numCols);
            CommonOps_DDRM.multTransB(tmp, V, S);

            return(S);
        }
예제 #7
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 DMatrixRMaj singleValues(int numRows, int numCols,
                                               IMersenneTwister rand, double[] sv)
        {
            DMatrixRMaj U = RandomMatrices_DDRM.orthogonal(numRows, numRows, rand);
            DMatrixRMaj V = RandomMatrices_DDRM.orthogonal(numCols, numCols, rand);

            DMatrixRMaj S = new DMatrixRMaj(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]);
            }

            DMatrixRMaj tmp = new DMatrixRMaj(numRows, numCols);

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

            return(S);
        }
예제 #8
0
        public virtual bool decompose(DMatrixRMaj orig)
        {
            if (!decompQRP.decompose(orig))
            {
                return(false);
            }

            m   = orig.numRows;
            n   = orig.numCols;
            min = Math.Min(m, n);
            B.reshape(min, n, false);

            decompQRP.getR(B, true);

            // apply the column pivots.
            // TODO this is horribly inefficient
            DMatrixRMaj result = new DMatrixRMaj(min, n);
            DMatrixRMaj P      = decompQRP.getColPivotMatrix(null);

            CommonOps_DDRM.multTransB(B, P, result);
            B.set(result);

            return(decompBi.decompose(B));
        }