Teh first one
[mldemos:kalians-mldemos.git] / _AlgorithmsPlugins / KPCA / Eigen / src / Cholesky / LLT.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_LLT_H
26 #define EIGEN_LLT_H
27
28 namespace internal{
29 template<typename MatrixType, int UpLo> struct LLT_Traits;
30 }
31
32 /** \ingroup cholesky_Module
33   *
34   * \class LLT
35   *
36   * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features
37   *
38   * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition
39   *
40   * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite
41   * matrix A such that A = LL^* = U^*U, where L is lower triangular.
42   *
43   * While the Cholesky decomposition is particularly useful to solve selfadjoint problems like  D^*D x = b,
44   * for that purpose, we recommend the Cholesky decomposition without square root which is more stable
45   * and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other
46   * situations like generalised eigen problems with hermitian matrices.
47   *
48   * Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices,
49   * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations
50   * has a solution.
51   *
52   * \sa MatrixBase::llt(), class LDLT
53   */
54  /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH)
55   * Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
56   * the strict lower part does not have to store correct values.
57   */
58 template<typename _MatrixType, int _UpLo> class LLT
59 {
60   public:
61     typedef _MatrixType MatrixType;
62     enum {
63       RowsAtCompileTime = MatrixType::RowsAtCompileTime,
64       ColsAtCompileTime = MatrixType::ColsAtCompileTime,
65       Options = MatrixType::Options,
66       MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
67     };
68     typedef typename MatrixType::Scalar Scalar;
69     typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
70     typedef typename MatrixType::Index Index;
71
72     enum {
73       PacketSize = internal::packet_traits<Scalar>::size,
74       AlignmentMask = int(PacketSize)-1,
75       UpLo = _UpLo
76     };
77
78     typedef internal::LLT_Traits<MatrixType,UpLo> Traits;
79
80     /**
81       * \brief Default Constructor.
82       *
83       * The default constructor is useful in cases in which the user intends to
84       * perform decompositions via LLT::compute(const MatrixType&).
85       */
86     LLT() : m_matrix(), m_isInitialized(false) {}
87
88     /** \brief Default Constructor with memory preallocation
89       *
90       * Like the default constructor but with preallocation of the internal data
91       * according to the specified problem \a size.
92       * \sa LLT()
93       */
94     LLT(Index size) : m_matrix(size, size),
95                     m_isInitialized(false) {}
96
97     LLT(const MatrixType& matrix)
98       : m_matrix(matrix.rows(), matrix.cols()),
99         m_isInitialized(false)
100     {
101       compute(matrix);
102     }
103
104     /** \returns a view of the upper triangular matrix U */
105     inline typename Traits::MatrixU matrixU() const
106     {
107       eigen_assert(m_isInitialized && "LLT is not initialized.");
108       return Traits::getU(m_matrix);
109     }
110
111     /** \returns a view of the lower triangular matrix L */
112     inline typename Traits::MatrixL matrixL() const
113     {
114       eigen_assert(m_isInitialized && "LLT is not initialized.");
115       return Traits::getL(m_matrix);
116     }
117
118     /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
119       *
120       * Since this LLT class assumes anyway that the matrix A is invertible, the solution
121       * theoretically exists and is unique regardless of b.
122       *
123       * Example: \include LLT_solve.cpp
124       * Output: \verbinclude LLT_solve.out
125       *
126       * \sa solveInPlace(), MatrixBase::llt()
127       */
128     template<typename Rhs>
129     inline const internal::solve_retval<LLT, Rhs>
130     solve(const MatrixBase<Rhs>& b) const
131     {
132       eigen_assert(m_isInitialized && "LLT is not initialized.");
133       eigen_assert(m_matrix.rows()==b.rows()
134                 && "LLT::solve(): invalid number of rows of the right hand side matrix b");
135       return internal::solve_retval<LLT, Rhs>(*this, b.derived());
136     }
137
138     #ifdef EIGEN2_SUPPORT
139     template<typename OtherDerived, typename ResultType>
140     bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const
141     {
142       *result = this->solve(b);
143       return true;
144     }
145     
146     bool isPositiveDefinite() const { return true; }
147     #endif
148
149     template<typename Derived>
150     void solveInPlace(MatrixBase<Derived> &bAndX) const;
151
152     LLT& compute(const MatrixType& matrix);
153
154     /** \returns the LLT decomposition matrix
155       *
156       * TODO: document the storage layout
157       */
158     inline const MatrixType& matrixLLT() const
159     {
160       eigen_assert(m_isInitialized && "LLT is not initialized.");
161       return m_matrix;
162     }
163
164     MatrixType reconstructedMatrix() const;
165
166
167     /** \brief Reports whether previous computation was successful.
168       *
169       * \returns \c Success if computation was succesful,
170       *          \c NumericalIssue if the matrix.appears to be negative.
171       */
172     ComputationInfo info() const
173     {
174       eigen_assert(m_isInitialized && "LLT is not initialized.");
175       return m_info;
176     }
177
178     inline Index rows() const { return m_matrix.rows(); }
179     inline Index cols() const { return m_matrix.cols(); }
180
181   protected:
182     /** \internal
183       * Used to compute and store L
184       * The strict upper part is not used and even not initialized.
185       */
186     MatrixType m_matrix;
187     bool m_isInitialized;
188     ComputationInfo m_info;
189 };
190
191 namespace internal {
192
193 template<int UpLo> struct llt_inplace;
194
195 template<> struct llt_inplace<Lower>
196 {
197   template<typename MatrixType>
198   static typename MatrixType::Index unblocked(MatrixType& mat)
199   {
200     typedef typename MatrixType::Index Index;
201     typedef typename MatrixType::Scalar Scalar;
202     typedef typename MatrixType::RealScalar RealScalar;
203     
204     eigen_assert(mat.rows()==mat.cols());
205     const Index size = mat.rows();
206     for(Index k = 0; k < size; ++k)
207     {
208       Index rs = size-k-1; // remaining size
209
210       Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1);
211       Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
212       Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
213
214       RealScalar x = real(mat.coeff(k,k));
215       if (k>0) x -= A10.squaredNorm();
216       if (x<=RealScalar(0))
217         return k;
218       mat.coeffRef(k,k) = x = sqrt(x);
219       if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint();
220       if (rs>0) A21 *= RealScalar(1)/x;
221     }
222     return -1;
223   }
224
225   template<typename MatrixType>
226   static typename MatrixType::Index blocked(MatrixType& m)
227   {
228     typedef typename MatrixType::Index Index;
229     eigen_assert(m.rows()==m.cols());
230     Index size = m.rows();
231     if(size<32)
232       return unblocked(m);
233
234     Index blockSize = size/8;
235     blockSize = (blockSize/16)*16;
236     blockSize = std::min(std::max(blockSize,Index(8)), Index(128));
237
238     for (Index k=0; k<size; k+=blockSize)
239     {
240       // partition the matrix:
241       //       A00 |  -  |  -
242       // lu  = A10 | A11 |  -
243       //       A20 | A21 | A22
244       Index bs = std::min(blockSize, size-k);
245       Index rs = size - k - bs;
246       Block<MatrixType,Dynamic,Dynamic> A11(m,k,   k,   bs,bs);
247       Block<MatrixType,Dynamic,Dynamic> A21(m,k+bs,k,   rs,bs);
248       Block<MatrixType,Dynamic,Dynamic> A22(m,k+bs,k+bs,rs,rs);
249
250       Index ret;
251       if((ret=unblocked(A11))>=0) return k+ret;
252       if(rs>0) A11.adjoint().template triangularView<Upper>().template solveInPlace<OnTheRight>(A21);
253       if(rs>0) A22.template selfadjointView<Lower>().rankUpdate(A21,-1); // bottleneck
254     }
255     return -1;
256   }
257 };
258
259 template<> struct llt_inplace<Upper>
260 {
261   template<typename MatrixType>
262   static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat)
263   {
264     Transpose<MatrixType> matt(mat);
265     return llt_inplace<Lower>::unblocked(matt);
266   }
267   template<typename MatrixType>
268   static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat)
269   {
270     Transpose<MatrixType> matt(mat);
271     return llt_inplace<Lower>::blocked(matt);
272   }
273 };
274
275 template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
276 {
277   typedef TriangularView<MatrixType, Lower> MatrixL;
278   typedef TriangularView<typename MatrixType::AdjointReturnType, Upper> MatrixU;
279   inline static MatrixL getL(const MatrixType& m) { return m; }
280   inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
281   static bool inplace_decomposition(MatrixType& m)
282   { return llt_inplace<Lower>::blocked(m)==-1; }
283 };
284
285 template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
286 {
287   typedef TriangularView<typename MatrixType::AdjointReturnType, Lower> MatrixL;
288   typedef TriangularView<MatrixType, Upper> MatrixU;
289   inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
290   inline static MatrixU getU(const MatrixType& m) { return m; }
291   static bool inplace_decomposition(MatrixType& m)
292   { return llt_inplace<Upper>::blocked(m)==-1; }
293 };
294
295 } // end namespace internal
296
297 /** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix
298   *
299   *
300   * \returns a reference to *this
301   */
302 template<typename MatrixType, int _UpLo>
303 LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a)
304 {
305   assert(a.rows()==a.cols());
306   const Index size = a.rows();
307   m_matrix.resize(size, size);
308   m_matrix = a;
309
310   m_isInitialized = true;
311   bool ok = Traits::inplace_decomposition(m_matrix);
312   m_info = ok ? Success : NumericalIssue;
313
314   return *this;
315 }
316
317 namespace internal {
318 template<typename _MatrixType, int UpLo, typename Rhs>
319 struct solve_retval<LLT<_MatrixType, UpLo>, Rhs>
320   : solve_retval_base<LLT<_MatrixType, UpLo>, Rhs>
321 {
322   typedef LLT<_MatrixType,UpLo> LLTType;
323   EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs)
324
325   template<typename Dest> void evalTo(Dest& dst) const
326   {
327     dst = rhs();
328     dec().solveInPlace(dst);
329   }
330 };
331 }
332
333 /** \internal use x = llt_object.solve(x);
334   * 
335   * This is the \em in-place version of solve().
336   *
337   * \param bAndX represents both the right-hand side matrix b and result x.
338   *
339   * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD.
340   *
341   * This version avoids a copy when the right hand side matrix b is not
342   * needed anymore.
343   *
344   * \sa LLT::solve(), MatrixBase::llt()
345   */
346 template<typename MatrixType, int _UpLo>
347 template<typename Derived>
348 void LLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
349 {
350   eigen_assert(m_isInitialized && "LLT is not initialized.");
351   eigen_assert(m_matrix.rows()==bAndX.rows());
352   matrixL().solveInPlace(bAndX);
353   matrixU().solveInPlace(bAndX);
354 }
355
356 /** \returns the matrix represented by the decomposition,
357  * i.e., it returns the product: L L^*.
358  * This function is provided for debug purpose. */
359 template<typename MatrixType, int _UpLo>
360 MatrixType LLT<MatrixType,_UpLo>::reconstructedMatrix() const
361 {
362   eigen_assert(m_isInitialized && "LLT is not initialized.");
363   return matrixL() * matrixL().adjoint().toDenseMatrix();
364 }
365
366 /** \cholesky_module
367   * \returns the LLT decomposition of \c *this
368   */
369 template<typename Derived>
370 inline const LLT<typename MatrixBase<Derived>::PlainObject>
371 MatrixBase<Derived>::llt() const
372 {
373   return LLT<PlainObject>(derived());
374 }
375
376 /** \cholesky_module
377   * \returns the LLT decomposition of \c *this
378   */
379 template<typename MatrixType, unsigned int UpLo>
380 inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
381 SelfAdjointView<MatrixType, UpLo>::llt() const
382 {
383   return LLT<PlainObject,UpLo>(m_matrix);
384 }
385
386 #endif // EIGEN_LLT_H