mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
the Index types change.
As discussed on the list (too long to explain here).
This commit is contained in:
@@ -68,6 +68,7 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
/** \brief Scalar type for matrices of type \p _MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
/** \brief Complex scalar type for \p _MatrixType.
|
||||
*
|
||||
@@ -110,7 +111,7 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
* according to the specified problem \a size.
|
||||
* \sa ComplexEigenSolver()
|
||||
*/
|
||||
ComplexEigenSolver(int size)
|
||||
ComplexEigenSolver(Index size)
|
||||
: m_eivec(size, size),
|
||||
m_eivalues(size),
|
||||
m_schur(size),
|
||||
@@ -216,7 +217,7 @@ void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix)
|
||||
{
|
||||
// this code is inspired from Jampack
|
||||
assert(matrix.cols() == matrix.rows());
|
||||
const int n = matrix.cols();
|
||||
const Index n = matrix.cols();
|
||||
const RealScalar matrixnorm = matrix.norm();
|
||||
|
||||
// Step 1: Do a complex Schur decomposition, A = U T U^*
|
||||
@@ -227,11 +228,11 @@ void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix)
|
||||
// Step 2: Compute X such that T = X D X^(-1), where D is the diagonal of T.
|
||||
// The matrix X is unit triangular.
|
||||
m_matX = EigenvectorType::Zero(n, n);
|
||||
for(int k=n-1 ; k>=0 ; k--)
|
||||
for(Index k=n-1 ; k>=0 ; k--)
|
||||
{
|
||||
m_matX.coeffRef(k,k) = ComplexScalar(1.0,0.0);
|
||||
// Compute X(i,k) using the (i,k) entry of the equation X T = D X
|
||||
for(int i=k-1 ; i>=0 ; i--)
|
||||
for(Index i=k-1 ; i>=0 ; i--)
|
||||
{
|
||||
m_matX.coeffRef(i,k) = -m_schur.matrixT().coeff(i,k);
|
||||
if(k-i-1>0)
|
||||
@@ -250,16 +251,16 @@ void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix)
|
||||
// Step 3: Compute V as V = U X; now A = U T U^* = U X D X^(-1) U^* = V D V^(-1)
|
||||
m_eivec.noalias() = m_schur.matrixU() * m_matX;
|
||||
// .. and normalize the eigenvectors
|
||||
for(int k=0 ; k<n ; k++)
|
||||
for(Index k=0 ; k<n ; k++)
|
||||
{
|
||||
m_eivec.col(k).normalize();
|
||||
}
|
||||
m_isInitialized = true;
|
||||
|
||||
// Step 4: Sort the eigenvalues
|
||||
for (int i=0; i<n; i++)
|
||||
for (Index i=0; i<n; i++)
|
||||
{
|
||||
int k;
|
||||
Index k;
|
||||
m_eivalues.cwiseAbs().tail(n-i).minCoeff(&k);
|
||||
if (k != 0)
|
||||
{
|
||||
|
||||
@@ -71,8 +71,8 @@ template<typename _MatrixType> class ComplexSchur
|
||||
|
||||
/** \brief Scalar type for matrices of type \p _MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
/** \brief Complex scalar type for \p _MatrixType.
|
||||
*
|
||||
@@ -100,7 +100,7 @@ template<typename _MatrixType> class ComplexSchur
|
||||
*
|
||||
* \sa compute() for an example.
|
||||
*/
|
||||
ComplexSchur(int size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
|
||||
ComplexSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
|
||||
: m_matT(size,size),
|
||||
m_matU(size,size),
|
||||
m_hess(size),
|
||||
@@ -197,8 +197,8 @@ template<typename _MatrixType> class ComplexSchur
|
||||
bool m_matUisUptodate;
|
||||
|
||||
private:
|
||||
bool subdiagonalEntryIsNeglegible(int i);
|
||||
ComplexScalar computeShift(int iu, int iter);
|
||||
bool subdiagonalEntryIsNeglegible(Index i);
|
||||
ComplexScalar computeShift(Index iu, Index iter);
|
||||
void reduceToTriangularForm(bool skipU);
|
||||
friend struct ei_complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>;
|
||||
};
|
||||
@@ -244,7 +244,7 @@ std::complex<RealScalar> ei_sqrt(const std::complex<RealScalar> &z)
|
||||
* compared to m_matT(i,i) and m_matT(j,j), then set it to zero and
|
||||
* return true, else return false. */
|
||||
template<typename MatrixType>
|
||||
inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(int i)
|
||||
inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(Index i)
|
||||
{
|
||||
RealScalar d = ei_norm1(m_matT.coeff(i,i)) + ei_norm1(m_matT.coeff(i+1,i+1));
|
||||
RealScalar sd = ei_norm1(m_matT.coeff(i+1,i));
|
||||
@@ -259,7 +259,7 @@ inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(int i)
|
||||
|
||||
/** Compute the shift in the current QR iteration. */
|
||||
template<typename MatrixType>
|
||||
typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(int iu, int iter)
|
||||
typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(Index iu, Index iter)
|
||||
{
|
||||
if (iter == 10 || iter == 20)
|
||||
{
|
||||
@@ -356,9 +356,9 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool skipU)
|
||||
// Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
|
||||
// Rows il,...,iu is the part we are working on (the active submatrix).
|
||||
// Rows iu+1,...,end are already brought in triangular form.
|
||||
int iu = m_matT.cols() - 1;
|
||||
int il;
|
||||
int iter = 0; // number of iterations we are working on the (iu,iu) element
|
||||
Index iu = m_matT.cols() - 1;
|
||||
Index il;
|
||||
Index iter = 0; // number of iterations we are working on the (iu,iu) element
|
||||
|
||||
while(true)
|
||||
{
|
||||
@@ -395,7 +395,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool skipU)
|
||||
m_matT.topRows(std::min(il+2,iu)+1).applyOnTheRight(il, il+1, rot);
|
||||
if(!skipU) m_matU.applyOnTheRight(il, il+1, rot);
|
||||
|
||||
for(int i=il+1 ; i<iu ; i++)
|
||||
for(Index i=il+1 ; i<iu ; i++)
|
||||
{
|
||||
rot.makeGivens(m_matT.coeffRef(i,i-1), m_matT.coeffRef(i+1,i-1), &m_matT.coeffRef(i,i-1));
|
||||
m_matT.coeffRef(i+1,i-1) = ComplexScalar(0);
|
||||
|
||||
@@ -90,6 +90,7 @@ template<typename _MatrixType> class EigenSolver
|
||||
/** \brief Scalar type for matrices of type \p _MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
/** \brief Complex scalar type for \p _MatrixType.
|
||||
*
|
||||
@@ -128,7 +129,7 @@ template<typename _MatrixType> class EigenSolver
|
||||
* according to the specified problem \a size.
|
||||
* \sa EigenSolver()
|
||||
*/
|
||||
EigenSolver(int size)
|
||||
EigenSolver(Index size)
|
||||
: m_eivec(size, size),
|
||||
m_eivalues(size),
|
||||
m_isInitialized(false),
|
||||
@@ -285,9 +286,9 @@ template<typename MatrixType>
|
||||
MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "EigenSolver is not initialized.");
|
||||
int n = m_eivec.cols();
|
||||
Index n = m_eivec.cols();
|
||||
MatrixType matD = MatrixType::Zero(n,n);
|
||||
for (int i=0; i<n; ++i)
|
||||
for (Index i=0; i<n; ++i)
|
||||
{
|
||||
if (ei_isMuchSmallerThan(ei_imag(m_eivalues.coeff(i)), ei_real(m_eivalues.coeff(i))))
|
||||
matD.coeffRef(i,i) = ei_real(m_eivalues.coeff(i));
|
||||
@@ -305,9 +306,9 @@ template<typename MatrixType>
|
||||
typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eigenvectors() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "EigenSolver is not initialized.");
|
||||
int n = m_eivec.cols();
|
||||
Index n = m_eivec.cols();
|
||||
EigenvectorsType matV(n,n);
|
||||
for (int j=0; j<n; ++j)
|
||||
for (Index j=0; j<n; ++j)
|
||||
{
|
||||
if (ei_isMuchSmallerThan(ei_imag(m_eivalues.coeff(j)), ei_real(m_eivalues.coeff(j))))
|
||||
{
|
||||
@@ -317,7 +318,7 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
|
||||
else
|
||||
{
|
||||
// we have a pair of complex eigen values
|
||||
for (int i=0; i<n; ++i)
|
||||
for (Index i=0; i<n; ++i)
|
||||
{
|
||||
matV.coeffRef(i,j) = ComplexScalar(m_eivec.coeff(i,j), m_eivec.coeff(i,j+1));
|
||||
matV.coeffRef(i,j+1) = ComplexScalar(m_eivec.coeff(i,j), -m_eivec.coeff(i,j+1));
|
||||
@@ -342,7 +343,7 @@ EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const MatrixType& matr
|
||||
|
||||
// Compute eigenvalues from matT
|
||||
m_eivalues.resize(matrix.cols());
|
||||
int i = 0;
|
||||
Index i = 0;
|
||||
while (i < matrix.cols())
|
||||
{
|
||||
if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0))
|
||||
@@ -390,14 +391,14 @@ std::complex<Scalar> cdiv(Scalar xr, Scalar xi, Scalar yr, Scalar yi)
|
||||
template<typename MatrixType>
|
||||
void EigenSolver<MatrixType>::computeEigenvectors()
|
||||
{
|
||||
const int size = m_eivec.cols();
|
||||
const Index size = m_eivec.cols();
|
||||
const Scalar eps = NumTraits<Scalar>::epsilon();
|
||||
|
||||
// inefficient! this is already computed in RealSchur
|
||||
Scalar norm = 0.0;
|
||||
for (int j = 0; j < size; ++j)
|
||||
for (Index j = 0; j < size; ++j)
|
||||
{
|
||||
norm += m_matT.row(j).segment(std::max(j-1,0), size-std::max(j-1,0)).cwiseAbs().sum();
|
||||
norm += m_matT.row(j).segment(std::max(j-1,Index(0)), size-std::max(j-1,Index(0))).cwiseAbs().sum();
|
||||
}
|
||||
|
||||
// Backsubstitute to find vectors of upper triangular form
|
||||
@@ -406,7 +407,7 @@ void EigenSolver<MatrixType>::computeEigenvectors()
|
||||
return;
|
||||
}
|
||||
|
||||
for (int n = size-1; n >= 0; n--)
|
||||
for (Index n = size-1; n >= 0; n--)
|
||||
{
|
||||
Scalar p = m_eivalues.coeff(n).real();
|
||||
Scalar q = m_eivalues.coeff(n).imag();
|
||||
@@ -415,10 +416,10 @@ void EigenSolver<MatrixType>::computeEigenvectors()
|
||||
if (q == 0)
|
||||
{
|
||||
Scalar lastr=0, lastw=0;
|
||||
int l = n;
|
||||
Index l = n;
|
||||
|
||||
m_matT.coeffRef(n,n) = 1.0;
|
||||
for (int i = n-1; i >= 0; i--)
|
||||
for (Index i = n-1; i >= 0; i--)
|
||||
{
|
||||
Scalar w = m_matT.coeff(i,i) - p;
|
||||
Scalar r = m_matT.row(i).segment(l,n-l+1).dot(m_matT.col(n).segment(l, n-l+1));
|
||||
@@ -461,7 +462,7 @@ void EigenSolver<MatrixType>::computeEigenvectors()
|
||||
else if (q < 0) // Complex vector
|
||||
{
|
||||
Scalar lastra=0, lastsa=0, lastw=0;
|
||||
int l = n-1;
|
||||
Index l = n-1;
|
||||
|
||||
// Last vector component imaginary so matrix is triangular
|
||||
if (ei_abs(m_matT.coeff(n,n-1)) > ei_abs(m_matT.coeff(n-1,n)))
|
||||
@@ -477,7 +478,7 @@ void EigenSolver<MatrixType>::computeEigenvectors()
|
||||
}
|
||||
m_matT.coeffRef(n,n-1) = 0.0;
|
||||
m_matT.coeffRef(n,n) = 1.0;
|
||||
for (int i = n-2; i >= 0; i--)
|
||||
for (Index i = n-2; i >= 0; i--)
|
||||
{
|
||||
Scalar ra = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n-1).segment(l, n-l+1));
|
||||
Scalar sa = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n).segment(l, n-l+1));
|
||||
@@ -535,7 +536,7 @@ void EigenSolver<MatrixType>::computeEigenvectors()
|
||||
}
|
||||
|
||||
// Back transformation to get eigenvectors of original matrix
|
||||
for (int j = size-1; j >= 0; j--)
|
||||
for (Index j = size-1; j >= 0; j--)
|
||||
{
|
||||
m_tmp.noalias() = m_eivec.leftCols(j+1) * m_matT.col(j).segment(0, j+1);
|
||||
m_eivec.col(j) = m_tmp;
|
||||
|
||||
@@ -81,6 +81,7 @@ template<typename _MatrixType> class HessenbergDecomposition
|
||||
|
||||
/** \brief Scalar type for matrices of type #MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
/** \brief Type for vector of Householder coefficients.
|
||||
*
|
||||
@@ -104,7 +105,7 @@ template<typename _MatrixType> class HessenbergDecomposition
|
||||
*
|
||||
* \sa compute() for an example.
|
||||
*/
|
||||
HessenbergDecomposition(int size = Size==Dynamic ? 2 : Size)
|
||||
HessenbergDecomposition(Index size = Size==Dynamic ? 2 : Size)
|
||||
: m_matrix(size,size),
|
||||
m_temp(size)
|
||||
{
|
||||
@@ -276,12 +277,12 @@ template<typename MatrixType>
|
||||
void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp)
|
||||
{
|
||||
assert(matA.rows()==matA.cols());
|
||||
int n = matA.rows();
|
||||
Index n = matA.rows();
|
||||
temp.resize(n);
|
||||
for (int i = 0; i<n-1; ++i)
|
||||
for (Index i = 0; i<n-1; ++i)
|
||||
{
|
||||
// let's consider the vector v = i-th column starting at position i+1
|
||||
int remainingSize = n-i-1;
|
||||
Index remainingSize = n-i-1;
|
||||
RealScalar beta;
|
||||
Scalar h;
|
||||
matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
|
||||
@@ -321,6 +322,7 @@ void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVector
|
||||
template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType
|
||||
: public ReturnByValue<HessenbergDecompositionMatrixHReturnType<MatrixType> >
|
||||
{
|
||||
typedef typename MatrixType::Index Index;
|
||||
public:
|
||||
/** \brief Constructor.
|
||||
*
|
||||
@@ -337,13 +339,13 @@ template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType
|
||||
inline void evalTo(ResultType& result) const
|
||||
{
|
||||
result = m_hess.packedMatrix();
|
||||
int n = result.rows();
|
||||
Index n = result.rows();
|
||||
if (n>2)
|
||||
result.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
|
||||
}
|
||||
|
||||
int rows() const { return m_hess.packedMatrix().rows(); }
|
||||
int cols() const { return m_hess.packedMatrix().cols(); }
|
||||
Index rows() const { return m_hess.packedMatrix().rows(); }
|
||||
Index cols() const { return m_hess.packedMatrix().cols(); }
|
||||
|
||||
protected:
|
||||
const HessenbergDecomposition<MatrixType>& m_hess;
|
||||
|
||||
@@ -77,6 +77,8 @@ template<typename _MatrixType> class RealSchur
|
||||
};
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> EigenvalueType;
|
||||
typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
|
||||
|
||||
@@ -91,7 +93,7 @@ template<typename _MatrixType> class RealSchur
|
||||
*
|
||||
* \sa compute() for an example.
|
||||
*/
|
||||
RealSchur(int size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
|
||||
RealSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
|
||||
: m_matT(size, size),
|
||||
m_matU(size, size),
|
||||
m_workspaceVector(size),
|
||||
@@ -177,11 +179,11 @@ template<typename _MatrixType> class RealSchur
|
||||
typedef Matrix<Scalar,3,1> Vector3s;
|
||||
|
||||
Scalar computeNormOfT();
|
||||
int findSmallSubdiagEntry(int iu, Scalar norm);
|
||||
void splitOffTwoRows(int iu, Scalar exshift);
|
||||
void computeShift(int iu, int iter, Scalar& exshift, Vector3s& shiftInfo);
|
||||
void initFrancisQRStep(int il, int iu, const Vector3s& shiftInfo, int& im, Vector3s& firstHouseholderVector);
|
||||
void performFrancisQRStep(int il, int im, int iu, const Vector3s& firstHouseholderVector, Scalar* workspace);
|
||||
Index findSmallSubdiagEntry(Index iu, Scalar norm);
|
||||
void splitOffTwoRows(Index iu, Scalar exshift);
|
||||
void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo);
|
||||
void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector);
|
||||
void performFrancisQRStep(Index il, Index im, Index iu, const Vector3s& firstHouseholderVector, Scalar* workspace);
|
||||
};
|
||||
|
||||
|
||||
@@ -204,14 +206,14 @@ void RealSchur<MatrixType>::compute(const MatrixType& matrix)
|
||||
// Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
|
||||
// Rows il,...,iu is the part we are working on (the active window).
|
||||
// Rows iu+1,...,end are already brought in triangular form.
|
||||
int iu = m_matU.cols() - 1;
|
||||
int iter = 0; // iteration count
|
||||
Index iu = m_matU.cols() - 1;
|
||||
Index iter = 0; // iteration count
|
||||
Scalar exshift = 0.0; // sum of exceptional shifts
|
||||
Scalar norm = computeNormOfT();
|
||||
|
||||
while (iu >= 0)
|
||||
{
|
||||
int il = findSmallSubdiagEntry(iu, norm);
|
||||
Index il = findSmallSubdiagEntry(iu, norm);
|
||||
|
||||
// Check for convergence
|
||||
if (il == iu) // One root found
|
||||
@@ -233,7 +235,7 @@ void RealSchur<MatrixType>::compute(const MatrixType& matrix)
|
||||
Vector3s firstHouseholderVector, shiftInfo;
|
||||
computeShift(iu, iter, exshift, shiftInfo);
|
||||
iter = iter + 1; // (Could check iteration count here.)
|
||||
int im;
|
||||
Index im;
|
||||
initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
|
||||
performFrancisQRStep(il, im, iu, firstHouseholderVector, workspace);
|
||||
}
|
||||
@@ -246,21 +248,21 @@ void RealSchur<MatrixType>::compute(const MatrixType& matrix)
|
||||
template<typename MatrixType>
|
||||
inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT()
|
||||
{
|
||||
const int size = m_matU.cols();
|
||||
const Index size = m_matU.cols();
|
||||
// FIXME to be efficient the following would requires a triangular reduxion code
|
||||
// Scalar norm = m_matT.upper().cwiseAbs().sum()
|
||||
// + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
|
||||
Scalar norm = 0.0;
|
||||
for (int j = 0; j < size; ++j)
|
||||
norm += m_matT.row(j).segment(std::max(j-1,0), size-std::max(j-1,0)).cwiseAbs().sum();
|
||||
for (Index j = 0; j < size; ++j)
|
||||
norm += m_matT.row(j).segment(std::max(j-1,Index(0)), size-std::max(j-1,Index(0))).cwiseAbs().sum();
|
||||
return norm;
|
||||
}
|
||||
|
||||
/** \internal Look for single small sub-diagonal element and returns its index */
|
||||
template<typename MatrixType>
|
||||
inline int RealSchur<MatrixType>::findSmallSubdiagEntry(int iu, Scalar norm)
|
||||
inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, Scalar norm)
|
||||
{
|
||||
int res = iu;
|
||||
Index res = iu;
|
||||
while (res > 0)
|
||||
{
|
||||
Scalar s = ei_abs(m_matT.coeff(res-1,res-1)) + ei_abs(m_matT.coeff(res,res));
|
||||
@@ -275,9 +277,9 @@ inline int RealSchur<MatrixType>::findSmallSubdiagEntry(int iu, Scalar norm)
|
||||
|
||||
/** \internal Update T given that rows iu-1 and iu decouple from the rest. */
|
||||
template<typename MatrixType>
|
||||
inline void RealSchur<MatrixType>::splitOffTwoRows(int iu, Scalar exshift)
|
||||
inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, Scalar exshift)
|
||||
{
|
||||
const int size = m_matU.cols();
|
||||
const Index size = m_matU.cols();
|
||||
|
||||
// The eigenvalues of the 2x2 matrix [a b; c d] are
|
||||
// trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc
|
||||
@@ -307,7 +309,7 @@ inline void RealSchur<MatrixType>::splitOffTwoRows(int iu, Scalar exshift)
|
||||
|
||||
/** \internal Form shift in shiftInfo, and update exshift if an exceptional shift is performed. */
|
||||
template<typename MatrixType>
|
||||
inline void RealSchur<MatrixType>::computeShift(int iu, int iter, Scalar& exshift, Vector3s& shiftInfo)
|
||||
inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo)
|
||||
{
|
||||
shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu);
|
||||
shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1);
|
||||
@@ -317,7 +319,7 @@ inline void RealSchur<MatrixType>::computeShift(int iu, int iter, Scalar& exshif
|
||||
if (iter == 10)
|
||||
{
|
||||
exshift += shiftInfo.coeff(0);
|
||||
for (int i = 0; i <= iu; ++i)
|
||||
for (Index i = 0; i <= iu; ++i)
|
||||
m_matT.coeffRef(i,i) -= shiftInfo.coeff(0);
|
||||
Scalar s = ei_abs(m_matT.coeff(iu,iu-1)) + ei_abs(m_matT.coeff(iu-1,iu-2));
|
||||
shiftInfo.coeffRef(0) = Scalar(0.75) * s;
|
||||
@@ -338,7 +340,7 @@ inline void RealSchur<MatrixType>::computeShift(int iu, int iter, Scalar& exshif
|
||||
s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
|
||||
s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s;
|
||||
exshift += s;
|
||||
for (int i = 0; i <= iu; ++i)
|
||||
for (Index i = 0; i <= iu; ++i)
|
||||
m_matT.coeffRef(i,i) -= s;
|
||||
shiftInfo.setConstant(Scalar(0.964));
|
||||
}
|
||||
@@ -347,7 +349,7 @@ inline void RealSchur<MatrixType>::computeShift(int iu, int iter, Scalar& exshif
|
||||
|
||||
/** \internal Compute index im at which Francis QR step starts and the first Householder vector. */
|
||||
template<typename MatrixType>
|
||||
inline void RealSchur<MatrixType>::initFrancisQRStep(int il, int iu, const Vector3s& shiftInfo, int& im, Vector3s& firstHouseholderVector)
|
||||
inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector)
|
||||
{
|
||||
Vector3s& v = firstHouseholderVector; // alias to save typing
|
||||
|
||||
@@ -373,14 +375,14 @@ inline void RealSchur<MatrixType>::initFrancisQRStep(int il, int iu, const Vecto
|
||||
|
||||
/** \internal Perform a Francis QR step involving rows il:iu and columns im:iu. */
|
||||
template<typename MatrixType>
|
||||
inline void RealSchur<MatrixType>::performFrancisQRStep(int il, int im, int iu, const Vector3s& firstHouseholderVector, Scalar* workspace)
|
||||
inline void RealSchur<MatrixType>::performFrancisQRStep(Index il, Index im, Index iu, const Vector3s& firstHouseholderVector, Scalar* workspace)
|
||||
{
|
||||
assert(im >= il);
|
||||
assert(im <= iu-2);
|
||||
|
||||
const int size = m_matU.cols();
|
||||
const Index size = m_matU.cols();
|
||||
|
||||
for (int k = im; k <= iu-2; ++k)
|
||||
for (Index k = im; k <= iu-2; ++k)
|
||||
{
|
||||
bool firstIteration = (k == im);
|
||||
|
||||
@@ -422,7 +424,7 @@ inline void RealSchur<MatrixType>::performFrancisQRStep(int il, int im, int iu,
|
||||
}
|
||||
|
||||
// clean up pollution due to round-off errors
|
||||
for (int i = im+2; i <= iu; ++i)
|
||||
for (Index i = im+2; i <= iu; ++i)
|
||||
{
|
||||
m_matT.coeffRef(i,i-2) = Scalar(0);
|
||||
if (i > im+2)
|
||||
|
||||
@@ -82,6 +82,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
|
||||
/** \brief Scalar type for matrices of type \p _MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
/** \brief Real scalar type for \p _MatrixType.
|
||||
*
|
||||
@@ -105,7 +106,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
* perform decompositions via compute(const MatrixType&, bool) or
|
||||
* compute(const MatrixType&, const MatrixType&, bool). This constructor
|
||||
* can only be used if \p _MatrixType is a fixed-size matrix; use
|
||||
* SelfAdjointEigenSolver(int) for dynamic-size matrices.
|
||||
* SelfAdjointEigenSolver(Index) for dynamic-size matrices.
|
||||
*
|
||||
* Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp
|
||||
* Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver.out
|
||||
@@ -132,7 +133,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
*
|
||||
* \sa compute(const MatrixType&, bool) for an example
|
||||
*/
|
||||
SelfAdjointEigenSolver(int size)
|
||||
SelfAdjointEigenSolver(Index size)
|
||||
: m_eivec(size, size),
|
||||
m_eivalues(size),
|
||||
m_tridiag(size),
|
||||
@@ -379,8 +380,8 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
* Implemented from Golub's "Matrix Computations", algorithm 8.3.2:
|
||||
* "implicit symmetric QR step with Wilkinson shift"
|
||||
*/
|
||||
template<typename RealScalar, typename Scalar>
|
||||
static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, int start, int end, Scalar* matrixQ, int n);
|
||||
template<typename RealScalar, typename Scalar, typename Index>
|
||||
static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
|
||||
|
||||
template<typename MatrixType>
|
||||
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
|
||||
@@ -389,7 +390,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::compute(
|
||||
m_eigenvectorsOk = computeEigenvectors;
|
||||
#endif
|
||||
assert(matrix.cols() == matrix.rows());
|
||||
int n = matrix.cols();
|
||||
Index n = matrix.cols();
|
||||
m_eivalues.resize(n,1);
|
||||
m_eivec.resize(n,n);
|
||||
|
||||
@@ -407,11 +408,11 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::compute(
|
||||
if (computeEigenvectors)
|
||||
m_eivec = m_tridiag.matrixQ();
|
||||
|
||||
int end = n-1;
|
||||
int start = 0;
|
||||
Index end = n-1;
|
||||
Index start = 0;
|
||||
while (end>0)
|
||||
{
|
||||
for (int i = start; i<end; ++i)
|
||||
for (Index i = start; i<end; ++i)
|
||||
if (ei_isMuchSmallerThan(ei_abs(m_subdiag[i]),(ei_abs(diag[i])+ei_abs(diag[i+1]))))
|
||||
m_subdiag[i] = 0;
|
||||
|
||||
@@ -430,9 +431,9 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::compute(
|
||||
// Sort eigenvalues and corresponding vectors.
|
||||
// TODO make the sort optional ?
|
||||
// TODO use a better sort algorithm !!
|
||||
for (int i = 0; i < n-1; ++i)
|
||||
for (Index i = 0; i < n-1; ++i)
|
||||
{
|
||||
int k;
|
||||
Index k;
|
||||
m_eivalues.segment(i,n-i).minCoeff(&k);
|
||||
if (k > 0)
|
||||
{
|
||||
@@ -473,7 +474,7 @@ compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors
|
||||
{
|
||||
// transform back the eigen vectors: evecs = inv(U) * evecs
|
||||
cholB.matrixU().solveInPlace(m_eivec);
|
||||
for (int i=0; i<m_eivec.cols(); ++i)
|
||||
for (Index i=0; i<m_eivec.cols(); ++i)
|
||||
m_eivec.col(i) = m_eivec.col(i).normalized();
|
||||
}
|
||||
return *this;
|
||||
@@ -482,8 +483,8 @@ compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors
|
||||
#endif // EIGEN_HIDE_HEAVY_CODE
|
||||
|
||||
#ifndef EIGEN_EXTERN_INSTANTIATIONS
|
||||
template<typename RealScalar, typename Scalar>
|
||||
static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, int start, int end, Scalar* matrixQ, int n)
|
||||
template<typename RealScalar, typename Scalar, typename Index>
|
||||
static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
|
||||
{
|
||||
RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
|
||||
RealScalar e2 = ei_abs2(subdiag[end-1]);
|
||||
@@ -491,7 +492,7 @@ static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, int st
|
||||
RealScalar x = diag[start] - mu;
|
||||
RealScalar z = subdiag[start];
|
||||
|
||||
for (int k = start; k < end; ++k)
|
||||
for (Index k = start; k < end; ++k)
|
||||
{
|
||||
PlanarRotation<RealScalar> rot;
|
||||
rot.makeGivens(x, z);
|
||||
|
||||
@@ -67,6 +67,7 @@ template<typename _MatrixType> class Tridiagonalization
|
||||
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
enum {
|
||||
Size = MatrixType::RowsAtCompileTime,
|
||||
@@ -107,7 +108,7 @@ template<typename _MatrixType> class Tridiagonalization
|
||||
*
|
||||
* \sa compute() for an example.
|
||||
*/
|
||||
Tridiagonalization(int size = Size==Dynamic ? 2 : Size)
|
||||
Tridiagonalization(Index size = Size==Dynamic ? 2 : Size)
|
||||
: m_matrix(size,size), m_hCoeffs(size > 1 ? size-1 : 1)
|
||||
{}
|
||||
|
||||
@@ -324,7 +325,7 @@ template<typename MatrixType>
|
||||
const typename Tridiagonalization<MatrixType>::SubDiagonalReturnType
|
||||
Tridiagonalization<MatrixType>::subDiagonal() const
|
||||
{
|
||||
int n = m_matrix.rows();
|
||||
Index n = m_matrix.rows();
|
||||
return Block<MatrixType,SizeMinusOne,SizeMinusOne>(m_matrix, 1, 0, n-1,n-1).diagonal();
|
||||
}
|
||||
|
||||
@@ -334,7 +335,7 @@ Tridiagonalization<MatrixType>::matrixT() const
|
||||
{
|
||||
// FIXME should this function (and other similar ones) rather take a matrix as argument
|
||||
// and fill it ? (to avoid temporaries)
|
||||
int n = m_matrix.rows();
|
||||
Index n = m_matrix.rows();
|
||||
MatrixType matT = m_matrix;
|
||||
matT.topRightCorner(n-1, n-1).diagonal() = subDiagonal().template cast<Scalar>().conjugate();
|
||||
if (n>2)
|
||||
@@ -363,10 +364,10 @@ template<typename MatrixType>
|
||||
void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs)
|
||||
{
|
||||
assert(matA.rows()==matA.cols());
|
||||
int n = matA.rows();
|
||||
for (int i = 0; i<n-1; ++i)
|
||||
Index n = matA.rows();
|
||||
for (Index i = 0; i<n-1; ++i)
|
||||
{
|
||||
int remainingSize = n-i-1;
|
||||
Index remainingSize = n-i-1;
|
||||
RealScalar beta;
|
||||
Scalar h;
|
||||
matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
|
||||
@@ -391,7 +392,7 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
|
||||
template<typename MatrixType>
|
||||
void Tridiagonalization<MatrixType>::decomposeInPlace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
|
||||
{
|
||||
int n = mat.rows();
|
||||
Index n = mat.rows();
|
||||
ei_assert(mat.cols()==n && diag.size()==n && subdiag.size()==n-1);
|
||||
if (n==3 && (!NumTraits<Scalar>::IsComplex) )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user