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 #ifndef EIGEN_LLT_H
00026 #define EIGEN_LLT_H
00027
00050
00051
00052
00053
00054 template<typename MatrixType> class LLT
00055 {
00056 private:
00057 typedef typename MatrixType::Scalar Scalar;
00058 typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
00059 typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
00060
00061 enum {
00062 PacketSize = ei_packet_traits<Scalar>::size,
00063 AlignmentMask = int(PacketSize)-1
00064 };
00065
00066 public:
00067
00074 LLT() : m_matrix(), m_isInitialized(false) {}
00075
00076 LLT(const MatrixType& matrix)
00077 : m_matrix(matrix.rows(), matrix.cols()),
00078 m_isInitialized(false)
00079 {
00080 compute(matrix);
00081 }
00082
00084 inline Part<MatrixType, LowerTriangular> matrixL(void) const
00085 {
00086 ei_assert(m_isInitialized && "LLT is not initialized.");
00087 return m_matrix;
00088 }
00089
00091 inline bool isPositiveDefinite(void) const { return m_isInitialized && m_isPositiveDefinite; }
00092
00093 template<typename RhsDerived, typename ResultType>
00094 bool solve(const MatrixBase<RhsDerived> &b, ResultType *result) const;
00095
00096 template<typename Derived>
00097 bool solveInPlace(MatrixBase<Derived> &bAndX) const;
00098
00099 void compute(const MatrixType& matrix);
00100
00101 protected:
00106 MatrixType m_matrix;
00107 bool m_isInitialized;
00108 bool m_isPositiveDefinite;
00109 };
00110
00113 template<typename MatrixType>
00114 void LLT<MatrixType>::compute(const MatrixType& a)
00115 {
00116 assert(a.rows()==a.cols());
00117 m_isPositiveDefinite = true;
00118 const int size = a.rows();
00119 m_matrix.resize(size, size);
00120
00121
00122
00123
00124
00125
00126 const RealScalar cutoff = machine_epsilon<Scalar>() * size * a.diagonal().cwise().abs().maxCoeff();
00127 RealScalar x;
00128 x = ei_real(a.coeff(0,0));
00129 m_matrix.coeffRef(0,0) = ei_sqrt(x);
00130 if(size==1)
00131 {
00132 m_isInitialized = true;
00133 return;
00134 }
00135 if(ei_real(m_matrix.coeff(0,0))>0)
00136 m_matrix.col(0).end(size-1) = a.row(0).end(size-1).adjoint() / ei_real(m_matrix.coeff(0,0));
00137 for (int j = 1; j < size; ++j)
00138 {
00139 x = ei_real(a.coeff(j,j)) - m_matrix.row(j).start(j).squaredNorm();
00140 if (x <= cutoff)
00141 {
00142 m_isPositiveDefinite = false;
00143 continue;
00144 }
00145
00146 m_matrix.coeffRef(j,j) = x = ei_sqrt(x);
00147
00148 int endSize = size-j-1;
00149 if (endSize>0) {
00150
00151
00152 m_matrix.col(j).end(endSize) =
00153 (m_matrix.block(j+1, 0, endSize, j) * m_matrix.row(j).start(j).adjoint()).lazy();
00154
00155
00156 m_matrix.col(j).end(endSize) = (a.row(j).end(endSize).adjoint()
00157 - m_matrix.col(j).end(endSize) ) / x;
00158 }
00159 }
00160
00161 m_isInitialized = true;
00162 }
00163
00177 template<typename MatrixType>
00178 template<typename RhsDerived, typename ResultType>
00179 bool LLT<MatrixType>::solve(const MatrixBase<RhsDerived> &b, ResultType *result) const
00180 {
00181 ei_assert(m_isInitialized && "LLT is not initialized.");
00182 const int size = m_matrix.rows();
00183 ei_assert(size==b.rows() && "LLT::solve(): invalid number of rows of the right hand side matrix b");
00184 return solveInPlace((*result) = b);
00185 }
00186
00198 template<typename MatrixType>
00199 template<typename Derived>
00200 bool LLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
00201 {
00202 ei_assert(m_isInitialized && "LLT is not initialized.");
00203 const int size = m_matrix.rows();
00204 ei_assert(size==bAndX.rows());
00205 matrixL().solveTriangularInPlace(bAndX);
00206 m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
00207 return true;
00208 }
00209
00213 template<typename Derived>
00214 inline const LLT<typename MatrixBase<Derived>::PlainMatrixType>
00215 MatrixBase<Derived>::llt() const
00216 {
00217 return LLT<PlainMatrixType>(derived());
00218 }
00219
00220 #endif // EIGEN_LLT_H