public /**/ double quality()
        {
            return(SpecializedOps_DDRM.qualityTriangular(LU));
        }

        /**
         * a specialized version of solve that avoid additional checks that are not needed.
         */
        public void _solveVectorInternal(double[] vv)
        {
            // Solve L*Y = B
            int ii = 0;

            for (int i = 0; i < n; i++)
            {
                int    ip  = indx[i];
                double sum = vv[ip];
                vv[ip] = vv[i];
                if (ii != 0)
                {
//                for( int j = ii-1; j < i; j++ )
//                    sum -= dataLU[i* n +j]*vv[j];
                    int index = i * n + ii - 1;
                    for (int j = ii - 1; j < i; j++)
                    {
                        sum -= dataLU[index++] * vv[j];
                    }
                }
                else if (sum != 0.0)
                {
                    ii = i + 1;
                }
                vv[i] = sum;
            }

            // Solve U*X = Y;
            TriangularSolver_DDRM.solveU(dataLU, vv, n);
        }
        public override /**/ double quality()
        {
            return(SpecializedOps_DDRM.qualityTriangular(QR));
        }

        /**
         * Solves for X using the QR decomposition.
         *
         * @param B A matrix that is n by m.  Not modified.
         * @param X An n by m matrix where the solution is writen to.  Modified.
         */
        public override void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X");
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            int BnumCols = B.numCols;

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    a[i] = B.data[i * BnumCols + colB];
                }

                // Solve Qa=b
                // a = Q'b
                // a = Q_{n-1}...Q_2*Q_1*b
                //
                // Q_n*b = (I-gamma*u*u^T)*b = b - u*(gamma*U^T*b)
                for (int n = 0; n < numCols; n++)
                {
                    u[n] = 1;
                    double ub = a[n];
                    // U^T*b
                    for (int i = n + 1; i < numRows; i++)
                    {
                        ub += (u[i] = QR.unsafe_get(i, n)) * a[i];
                    }

                    // gamma*U^T*b
                    ub *= gammas[n];

                    for (int i = n; i < numRows; i++)
                    {
                        a[i] -= u[i] * ub;
                    }
                }

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_DDRM.solveU(QR.data, a, numCols);

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.data[i * X.numCols + colB] = a[i];
                }
            }
        }
        public override void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X");
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            int BnumCols = B.numCols;

            // get the pivots and transpose them
            int[] pivots = decomposition.getColPivots();

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                x_basic.reshape(numRows, 1);
                Y.reshape(numRows, 1);

                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    Y.data[i] = B.get(i, colB);
                }

                // Solve Q*a=b => a = Q'*b
                CommonOps_DDRM.multTransA(Q, Y, x_basic);

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_DDRM.solveU(R11.data, x_basic.data, rank);

                // finish the basic solution by filling in zeros
                x_basic.reshape(numCols, 1, true);
                for (int i = rank; i < numCols; i++)
                {
                    x_basic.data[i] = 0;
                }

                if (norm2Solution && rank < numCols)
                {
                    upgradeSolution(x_basic);
                }

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.set(pivots[i], colB, x_basic.data[i]);
                }
            }
        }
        public override /**/ double quality()
        {
            return(SpecializedOps_DDRM.qualityTriangular(R));
        }

        /**
         * Solves for X using the QR decomposition.
         *
         * @param B A matrix that is n by m.  Not modified.
         * @param X An n by m matrix where the solution is written to.  Modified.
         */
        public override void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X: X rows = " + X.numRows + " expected = " +
                                            numCols);
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            int BnumCols = B.numCols;

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    a.data[i] = B.data[i * BnumCols + colB];
                }

                // Solve Qa=b
                // a = Q'b
                // a = Q_{n-1}...Q_2*Q_1*b
                //
                // Q_n*b = (I-gamma*u*u^T)*b = b - u*(gamma*U^T*b)
                for (int n = 0; n < numCols; n++)
                {
                    double[] u = QR[n];

                    double vv = u[n];
                    u[n] = 1;
                    QrHelperFunctions_DDRM.rank1UpdateMultR(a, u, gammas[n], 0, n, numRows, temp.data);
                    u[n] = vv;
                }

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_DDRM.solveU(R.data, a.data, numCols);

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.data[i * X.numCols + colB] = a.data[i];
                }
            }
        }
        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);
        }
        private void solveUsingTriangle(double real, int index, DMatrixRMaj r)
        {
            for (int i = 0; i < index; i++)
            {
                _implicit.A.add(i, i, -real);
            }

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

            TriangularSolver_DDRM.solveU(_implicit.A.data, r.data, _implicit.A.numRows, 0, index);

            for (int i = 0; i < index; i++)
            {
                _implicit.A.add(i, i, real);
            }
        }
