| // This file is part of Eigen, a lightweight C++ template library | 
 | // for linear algebra. | 
 | // | 
 | // Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org> | 
 | // Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr> | 
 | // | 
 | // This code initially comes from MINPACK whose original authors are: | 
 | // Copyright Jorge More - Argonne National Laboratory | 
 | // Copyright Burt Garbow - Argonne National Laboratory | 
 | // Copyright Ken Hillstrom - Argonne National Laboratory | 
 | // | 
 | // This Source Code Form is subject to the terms of the Minpack license | 
 | // (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file. | 
 |  | 
 | #ifndef EIGEN_LMQRSOLV_H | 
 | #define EIGEN_LMQRSOLV_H | 
 |  | 
 | namespace Eigen {  | 
 |  | 
 | namespace internal { | 
 |  | 
 | template <typename Scalar,int Rows, int Cols, typename PermIndex> | 
 | void lmqrsolv( | 
 |   Matrix<Scalar,Rows,Cols> &s, | 
 |   const PermutationMatrix<Dynamic,Dynamic,PermIndex> &iPerm, | 
 |   const Matrix<Scalar,Dynamic,1> &diag, | 
 |   const Matrix<Scalar,Dynamic,1> &qtb, | 
 |   Matrix<Scalar,Dynamic,1> &x, | 
 |   Matrix<Scalar,Dynamic,1> &sdiag) | 
 | { | 
 |     /* Local variables */ | 
 |     Index i, j, k; | 
 |     Scalar temp; | 
 |     Index n = s.cols(); | 
 |     Matrix<Scalar,Dynamic,1>  wa(n); | 
 |     JacobiRotation<Scalar> givens; | 
 |  | 
 |     /* Function Body */ | 
 |     // the following will only change the lower triangular part of s, including | 
 |     // the diagonal, though the diagonal is restored afterward | 
 |  | 
 |     /*     copy r and (q transpose)*b to preserve input and initialize s. */ | 
 |     /*     in particular, save the diagonal elements of r in x. */ | 
 |     x = s.diagonal(); | 
 |     wa = qtb; | 
 |      | 
 |     | 
 |     s.topLeftCorner(n,n).template triangularView<StrictlyLower>() = s.topLeftCorner(n,n).transpose(); | 
 |     /*     eliminate the diagonal matrix d using a givens rotation. */ | 
 |     for (j = 0; j < n; ++j) { | 
 |  | 
 |         /*        prepare the row of d to be eliminated, locating the */ | 
 |         /*        diagonal element using p from the qr factorization. */ | 
 |         const PermIndex l = iPerm.indices()(j); | 
 |         if (diag[l] == 0.) | 
 |             break; | 
 |         sdiag.tail(n-j).setZero(); | 
 |         sdiag[j] = diag[l]; | 
 |  | 
 |         /*        the transformations to eliminate the row of d */ | 
 |         /*        modify only a single element of (q transpose)*b */ | 
 |         /*        beyond the first n, which is initially zero. */ | 
 |         Scalar qtbpj = 0.; | 
 |         for (k = j; k < n; ++k) { | 
 |             /*           determine a givens rotation which eliminates the */ | 
 |             /*           appropriate element in the current row of d. */ | 
 |             givens.makeGivens(-s(k,k), sdiag[k]); | 
 |  | 
 |             /*           compute the modified diagonal element of r and */ | 
 |             /*           the modified element of ((q transpose)*b,0). */ | 
 |             s(k,k) = givens.c() * s(k,k) + givens.s() * sdiag[k]; | 
 |             temp = givens.c() * wa[k] + givens.s() * qtbpj; | 
 |             qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj; | 
 |             wa[k] = temp; | 
 |  | 
 |             /*           accumulate the transformation in the row of s. */ | 
 |             for (i = k+1; i<n; ++i) { | 
 |                 temp = givens.c() * s(i,k) + givens.s() * sdiag[i]; | 
 |                 sdiag[i] = -givens.s() * s(i,k) + givens.c() * sdiag[i]; | 
 |                 s(i,k) = temp; | 
 |             } | 
 |         } | 
 |     } | 
 |    | 
 |     /*     solve the triangular system for z. if the system is */ | 
 |     /*     singular, then obtain a least squares solution. */ | 
 |     Index nsing; | 
 |     for(nsing=0; nsing<n && sdiag[nsing]!=0; nsing++) {} | 
 |  | 
 |     wa.tail(n-nsing).setZero(); | 
 |     s.topLeftCorner(nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing)); | 
 |    | 
 |     // restore | 
 |     sdiag = s.diagonal(); | 
 |     s.diagonal() = x; | 
 |  | 
 |     /* permute the components of z back to components of x. */ | 
 |     x = iPerm * wa;  | 
 | } | 
 |  | 
 | template <typename Scalar, int _Options, typename Index> | 
 | void lmqrsolv( | 
 |   SparseMatrix<Scalar,_Options,Index> &s, | 
 |   const PermutationMatrix<Dynamic,Dynamic> &iPerm, | 
 |   const Matrix<Scalar,Dynamic,1> &diag, | 
 |   const Matrix<Scalar,Dynamic,1> &qtb, | 
 |   Matrix<Scalar,Dynamic,1> &x, | 
 |   Matrix<Scalar,Dynamic,1> &sdiag) | 
 | { | 
 |   /* Local variables */ | 
 |   typedef SparseMatrix<Scalar,RowMajor,Index> FactorType; | 
 |     Index i, j, k, l; | 
 |     Scalar temp; | 
 |     Index n = s.cols(); | 
 |     Matrix<Scalar,Dynamic,1>  wa(n); | 
 |     JacobiRotation<Scalar> givens; | 
 |  | 
 |     /* Function Body */ | 
 |     // the following will only change the lower triangular part of s, including | 
 |     // the diagonal, though the diagonal is restored afterward | 
 |  | 
 |     /*     copy r and (q transpose)*b to preserve input and initialize R. */ | 
 |     wa = qtb; | 
 |     FactorType R(s); | 
 |     // Eliminate the diagonal matrix d using a givens rotation | 
 |     for (j = 0; j < n; ++j) | 
 |     { | 
 |       // Prepare the row of d to be eliminated, locating the  | 
 |       // diagonal element using p from the qr factorization | 
 |       l = iPerm.indices()(j); | 
 |       if (diag(l) == Scalar(0))  | 
 |         break;  | 
 |       sdiag.tail(n-j).setZero(); | 
 |       sdiag[j] = diag[l]; | 
 |       // the transformations to eliminate the row of d | 
 |       // modify only a single element of (q transpose)*b | 
 |       // beyond the first n, which is initially zero.  | 
 |        | 
 |       Scalar qtbpj = 0;  | 
 |       // Browse the nonzero elements of row j of the upper triangular s | 
 |       for (k = j; k < n; ++k) | 
 |       { | 
 |         typename FactorType::InnerIterator itk(R,k); | 
 |         for (; itk; ++itk){ | 
 |           if (itk.index() < k) continue; | 
 |           else break; | 
 |         } | 
 |         //At this point, we have the diagonal element R(k,k) | 
 |         // Determine a givens rotation which eliminates  | 
 |         // the appropriate element in the current row of d | 
 |         givens.makeGivens(-itk.value(), sdiag(k)); | 
 |          | 
 |         // Compute the modified diagonal element of r and  | 
 |         // the modified element of ((q transpose)*b,0). | 
 |         itk.valueRef() = givens.c() * itk.value() + givens.s() * sdiag(k); | 
 |         temp = givens.c() * wa(k) + givens.s() * qtbpj;  | 
 |         qtbpj = -givens.s() * wa(k) + givens.c() * qtbpj; | 
 |         wa(k) = temp; | 
 |          | 
 |         // Accumulate the transformation in the remaining k row/column of R | 
 |         for (++itk; itk; ++itk) | 
 |         { | 
 |           i = itk.index(); | 
 |           temp = givens.c() *  itk.value() + givens.s() * sdiag(i); | 
 |           sdiag(i) = -givens.s() * itk.value() + givens.c() * sdiag(i); | 
 |           itk.valueRef() = temp; | 
 |         } | 
 |       } | 
 |     } | 
 |      | 
 |     // Solve the triangular system for z. If the system is  | 
 |     // singular, then obtain a least squares solution | 
 |     Index nsing; | 
 |     for(nsing = 0; nsing<n && sdiag(nsing) !=0; nsing++) {} | 
 |      | 
 |     wa.tail(n-nsing).setZero(); | 
 | //     x = wa;  | 
 |     wa.head(nsing) = R.topLeftCorner(nsing,nsing).template triangularView<Upper>().solve/*InPlace*/(wa.head(nsing)); | 
 |      | 
 |     sdiag = R.diagonal(); | 
 |     // Permute the components of z back to components of x | 
 |     x = iPerm * wa;  | 
 | } | 
 | } // end namespace internal | 
 |  | 
 | } // end namespace Eigen | 
 |  | 
 | #endif // EIGEN_LMQRSOLV_H |