ADD: added other eigen lib
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
3
libs/eigen/Eigen/src/QR/InternalHeaderCheck.h
Normal file
3
libs/eigen/Eigen/src/QR/InternalHeaderCheck.h
Normal 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
|
||||
Reference in New Issue
Block a user