10 #ifndef EIGEN_MATRIX_FUNCTION 11 #define EIGEN_MATRIX_FUNCTION 34 template <
typename MatrixType,
36 int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>
59 template <
typename ResultType>
60 void compute(ResultType &result);
67 template <
typename MatrixType,
typename AtomicType>
73 typedef typename Traits::Scalar
Scalar;
74 static const int Rows = Traits::RowsAtCompileTime;
75 static const int Cols = Traits::ColsAtCompileTime;
76 static const int Options = MatrixType::Options;
77 static const int MaxRows = Traits::MaxRowsAtCompileTime;
78 static const int MaxCols = Traits::MaxColsAtCompileTime;
90 MatrixFunction(
const MatrixType&
A, AtomicType& atomic) : m_A(A), m_atomic(atomic) { }
101 template <
typename ResultType>
104 ComplexMatrix CA = m_A.template cast<ComplexScalar>();
105 ComplexMatrix Cresult;
108 result = Cresult.real();
122 template <
typename MatrixType,
typename AtomicType>
128 typedef typename MatrixType::Scalar
Scalar;
129 typedef typename MatrixType::Index
Index;
130 static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
131 static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
132 static const int Options = MatrixType::Options;
144 template <
typename ResultType>
void compute(ResultType& result);
148 void computeSchurDecomposition();
149 void partitionEigenvalues();
150 typename ListOfClusters::iterator findCluster(Scalar key);
151 void computeClusterSize();
152 void computeBlockStart();
153 void constructPermutation();
155 void swapEntriesInSchur(Index index);
156 void computeBlockAtomic();
158 void computeOffDiagonal();
159 DynMatrixType solveTriangularSylvester(
const DynMatrixType&
A,
const DynMatrixType& B,
const DynMatrixType& C);
178 static const RealScalar
separation() {
return static_cast<RealScalar
>(0.1); }
188 template <
typename MatrixType,
typename AtomicType>
190 : m_A(A), m_atomic(atomic)
200 template <
typename MatrixType,
typename AtomicType>
201 template <
typename ResultType>
204 computeSchurDecomposition();
205 partitionEigenvalues();
206 computeClusterSize();
208 constructPermutation();
210 computeBlockAtomic();
211 computeOffDiagonal();
212 result = m_U * (m_fT.template triangularView<Upper>() * m_U.adjoint());
216 template <
typename MatrixType,
typename AtomicType>
235 template <
typename MatrixType,
typename AtomicType>
239 const Index rows = m_T.rows();
242 for (
Index i=0; i<rows; ++i) {
244 typename ListOfClusters::iterator qi = findCluster(diag(i));
245 if (qi == m_clusters.end()) {
247 l.push_back(diag(i));
248 m_clusters.push_back(l);
249 qi = m_clusters.end();
254 for (
Index j=i+1; j<rows; ++j) {
255 if (
abs(diag(j) - diag(i)) <= separation() && std::find(qi->begin(), qi->end(), diag(j)) == qi->end()) {
256 typename ListOfClusters::iterator qj = findCluster(diag(j));
257 if (qj == m_clusters.end()) {
258 qi->push_back(diag(j));
260 qi->insert(qi->end(), qj->begin(), qj->end());
261 m_clusters.erase(qj);
273 template <
typename MatrixType,
typename AtomicType>
276 typename Cluster::iterator j;
277 for (
typename ListOfClusters::iterator i = m_clusters.begin(); i != m_clusters.end(); ++i) {
278 j = std::find(i->begin(), i->end(), key);
282 return m_clusters.end();
286 template <
typename MatrixType,
typename AtomicType>
289 const Index rows = m_T.rows();
291 const Index numClusters =
static_cast<Index>(m_clusters.size());
293 m_clusterSize.
setZero(numClusters);
294 m_eivalToCluster.resize(rows);
295 Index clusterIndex = 0;
296 for (
typename ListOfClusters::const_iterator cluster = m_clusters.begin(); cluster != m_clusters.end(); ++cluster) {
297 for (
Index i = 0; i < diag.
rows(); ++i) {
298 if (std::find(cluster->begin(), cluster->end(), diag(i)) != cluster->end()) {
299 ++m_clusterSize[clusterIndex];
300 m_eivalToCluster[i] = clusterIndex;
308 template <
typename MatrixType,
typename AtomicType>
311 m_blockStart.resize(m_clusterSize.rows());
313 for (
Index i = 1; i < m_clusterSize.rows(); i++) {
314 m_blockStart(i) = m_blockStart(i-1) + m_clusterSize(i-1);
319 template <
typename MatrixType,
typename AtomicType>
323 m_permutation.
resize(m_T.rows());
324 for (
Index i = 0; i < m_T.rows(); i++) {
325 Index cluster = m_eivalToCluster[i];
326 m_permutation[i] = indexNextEntry[cluster];
327 ++indexNextEntry[cluster];
332 template <
typename MatrixType,
typename AtomicType>
336 for (
Index i = 0; i < p.
rows() - 1; i++) {
338 for (j = i; j < p.
rows(); j++) {
339 if (p(j) == i)
break;
342 for (
Index k = j-1; k >= i; k--) {
343 swapEntriesInSchur(k);
350 template <
typename MatrixType,
typename AtomicType>
354 rotation.
makeGivens(m_T(index, index+1), m_T(index+1, index+1) - m_T(index, index));
355 m_T.applyOnTheLeft(index, index+1, rotation.
adjoint());
356 m_T.applyOnTheRight(index, index+1, rotation);
357 m_U.applyOnTheRight(index, index+1, rotation);
366 template <
typename MatrixType,
typename AtomicType>
369 m_fT.resize(m_T.rows(), m_T.cols());
371 for (
Index i = 0; i < m_clusterSize.rows(); ++i) {
372 block(m_fT, i, i) = m_atomic.compute(
block(m_T, i, i));
377 template <
typename MatrixType,
typename AtomicType>
380 return A.block(m_blockStart(i), m_blockStart(j), m_clusterSize(i), m_clusterSize(j));
390 template <
typename MatrixType,
typename AtomicType>
393 for (
Index diagIndex = 1; diagIndex < m_clusterSize.rows(); diagIndex++) {
394 for (
Index blockIndex = 0; blockIndex < m_clusterSize.rows() - diagIndex; blockIndex++) {
399 C -=
block(m_T, blockIndex, blockIndex+diagIndex) *
block(m_fT, blockIndex+diagIndex, blockIndex+diagIndex);
400 for (
Index k = blockIndex + 1; k < blockIndex + diagIndex; k++) {
401 C +=
block(m_fT, blockIndex, k) *
block(m_T, k, blockIndex+diagIndex);
402 C -=
block(m_T, blockIndex, k) *
block(m_fT, k, blockIndex+diagIndex);
404 block(m_fT, blockIndex, blockIndex+diagIndex) = solveTriangularSylvester(A, B, C);
432 template <
typename MatrixType,
typename AtomicType>
449 for (
Index i = m - 1; i >= 0; --i) {
450 for (
Index j = 0; j < n; ++j) {
470 X(i,j) = (C(i,j) - AX - XB) / (
A(i,i) + B(j,j));
494 typedef typename Derived::Index
Index;
510 template <
typename ResultType>
511 inline void evalTo(ResultType& result)
const 513 typedef typename Derived::PlainObject PlainObject;
515 static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
516 static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
517 static const int Options = PlainObject::Options;
518 typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
521 AtomicType atomic(m_f);
523 const PlainObject Aevaluated = m_A.eval();
528 Index
rows()
const {
return m_A.rows(); }
529 Index
cols()
const {
return m_A.cols(); }
539 template<
typename Derived>
550 template <
typename Derived>
557 template <
typename Derived>
565 template <
typename Derived>
573 template <
typename Derived>
581 template <
typename Derived>
591 #endif // EIGEN_MATRIX_FUNCTION Derived::PlainObject ReturnType
internal::traits< MatrixType > Traits
std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
void makeGivens(const Scalar &p, const Scalar &q, Scalar *z=0)
NumTraits< Scalar >::Real RealScalar
DynamicIntVectorType m_eivalToCluster
m_eivalToCluster[i] = j means i-th ei'val is in j-th cluster
DynamicIntVectorType m_blockStart
Row index at which block corresponding to i-th cluster starts.
iterative scaling algorithm to equilibrate rows and column norms in matrices
Rotation given by a cosine-sine pair.
Block< Derived > block(Index startRow, Index startCol, Index blockRows, Index blockCols)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
void compute(ResultType &result)
Compute the matrix function.
Matrix< Scalar, Traits::RowsAtCompileTime, 1 > VectorType
Class for computing matrix functions.
const MatrixFunctionReturnValue< Derived > sinh() const
Proxy for the matrix function of some matrix (expression).
static const RealScalar separation()
Maximum distance allowed between eigenvalues to be considered "close".
const MatrixFunctionReturnValue< Derived > cos() const
MatrixFunctionReturnValue(const Derived &A, StemFunction f)
Constructor.
EIGEN_STRONG_INLINE Index rows() const
EIGEN_STRONG_INLINE const CwiseUnaryOp< internal::scalar_abs_op< Scalar >, const Derived > abs() const
internal::nested< MatrixType >::type m_A
Reference to argument of matrix function.
internal::nested< Derived >::type m_A
internal::traits< MatrixType > Traits
const MatrixFunctionReturnValue< Derived > cosh() const
EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
std::list< Scalar > Cluster
EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
std::complex< Scalar > ComplexScalar
Provides a generic way to set and pass user-specified options.
void compute(ResultType &result)
Compute the matrix function.
JacobiRotation adjoint() const
DynamicIntVectorType m_clusterSize
Number of eigenvalues in each clusters.
MatrixType m_U
Unitary part of Schur decomposition.
const ComplexMatrixType & matrixT() const
Returns the triangular matrix in the Schur decomposition.
Derived & setZero(Index size)
Stem functions corresponding to standard mathematical functions.
Matrix< Index, Traits::RowsAtCompileTime, 1 > IntVectorType
Helper class for computing matrix functions of atomic matrices.
MatrixType m_fT
Matrix function applied to m_T
internal::stem_function< Scalar >::type StemFunction
void evalTo(ResultType &result) const
Compute the matrix function.
MatrixFunction(const MatrixType &A, AtomicType &atomic)
Constructor.
MatrixType::Scalar Scalar
MatrixType m_T
Triangular part of Schur decomposition.
Expression of a fixed-size or dynamic-size block.
IntVectorType m_permutation
Permutation which groups ei'vals in the same cluster together.
ListOfClusters m_clusters
Partition of eigenvalues into clusters of ei'vals "close" to each other.
Matrix< ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols > ComplexMatrix
std::list< Cluster > ListOfClusters
const MatrixFunctionReturnValue< Derived > matrixFunction(StemFunction f) const
AtomicType & m_atomic
Class for computing matrix function of atomic blocks.
The matrix class, also used for vectors and row-vectors.
EIGEN_STRONG_INLINE Index cols() const
Matrix< Index, Dynamic, 1 > DynamicIntVectorType
const ComplexMatrixType & matrixU() const
Returns the unitary matrix in the Schur decomposition.
Matrix< Scalar, Dynamic, Dynamic, Options, RowsAtCompileTime, ColsAtCompileTime > DynMatrixType
const MatrixFunctionReturnValue< Derived > sin() const
AtomicType & m_atomic
Class for computing matrix function of atomic blocks.
MatrixFunction(const MatrixType &A, AtomicType &atomic)
Constructor.
internal::nested< MatrixType >::type m_A
Reference to argument of matrix function.