mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
bug #707: add inplace decomposition through Ref<> for Cholesky, LU and QR decompositions.
This commit is contained in:
@@ -97,6 +97,15 @@ template<typename _MatrixType> class FullPivLU
|
||||
template<typename InputType>
|
||||
explicit FullPivLU(const EigenBase<InputType>& matrix);
|
||||
|
||||
/** \brief Constructs a LU factorization from a given matrix
|
||||
*
|
||||
* This overloaded constructor is provided for inplace solving when \c MatrixType is a Eigen::Ref.
|
||||
*
|
||||
* \sa FullPivLU(const EigenBase&)
|
||||
*/
|
||||
template<typename InputType>
|
||||
explicit FullPivLU(EigenBase<InputType>& matrix);
|
||||
|
||||
/** Computes the LU decomposition of the given matrix.
|
||||
*
|
||||
* \param matrix the matrix of which to compute the LU decomposition.
|
||||
@@ -105,7 +114,11 @@ template<typename _MatrixType> class FullPivLU
|
||||
* \returns a reference to *this
|
||||
*/
|
||||
template<typename InputType>
|
||||
FullPivLU& compute(const EigenBase<InputType>& matrix);
|
||||
FullPivLU& compute(const EigenBase<InputType>& matrix) {
|
||||
m_lu = matrix.derived();
|
||||
computeInPlace();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** \returns the LU decomposition matrix: the upper-triangular part is U, the
|
||||
* unit-lower-triangular part is L (at least for square matrices; in the non-square
|
||||
@@ -459,25 +472,28 @@ FullPivLU<MatrixType>::FullPivLU(const EigenBase<InputType>& matrix)
|
||||
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const EigenBase<InputType>& matrix)
|
||||
FullPivLU<MatrixType>::FullPivLU(EigenBase<InputType>& matrix)
|
||||
: m_lu(matrix.derived()),
|
||||
m_p(matrix.rows()),
|
||||
m_q(matrix.cols()),
|
||||
m_rowsTranspositions(matrix.rows()),
|
||||
m_colsTranspositions(matrix.cols()),
|
||||
m_isInitialized(false),
|
||||
m_usePrescribedThreshold(false)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the permutations are stored as int indices, so just to be sure:
|
||||
eigen_assert(matrix.rows()<=NumTraits<int>::highest() && matrix.cols()<=NumTraits<int>::highest());
|
||||
|
||||
m_lu = matrix.derived();
|
||||
m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
|
||||
|
||||
computeInPlace();
|
||||
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
void FullPivLU<MatrixType>::computeInPlace()
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the permutations are stored as int indices, so just to be sure:
|
||||
eigen_assert(m_lu.rows()<=NumTraits<int>::highest() && m_lu.cols()<=NumTraits<int>::highest());
|
||||
|
||||
m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
|
||||
|
||||
const Index size = m_lu.diagonalSize();
|
||||
const Index rows = m_lu.rows();
|
||||
const Index cols = m_lu.cols();
|
||||
@@ -557,6 +573,8 @@ void FullPivLU<MatrixType>::computeInPlace()
|
||||
m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
|
||||
|
||||
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
||||
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
|
||||
@@ -26,6 +26,17 @@ template<typename _MatrixType> struct traits<PartialPivLU<_MatrixType> >
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T,typename Derived>
|
||||
struct enable_if_ref;
|
||||
// {
|
||||
// typedef Derived type;
|
||||
// };
|
||||
|
||||
template<typename T,typename Derived>
|
||||
struct enable_if_ref<Ref<T>,Derived> {
|
||||
typedef Derived type;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \ingroup LU_Module
|
||||
@@ -102,8 +113,29 @@ template<typename _MatrixType> class PartialPivLU
|
||||
template<typename InputType>
|
||||
explicit PartialPivLU(const EigenBase<InputType>& matrix);
|
||||
|
||||
/** Constructor for inplace decomposition
|
||||
*
|
||||
* \param matrix the matrix of which to compute the LU decomposition.
|
||||
*
|
||||
* If \c MatrixType is an Eigen::Ref, then the storage of \a matrix will be shared
|
||||
* between \a matrix and \c *this and the decomposition will take place in-place.
|
||||
* The memory of \a matrix will be used througrough the lifetime of \c *this. In
|
||||
* particular, further calls to \c this->compute(A) will still operate on the memory
|
||||
* of \a matrix meaning. This also implies that the sizes of \c A must match the
|
||||
* ones of \a matrix.
|
||||
*
|
||||
* \warning The matrix should have full rank (e.g. if it's square, it should be invertible).
|
||||
* If you need to deal with non-full rank, use class FullPivLU instead.
|
||||
*/
|
||||
template<typename InputType>
|
||||
PartialPivLU& compute(const EigenBase<InputType>& matrix);
|
||||
explicit PartialPivLU(EigenBase<InputType>& matrix);
|
||||
|
||||
template<typename InputType>
|
||||
PartialPivLU& compute(const EigenBase<InputType>& matrix) {
|
||||
m_lu = matrix.derived();
|
||||
compute();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** \returns the LU decomposition matrix: the upper-triangular part is U, the
|
||||
* unit-lower-triangular part is L (at least for square matrices; in the non-square
|
||||
@@ -251,6 +283,8 @@ template<typename _MatrixType> class PartialPivLU
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
void compute();
|
||||
|
||||
MatrixType m_lu;
|
||||
PermutationType m_p;
|
||||
TranspositionType m_rowsTranspositions;
|
||||
@@ -284,7 +318,7 @@ PartialPivLU<MatrixType>::PartialPivLU(Index size)
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
PartialPivLU<MatrixType>::PartialPivLU(const EigenBase<InputType>& matrix)
|
||||
: m_lu(matrix.rows(), matrix.rows()),
|
||||
: m_lu(matrix.rows(),matrix.cols()),
|
||||
m_p(matrix.rows()),
|
||||
m_rowsTranspositions(matrix.rows()),
|
||||
m_l1_norm(0),
|
||||
@@ -294,6 +328,19 @@ PartialPivLU<MatrixType>::PartialPivLU(const EigenBase<InputType>& matrix)
|
||||
compute(matrix.derived());
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
PartialPivLU<MatrixType>::PartialPivLU(EigenBase<InputType>& matrix)
|
||||
: m_lu(matrix.derived()),
|
||||
m_p(matrix.rows()),
|
||||
m_rowsTranspositions(matrix.rows()),
|
||||
m_l1_norm(0),
|
||||
m_det_p(0),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
compute();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
/** \internal This is the blocked version of fullpivlu_unblocked() */
|
||||
@@ -470,19 +517,17 @@ void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions, t
|
||||
} // end namespace internal
|
||||
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const EigenBase<InputType>& matrix)
|
||||
void PartialPivLU<MatrixType>::compute()
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the row permutation is stored as int indices, so just to be sure:
|
||||
eigen_assert(matrix.rows()<NumTraits<int>::highest());
|
||||
eigen_assert(m_lu.rows()<NumTraits<int>::highest());
|
||||
|
||||
m_lu = matrix.derived();
|
||||
m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
|
||||
|
||||
eigen_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
|
||||
const Index size = matrix.rows();
|
||||
eigen_assert(m_lu.rows() == m_lu.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
|
||||
const Index size = m_lu.rows();
|
||||
|
||||
m_rowsTranspositions.resize(size);
|
||||
|
||||
@@ -493,7 +538,6 @@ PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const EigenBase<Inpu
|
||||
m_p = m_rowsTranspositions;
|
||||
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
|
||||
Reference in New Issue
Block a user