Beispiel #1
0
        //! QR decompoisition

        /*! This implementation is based on MINPACK
         *  (<http://www.netlib.org/minpack>,
         *  <http://www.netlib.org/cephes/linalg.tgz>)
         *
         *  This subroutine uses householder transformations with column
         *  pivoting (optional) to compute a qr factorization of the
         *  m by n matrix A. That is, qrfac determines an orthogonal
         *  matrix q, a permutation matrix p, and an upper trapezoidal
         *  matrix r with diagonal elements of nonincreasing magnitude,
         *  such that A*p = q*r.
         *
         *  Return value ipvt is an integer array of length n, which
         *  defines the permutation matrix p such that A*p = q*r.
         *  Column j of p is column ipvt(j) of the identity matrix.
         *
         *  See lmdiff.cpp for further details.
         */
        public static List <int> qrDecomposition(Matrix M, ref Matrix q, ref Matrix r, bool pivot)
        {
            Matrix mT = Matrix.transpose(M);
            int    m  = M.rows();
            int    n  = M.columns();

            List <int> lipvt = new InitializedList <int>(n);
            Vector     rdiag = new Vector(n);
            Vector     wa    = new Vector(n);

            MINPACK.qrfac(m, n, mT, 0, (pivot) ? 1 : 0, ref lipvt, n, ref rdiag, ref rdiag, wa);

            if (r.columns() != n || r.rows() != n)
            {
                r = new Matrix(n, n);
            }

            for (int i = 0; i < n; ++i)
            {
                r[i, i] = rdiag[i];
                if (i < m)
                {
                    for (int j = i; j < mT.rows() - 1; j++)
                    {
                        r[i, j + 1] = mT[j + 1, i];
                    }
                }
            }

            if (q.rows() != m || q.columns() != n)
            {
                q = new Matrix(m, n);
            }

            Vector w = new Vector(m);

            for (int k = 0; k < m; ++k)
            {
                w.Erase();
                w[k] = 1.0;

                for (int j = 0; j < Math.Min(n, m); ++j)
                {
                    double t3 = mT[j, j];
                    if (t3.IsNotEqual(0.0))
                    {
                        double t = 0;
                        for (int kk = j; kk < mT.columns(); kk++)
                        {
                            t += (mT[j, kk] * w[kk]) / t3;
                        }

                        for (int i = j; i < m; ++i)
                        {
                            w[i] -= mT[j, i] * t;
                        }
                    }
                    q[k, j] = w[j];
                }
            }

            List <int> ipvt = new InitializedList <int>(n);

            if (pivot)
            {
                for (int i = 0; i < n; ++i)
                {
                    ipvt[i] = lipvt[i];
                }
            }
            else
            {
                for (int i = 0; i < n; ++i)
                {
                    ipvt[i] = i;
                }
            }

            return(ipvt);
        }
Beispiel #2
0
        //! QR decompoisition

        /*! This implementation is based on MINPACK
         *  (<http://www.netlib.org/minpack>,
         *  <http://www.netlib.org/cephes/linalg.tgz>)
         *
         *  This subroutine uses householder transformations with column
         *  pivoting (optional) to compute a qr factorization of the
         *  m by n matrix A. That is, qrfac determines an orthogonal
         *  matrix q, a permutation matrix p, and an upper trapezoidal
         *  matrix r with diagonal elements of nonincreasing magnitude,
         *  such that A*p = q*r.
         *
         *  Return value ipvt is an integer array of length n, which
         *  defines the permutation matrix p such that A*p = q*r.
         *  Column j of p is column ipvt(j) of the identity matrix.
         *
         *  See lmdiff.cpp for further details.
         */
        //public static List<int> qrDecomposition(Matrix A, Matrix q, Matrix r, bool pivot = true) {
        public static List <int> qrDecomposition(Matrix M, Matrix q, Matrix r, bool pivot)
        {
            Matrix mT = Matrix.transpose(M);
            int    m  = M.rows();
            int    n  = M.columns();

            List <int> lipvt = new InitializedList <int>(n);
            Vector     rdiag = new Vector(n);
            Vector     wa    = new Vector(n);

            MINPACK.qrfac(m, n, mT, 0, (pivot)?1:0, ref lipvt, n, ref rdiag, ref rdiag, wa);

            if (r.columns() != n || r.rows() != n)
            {
                r = new Matrix(n, n);
            }

            for (int i = 0; i < n; ++i)
            {
                //    std::fill(r.row_begin(i), r.row_begin(i)+i, 0.0);
                r[i, i] = rdiag[i];
                if (i < m)
                {
                    //        std::copy(mT.column_begin(i)+i+1, mT.column_end(i),
                    //                  r.row_begin(i)+i+1);
                }
                else
                {
                    //        std::fill(r.row_begin(i)+i+1, r.row_end(i), 0.0);
                }
            }

            if (q.rows() != m || q.columns() != n)
            {
                q = new Matrix(m, n);
            }

            Vector w = new Vector(m);
            //for (int k=0; k < m; ++k) {
            //    std::fill(w.begin(), w.end(), 0.0);
            //    w[k] = 1.0;

            //    for (int j=0; j < Math.Min(n, m); ++j) {
            //        double t3 = mT[j,j];
            //        if (t3 != 0.0) {
            //            double t
            //                = std::inner_product(mT.row_begin(j)+j, mT.row_end(j),
            //                                     w.begin()+j, 0.0)/t3;
            //            for (int i=j; i<m; ++i) {
            //                w[i]-=mT[j,i]*t;
            //            }
            //        }
            //        q[k,j] = w[j];
            //    }
            //    std::fill(q.row_begin(k) + Math.Min(n, m), q.row_end(k), 0.0);
            //}

            List <int> ipvt = new InitializedList <int>(n);

            //if (pivot) {
            //    std::copy(lipvt.get(), lipvt.get()+n, ipvt.begin());
            //}
            //else {
            //    for (int i=0; i < n; ++i)
            //        ipvt[i] = i;
            //}

            return(ipvt);
        }