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_LDLT_H
00026 #define EIGEN_LDLT_H
00027
00048 template<typename MatrixType> class LDLT
00049 {
00050 public:
00051
00052 typedef typename MatrixType::Scalar Scalar;
00053 typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
00054 typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
00055
00056 LDLT(const MatrixType& matrix)
00057 : m_matrix(matrix.rows(), matrix.cols())
00058 {
00059 compute(matrix);
00060 }
00061
00063 inline Part<MatrixType, UnitLowerTriangular> matrixL(void) const { return m_matrix; }
00064
00066 inline DiagonalCoeffs<MatrixType> vectorD(void) const { return m_matrix.diagonal(); }
00067
00069 inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
00070
00071 template<typename RhsDerived, typename ResultType>
00072 bool solve(const MatrixBase<RhsDerived> &b, ResultType *result) const;
00073
00074 template<typename Derived>
00075 bool solveInPlace(MatrixBase<Derived> &bAndX) const;
00076
00077 void compute(const MatrixType& matrix);
00078
00079 protected:
00086 MatrixType m_matrix;
00087
00088 bool m_isPositiveDefinite;
00089 };
00090
00093 template<typename MatrixType>
00094 void LDLT<MatrixType>::compute(const MatrixType& a)
00095 {
00096 assert(a.rows()==a.cols());
00097 const int size = a.rows();
00098 m_matrix.resize(size, size);
00099 m_isPositiveDefinite = true;
00100
00101 if (size<=1)
00102 {
00103 m_matrix = a;
00104 return;
00105 }
00106
00107
00108
00109
00110
00111 Matrix<Scalar,MatrixType::RowsAtCompileTime,1> _temporary(size);
00112
00113
00114
00115
00116 m_matrix.row(0) = a.row(0).conjugate();
00117 m_matrix.col(0).end(size-1) = m_matrix.row(0).end(size-1) / m_matrix.coeff(0,0);
00118 for (int j = 1; j < size; ++j)
00119 {
00120 RealScalar tmp = ei_real(a.coeff(j,j) - (m_matrix.row(j).start(j) * m_matrix.col(j).start(j).conjugate()).coeff(0,0));
00121 m_matrix.coeffRef(j,j) = tmp;
00122
00123 int endSize = size-j-1;
00124 if (endSize>0)
00125 {
00126 _temporary.end(endSize) = ( m_matrix.block(j+1,0, endSize, j)
00127 * m_matrix.col(j).start(j).conjugate() ).lazy();
00128
00129 m_matrix.row(j).end(endSize) = a.row(j).end(endSize).conjugate()
00130 - _temporary.end(endSize).transpose();
00131
00132 if(tmp != RealScalar(0))
00133 m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
00134 }
00135 }
00136 }
00137
00148 template<typename MatrixType>
00149 template<typename RhsDerived, typename ResultType>
00150 bool LDLT<MatrixType>
00151 ::solve(const MatrixBase<RhsDerived> &b, ResultType *result) const
00152 {
00153 const int size = m_matrix.rows();
00154 ei_assert(size==b.rows() && "LLT::solve(): invalid number of rows of the right hand side matrix b");
00155 *result = b;
00156 return solveInPlace(*result);
00157 }
00158
00168 template<typename MatrixType>
00169 template<typename Derived>
00170 bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
00171 {
00172 const int size = m_matrix.rows();
00173 ei_assert(size==bAndX.rows());
00174 if (!m_isPositiveDefinite)
00175 return false;
00176 matrixL().solveTriangularInPlace(bAndX);
00177 bAndX = (m_matrix.cwise().inverse().template part<Diagonal>() * bAndX).lazy();
00178 m_matrix.adjoint().template part<UnitUpperTriangular>().solveTriangularInPlace(bAndX);
00179 return true;
00180 }
00181
00185 template<typename Derived>
00186 inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
00187 MatrixBase<Derived>::ldlt() const
00188 {
00189 return LDLT<PlainMatrixType>(derived());
00190 }
00191
00192 #endif // EIGEN_LDLT_H