private void copyZeros(DSubmatrixD1 subU)
        {
            int N = Math.Min(A.blockLength, subU.col1 - subU.col0);

            for (int i = 0; i < N; i++)
            {
                // save the zeros
                for (int j = 0; j <= i; j++)
                {
                    zerosM.unsafe_set(i, j, subU.get(i, j));
                    subU.set(i, j, 0);
                }
                // save the one
                if (subU.col0 + i + 1 < subU.original.numCols)
                {
                    zerosM.unsafe_set(i, i + 1, subU.get(i, i + 1));
                    subU.set(i, i + 1, 1);
                }
            }
        }
예제 #2
0
        /**
         * Returns the R matrix.
         */
        public DMatrixRMaj getR()
        {
            DMatrixRMaj R = new DMatrixRMaj(QR.numRows, QR.numCols);
            int         N = Math.Min(QR.numCols, QR.numRows);

            for (int i = 0; i < N; i++)
            {
                for (int j = i; j < QR.numCols; j++)
                {
                    R.unsafe_set(i, j, QR.unsafe_get(i, j));
                }
            }

            return(R);
        }
예제 #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)
        {
            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;
                }
            }
        }