Esempio n. 7
0
        public override /**/ double quality()
        {
            return(SpecializedOps_DDRM.qualityTriangular(R));
        }

        /**
         * Solves for X using the QR decomposition.
         *
         * @param B A matrix that is n by m.  Not modified.
         * @param X An n by m matrix where the solution is written to.  Modified.
         */
        public override void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X");
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            int BnumCols = B.numCols;

            Y.reshape(numRows, 1, false);
            Z.reshape(numRows, 1, false);

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    Y.data[i] = B.get(i, colB);
                }

                // Solve Qa=b
                // a = Q'b
                CommonOps_DDRM.multTransA(Q, Y, Z);

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_DDRM.solveU(R.data, Z.data, numCols);

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.set(i, colB, Z.data[i]);
                }
            }
        }
        public override /**/ double quality()
        {
            // even those it is transposed the diagonal elements are at the same
            // elements
            return(SpecializedOps_DDRM.qualityTriangular(QR));
        }

        /**
         * Solves for X using the QR decomposition.
         *
         * @param B A matrix that is n by m.  Not modified.
         * @param X An n by m matrix where the solution is written to.  Modified.
         */
        //@Override
        public override void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X: X rows = " + X.numRows + " expected = " +
                                            numCols);
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            U = decomposer.getR(U, true);
            double[] gammas = decomposer.getGammas();
            double[] dataQR = QR.data;

            int BnumCols = B.numCols;

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    a[i] = B.data[i * BnumCols + colB];
                }

                // Solve Qa=b
                // a = Q'b
                // a = Q_{n-1}...Q_2*Q_1*b
                //
                // Q_n*b = (I-gamma*u*u^T)*b = b - u*(gamma*U^T*b)
                for (int n = 0; n < numCols; n++)
                {
                    int indexU = n * numRows + n + 1;

                    double ub = a[n];
                    // U^T*b
                    for (int i = n + 1; i < numRows; i++, indexU++)
                    {
                        ub += dataQR[indexU] * a[i];
                    }

                    // gamma*U^T*b
                    ub *= gammas[n];

                    a[n]  -= ub;
                    indexU = n * numRows + n + 1;
                    for (int i = n + 1; i < numRows; i++, indexU++)
                    {
                        a[i] -= dataQR[indexU] * ub;
                    }
                }

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_DDRM.solveU(U.data, a, numCols);

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.data[i * X.numCols + colB] = a[i];
                }
            }
        }
        public override void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X");
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            int BnumCols = B.numCols;

            // get the pivots and transpose them
            int[] pivots = decomposition.getColPivots();

            double[][] qr     = decomposition.getQR();
            double[]   gammas = decomposition.getGammas();

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                x_basic.reshape(numRows, 1);
                Y.reshape(numRows, 1);

                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    x_basic.data[i] = B.get(i, colB);
                }

                // Solve Q*x=b => x = Q'*b
                // Q_n*b = (I-gamma*u*u^T)*b = b - u*(gamma*U^T*b)
                for (int i = 0; i < rank; i++)
                {
                    double[] u = qr[i];

                    double vv = u[i];
                    u[i] = 1;
                    QrHelperFunctions_DDRM.rank1UpdateMultR(x_basic, u, gammas[i], 0, i, numRows, Y.data);
                    u[i] = vv;
                }

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_DDRM.solveU(R11.data, x_basic.data, rank);

                // finish the basic solution by filling in zeros
                x_basic.reshape(numCols, 1, true);
                for (int i = rank; i < numCols; i++)
                {
                    x_basic.data[i] = 0;
                }

                if (norm2Solution && rank < numCols)
                {
                    upgradeSolution(x_basic);
                }

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.set(pivots[i], colB, x_basic.data[i]);
                }
            }
        }