11 #ifndef EIGEN_PARTIALLU_H
12 #define EIGEN_PARTIALLU_H
47 template<
typename _MatrixType>
class PartialPivLU
51 typedef _MatrixType MatrixType;
53 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
54 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
55 Options = MatrixType::Options,
56 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
57 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
59 typedef typename MatrixType::Scalar Scalar;
60 typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
61 typedef typename internal::traits<MatrixType>::StorageKind StorageKind;
62 typedef typename MatrixType::Index Index;
63 typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationType;
64 typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
102 eigen_assert(m_isInitialized &&
"PartialPivLU is not initialized.");
110 eigen_assert(m_isInitialized &&
"PartialPivLU is not initialized.");
131 template<
typename Rhs>
132 inline const internal::solve_retval<PartialPivLU, Rhs>
135 eigen_assert(m_isInitialized &&
"PartialPivLU is not initialized.");
136 return internal::solve_retval<PartialPivLU, Rhs>(*
this, b.derived());
146 inline const internal::solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType>
inverse()
const
148 eigen_assert(m_isInitialized &&
"PartialPivLU is not initialized.");
149 return internal::solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType>
150 (*
this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
166 typename internal::traits<MatrixType>::Scalar
determinant()
const;
170 inline Index rows()
const {
return m_lu.rows(); }
171 inline Index cols()
const {
return m_lu.cols(); }
175 static void check_template_parameters()
177 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
182 TranspositionType m_rowsTranspositions;
184 bool m_isInitialized;
187 template<
typename MatrixType>
191 m_rowsTranspositions(),
193 m_isInitialized(false)
197 template<
typename MatrixType>
201 m_rowsTranspositions(size),
203 m_isInitialized(false)
207 template<
typename MatrixType>
209 : m_lu(matrix.rows(), matrix.rows()),
211 m_rowsTranspositions(matrix.rows()),
213 m_isInitialized(false)
221 template<
typename Scalar,
int StorageOrder,
typename PivIndex>
222 struct partial_lu_impl
232 typedef typename MatrixType::RealScalar RealScalar;
233 typedef typename MatrixType::Index Index;
245 static Index unblocked_lu(MatrixType& lu, PivIndex* row_transpositions, PivIndex& nb_transpositions)
247 const Index rows = lu.rows();
248 const Index cols = lu.cols();
249 const Index size = (std::min)(rows,cols);
250 nb_transpositions = 0;
251 Index first_zero_pivot = -1;
252 for(Index k = 0; k < size; ++k)
254 Index rrows = rows-k-1;
255 Index rcols = cols-k-1;
257 Index row_of_biggest_in_col;
258 RealScalar biggest_in_corner
259 = lu.col(k).tail(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col);
260 row_of_biggest_in_col += k;
262 row_transpositions[k] = PivIndex(row_of_biggest_in_col);
264 if(biggest_in_corner != RealScalar(0))
266 if(k != row_of_biggest_in_col)
268 lu.row(k).swap(lu.row(row_of_biggest_in_col));
274 lu.col(k).tail(rrows) /= lu.coeff(k,k);
276 else if(first_zero_pivot==-1)
280 first_zero_pivot = k;
284 lu.bottomRightCorner(rrows,rcols).noalias() -= lu.col(k).tail(rrows) * lu.row(k).tail(rcols);
286 return first_zero_pivot;
304 static Index blocked_lu(Index rows, Index cols, Scalar* lu_data, Index luStride, PivIndex* row_transpositions, PivIndex& nb_transpositions, Index maxBlockSize=256)
306 MapLU lu1(lu_data,StorageOrder==
RowMajor?rows:luStride,StorageOrder==
RowMajor?luStride:cols);
307 MatrixType lu(lu1,0,0,rows,cols);
309 const Index size = (std::min)(rows,cols);
314 return unblocked_lu(lu, row_transpositions, nb_transpositions);
322 blockSize = (blockSize/16)*16;
323 blockSize = (std::min)((std::max)(blockSize,Index(8)), maxBlockSize);
326 nb_transpositions = 0;
327 Index first_zero_pivot = -1;
328 for(Index k = 0; k < size; k+=blockSize)
330 Index bs = (std::min)(size-k,blockSize);
331 Index trows = rows - k - bs;
332 Index tsize = size - k - bs;
338 BlockType A_0(lu,0,0,rows,k);
339 BlockType A_2(lu,0,k+bs,rows,tsize);
340 BlockType A11(lu,k,k,bs,bs);
341 BlockType A12(lu,k,k+bs,bs,tsize);
342 BlockType A21(lu,k+bs,k,trows,bs);
343 BlockType A22(lu,k+bs,k+bs,trows,tsize);
345 PivIndex nb_transpositions_in_panel;
348 Index ret = blocked_lu(trows+bs, bs, &lu.coeffRef(k,k), luStride,
349 row_transpositions+k, nb_transpositions_in_panel, 16);
350 if(ret>=0 && first_zero_pivot==-1)
351 first_zero_pivot = k+ret;
353 nb_transpositions += nb_transpositions_in_panel;
355 for(Index i=k; i<k+bs; ++i)
357 Index piv = (row_transpositions[i] += k);
358 A_0.row(i).swap(A_0.row(piv));
364 for(Index i=k;i<k+bs; ++i)
365 A_2.row(i).swap(A_2.row(row_transpositions[i]));
368 A11.template triangularView<UnitLower>().solveInPlace(A12);
370 A22.noalias() -= A21 * A12;
373 return first_zero_pivot;
379 template<
typename MatrixType,
typename TranspositionType>
380 void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions,
typename TranspositionType::Index& nb_transpositions)
382 eigen_assert(lu.cols() == row_transpositions.size());
383 eigen_assert((&row_transpositions.coeffRef(1)-&row_transpositions.coeffRef(0)) == 1);
387 ::blocked_lu(lu.rows(), lu.cols(), &lu.coeffRef(0,0), lu.outerStride(), &row_transpositions.coeffRef(0), nb_transpositions);
392 template<
typename MatrixType>
393 PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(
const MatrixType& matrix)
395 check_template_parameters();
398 eigen_assert(matrix.rows()<NumTraits<int>::highest());
402 eigen_assert(matrix.rows() == matrix.cols() &&
"PartialPivLU is only for square (and moreover invertible) matrices");
403 const Index size = matrix.rows();
405 m_rowsTranspositions.resize(size);
407 typename TranspositionType::Index nb_transpositions;
408 internal::partial_lu_inplace(m_lu, m_rowsTranspositions, nb_transpositions);
409 m_det_p = (nb_transpositions%2) ? -1 : 1;
411 m_p = m_rowsTranspositions;
413 m_isInitialized =
true;
417 template<
typename MatrixType>
420 eigen_assert(m_isInitialized &&
"PartialPivLU is not initialized.");
421 return Scalar(m_det_p) * m_lu.diagonal().prod();
427 template<
typename MatrixType>
430 eigen_assert(m_isInitialized &&
"LU is not initialized.");
432 MatrixType res = m_lu.template triangularView<UnitLower>().toDenseMatrix()
433 * m_lu.template triangularView<Upper>();
436 res = m_p.inverse() * res;
445 template<
typename _MatrixType,
typename Rhs>
447 : solve_retval_base<PartialPivLU<_MatrixType>, Rhs>
451 template<typename Dest>
void evalTo(Dest& dst)
const
460 eigen_assert(rhs().rows() == dec().matrixLU().rows());
463 dst = dec().permutationP() * rhs();
466 dec().matrixLU().template triangularView<UnitLower>().solveInPlace(dst);
469 dec().matrixLU().template triangularView<Upper>().solveInPlace(dst);
483 template<
typename Derived>
484 inline const PartialPivLU<typename MatrixBase<Derived>::PlainObject>
490 #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
499 template<
typename Derived>
509 #endif // EIGEN_PARTIALLU_H
const PartialPivLU< PlainObject > lu() const
Definition: PartialPivLU.h:501
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:104
LU decomposition of a matrix with partial pivoting, and related features.
Definition: ForwardDeclarations.h:217
PartialPivLU()
Default Constructor.
Definition: PartialPivLU.h:188
Definition: Constants.h:264
MatrixType reconstructedMatrix() const
Definition: PartialPivLU.h:428
const internal::solve_retval< PartialPivLU, typename MatrixType::IdentityReturnType > inverse() const
Definition: PartialPivLU.h:146
const PartialPivLU< PlainObject > partialPivLu() const
Definition: PartialPivLU.h:485
internal::traits< MatrixType >::Scalar determinant() const
Definition: PartialPivLU.h:418
const PermutationType & permutationP() const
Definition: PartialPivLU.h:108
const MatrixType & matrixLU() const
Definition: PartialPivLU.h:100
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
Definition: Constants.h:266
const unsigned int RowMajorBit
Definition: Constants.h:53
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
const internal::solve_retval< PartialPivLU, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition: PartialPivLU.h:133