ADD: added other eigen lib

This commit is contained in:
Henry Winkel
2022-12-21 16:19:04 +01:00
parent a570766dc6
commit 9e56c7f2c0
832 changed files with 36586 additions and 20006 deletions

View File

@@ -11,11 +11,13 @@
#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
#include "./InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
template<typename _MatrixType> struct traits<ColPivHouseholderQR<_MatrixType> >
: traits<_MatrixType>
template<typename MatrixType_> struct traits<ColPivHouseholderQR<MatrixType_> >
: traits<MatrixType_>
{
typedef MatrixXpr XprKind;
typedef SolverStorage StorageKind;
@@ -31,7 +33,7 @@ template<typename _MatrixType> struct traits<ColPivHouseholderQR<_MatrixType> >
*
* \brief Householder rank-revealing QR decomposition of a matrix with column-pivoting
*
* \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition
* \tparam MatrixType_ the type of the matrix of which we are computing the QR decomposition
*
* This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b Q and \b R
* such that
@@ -48,12 +50,12 @@ template<typename _MatrixType> struct traits<ColPivHouseholderQR<_MatrixType> >
*
* \sa MatrixBase::colPivHouseholderQr()
*/
template<typename _MatrixType> class ColPivHouseholderQR
: public SolverBase<ColPivHouseholderQR<_MatrixType> >
template<typename MatrixType_> class ColPivHouseholderQR
: public SolverBase<ColPivHouseholderQR<MatrixType_> >
{
public:
typedef _MatrixType MatrixType;
typedef MatrixType_ MatrixType;
typedef SolverBase<ColPivHouseholderQR> Base;
friend class SolverBase<ColPivHouseholderQR>;
@@ -67,7 +69,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
typedef typename internal::plain_row_type<MatrixType, Index>::type IntRowVectorType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType;
typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
typedef HouseholderSequence<MatrixType,internal::remove_all_t<typename HCoeffsType::ConjugateReturnType>> HouseholderSequenceType;
typedef typename MatrixType::PlainObject PlainObject;
private:
@@ -217,6 +219,21 @@ template<typename _MatrixType> class ColPivHouseholderQR
return m_colsPermutation;
}
/** \returns the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
* as the QR decomposition has already been computed.
*
* \note This is only for square matrices.
*
* \warning a determinant can be very big or small, so for matrices
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::Scalar determinant() const;
/** \returns the absolute value of the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
@@ -228,7 +245,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa logAbsDeterminant(), MatrixBase::determinant()
* \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -242,7 +259,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
* \note This method is useful to work around the risk of overflow/underflow that's inherent
* to determinant computation.
*
* \sa absDeterminant(), MatrixBase::determinant()
* \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -426,10 +443,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
friend class CompleteOrthogonalDecomposition<MatrixType>;
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
void computeInPlace();
@@ -443,9 +457,19 @@ template<typename _MatrixType> class ColPivHouseholderQR
bool m_isInitialized, m_usePrescribedThreshold;
RealScalar m_prescribedThreshold, m_maxpivot;
Index m_nonzero_pivots;
Index m_det_pq;
Index m_det_p;
};
template<typename MatrixType>
typename MatrixType::Scalar ColPivHouseholderQR<MatrixType>::determinant() const
{
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
Scalar detQ;
internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
return m_qr.diagonal().prod() * detQ * Scalar(m_det_p);
}
template<typename MatrixType>
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
{
@@ -481,8 +505,6 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
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());
@@ -555,7 +577,7 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
// and used in LAPACK routines xGEQPF and xGEQP3.
// See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) {
if (!numext::is_exactly_zero(m_colNormsUpdated.coeffRef(j))) {
RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j);
temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
temp = temp < RealScalar(0) ? RealScalar(0) : temp;
@@ -577,14 +599,14 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k)
m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k)));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
m_det_p = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename _MatrixType>
template<typename MatrixType_>
template<typename RhsType, typename DstType>
void ColPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
void ColPivHouseholderQR<MatrixType_>::_solve_impl(const RhsType &rhs, DstType &dst) const
{
const Index nonzero_pivots = nonzeroPivots();
@@ -606,9 +628,9 @@ void ColPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &
for(Index i = nonzero_pivots; i < cols(); ++i) dst.row(m_colsPermutation.indices().coeff(i)).setZero();
}
template<typename _MatrixType>
template<typename MatrixType_>
template<bool Conjugate, typename RhsType, typename DstType>
void ColPivHouseholderQR<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
void ColPivHouseholderQR<MatrixType_>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
{
const Index nonzero_pivots = nonzeroPivots();

View File

@@ -34,6 +34,8 @@
#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
#include "./InternalHeaderCheck.h"
namespace Eigen {
/** \internal Specialization for the data types supported by LAPACKe */

View File

@@ -10,12 +10,14 @@
#ifndef EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
#define EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
#include "./InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
template <typename _MatrixType>
struct traits<CompleteOrthogonalDecomposition<_MatrixType> >
: traits<_MatrixType> {
template <typename MatrixType_>
struct traits<CompleteOrthogonalDecomposition<MatrixType_> >
: traits<MatrixType_> {
typedef MatrixXpr XprKind;
typedef SolverStorage StorageKind;
typedef int StorageIndex;
@@ -30,7 +32,7 @@ struct traits<CompleteOrthogonalDecomposition<_MatrixType> >
*
* \brief Complete orthogonal decomposition (COD) of a matrix.
*
* \param MatrixType the type of the matrix of which we are computing the COD.
* \tparam MatrixType_ the type of the matrix of which we are computing the COD.
*
* This class performs a rank-revealing complete orthogonal decomposition of a
* matrix \b A into matrices \b P, \b Q, \b T, and \b Z such that
@@ -47,11 +49,11 @@ struct traits<CompleteOrthogonalDecomposition<_MatrixType> >
*
* \sa MatrixBase::completeOrthogonalDecomposition()
*/
template <typename _MatrixType> class CompleteOrthogonalDecomposition
: public SolverBase<CompleteOrthogonalDecomposition<_MatrixType> >
template <typename MatrixType_> class CompleteOrthogonalDecomposition
: public SolverBase<CompleteOrthogonalDecomposition<MatrixType_> >
{
public:
typedef _MatrixType MatrixType;
typedef MatrixType_ MatrixType;
typedef SolverBase<CompleteOrthogonalDecomposition> Base;
template<typename Derived>
@@ -71,8 +73,8 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
typedef typename internal::plain_row_type<MatrixType, RealScalar>::type
RealRowVectorType;
typedef HouseholderSequence<
MatrixType, typename internal::remove_all<
typename HCoeffsType::ConjugateReturnType>::type>
MatrixType, internal::remove_all_t<
typename HCoeffsType::ConjugateReturnType>>
HouseholderSequenceType;
typedef typename MatrixType::PlainObject PlainObject;
@@ -177,7 +179,7 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
* \code matrixT().template triangularView<Upper>() \endcode
* For rank-deficient matrices, use
* \code
* matrixR().topLeftCorner(rank(), rank()).template triangularView<Upper>()
* matrixT().topLeftCorner(rank(), rank()).template triangularView<Upper>()
* \endcode
*/
const MatrixType& matrixT() const { return m_cpqr.matrixQR(); }
@@ -195,6 +197,21 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
return m_cpqr.colsPermutation();
}
/** \returns the determinant of the matrix of which
* *this is the complete orthogonal decomposition. It has only linear
* complexity (that is, O(n) where n is the dimension of the square matrix)
* as the complete orthogonal decomposition has already been computed.
*
* \note This is only for square matrices.
*
* \warning a determinant can be very big or small, so for matrices
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::Scalar determinant() const;
/** \returns the absolute value of the determinant of the matrix of which
* *this is the complete orthogonal decomposition. It has only linear
* complexity (that is, O(n) where n is the dimension of the square matrix)
@@ -206,7 +223,7 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa logAbsDeterminant(), MatrixBase::determinant()
* \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -221,7 +238,7 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
* \note This method is useful to work around the risk of overflow/underflow
* that's inherent to determinant computation.
*
* \sa absDeterminant(), MatrixBase::determinant()
* \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -377,9 +394,7 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
#endif
protected:
static void check_template_parameters() {
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
template<bool Transpose_, typename Rhs>
void _check_solve_assertion(const Rhs& b) const {
@@ -407,6 +422,12 @@ template <typename _MatrixType> class CompleteOrthogonalDecomposition
RowVectorType m_temp;
};
template <typename MatrixType>
typename MatrixType::Scalar
CompleteOrthogonalDecomposition<MatrixType>::determinant() const {
return m_cpqr.determinant();
}
template <typename MatrixType>
typename MatrixType::RealScalar
CompleteOrthogonalDecomposition<MatrixType>::absDeterminant() const {
@@ -429,8 +450,6 @@ CompleteOrthogonalDecomposition<MatrixType>::logAbsDeterminant() const {
template <typename MatrixType>
void CompleteOrthogonalDecomposition<MatrixType>::computeInPlace()
{
check_template_parameters();
// the column permutation is stored as int indices, so just to be sure:
eigen_assert(m_cpqr.cols() <= NumTraits<int>::highest());
@@ -529,9 +548,9 @@ void CompleteOrthogonalDecomposition<MatrixType>::applyZAdjointOnTheLeftInPlace(
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
template <typename _MatrixType>
template <typename MatrixType_>
template <typename RhsType, typename DstType>
void CompleteOrthogonalDecomposition<_MatrixType>::_solve_impl(
void CompleteOrthogonalDecomposition<MatrixType_>::_solve_impl(
const RhsType& rhs, DstType& dst) const {
const Index rank = this->rank();
if (rank == 0) {
@@ -561,9 +580,9 @@ void CompleteOrthogonalDecomposition<_MatrixType>::_solve_impl(
dst = colsPermutation() * dst;
}
template<typename _MatrixType>
template<typename MatrixType_>
template<bool Conjugate, typename RhsType, typename DstType>
void CompleteOrthogonalDecomposition<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
void CompleteOrthogonalDecomposition<MatrixType_>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
{
const Index rank = this->rank();

View File

@@ -11,12 +11,14 @@
#ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
#define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
#include "./InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
template<typename _MatrixType> struct traits<FullPivHouseholderQR<_MatrixType> >
: traits<_MatrixType>
template<typename MatrixType_> struct traits<FullPivHouseholderQR<MatrixType_> >
: traits<MatrixType_>
{
typedef MatrixXpr XprKind;
typedef SolverStorage StorageKind;
@@ -40,7 +42,7 @@ struct traits<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
*
* \brief Householder rank-revealing QR decomposition of a matrix with full pivoting
*
* \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition
* \tparam MatrixType_ the type of the matrix of which we are computing the QR decomposition
*
* This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b P', \b Q and \b R
* such that
@@ -57,12 +59,12 @@ struct traits<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
*
* \sa MatrixBase::fullPivHouseholderQr()
*/
template<typename _MatrixType> class FullPivHouseholderQR
: public SolverBase<FullPivHouseholderQR<_MatrixType> >
template<typename MatrixType_> class FullPivHouseholderQR
: public SolverBase<FullPivHouseholderQR<MatrixType_> >
{
public:
typedef _MatrixType MatrixType;
typedef MatrixType_ MatrixType;
typedef SolverBase<FullPivHouseholderQR> Base;
friend class SolverBase<FullPivHouseholderQR>;
@@ -74,8 +76,8 @@ template<typename _MatrixType> class FullPivHouseholderQR
typedef internal::FullPivHouseholderQRMatrixQReturnType<MatrixType> MatrixQReturnType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef Matrix<StorageIndex, 1,
EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime,RowsAtCompileTime), RowMajor, 1,
EIGEN_SIZE_MIN_PREFER_FIXED(MaxColsAtCompileTime,MaxRowsAtCompileTime)> IntDiagSizeVectorType;
internal::min_size_prefer_dynamic(ColsAtCompileTime,RowsAtCompileTime), RowMajor, 1,
internal::min_size_prefer_fixed(MaxColsAtCompileTime, MaxRowsAtCompileTime)> IntDiagSizeVectorType;
typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_col_type<MatrixType>::type ColVectorType;
@@ -208,6 +210,21 @@ template<typename _MatrixType> class FullPivHouseholderQR
return m_rows_transpositions;
}
/** \returns the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
* as the QR decomposition has already been computed.
*
* \note This is only for square matrices.
*
* \warning a determinant can be very big or small, so for matrices
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::Scalar determinant() const;
/** \returns the absolute value of the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
@@ -219,7 +236,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa logAbsDeterminant(), MatrixBase::determinant()
* \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -233,7 +250,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
* \note This method is useful to work around the risk of overflow/underflow that's inherent
* to determinant computation.
*
* \sa absDeterminant(), MatrixBase::determinant()
* \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -403,10 +420,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
protected:
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
void computeInPlace();
@@ -420,9 +434,19 @@ template<typename _MatrixType> class FullPivHouseholderQR
RealScalar m_prescribedThreshold, m_maxpivot;
Index m_nonzero_pivots;
RealScalar m_precision;
Index m_det_pq;
Index m_det_p;
};
template<typename MatrixType>
typename MatrixType::Scalar FullPivHouseholderQR<MatrixType>::determinant() const
{
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
Scalar detQ;
internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
return m_qr.diagonal().prod() * detQ * Scalar(m_det_p);
}
template<typename MatrixType>
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
{
@@ -458,8 +482,6 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
template<typename MatrixType>
void FullPivHouseholderQR<MatrixType>::computeInPlace()
{
check_template_parameters();
using std::abs;
Index rows = m_qr.rows();
Index cols = m_qr.cols();
@@ -534,14 +556,14 @@ void FullPivHouseholderQR<MatrixType>::computeInPlace()
for(Index k = 0; k < size; ++k)
m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
m_det_p = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename _MatrixType>
template<typename MatrixType_>
template<typename RhsType, typename DstType>
void FullPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
void FullPivHouseholderQR<MatrixType_>::_solve_impl(const RhsType &rhs, DstType &dst) const
{
const Index l_rank = rank();
@@ -573,9 +595,9 @@ void FullPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType
for(Index i = l_rank; i < cols(); ++i) dst.row(m_cols_permutation.indices().coeff(i)).setZero();
}
template<typename _MatrixType>
template<typename MatrixType_>
template<bool Conjugate, typename RhsType, typename DstType>
void FullPivHouseholderQR<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
void FullPivHouseholderQR<MatrixType_>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
{
const Index l_rank = rank();

View File

@@ -12,11 +12,13 @@
#ifndef EIGEN_QR_H
#define EIGEN_QR_H
#include "./InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
template<typename _MatrixType> struct traits<HouseholderQR<_MatrixType> >
: traits<_MatrixType>
template<typename MatrixType_> struct traits<HouseholderQR<MatrixType_> >
: traits<MatrixType_>
{
typedef MatrixXpr XprKind;
typedef SolverStorage StorageKind;
@@ -33,7 +35,7 @@ template<typename _MatrixType> struct traits<HouseholderQR<_MatrixType> >
*
* \brief Householder QR decomposition of a matrix
*
* \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition
* \tparam MatrixType_ the type of the matrix of which we are computing the QR decomposition
*
* This class performs a QR decomposition of a matrix \b A into matrices \b Q and \b R
* such that
@@ -53,12 +55,12 @@ template<typename _MatrixType> struct traits<HouseholderQR<_MatrixType> >
*
* \sa MatrixBase::householderQr()
*/
template<typename _MatrixType> class HouseholderQR
: public SolverBase<HouseholderQR<_MatrixType> >
template<typename MatrixType_> class HouseholderQR
: public SolverBase<HouseholderQR<MatrixType_> >
{
public:
typedef _MatrixType MatrixType;
typedef MatrixType_ MatrixType;
typedef SolverBase<HouseholderQR> Base;
friend class SolverBase<HouseholderQR>;
@@ -70,7 +72,7 @@ template<typename _MatrixType> class HouseholderQR
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, (MatrixType::Flags&RowMajorBit) ? RowMajor : ColMajor, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
typedef HouseholderSequence<MatrixType,internal::remove_all_t<typename HCoeffsType::ConjugateReturnType>> HouseholderSequenceType;
/**
* \brief Default Constructor.
@@ -182,6 +184,21 @@ template<typename _MatrixType> class HouseholderQR
return *this;
}
/** \returns the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
* as the QR decomposition has already been computed.
*
* \note This is only for square matrices.
*
* \warning a determinant can be very big or small, so for matrices
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::Scalar determinant() const;
/** \returns the absolute value of the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
@@ -193,7 +210,7 @@ template<typename _MatrixType> class HouseholderQR
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
* \sa logAbsDeterminant(), MatrixBase::determinant()
* \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -207,7 +224,7 @@ template<typename _MatrixType> class HouseholderQR
* \note This method is useful to work around the risk of overflow/underflow that's inherent
* to determinant computation.
*
* \sa absDeterminant(), MatrixBase::determinant()
* \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -230,10 +247,7 @@ template<typename _MatrixType> class HouseholderQR
protected:
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
void computeInPlace();
@@ -243,6 +257,57 @@ template<typename _MatrixType> class HouseholderQR
bool m_isInitialized;
};
namespace internal {
/** \internal */
template<typename HCoeffs, typename Scalar, bool IsComplex>
struct householder_determinant
{
static void run(const HCoeffs& hCoeffs, Scalar& out_det)
{
out_det = Scalar(1);
Index size = hCoeffs.rows();
for (Index i = 0; i < size; i ++)
{
// For each valid reflection Q_n,
// det(Q_n) = - conj(h_n) / h_n
// where h_n is the Householder coefficient.
if (hCoeffs(i) != Scalar(0))
out_det *= - numext::conj(hCoeffs(i)) / hCoeffs(i);
}
}
};
/** \internal */
template<typename HCoeffs, typename Scalar>
struct householder_determinant<HCoeffs, Scalar, false>
{
static void run(const HCoeffs& hCoeffs, Scalar& out_det)
{
bool negated = false;
Index size = hCoeffs.rows();
for (Index i = 0; i < size; i ++)
{
// Each valid reflection negates the determinant.
if (hCoeffs(i) != Scalar(0))
negated ^= true;
}
out_det = negated ? Scalar(-1) : Scalar(1);
}
};
} // end namespace internal
template<typename MatrixType>
typename MatrixType::Scalar HouseholderQR<MatrixType>::determinant() const
{
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
Scalar detQ;
internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
return m_qr.diagonal().prod() * detQ;
}
template<typename MatrixType>
typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
{
@@ -297,6 +362,43 @@ void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs, typename
}
}
// TODO: add a corresponding public API for updating a QR factorization
/** \internal
* Basically a modified copy of @c Eigen::internal::householder_qr_inplace_unblocked that
* performs a rank-1 update of the QR matrix in compact storage. This function assumes, that
* the first @c k-1 columns of the matrix @c mat contain the QR decomposition of \f$A^N\f$ up to
* column k-1. Then the QR decomposition of the k-th column (given by @c newColumn) is computed by
* applying the k-1 Householder projectors on it and finally compute the projector \f$H_k\f$ of
* it. On exit the matrix @c mat and the vector @c hCoeffs contain the QR decomposition of the
* first k columns of \f$A^N\f$. The \a tempData argument must point to at least mat.cols() scalars. */
template <typename MatrixQR, typename HCoeffs, typename VectorQR>
void householder_qr_inplace_update(MatrixQR& mat, HCoeffs& hCoeffs, const VectorQR& newColumn,
typename MatrixQR::Index k, typename MatrixQR::Scalar* tempData) {
typedef typename MatrixQR::Index Index;
typedef typename MatrixQR::RealScalar RealScalar;
Index rows = mat.rows();
eigen_assert(k < mat.cols());
eigen_assert(k < rows);
eigen_assert(hCoeffs.size() == mat.cols());
eigen_assert(newColumn.size() == rows);
eigen_assert(tempData);
// Store new column in mat at column k
mat.col(k) = newColumn;
// Apply H = H_1...H_{k-1} on newColumn (skip if k=0)
for (Index i = 0; i < k; ++i) {
Index remainingRows = rows - i;
mat.col(k)
.tail(remainingRows)
.applyHouseholderOnTheLeft(mat.col(i).tail(remainingRows - 1), hCoeffs.coeffRef(i), tempData + i + 1);
}
// Construct Householder projector in-place in column k
RealScalar beta;
mat.col(k).tail(rows - k).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta);
mat.coeffRef(k, k) = beta;
}
/** \internal */
template<typename MatrixQR, typename HCoeffs,
typename MatrixQRScalar = typename MatrixQR::Scalar,
@@ -356,9 +458,9 @@ struct householder_qr_inplace_blocked
} // end namespace internal
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename _MatrixType>
template<typename MatrixType_>
template<typename RhsType, typename DstType>
void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
void HouseholderQR<MatrixType_>::_solve_impl(const RhsType &rhs, DstType &dst) const
{
const Index rank = (std::min)(rows(), cols());
@@ -374,9 +476,9 @@ void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) c
dst.bottomRows(cols()-rank).setZero();
}
template<typename _MatrixType>
template<typename MatrixType_>
template<bool Conjugate, typename RhsType, typename DstType>
void HouseholderQR<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
void HouseholderQR<MatrixType_>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
{
const Index rank = (std::min)(rows(), cols());
@@ -403,8 +505,6 @@ void HouseholderQR<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstT
template<typename MatrixType>
void HouseholderQR<MatrixType>::computeInPlace()
{
check_template_parameters();
Index rows = m_qr.rows();
Index cols = m_qr.cols();
Index size = (std::min)(rows,cols);

View File

@@ -34,32 +34,41 @@
#ifndef EIGEN_QR_LAPACKE_H
#define EIGEN_QR_LAPACKE_H
#include "./InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
/** \internal Specialization for the data types supported by LAPACKe */
namespace lapacke_helpers {
#define EIGEN_LAPACKE_QR_NOPIV(EIGTYPE, LAPACKE_TYPE, LAPACKE_PREFIX) \
template<typename MatrixQR, typename HCoeffs> \
struct householder_qr_inplace_blocked<MatrixQR, HCoeffs, EIGTYPE, true> \
{ \
static void run(MatrixQR& mat, HCoeffs& hCoeffs, Index = 32, \
typename MatrixQR::Scalar* = 0) \
{ \
lapack_int m = (lapack_int) mat.rows(); \
lapack_int n = (lapack_int) mat.cols(); \
lapack_int lda = (lapack_int) mat.outerStride(); \
lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \
LAPACKE_##LAPACKE_PREFIX##geqrf( matrix_order, m, n, (LAPACKE_TYPE*)mat.data(), lda, (LAPACKE_TYPE*)hCoeffs.data()); \
hCoeffs.adjointInPlace(); \
} \
template<typename MatrixQR, typename HCoeffs>
struct lapacke_hqr
{
static void run(MatrixQR& mat, HCoeffs& hCoeffs, Index = 32, typename MatrixQR::Scalar* = 0)
{
lapack_int m = to_lapack(mat.rows());
lapack_int n = to_lapack(mat.cols());
lapack_int lda = to_lapack(mat.outerStride());
lapack_int matrix_order = lapack_storage_of(mat);
geqrf(matrix_order, m, n, to_lapack(mat.data()), lda, to_lapack(hCoeffs.data()));
hCoeffs.adjointInPlace();
}
};
EIGEN_LAPACKE_QR_NOPIV(double, double, d)
EIGEN_LAPACKE_QR_NOPIV(float, float, s)
EIGEN_LAPACKE_QR_NOPIV(dcomplex, lapack_complex_double, z)
EIGEN_LAPACKE_QR_NOPIV(scomplex, lapack_complex_float, c)
}
/** \internal Specialization for the data types supported by LAPACKe */
#define EIGEN_LAPACKE_HH_QR(EIGTYPE) \
template<typename MatrixQR, typename HCoeffs> \
struct householder_qr_inplace_blocked<MatrixQR, HCoeffs, EIGTYPE, true> : public lapacke_helpers::lapacke_hqr<MatrixQR, HCoeffs> {};
EIGEN_LAPACKE_HH_QR(double)
EIGEN_LAPACKE_HH_QR(float)
EIGEN_LAPACKE_HH_QR(std::complex<double>)
EIGEN_LAPACKE_HH_QR(std::complex<float>)
#undef EIGEN_LAPACKE_HH_QR
} // end namespace internal

View File

@@ -0,0 +1,3 @@
#ifndef EIGEN_QR_MODULE_H
#error "Please include Eigen/QR instead of including headers inside the src directory directly."
#endif