コード例 #1
0
        /**
         * Returns the Q matrix.
         */
        public DMatrixRMaj getQ()
        {
            DMatrixRMaj Q   = CommonOps_DDRM.identity(QR.numRows);
            DMatrixRMaj Q_k = new DMatrixRMaj(QR.numRows, QR.numRows);
            DMatrixRMaj u   = new DMatrixRMaj(QR.numRows, 1);

            DMatrixRMaj temp = new DMatrixRMaj(QR.numRows, QR.numRows);

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

            // compute Q by first extracting the householder vectors from the columns of QR and then applying it to Q
            for (int j = N - 1; j >= 0; j--)
            {
                CommonOps_DDRM.extract(QR, j, QR.numRows, j, j + 1, u, j, 0);
                u.set(j, 1.0);

                // A = (I - &gamma;*u*u<sup>T</sup>)*A<br>
                CommonOps_DDRM.setIdentity(Q_k);
                CommonOps_DDRM.multAddTransB(-gammas[j], u, u, Q_k);
                CommonOps_DDRM.mult(Q_k, Q, temp);
                Q.set(temp);
            }

            return(Q);
        }
コード例 #2
0
        public virtual DMatrixRMaj getU(DMatrixRMaj U, bool transpose, bool compact)
        {
            U = BidiagonalDecompositionRow_DDRM.handleU(U, false, compact, m, n, min);

            if (compact)
            {
                // U = Q*U1
                DMatrixRMaj Q1 = decompQRP.getQ(null, true);
                DMatrixRMaj U1 = decompBi.getU(null, false, true);
                CommonOps_DDRM.mult(Q1, U1, U);
            }
            else
            {
                // U = [Q1*U1 Q2]
                DMatrixRMaj Q   = decompQRP.getQ(U, false);
                DMatrixRMaj U1  = decompBi.getU(null, false, true);
                DMatrixRMaj Q1  = CommonOps_DDRM.extract(Q, 0, Q.numRows, 0, min);
                DMatrixRMaj tmp = new DMatrixRMaj(Q1.numRows, U1.numCols);
                CommonOps_DDRM.mult(Q1, U1, tmp);
                CommonOps_DDRM.insert(tmp, Q, 0, 0);
            }

            if (transpose)
            {
                CommonOps_DDRM.transpose(U);
            }

            return(U);
        }
コード例 #3
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.EPS.
         * @return The null space.
         */
        public static DMatrixRMaj nullSpace(SingularValueDecomposition_F64 <DMatrixRMaj> svd,
                                            DMatrixRMaj nullSpace, double tol)
        {
            int N = svd.numberOfSingularValues();

            double[] s = svd.getSingularValues();

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

            CommonOps_DDRM.transpose(nullSpace);

            return(nullSpace);
        }
コード例 #4
0
        /**
         * Returns a vector from the PCA's basis.
         *
         * @param which Which component's vector is to be returned.
         * @return Vector from the PCA basis.
         */
        public double[] getBasisVector(int which)
        {
            if (which < 0 || which >= numComponents)
            {
                throw new ArgumentException("Invalid component");
            }

            DMatrixRMaj v = new DMatrixRMaj(1, A.numCols);

            CommonOps_DDRM.extract(V_t, which, which + 1, 0, A.numCols, v, 0, 0);

            return(v.data);
        }
コード例 #5
0
        public override bool setA(DMatrixRMaj A)
        {
            _setA(A);

            if (!decomposition.decompose(A))
            {
                return(false);
            }

            rank = decomposition.getRank();

            R.reshape(numRows, numCols);
            decomposition.getR(R, false);

            // extract the r11 triangle sub matrix
            R11.reshape(rank, rank);
            CommonOps_DDRM.extract(R, 0, rank, 0, rank, R11, 0, 0);

            if (norm2Solution && rank < numCols)
            {
                // extract the R12 sub-matrix
                W.reshape(rank, numCols - rank);
                CommonOps_DDRM.extract(R, 0, rank, rank, numCols, W, 0, 0);

                // W=inv(R11)*R12
                TriangularSolver_DDRM.solveU(R11.data, 0, R11.numCols, R11.numCols, W.data, 0, W.numCols, W.numCols);

                // set the identity matrix in the upper portion
                W.reshape(numCols, W.numCols, true);

                for (int i = 0; i < numCols - rank; i++)
                {
                    for (int j = 0; j < numCols - rank; j++)
                    {
                        if (i == j)
                        {
                            W.set(i + rank, j, -1);
                        }
                        else
                        {
                            W.set(i + rank, j, 0);
                        }
                    }
                }
            }

            return(true);
        }
コード例 #6
0
        public bool process(DMatrixRMaj A, int numSingularValues, DMatrixRMaj nullspace)
        {
            decomposition.decompose(A);

            if (A.numRows > A.numCols)
            {
                Q.reshape(A.numCols, Math.Min(A.numRows, A.numCols));
                decomposition.getQ(Q, true);
            }
            else
            {
                Q.reshape(A.numCols, A.numCols);
                decomposition.getQ(Q, false);
            }

            nullspace.reshape(Q.numRows, numSingularValues);
            CommonOps_DDRM.extract(Q, 0, Q.numRows, Q.numCols - numSingularValues, Q.numCols, nullspace, 0, 0);

            return(true);
        }
コード例 #7
0
        private void solveWithLU(double real, int index, DMatrixRMaj r)
        {
            DMatrixRMaj A = new DMatrixRMaj(index, index);

            CommonOps_DDRM.extract(_implicit.A, 0, index, 0, index, A, 0, 0);

            for (int i = 0; i < index; i++)
            {
                A.add(i, i, -real);
            }

            r.reshape(index, 1, false);

            SpecializedOps_DDRM.subvector(_implicit.A, 0, index, index, false, 0, r);
            CommonOps_DDRM.changeSign(r);

            // TODO this must be very inefficient
            if (!solver.setA(A))
            {
                throw new InvalidOperationException("Solve failed");
            }
            solver.solve(r, r);
        }
コード例 #8
0
 public void extract(Matrix src, int srcY0, int srcY1, int srcX0, int srcX1, Matrix dst, int dstY0, int dstX0)
 {
     CommonOps_DDRM.extract((DMatrixRMaj)src, srcY0, srcY1, srcX0, srcX1, (DMatrixRMaj)dst, dstY0, dstX0);
 }
コード例 #9
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;
                }
            }
        }