00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "../Core/util/NonMPL2.h"
00049
00050 #ifndef EIGEN_SIMPLICIAL_CHOLESKY_H
00051 #define EIGEN_SIMPLICIAL_CHOLESKY_H
00052
00053 namespace Eigen {
00054
00055 enum SimplicialCholeskyMode {
00056 SimplicialCholeskyLLT,
00057 SimplicialCholeskyLDLT
00058 };
00059
00075 template<typename Derived>
00076 class SimplicialCholeskyBase : internal::noncopyable
00077 {
00078 public:
00079 typedef typename internal::traits<Derived>::MatrixType MatrixType;
00080 enum { UpLo = internal::traits<Derived>::UpLo };
00081 typedef typename MatrixType::Scalar Scalar;
00082 typedef typename MatrixType::RealScalar RealScalar;
00083 typedef typename MatrixType::Index Index;
00084 typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType;
00085 typedef Matrix<Scalar,Dynamic,1> VectorType;
00086
00087 public:
00088
00090 SimplicialCholeskyBase()
00091 : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1)
00092 {}
00093
00094 SimplicialCholeskyBase(const MatrixType& matrix)
00095 : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1)
00096 {
00097 derived().compute(matrix);
00098 }
00099
00100 ~SimplicialCholeskyBase()
00101 {
00102 }
00103
00104 Derived& derived() { return *static_cast<Derived*>(this); }
00105 const Derived& derived() const { return *static_cast<const Derived*>(this); }
00106
00107 inline Index cols() const { return m_matrix.cols(); }
00108 inline Index rows() const { return m_matrix.rows(); }
00109
00115 ComputationInfo info() const
00116 {
00117 eigen_assert(m_isInitialized && "Decomposition is not initialized.");
00118 return m_info;
00119 }
00120
00125 template<typename Rhs>
00126 inline const internal::solve_retval<SimplicialCholeskyBase, Rhs>
00127 solve(const MatrixBase<Rhs>& b) const
00128 {
00129 eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized.");
00130 eigen_assert(rows()==b.rows()
00131 && "SimplicialCholeskyBase::solve(): invalid number of rows of the right hand side matrix b");
00132 return internal::solve_retval<SimplicialCholeskyBase, Rhs>(*this, b.derived());
00133 }
00134
00139 template<typename Rhs>
00140 inline const internal::sparse_solve_retval<SimplicialCholeskyBase, Rhs>
00141 solve(const SparseMatrixBase<Rhs>& b) const
00142 {
00143 eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized.");
00144 eigen_assert(rows()==b.rows()
00145 && "SimplicialCholesky::solve(): invalid number of rows of the right hand side matrix b");
00146 return internal::sparse_solve_retval<SimplicialCholeskyBase, Rhs>(*this, b.derived());
00147 }
00148
00151 const PermutationMatrix<Dynamic,Dynamic,Index>& permutationP() const
00152 { return m_P; }
00153
00156 const PermutationMatrix<Dynamic,Dynamic,Index>& permutationPinv() const
00157 { return m_Pinv; }
00158
00168 Derived& setShift(const RealScalar& offset, const RealScalar& scale = 1)
00169 {
00170 m_shiftOffset = offset;
00171 m_shiftScale = scale;
00172 return derived();
00173 }
00174
00175 #ifndef EIGEN_PARSED_BY_DOXYGEN
00176
00177 template<typename Stream>
00178 void dumpMemory(Stream& s)
00179 {
00180 int total = 0;
00181 s << " L: " << ((total+=(m_matrix.cols()+1) * sizeof(int) + m_matrix.nonZeros()*(sizeof(int)+sizeof(Scalar))) >> 20) << "Mb" << "\n";
00182 s << " diag: " << ((total+=m_diag.size() * sizeof(Scalar)) >> 20) << "Mb" << "\n";
00183 s << " tree: " << ((total+=m_parent.size() * sizeof(int)) >> 20) << "Mb" << "\n";
00184 s << " nonzeros: " << ((total+=m_nonZerosPerCol.size() * sizeof(int)) >> 20) << "Mb" << "\n";
00185 s << " perm: " << ((total+=m_P.size() * sizeof(int)) >> 20) << "Mb" << "\n";
00186 s << " perm^-1: " << ((total+=m_Pinv.size() * sizeof(int)) >> 20) << "Mb" << "\n";
00187 s << " TOTAL: " << (total>> 20) << "Mb" << "\n";
00188 }
00189
00191 template<typename Rhs,typename Dest>
00192 void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
00193 {
00194 eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
00195 eigen_assert(m_matrix.rows()==b.rows());
00196
00197 if(m_info!=Success)
00198 return;
00199
00200 if(m_P.size()>0)
00201 dest = m_P * b;
00202 else
00203 dest = b;
00204
00205 if(m_matrix.nonZeros()>0)
00206 derived().matrixL().solveInPlace(dest);
00207
00208 if(m_diag.size()>0)
00209 dest = m_diag.asDiagonal().inverse() * dest;
00210
00211 if (m_matrix.nonZeros()>0)
00212 derived().matrixU().solveInPlace(dest);
00213
00214 if(m_P.size()>0)
00215 dest = m_Pinv * dest;
00216 }
00217
00219 template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
00220 void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
00221 {
00222 eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
00223 eigen_assert(m_matrix.rows()==b.rows());
00224
00225
00226 static const int NbColsAtOnce = 4;
00227 int rhsCols = b.cols();
00228 int size = b.rows();
00229 Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols);
00230 for(int k=0; k<rhsCols; k+=NbColsAtOnce)
00231 {
00232 int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce);
00233 tmp.leftCols(actualCols) = b.middleCols(k,actualCols);
00234 tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols));
00235 dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView();
00236 }
00237 }
00238
00239 #endif // EIGEN_PARSED_BY_DOXYGEN
00240
00241 protected:
00242
00244 template<bool DoLDLT>
00245 void compute(const MatrixType& matrix)
00246 {
00247 eigen_assert(matrix.rows()==matrix.cols());
00248 Index size = matrix.cols();
00249 CholMatrixType ap(size,size);
00250 ordering(matrix, ap);
00251 analyzePattern_preordered(ap, DoLDLT);
00252 factorize_preordered<DoLDLT>(ap);
00253 }
00254
00255 template<bool DoLDLT>
00256 void factorize(const MatrixType& a)
00257 {
00258 eigen_assert(a.rows()==a.cols());
00259 int size = a.cols();
00260 CholMatrixType ap(size,size);
00261 ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
00262 factorize_preordered<DoLDLT>(ap);
00263 }
00264
00265 template<bool DoLDLT>
00266 void factorize_preordered(const CholMatrixType& a);
00267
00268 void analyzePattern(const MatrixType& a, bool doLDLT)
00269 {
00270 eigen_assert(a.rows()==a.cols());
00271 int size = a.cols();
00272 CholMatrixType ap(size,size);
00273 ordering(a, ap);
00274 analyzePattern_preordered(ap,doLDLT);
00275 }
00276 void analyzePattern_preordered(const CholMatrixType& a, bool doLDLT);
00277
00278 void ordering(const MatrixType& a, CholMatrixType& ap);
00279
00281 struct keep_diag {
00282 inline bool operator() (const Index& row, const Index& col, const Scalar&) const
00283 {
00284 return row!=col;
00285 }
00286 };
00287
00288 mutable ComputationInfo m_info;
00289 bool m_isInitialized;
00290 bool m_factorizationIsOk;
00291 bool m_analysisIsOk;
00292
00293 CholMatrixType m_matrix;
00294 VectorType m_diag;
00295 VectorXi m_parent;
00296 VectorXi m_nonZerosPerCol;
00297 PermutationMatrix<Dynamic,Dynamic,Index> m_P;
00298 PermutationMatrix<Dynamic,Dynamic,Index> m_Pinv;
00299
00300 RealScalar m_shiftOffset;
00301 RealScalar m_shiftScale;
00302 };
00303
00304 template<typename _MatrixType, int _UpLo = Lower> class SimplicialLLT;
00305 template<typename _MatrixType, int _UpLo = Lower> class SimplicialLDLT;
00306 template<typename _MatrixType, int _UpLo = Lower> class SimplicialCholesky;
00307
00308 namespace internal {
00309
00310 template<typename _MatrixType, int _UpLo> struct traits<SimplicialLLT<_MatrixType,_UpLo> >
00311 {
00312 typedef _MatrixType MatrixType;
00313 enum { UpLo = _UpLo };
00314 typedef typename MatrixType::Scalar Scalar;
00315 typedef typename MatrixType::Index Index;
00316 typedef SparseMatrix<Scalar, ColMajor, Index> CholMatrixType;
00317 typedef SparseTriangularView<CholMatrixType, Eigen::Lower> MatrixL;
00318 typedef SparseTriangularView<typename CholMatrixType::AdjointReturnType, Eigen::Upper> MatrixU;
00319 static inline MatrixL getL(const MatrixType& m) { return m; }
00320 static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); }
00321 };
00322
00323 template<typename _MatrixType,int _UpLo> struct traits<SimplicialLDLT<_MatrixType,_UpLo> >
00324 {
00325 typedef _MatrixType MatrixType;
00326 enum { UpLo = _UpLo };
00327 typedef typename MatrixType::Scalar Scalar;
00328 typedef typename MatrixType::Index Index;
00329 typedef SparseMatrix<Scalar, ColMajor, Index> CholMatrixType;
00330 typedef SparseTriangularView<CholMatrixType, Eigen::UnitLower> MatrixL;
00331 typedef SparseTriangularView<typename CholMatrixType::AdjointReturnType, Eigen::UnitUpper> MatrixU;
00332 static inline MatrixL getL(const MatrixType& m) { return m; }
00333 static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); }
00334 };
00335
00336 template<typename _MatrixType, int _UpLo> struct traits<SimplicialCholesky<_MatrixType,_UpLo> >
00337 {
00338 typedef _MatrixType MatrixType;
00339 enum { UpLo = _UpLo };
00340 };
00341
00342 }
00343
00361 template<typename _MatrixType, int _UpLo>
00362 class SimplicialLLT : public SimplicialCholeskyBase<SimplicialLLT<_MatrixType,_UpLo> >
00363 {
00364 public:
00365 typedef _MatrixType MatrixType;
00366 enum { UpLo = _UpLo };
00367 typedef SimplicialCholeskyBase<SimplicialLLT> Base;
00368 typedef typename MatrixType::Scalar Scalar;
00369 typedef typename MatrixType::RealScalar RealScalar;
00370 typedef typename MatrixType::Index Index;
00371 typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType;
00372 typedef Matrix<Scalar,Dynamic,1> VectorType;
00373 typedef internal::traits<SimplicialLLT> Traits;
00374 typedef typename Traits::MatrixL MatrixL;
00375 typedef typename Traits::MatrixU MatrixU;
00376 public:
00378 SimplicialLLT() : Base() {}
00380 SimplicialLLT(const MatrixType& matrix)
00381 : Base(matrix) {}
00382
00384 inline const MatrixL matrixL() const {
00385 eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized");
00386 return Traits::getL(Base::m_matrix);
00387 }
00388
00390 inline const MatrixU matrixU() const {
00391 eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized");
00392 return Traits::getU(Base::m_matrix);
00393 }
00394
00396 SimplicialLLT& compute(const MatrixType& matrix)
00397 {
00398 Base::template compute<false>(matrix);
00399 return *this;
00400 }
00401
00408 void analyzePattern(const MatrixType& a)
00409 {
00410 Base::analyzePattern(a, false);
00411 }
00412
00419 void factorize(const MatrixType& a)
00420 {
00421 Base::template factorize<false>(a);
00422 }
00423
00425 Scalar determinant() const
00426 {
00427 Scalar detL = Base::m_matrix.diagonal().prod();
00428 return internal::abs2(detL);
00429 }
00430 };
00431
00449 template<typename _MatrixType, int _UpLo>
00450 class SimplicialLDLT : public SimplicialCholeskyBase<SimplicialLDLT<_MatrixType,_UpLo> >
00451 {
00452 public:
00453 typedef _MatrixType MatrixType;
00454 enum { UpLo = _UpLo };
00455 typedef SimplicialCholeskyBase<SimplicialLDLT> Base;
00456 typedef typename MatrixType::Scalar Scalar;
00457 typedef typename MatrixType::RealScalar RealScalar;
00458 typedef typename MatrixType::Index Index;
00459 typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType;
00460 typedef Matrix<Scalar,Dynamic,1> VectorType;
00461 typedef internal::traits<SimplicialLDLT> Traits;
00462 typedef typename Traits::MatrixL MatrixL;
00463 typedef typename Traits::MatrixU MatrixU;
00464 public:
00466 SimplicialLDLT() : Base() {}
00467
00469 SimplicialLDLT(const MatrixType& matrix)
00470 : Base(matrix) {}
00471
00473 inline const VectorType vectorD() const {
00474 eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized");
00475 return Base::m_diag;
00476 }
00478 inline const MatrixL matrixL() const {
00479 eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized");
00480 return Traits::getL(Base::m_matrix);
00481 }
00482
00484 inline const MatrixU matrixU() const {
00485 eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized");
00486 return Traits::getU(Base::m_matrix);
00487 }
00488
00490 SimplicialLDLT& compute(const MatrixType& matrix)
00491 {
00492 Base::template compute<true>(matrix);
00493 return *this;
00494 }
00495
00502 void analyzePattern(const MatrixType& a)
00503 {
00504 Base::analyzePattern(a, true);
00505 }
00506
00513 void factorize(const MatrixType& a)
00514 {
00515 Base::template factorize<true>(a);
00516 }
00517
00519 Scalar determinant() const
00520 {
00521 return Base::m_diag.prod();
00522 }
00523 };
00524
00531 template<typename _MatrixType, int _UpLo>
00532 class SimplicialCholesky : public SimplicialCholeskyBase<SimplicialCholesky<_MatrixType,_UpLo> >
00533 {
00534 public:
00535 typedef _MatrixType MatrixType;
00536 enum { UpLo = _UpLo };
00537 typedef SimplicialCholeskyBase<SimplicialCholesky> Base;
00538 typedef typename MatrixType::Scalar Scalar;
00539 typedef typename MatrixType::RealScalar RealScalar;
00540 typedef typename MatrixType::Index Index;
00541 typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType;
00542 typedef Matrix<Scalar,Dynamic,1> VectorType;
00543 typedef internal::traits<SimplicialCholesky> Traits;
00544 typedef internal::traits<SimplicialLDLT<MatrixType,UpLo> > LDLTTraits;
00545 typedef internal::traits<SimplicialLLT<MatrixType,UpLo> > LLTTraits;
00546 public:
00547 SimplicialCholesky() : Base(), m_LDLT(true) {}
00548
00549 SimplicialCholesky(const MatrixType& matrix)
00550 : Base(), m_LDLT(true)
00551 {
00552 compute(matrix);
00553 }
00554
00555 SimplicialCholesky& setMode(SimplicialCholeskyMode mode)
00556 {
00557 switch(mode)
00558 {
00559 case SimplicialCholeskyLLT:
00560 m_LDLT = false;
00561 break;
00562 case SimplicialCholeskyLDLT:
00563 m_LDLT = true;
00564 break;
00565 default:
00566 break;
00567 }
00568
00569 return *this;
00570 }
00571
00572 inline const VectorType vectorD() const {
00573 eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized");
00574 return Base::m_diag;
00575 }
00576 inline const CholMatrixType rawMatrix() const {
00577 eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized");
00578 return Base::m_matrix;
00579 }
00580
00582 SimplicialCholesky& compute(const MatrixType& matrix)
00583 {
00584 if(m_LDLT)
00585 Base::template compute<true>(matrix);
00586 else
00587 Base::template compute<false>(matrix);
00588 return *this;
00589 }
00590
00597 void analyzePattern(const MatrixType& a)
00598 {
00599 Base::analyzePattern(a, m_LDLT);
00600 }
00601
00608 void factorize(const MatrixType& a)
00609 {
00610 if(m_LDLT)
00611 Base::template factorize<true>(a);
00612 else
00613 Base::template factorize<false>(a);
00614 }
00615
00617 template<typename Rhs,typename Dest>
00618 void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
00619 {
00620 eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
00621 eigen_assert(Base::m_matrix.rows()==b.rows());
00622
00623 if(Base::m_info!=Success)
00624 return;
00625
00626 if(Base::m_P.size()>0)
00627 dest = Base::m_P * b;
00628 else
00629 dest = b;
00630
00631 if(Base::m_matrix.nonZeros()>0)
00632 {
00633 if(m_LDLT)
00634 LDLTTraits::getL(Base::m_matrix).solveInPlace(dest);
00635 else
00636 LLTTraits::getL(Base::m_matrix).solveInPlace(dest);
00637 }
00638
00639 if(Base::m_diag.size()>0)
00640 dest = Base::m_diag.asDiagonal().inverse() * dest;
00641
00642 if (Base::m_matrix.nonZeros()>0)
00643 {
00644 if(m_LDLT)
00645 LDLTTraits::getU(Base::m_matrix).solveInPlace(dest);
00646 else
00647 LLTTraits::getU(Base::m_matrix).solveInPlace(dest);
00648 }
00649
00650 if(Base::m_P.size()>0)
00651 dest = Base::m_Pinv * dest;
00652 }
00653
00654 Scalar determinant() const
00655 {
00656 if(m_LDLT)
00657 {
00658 return Base::m_diag.prod();
00659 }
00660 else
00661 {
00662 Scalar detL = Diagonal<const CholMatrixType>(Base::m_matrix).prod();
00663 return internal::abs2(detL);
00664 }
00665 }
00666
00667 protected:
00668 bool m_LDLT;
00669 };
00670
00671 template<typename Derived>
00672 void SimplicialCholeskyBase<Derived>::ordering(const MatrixType& a, CholMatrixType& ap)
00673 {
00674 eigen_assert(a.rows()==a.cols());
00675 const Index size = a.rows();
00676
00677
00678 {
00679 CholMatrixType C;
00680 C = a.template selfadjointView<UpLo>();
00681
00682
00683
00684 internal::minimum_degree_ordering(C, m_Pinv);
00685 }
00686
00687 if(m_Pinv.size()>0)
00688 m_P = m_Pinv.inverse();
00689 else
00690 m_P.resize(0);
00691
00692 ap.resize(size,size);
00693 ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
00694 }
00695
00696 template<typename Derived>
00697 void SimplicialCholeskyBase<Derived>::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT)
00698 {
00699 const Index size = ap.rows();
00700 m_matrix.resize(size, size);
00701 m_parent.resize(size);
00702 m_nonZerosPerCol.resize(size);
00703
00704 ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
00705
00706 for(Index k = 0; k < size; ++k)
00707 {
00708
00709 m_parent[k] = -1;
00710 tags[k] = k;
00711 m_nonZerosPerCol[k] = 0;
00712 for(typename CholMatrixType::InnerIterator it(ap,k); it; ++it)
00713 {
00714 Index i = it.index();
00715 if(i < k)
00716 {
00717
00718 for(; tags[i] != k; i = m_parent[i])
00719 {
00720
00721 if (m_parent[i] == -1)
00722 m_parent[i] = k;
00723 m_nonZerosPerCol[i]++;
00724 tags[i] = k;
00725 }
00726 }
00727 }
00728 }
00729
00730
00731 Index* Lp = m_matrix.outerIndexPtr();
00732 Lp[0] = 0;
00733 for(Index k = 0; k < size; ++k)
00734 Lp[k+1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1);
00735
00736 m_matrix.resizeNonZeros(Lp[size]);
00737
00738 m_isInitialized = true;
00739 m_info = Success;
00740 m_analysisIsOk = true;
00741 m_factorizationIsOk = false;
00742 }
00743
00744
00745 template<typename Derived>
00746 template<bool DoLDLT>
00747 void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap)
00748 {
00749 eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
00750 eigen_assert(ap.rows()==ap.cols());
00751 const Index size = ap.rows();
00752 eigen_assert(m_parent.size()==size);
00753 eigen_assert(m_nonZerosPerCol.size()==size);
00754
00755 const Index* Lp = m_matrix.outerIndexPtr();
00756 Index* Li = m_matrix.innerIndexPtr();
00757 Scalar* Lx = m_matrix.valuePtr();
00758
00759 ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0);
00760 ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0);
00761 ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
00762
00763 bool ok = true;
00764 m_diag.resize(DoLDLT ? size : 0);
00765
00766 for(Index k = 0; k < size; ++k)
00767 {
00768
00769 y[k] = 0.0;
00770 Index top = size;
00771 tags[k] = k;
00772 m_nonZerosPerCol[k] = 0;
00773 for(typename MatrixType::InnerIterator it(ap,k); it; ++it)
00774 {
00775 Index i = it.index();
00776 if(i <= k)
00777 {
00778 y[i] += internal::conj(it.value());
00779 Index len;
00780 for(len = 0; tags[i] != k; i = m_parent[i])
00781 {
00782 pattern[len++] = i;
00783 tags[i] = k;
00784 }
00785 while(len > 0)
00786 pattern[--top] = pattern[--len];
00787 }
00788 }
00789
00790
00791
00792 RealScalar d = internal::real(y[k]) * m_shiftScale + m_shiftOffset;
00793 y[k] = 0.0;
00794 for(; top < size; ++top)
00795 {
00796 Index i = pattern[top];
00797 Scalar yi = y[i];
00798 y[i] = 0.0;
00799
00800
00801 Scalar l_ki;
00802 if(DoLDLT)
00803 l_ki = yi / m_diag[i];
00804 else
00805 yi = l_ki = yi / Lx[Lp[i]];
00806
00807 Index p2 = Lp[i] + m_nonZerosPerCol[i];
00808 Index p;
00809 for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p)
00810 y[Li[p]] -= internal::conj(Lx[p]) * yi;
00811 d -= internal::real(l_ki * internal::conj(yi));
00812 Li[p] = k;
00813 Lx[p] = l_ki;
00814 ++m_nonZerosPerCol[i];
00815 }
00816 if(DoLDLT)
00817 {
00818 m_diag[k] = d;
00819 if(d == RealScalar(0))
00820 {
00821 ok = false;
00822 break;
00823 }
00824 }
00825 else
00826 {
00827 Index p = Lp[k] + m_nonZerosPerCol[k]++;
00828 Li[p] = k ;
00829 if(d <= RealScalar(0)) {
00830 ok = false;
00831 break;
00832 }
00833 Lx[p] = internal::sqrt(d) ;
00834 }
00835 }
00836
00837 m_info = ok ? Success : NumericalIssue;
00838 m_factorizationIsOk = true;
00839 }
00840
00841 namespace internal {
00842
00843 template<typename Derived, typename Rhs>
00844 struct solve_retval<SimplicialCholeskyBase<Derived>, Rhs>
00845 : solve_retval_base<SimplicialCholeskyBase<Derived>, Rhs>
00846 {
00847 typedef SimplicialCholeskyBase<Derived> Dec;
00848 EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
00849
00850 template<typename Dest> void evalTo(Dest& dst) const
00851 {
00852 dec().derived()._solve(rhs(),dst);
00853 }
00854 };
00855
00856 template<typename Derived, typename Rhs>
00857 struct sparse_solve_retval<SimplicialCholeskyBase<Derived>, Rhs>
00858 : sparse_solve_retval_base<SimplicialCholeskyBase<Derived>, Rhs>
00859 {
00860 typedef SimplicialCholeskyBase<Derived> Dec;
00861 EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
00862
00863 template<typename Dest> void evalTo(Dest& dst) const
00864 {
00865 dec().derived()._solve_sparse(rhs(),dst);
00866 }
00867 };
00868
00869 }
00870
00871 }
00872
00873 #endif // EIGEN_SIMPLICIAL_CHOLESKY_H