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:
@@ -51,7 +51,6 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
Options = MatrixType::Options,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
||||
};
|
||||
@@ -59,7 +58,6 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
// FIXME should be int
|
||||
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;
|
||||
typedef typename internal::plain_row_type<MatrixType, Index>::type IntRowVectorType;
|
||||
@@ -135,6 +133,27 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
||||
compute(matrix.derived());
|
||||
}
|
||||
|
||||
/** \brief Constructs a QR factorization from a given matrix
|
||||
*
|
||||
* This overloaded constructor is provided for inplace solving when \c MatrixType is a Eigen::Ref.
|
||||
*
|
||||
* \sa ColPivHouseholderQR(const EigenBase&)
|
||||
*/
|
||||
template<typename InputType>
|
||||
explicit ColPivHouseholderQR(EigenBase<InputType>& matrix)
|
||||
: m_qr(matrix.derived()),
|
||||
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
|
||||
m_colsPermutation(PermIndexType(matrix.cols())),
|
||||
m_colsTranspositions(matrix.cols()),
|
||||
m_temp(matrix.cols()),
|
||||
m_colNormsUpdated(matrix.cols()),
|
||||
m_colNormsDirect(matrix.cols()),
|
||||
m_isInitialized(false),
|
||||
m_usePrescribedThreshold(false)
|
||||
{
|
||||
computeInPlace();
|
||||
}
|
||||
|
||||
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which
|
||||
* *this is the QR decomposition, if any exists.
|
||||
*
|
||||
@@ -453,21 +472,19 @@ template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const EigenBase<InputType>& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the column permutation is stored as int indices, so just to be sure:
|
||||
eigen_assert(matrix.cols()<=NumTraits<int>::highest());
|
||||
|
||||
m_qr = matrix;
|
||||
|
||||
m_qr = matrix.derived();
|
||||
computeInPlace();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the column permutation is stored as int indices, so just to be sure:
|
||||
eigen_assert(m_qr.cols()<=NumTraits<int>::highest());
|
||||
|
||||
using std::abs;
|
||||
|
||||
Index rows = m_qr.rows();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -60,7 +60,6 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
Options = MatrixType::Options,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
||||
};
|
||||
@@ -135,6 +134,26 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
||||
compute(matrix.derived());
|
||||
}
|
||||
|
||||
/** \brief Constructs a QR factorization from a given matrix
|
||||
*
|
||||
* This overloaded constructor is provided for inplace solving when \c MatrixType is a Eigen::Ref.
|
||||
*
|
||||
* \sa FullPivHouseholderQR(const EigenBase&)
|
||||
*/
|
||||
template<typename InputType>
|
||||
explicit FullPivHouseholderQR(EigenBase<InputType>& matrix)
|
||||
: m_qr(matrix.derived()),
|
||||
m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
|
||||
m_rows_transpositions((std::min)(matrix.rows(), matrix.cols())),
|
||||
m_cols_transpositions((std::min)(matrix.rows(), matrix.cols())),
|
||||
m_cols_permutation(matrix.cols()),
|
||||
m_temp(matrix.cols()),
|
||||
m_isInitialized(false),
|
||||
m_usePrescribedThreshold(false)
|
||||
{
|
||||
computeInPlace();
|
||||
}
|
||||
|
||||
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which
|
||||
* \c *this is the QR decomposition.
|
||||
*
|
||||
@@ -430,18 +449,16 @@ template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const EigenBase<InputType>& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
m_qr = matrix.derived();
|
||||
|
||||
computeInPlace();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
void FullPivHouseholderQR<MatrixType>::computeInPlace()
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::abs;
|
||||
Index rows = m_qr.rows();
|
||||
Index cols = m_qr.cols();
|
||||
|
||||
@@ -47,7 +47,6 @@ template<typename _MatrixType> class HouseholderQR
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
Options = MatrixType::Options,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
||||
};
|
||||
@@ -102,6 +101,24 @@ template<typename _MatrixType> class HouseholderQR
|
||||
compute(matrix.derived());
|
||||
}
|
||||
|
||||
|
||||
/** \brief Constructs a QR factorization from a given matrix
|
||||
*
|
||||
* This overloaded constructor is provided for inplace solving when
|
||||
* \c MatrixType is a Eigen::Ref.
|
||||
*
|
||||
* \sa HouseholderQR(const EigenBase&)
|
||||
*/
|
||||
template<typename InputType>
|
||||
explicit HouseholderQR(EigenBase<InputType>& matrix)
|
||||
: m_qr(matrix.derived()),
|
||||
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
|
||||
m_temp(matrix.cols()),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
computeInPlace();
|
||||
}
|
||||
|
||||
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which
|
||||
* *this is the QR decomposition, if any exists.
|
||||
*
|
||||
@@ -151,7 +168,11 @@ template<typename _MatrixType> class HouseholderQR
|
||||
}
|
||||
|
||||
template<typename InputType>
|
||||
HouseholderQR& compute(const EigenBase<InputType>& matrix);
|
||||
HouseholderQR& compute(const EigenBase<InputType>& matrix) {
|
||||
m_qr = matrix.derived();
|
||||
computeInPlace();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** \returns the absolute value of the determinant of the matrix of which
|
||||
* *this is the QR decomposition. It has only linear complexity
|
||||
@@ -203,6 +224,8 @@ template<typename _MatrixType> class HouseholderQR
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
void computeInPlace();
|
||||
|
||||
MatrixType m_qr;
|
||||
HCoeffsType m_hCoeffs;
|
||||
@@ -354,16 +377,14 @@ void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) c
|
||||
* \sa class HouseholderQR, HouseholderQR(const MatrixType&)
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const EigenBase<InputType>& matrix)
|
||||
void HouseholderQR<MatrixType>::computeInPlace()
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
Index rows = matrix.rows();
|
||||
Index cols = matrix.cols();
|
||||
Index rows = m_qr.rows();
|
||||
Index cols = m_qr.cols();
|
||||
Index size = (std::min)(rows,cols);
|
||||
|
||||
m_qr = matrix.derived();
|
||||
m_hCoeffs.resize(size);
|
||||
|
||||
m_temp.resize(cols);
|
||||
@@ -371,7 +392,6 @@ HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const EigenBase<In
|
||||
internal::householder_qr_inplace_blocked<MatrixType, HCoeffsType>::run(m_qr, m_hCoeffs, 48, m_temp.data());
|
||||
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef __CUDACC__
|
||||
|
||||
Reference in New Issue
Block a user