10 #ifndef EIGEN_MATRIX_FUNCTION 11 #define EIGEN_MATRIX_FUNCTION 13 #include "StemFunction.h" 14 #include "MatrixFunctionAtomic.h" 34 template <
typename MatrixType,
59 template <
typename ResultType>
60 void compute(ResultType &result);
67 template <
typename MatrixType,
typename AtomicType>
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;
80 typedef std::complex<Scalar> ComplexScalar;
101 template <
typename ResultType>
104 ComplexMatrix CA = m_A.template cast<ComplexScalar>();
105 ComplexMatrix Cresult;
108 result = Cresult.real();
113 AtomicType& m_atomic;
122 template <
typename MatrixType,
typename AtomicType>
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;
137 typedef std::list<Scalar> Cluster;
138 typedef std::list<Cluster> ListOfClusters;
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);
162 AtomicType& m_atomic;
166 ListOfClusters m_clusters;
167 DynamicIntVectorType m_eivalToCluster;
168 DynamicIntVectorType m_clusterSize;
169 DynamicIntVectorType m_blockStart;
170 IntVectorType m_permutation;
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;
341 eigen_assert(p(j) == i);
342 for (Index k = j-1; k >= i; k--) {
343 swapEntriesInSchur(k);
344 std::swap(p.coeffRef(k), p.coeffRef(k+1));
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++) {
397 DynMatrixType B = -block(m_T, blockIndex+diagIndex, blockIndex+diagIndex);
398 DynMatrixType C = block(m_fT, blockIndex, blockIndex) * block(m_T, blockIndex, blockIndex+diagIndex);
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>
438 eigen_assert(A.rows() == A.cols());
439 eigen_assert(A.isUpperTriangular());
440 eigen_assert(B.rows() == B.cols());
441 eigen_assert(B.isUpperTriangular());
442 eigen_assert(C.rows() == A.rows());
443 eigen_assert(C.cols() == B.rows());
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>
542 typedef typename Derived::PlainObject ReturnType;
550 template <
typename Derived>
553 eigen_assert(rows() == cols());
557 template <
typename Derived>
560 eigen_assert(rows() == cols());
561 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
565 template <
typename Derived>
568 eigen_assert(rows() == cols());
569 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
573 template <
typename Derived>
576 eigen_assert(rows() == cols());
577 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
581 template <
typename Derived>
584 eigen_assert(rows() == cols());
585 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
591 #endif // EIGEN_MATRIX_FUNCTION void makeGivens(const Scalar &p, const Scalar &q, Scalar *z=0)
Makes *this as a Givens rotation G such that applying to the left of the vector yields: ...
Definition: Jacobi.h:148
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: TestIMU_Common.h:87
Definition: ForwardDeclarations.h:228
Holds information about the various numeric (i.e.
Definition: NumTraits.h:88
void compute(ResultType &result)
Compute the matrix function.
Class for computing matrix functions.
Definition: MatrixFunction.h:37
Proxy for the matrix function of some matrix (expression).
Definition: ForwardDeclarations.h:273
Definition: ReturnByValue.h:50
MatrixFunctionReturnValue(const Derived &A, StemFunction f)
Constructor.
Definition: MatrixFunction.h:503
EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
Resizes *this to a rows x cols matrix.
Definition: PlainObjectBase.h:235
void compute(ResultType &result)
Compute the matrix function.
Definition: MatrixFunction.h:102
Definition: ForwardDeclarations.h:281
Derived & setZero(Index size)
Resizes to the given size, and sets all coefficients in this expression to zero.
Definition: CwiseNullaryOp.h:515
Stem functions corresponding to standard mathematical functions.
Definition: StemFunction.h:19
Helper class for computing matrix functions of atomic matrices.
Definition: MatrixFunctionAtomic.h:24
MatrixFunction(const MatrixType &A, AtomicType &atomic)
Constructor.
Definition: MatrixFunction.h:90
Definition: BandTriangularSolver.h:13
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
const ComplexMatrixType & matrixU() const
Returns the unitary matrix in the Schur decomposition.
Definition: ComplexSchur.h:137
void evalTo(ResultType &result) const
Compute the matrix function.
Definition: MatrixFunction.h:511
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
const ComplexMatrixType & matrixT() const
Returns the triangular matrix in the Schur decomposition.
Definition: ComplexSchur.h:161
Definition: osvr_print_tree.cpp:52
double Scalar
Common scalar type.
Definition: FlexibleKalmanBase.h:48
JacobiRotation adjoint() const
Returns the adjoint transformation.
Definition: Jacobi.h:62
MatrixFunction(const MatrixType &A, AtomicType &atomic)
Constructor.