Example #1
0
        public /**/ double quality()
        {
            return(SpecializedOps_ZDRM.qualityTriangular(LU));
        }

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

            // Solve U*X = Y;
            TriangularSolver_ZDRM.solveU(dataLU, vv, n);
        }
Example #2
0
        public override /**/ double quality()
        {
            return(SpecializedOps_ZDRM.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.
         */
        //@Override
        public override void solve(ZMatrixRMaj B, ZMatrixRMaj 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++)
                {
                    int indexB = (i * BnumCols + colB) * 2;
                    a.data[i * 2]     = B.data[indexB];
                    a.data[i * 2 + 1] = B.data[indexB + 1];
                }

                // 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 realVV = u[n * 2];
                    double imagVV = u[n * 2 + 1];

                    u[n * 2]     = 1;
                    u[n * 2 + 1] = 0;

                    QrHelperFunctions_ZDRM.rank1UpdateMultR(a, u, 0, gammas[n], 0, n, numRows, temp.data);

                    u[n * 2]     = realVV;
                    u[n * 2 + 1] = imagVV;
                }

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

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    int indexB = (i * BnumCols + colB) * 2;
                    X.data[indexB]     = a.data[i * 2];
                    X.data[indexB + 1] = a.data[i * 2 + 1];
                }
            }
        }
Example #3
0
        /**
         * Used internally to find the solution to a single column vector.
         */
        private void solveInternalL()
        {
            // This takes advantage of the diagonal elements always being real numbers

            // solve L*y=b storing y in x
            TriangularSolver_ZDRM.solveL_diagReal(t, vv, n);

            // solve L^T*x=y
            TriangularSolver_ZDRM.solveConjTranL_diagReal(t, vv, n);
        }
Example #4
0
 /**
  * Sets the matrix to the inverse using a lower triangular matrix.
  */
 public void setToInverseL(double[] a)
 {
     // the more direct method which takes full advantage of the sparsity of the data structures proved to
     // be difficult to get right due to the conjugates and reordering.
     // See comparable real number code for an example.
     for (int col = 0; col < n; col++)
     {
         Arrays.Fill(vv, 0);
         vv[col * 2] = 1;
         TriangularSolver_ZDRM.solveL_diagReal(t, vv, n);
         TriangularSolver_ZDRM.solveConjTranL_diagReal(t, vv, n);
         for (int i = 0; i < n; i++)
         {
             a[(i * numCols + col) * 2]     = vv[i * 2];
             a[(i * numCols + col) * 2 + 1] = vv[i * 2 + 1];
         }
     }
     // NOTE: If you want to make inverse faster take advantage of the sparsity
 }
Example #5
0
        public override /**/ double quality()
        {
            return(SpecializedOps_ZDRM.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.
         */
        //@Override
        public override void solve(ZMatrixRMaj B, ZMatrixRMaj 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);
            Z.reshape(numRows, 1);

            // 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++)
                {
                    int indexB = B.getIndex(i, colB);
                    Y.data[i * 2]     = B.data[indexB];
                    Y.data[i * 2 + 1] = B.data[indexB + 1];
                }

                // Solve Qa=b
                // a = Q'b
                CommonOps_ZDRM.mult(Qt, Y, Z);

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

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.set(i, colB, Z.data[i * 2], Z.data[i * 2 + 1]);
                }
            }
        }
Example #6
0
        public override /**/ double quality()
        {
            // even those it is transposed the diagonal elements are at the same
            // elements
            return(SpecializedOps_ZDRM.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(ZMatrixRMaj B, ZMatrixRMaj 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++)
                {
                    int indexB = (i * BnumCols + colB) * 2;
                    a[i * 2]     = B.data[indexB];
                    a[i * 2 + 1] = B.data[indexB + 1];
                }

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

                    double realUb = a[n * 2];
                    double imagUb = a[n * 2 + 1];

                    // U^H*b
                    for (int i = n + 1; i < numRows; i++)
                    {
                        double realU = dataQR[indexU++];
                        double imagU = -dataQR[indexU++];

                        double realB = a[i * 2];
                        double imagB = a[i * 2 + 1];

                        realUb += realU * realB - imagU * imagB;
                        imagUb += realU * imagB + imagU * realB;
                    }

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

                    a[n * 2]     -= realUb;
                    a[n * 2 + 1] -= imagUb;

                    indexU = (n * numRows + n + 1) * 2;
                    for (int i = n + 1; i < numRows; i++)
                    {
                        double realU = dataQR[indexU++];
                        double imagU = dataQR[indexU++];

                        a[i * 2]     -= realU * realUb - imagU * imagUb;
                        a[i * 2 + 1] -= realU * imagUb + imagU * realUb;
                    }
                }

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

                // save the results

                for (int i = 0; i < numCols; i++)
                {
                    int indexX = (i * X.numCols + colB) * 2;

                    X.data[indexX]     = a[i * 2];
                    X.data[indexX + 1] = a[i * 2 + 1];
                }
            }
        }
Example #7
0
        public override /**/ double quality()
        {
            return(SpecializedOps_ZDRM.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.
         */
        //@Override
        public override void solve(ZMatrixRMaj B, ZMatrixRMaj 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++)
                {
                    int indexB = (i * BnumCols + colB) * 2;
                    a[i * 2]     = B.data[indexB];
                    a[i * 2 + 1] = B.data[indexB + 1];
                }

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

                    double realUb = a[2 * n];
                    double imagUb = a[2 * n + 1];
                    // U^H*b
                    for (int i = n + 1; i < numRows; i++)
                    {
                        int    indexQR = (i * QR.numCols + n) * 2;
                        double realU   = u[i * 2] = QR.data[indexQR];
                        double imagU   = u[i * 2 + 1] = QR.data[indexQR + 1];

                        double realB = a[i * 2];
                        double imagB = a[i * 2 + 1];

                        realUb += realU * realB + imagU * imagB;
                        imagUb += realU * imagB - imagU * realB;
                    }

                    // gamma*U^H*b
                    realUb *= gammas[n];
                    imagUb *= gammas[n];

                    for (int i = n; i < numRows; i++)
                    {
                        double realU = u[i * 2];
                        double imagU = u[i * 2 + 1];

                        a[i * 2]     -= realU * realUb - imagU * imagUb;
                        a[i * 2 + 1] -= realU * imagUb + imagU * realUb;
                    }
                }

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

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    int indexX = (i * X.numCols + colB) * 2;

                    X.data[indexX]     = a[i * 2];
                    X.data[indexX + 1] = a[i * 2 + 1];
                }
            }
        }