bug #707: add inplace decomposition through Ref<> for Cholesky, LU and QR decompositions.

This commit is contained in:
Gael Guennebaud
2016-07-04 15:13:35 +02:00
parent 75e80792cc
commit 32a41ee659
10 changed files with 337 additions and 64 deletions

View File

@@ -48,16 +48,12 @@ class CompleteOrthogonalDecomposition {
enum {
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
Options = MatrixType::Options,
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
};
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef typename MatrixType::StorageIndex StorageIndex;
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, Options,
MaxRowsAtCompileTime, MaxRowsAtCompileTime>
MatrixQType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime>
PermutationType;
@@ -114,10 +110,27 @@ class CompleteOrthogonalDecomposition {
explicit CompleteOrthogonalDecomposition(const EigenBase<InputType>& matrix)
: m_cpqr(matrix.rows(), matrix.cols()),
m_zCoeffs((std::min)(matrix.rows(), matrix.cols())),
m_temp(matrix.cols()) {
m_temp(matrix.cols())
{
compute(matrix.derived());
}
/** \brief Constructs a complete orthogonal decomposition from a given matrix
*
* This overloaded constructor is provided for inplace solving when \c MatrixType is a Eigen::Ref.
*
* \sa CompleteOrthogonalDecomposition(const EigenBase&)
*/
template<typename InputType>
explicit CompleteOrthogonalDecomposition(EigenBase<InputType>& matrix)
: m_cpqr(matrix.derived()),
m_zCoeffs((std::min)(matrix.rows(), matrix.cols())),
m_temp(matrix.cols())
{
computeInPlace();
}
/** This method computes the minimum-norm solution X to a least squares
* problem \f[\mathrm{minimize} ||A X - B|| \f], where \b A is the matrix of
* which \c *this is the complete orthogonal decomposition.
@@ -165,7 +178,12 @@ class CompleteOrthogonalDecomposition {
const MatrixType& matrixT() const { return m_cpqr.matrixQR(); }
template <typename InputType>
CompleteOrthogonalDecomposition& compute(const EigenBase<InputType>& matrix);
CompleteOrthogonalDecomposition& compute(const EigenBase<InputType>& matrix) {
// Compute the column pivoted QR factorization A P = Q R.
m_cpqr.compute(matrix);
computeInPlace();
return *this;
}
/** \returns a const reference to the column permutation matrix */
const PermutationType& colsPermutation() const {
@@ -354,6 +372,8 @@ class CompleteOrthogonalDecomposition {
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
void computeInPlace();
/** Overwrites \b rhs with \f$ \mathbf{Z}^* * \mathbf{rhs} \f$.
*/
template <typename Rhs>
@@ -384,20 +404,16 @@ CompleteOrthogonalDecomposition<MatrixType>::logAbsDeterminant() const {
* CompleteOrthogonalDecomposition(const MatrixType&)
*/
template <typename MatrixType>
template <typename InputType>
CompleteOrthogonalDecomposition<MatrixType>& CompleteOrthogonalDecomposition<
MatrixType>::compute(const EigenBase<InputType>& matrix) {
void CompleteOrthogonalDecomposition<MatrixType>::computeInPlace()
{
check_template_parameters();
// the column permutation is stored as int indices, so just to be sure:
eigen_assert(matrix.cols() <= NumTraits<int>::highest());
// Compute the column pivoted QR factorization A P = Q R.
m_cpqr.compute(matrix);
eigen_assert(m_cpqr.cols() <= NumTraits<int>::highest());
const Index rank = m_cpqr.rank();
const Index cols = matrix.cols();
const Index rows = matrix.rows();
const Index cols = m_cpqr.cols();
const Index rows = m_cpqr.rows();
m_zCoeffs.resize((std::min)(rows, cols));
m_temp.resize(cols);
@@ -443,7 +459,6 @@ CompleteOrthogonalDecomposition<MatrixType>& CompleteOrthogonalDecomposition<
}
}
}
return *this;
}
template <typename MatrixType>