mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Generalize matrix ctor and compute() method of dense decomposition to 1) limit temporaries, 2) forward expressions to nested decompositions, 3) fix ambiguous ctor instanciation for square decomposition
This commit is contained in:
@@ -122,7 +122,8 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
*
|
||||
* This constructor calls compute() to compute the eigendecomposition.
|
||||
*/
|
||||
explicit ComplexEigenSolver(const MatrixType& matrix, bool computeEigenvectors = true)
|
||||
template<typename InputType>
|
||||
explicit ComplexEigenSolver(const EigenBase<InputType>& matrix, bool computeEigenvectors = true)
|
||||
: m_eivec(matrix.rows(),matrix.cols()),
|
||||
m_eivalues(matrix.cols()),
|
||||
m_schur(matrix.rows()),
|
||||
@@ -130,7 +131,7 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
m_eigenvectorsOk(false),
|
||||
m_matX(matrix.rows(),matrix.cols())
|
||||
{
|
||||
compute(matrix, computeEigenvectors);
|
||||
compute(matrix.derived(), computeEigenvectors);
|
||||
}
|
||||
|
||||
/** \brief Returns the eigenvectors of given matrix.
|
||||
@@ -208,7 +209,8 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
* Example: \include ComplexEigenSolver_compute.cpp
|
||||
* Output: \verbinclude ComplexEigenSolver_compute.out
|
||||
*/
|
||||
ComplexEigenSolver& compute(const MatrixType& matrix, bool computeEigenvectors = true);
|
||||
template<typename InputType>
|
||||
ComplexEigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);
|
||||
|
||||
/** \brief Reports whether previous computation was successful.
|
||||
*
|
||||
@@ -254,8 +256,9 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
ComplexEigenSolver<MatrixType>&
|
||||
ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
|
||||
ComplexEigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeEigenvectors)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
@@ -264,13 +267,13 @@ ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEi
|
||||
|
||||
// Do a complex Schur decomposition, A = U T U^*
|
||||
// The eigenvalues are on the diagonal of T.
|
||||
m_schur.compute(matrix, computeEigenvectors);
|
||||
m_schur.compute(matrix.derived(), computeEigenvectors);
|
||||
|
||||
if(m_schur.info() == Success)
|
||||
{
|
||||
m_eivalues = m_schur.matrixT().diagonal();
|
||||
if(computeEigenvectors)
|
||||
doComputeEigenvectors(matrix.norm());
|
||||
doComputeEigenvectors(m_schur.matrixT().norm());
|
||||
sortEigenvalues(computeEigenvectors);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,8 @@ template<typename _MatrixType> class ComplexSchur
|
||||
*
|
||||
* \sa matrixT() and matrixU() for examples.
|
||||
*/
|
||||
explicit ComplexSchur(const MatrixType& matrix, bool computeU = true)
|
||||
template<typename InputType>
|
||||
explicit ComplexSchur(const EigenBase<InputType>& matrix, bool computeU = true)
|
||||
: m_matT(matrix.rows(),matrix.cols()),
|
||||
m_matU(matrix.rows(),matrix.cols()),
|
||||
m_hess(matrix.rows()),
|
||||
@@ -117,7 +118,7 @@ template<typename _MatrixType> class ComplexSchur
|
||||
m_matUisUptodate(false),
|
||||
m_maxIters(-1)
|
||||
{
|
||||
compute(matrix, computeU);
|
||||
compute(matrix.derived(), computeU);
|
||||
}
|
||||
|
||||
/** \brief Returns the unitary matrix in the Schur decomposition.
|
||||
@@ -186,7 +187,8 @@ template<typename _MatrixType> class ComplexSchur
|
||||
*
|
||||
* \sa compute(const MatrixType&, bool, Index)
|
||||
*/
|
||||
ComplexSchur& compute(const MatrixType& matrix, bool computeU = true);
|
||||
template<typename InputType>
|
||||
ComplexSchur& compute(const EigenBase<InputType>& matrix, bool computeU = true);
|
||||
|
||||
/** \brief Compute Schur decomposition from a given Hessenberg matrix
|
||||
* \param[in] matrixH Matrix in Hessenberg form H
|
||||
@@ -313,14 +315,15 @@ typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::compu
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool computeU)
|
||||
template<typename InputType>
|
||||
ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeU)
|
||||
{
|
||||
m_matUisUptodate = false;
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
|
||||
if(matrix.cols() == 1)
|
||||
{
|
||||
m_matT = matrix.template cast<ComplexScalar>();
|
||||
m_matT = matrix.derived().template cast<ComplexScalar>();
|
||||
if(computeU) m_matU = ComplexMatrixType::Identity(1,1);
|
||||
m_info = Success;
|
||||
m_isInitialized = true;
|
||||
@@ -328,7 +331,7 @@ ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::compute(const MatrixType& ma
|
||||
return *this;
|
||||
}
|
||||
|
||||
internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix, computeU);
|
||||
internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix.derived(), computeU);
|
||||
computeFromHessenberg(m_matT, m_matU, computeU);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ template<typename _MatrixType> class EigenSolver
|
||||
*
|
||||
* \sa compute() for an example.
|
||||
*/
|
||||
EigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false), m_realSchur(), m_matT(), m_tmp() {}
|
||||
EigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false), m_realSchur(), m_matT(), m_tmp() {}
|
||||
|
||||
/** \brief Default constructor with memory preallocation
|
||||
*
|
||||
@@ -143,7 +143,8 @@ template<typename _MatrixType> class EigenSolver
|
||||
*
|
||||
* \sa compute()
|
||||
*/
|
||||
explicit EigenSolver(const MatrixType& matrix, bool computeEigenvectors = true)
|
||||
template<typename InputType>
|
||||
explicit EigenSolver(const EigenBase<InputType>& matrix, bool computeEigenvectors = true)
|
||||
: m_eivec(matrix.rows(), matrix.cols()),
|
||||
m_eivalues(matrix.cols()),
|
||||
m_isInitialized(false),
|
||||
@@ -152,7 +153,7 @@ template<typename _MatrixType> class EigenSolver
|
||||
m_matT(matrix.rows(), matrix.cols()),
|
||||
m_tmp(matrix.cols())
|
||||
{
|
||||
compute(matrix, computeEigenvectors);
|
||||
compute(matrix.derived(), computeEigenvectors);
|
||||
}
|
||||
|
||||
/** \brief Returns the eigenvectors of given matrix.
|
||||
@@ -273,7 +274,8 @@ template<typename _MatrixType> class EigenSolver
|
||||
* Example: \include EigenSolver_compute.cpp
|
||||
* Output: \verbinclude EigenSolver_compute.out
|
||||
*/
|
||||
EigenSolver& compute(const MatrixType& matrix, bool computeEigenvectors = true);
|
||||
template<typename InputType>
|
||||
EigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);
|
||||
|
||||
/** \returns NumericalIssue if the input contains INF or NaN values or overflow occured. Returns Success otherwise. */
|
||||
ComputationInfo info() const
|
||||
@@ -370,8 +372,9 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
EigenSolver<MatrixType>&
|
||||
EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
|
||||
EigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeEigenvectors)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
@@ -381,7 +384,7 @@ EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvect
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
|
||||
// Reduce to real Schur form.
|
||||
m_realSchur.compute(matrix, computeEigenvectors);
|
||||
m_realSchur.compute(matrix.derived(), computeEigenvectors);
|
||||
|
||||
m_info = m_realSchur.info();
|
||||
|
||||
|
||||
@@ -115,8 +115,9 @@ template<typename _MatrixType> class HessenbergDecomposition
|
||||
*
|
||||
* \sa matrixH() for an example.
|
||||
*/
|
||||
explicit HessenbergDecomposition(const MatrixType& matrix)
|
||||
: m_matrix(matrix),
|
||||
template<typename InputType>
|
||||
explicit HessenbergDecomposition(const EigenBase<InputType>& matrix)
|
||||
: m_matrix(matrix.derived()),
|
||||
m_temp(matrix.rows()),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
@@ -147,9 +148,10 @@ template<typename _MatrixType> class HessenbergDecomposition
|
||||
* Example: \include HessenbergDecomposition_compute.cpp
|
||||
* Output: \verbinclude HessenbergDecomposition_compute.out
|
||||
*/
|
||||
HessenbergDecomposition& compute(const MatrixType& matrix)
|
||||
template<typename InputType>
|
||||
HessenbergDecomposition& compute(const EigenBase<InputType>& matrix)
|
||||
{
|
||||
m_matrix = matrix;
|
||||
m_matrix = matrix.derived();
|
||||
if(matrix.rows()<2)
|
||||
{
|
||||
m_isInitialized = true;
|
||||
|
||||
@@ -100,7 +100,8 @@ template<typename _MatrixType> class RealSchur
|
||||
* Example: \include RealSchur_RealSchur_MatrixType.cpp
|
||||
* Output: \verbinclude RealSchur_RealSchur_MatrixType.out
|
||||
*/
|
||||
explicit RealSchur(const MatrixType& matrix, bool computeU = true)
|
||||
template<typename InputType>
|
||||
explicit RealSchur(const EigenBase<InputType>& matrix, bool computeU = true)
|
||||
: m_matT(matrix.rows(),matrix.cols()),
|
||||
m_matU(matrix.rows(),matrix.cols()),
|
||||
m_workspaceVector(matrix.rows()),
|
||||
@@ -109,7 +110,7 @@ template<typename _MatrixType> class RealSchur
|
||||
m_matUisUptodate(false),
|
||||
m_maxIters(-1)
|
||||
{
|
||||
compute(matrix, computeU);
|
||||
compute(matrix.derived(), computeU);
|
||||
}
|
||||
|
||||
/** \brief Returns the orthogonal matrix in the Schur decomposition.
|
||||
@@ -165,7 +166,8 @@ template<typename _MatrixType> class RealSchur
|
||||
*
|
||||
* \sa compute(const MatrixType&, bool, Index)
|
||||
*/
|
||||
RealSchur& compute(const MatrixType& matrix, bool computeU = true);
|
||||
template<typename InputType>
|
||||
RealSchur& compute(const EigenBase<InputType>& matrix, bool computeU = true);
|
||||
|
||||
/** \brief Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T
|
||||
* \param[in] matrixH Matrix in Hessenberg form H
|
||||
@@ -243,7 +245,8 @@ template<typename _MatrixType> class RealSchur
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix, bool computeU)
|
||||
template<typename InputType>
|
||||
RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeU)
|
||||
{
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
Index maxIters = m_maxIters;
|
||||
@@ -251,7 +254,7 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix,
|
||||
maxIters = m_maxIterationsPerRow * matrix.rows();
|
||||
|
||||
// Step 1. Reduce to Hessenberg form
|
||||
m_hess.compute(matrix);
|
||||
m_hess.compute(matrix.derived());
|
||||
|
||||
// Step 2. Reduce to real Schur form
|
||||
computeFromHessenberg(m_hess.matrixH(), m_hess.matrixQ(), computeU);
|
||||
|
||||
@@ -158,13 +158,14 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
* \sa compute(const MatrixType&, int)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit SelfAdjointEigenSolver(const MatrixType& matrix, int options = ComputeEigenvectors)
|
||||
template<typename InputType>
|
||||
explicit SelfAdjointEigenSolver(const EigenBase<InputType>& matrix, int options = ComputeEigenvectors)
|
||||
: m_eivec(matrix.rows(), matrix.cols()),
|
||||
m_eivalues(matrix.cols()),
|
||||
m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
compute(matrix, options);
|
||||
compute(matrix.derived(), options);
|
||||
}
|
||||
|
||||
/** \brief Computes eigendecomposition of given matrix.
|
||||
@@ -198,7 +199,8 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
* \sa SelfAdjointEigenSolver(const MatrixType&, int)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors);
|
||||
template<typename InputType>
|
||||
SelfAdjointEigenSolver& compute(const EigenBase<InputType>& matrix, int options = ComputeEigenvectors);
|
||||
|
||||
/** \brief Computes eigendecomposition of given matrix using a closed-form algorithm
|
||||
*
|
||||
@@ -389,12 +391,15 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
::compute(const MatrixType& matrix, int options)
|
||||
::compute(const EigenBase<InputType>& a_matrix, int options)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
const InputType &matrix(a_matrix);
|
||||
|
||||
using std::abs;
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
eigen_assert((options&~(EigVecMask|GenEigMask))==0
|
||||
|
||||
@@ -126,8 +126,9 @@ template<typename _MatrixType> class Tridiagonalization
|
||||
* Example: \include Tridiagonalization_Tridiagonalization_MatrixType.cpp
|
||||
* Output: \verbinclude Tridiagonalization_Tridiagonalization_MatrixType.out
|
||||
*/
|
||||
explicit Tridiagonalization(const MatrixType& matrix)
|
||||
: m_matrix(matrix),
|
||||
template<typename InputType>
|
||||
explicit Tridiagonalization(const EigenBase<InputType>& matrix)
|
||||
: m_matrix(matrix.derived()),
|
||||
m_hCoeffs(matrix.cols() > 1 ? matrix.cols()-1 : 1),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
@@ -152,9 +153,10 @@ template<typename _MatrixType> class Tridiagonalization
|
||||
* Example: \include Tridiagonalization_compute.cpp
|
||||
* Output: \verbinclude Tridiagonalization_compute.out
|
||||
*/
|
||||
Tridiagonalization& compute(const MatrixType& matrix)
|
||||
template<typename InputType>
|
||||
Tridiagonalization& compute(const EigenBase<InputType>& matrix)
|
||||
{
|
||||
m_matrix = matrix;
|
||||
m_matrix = matrix.derived();
|
||||
m_hCoeffs.resize(matrix.rows()-1, 1);
|
||||
internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
|
||||
m_isInitialized = true;
|
||||
|
||||
Reference in New Issue
Block a user