10 #ifndef EIGEN_MATRIX_FUNCTION 11 #define EIGEN_MATRIX_FUNCTION 13 #include "StemFunction.h" 21 static const float matrix_function_separation = 0.1f;
29 template <
typename MatrixType>
34 typedef typename MatrixType::Scalar Scalar;
46 MatrixType
compute(
const MatrixType&
A);
52 template <
typename MatrixType>
56 typename MatrixType::Index rows = A.rows();
57 const MatrixType N = MatrixType::Identity(rows, rows) - A;
58 VectorType e = VectorType::Ones(rows);
59 N.template triangularView<Upper>().solveInPlace(e);
60 return e.cwiseAbs().maxCoeff();
63 template <
typename MatrixType>
68 typedef typename MatrixType::Index
Index;
69 Index rows = A.rows();
70 Scalar avgEival = A.trace() / Scalar(RealScalar(rows));
71 MatrixType Ashifted = A - avgEival * MatrixType::Identity(rows, rows);
72 RealScalar mu = matrix_function_compute_mu(Ashifted);
73 MatrixType F = m_f(avgEival, 0) * MatrixType::Identity(rows, rows);
74 MatrixType P = Ashifted;
76 for (Index s = 1; s < 1.1 * rows + 10; s++) {
77 Fincr = m_f(avgEival, static_cast<int>(s)) * P;
79 P = Scalar(RealScalar(1.0/(s + 1))) * P * Ashifted;
82 const RealScalar F_norm = F.cwiseAbs().rowwise().sum().maxCoeff();
83 const RealScalar Fincr_norm = Fincr.cwiseAbs().rowwise().sum().maxCoeff();
86 RealScalar rfactorial = 1;
87 for (Index r = 0; r < rows; r++) {
89 for (Index i = 0; i < rows; i++)
90 mx = (std::max)(mx, std::abs(m_f(Ashifted(i, i) + avgEival, static_cast<int>(s+r))));
92 rfactorial *= RealScalar(r);
93 delta = (std::max)(delta, mx / rfactorial);
95 const RealScalar P_norm = P.cwiseAbs().rowwise().sum().maxCoeff();
108 template <
typename Index,
typename ListOfClusters>
111 typename std::list<Index>::iterator j;
112 for (
typename ListOfClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
113 j = std::find(i->begin(), i->end(), key);
117 return clusters.end();
131 template <
typename EivalsType,
typename Cluster>
134 typedef typename EivalsType::Index
Index;
135 typedef typename EivalsType::RealScalar RealScalar;
136 for (Index i=0; i<eivals.rows(); ++i) {
139 if (qi == clusters.end()) {
142 clusters.push_back(l);
148 for (Index j=i+1; j<eivals.rows(); ++j) {
149 if (abs(eivals(j) - eivals(i)) <= RealScalar(matrix_function_separation)
150 && std::find(qi->begin(), qi->end(), j) == qi->end()) {
152 if (qj == clusters.end()) {
155 qi->insert(qi->end(), qj->begin(), qj->end());
164 template <
typename ListOfClusters,
typename Index>
167 const Index numClusters =
static_cast<Index>(clusters.size());
168 clusterSize.
setZero(numClusters);
169 Index clusterIndex = 0;
170 for (
typename ListOfClusters::const_iterator cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
171 clusterSize[clusterIndex] = cluster->size();
177 template <
typename VectorType>
180 blockStart.resize(clusterSize.rows());
182 for (
typename VectorType::Index i = 1; i < clusterSize.rows(); i++) {
183 blockStart(i) = blockStart(i-1) + clusterSize(i-1);
188 template <
typename EivalsType,
typename ListOfClusters,
typename VectorType>
191 typedef typename EivalsType::Index
Index;
192 eivalToCluster.resize(eivals.rows());
193 Index clusterIndex = 0;
194 for (
typename ListOfClusters::const_iterator cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
195 for (Index i = 0; i < eivals.rows(); ++i) {
196 if (std::find(cluster->begin(), cluster->end(), i) != cluster->end()) {
197 eivalToCluster[i] = clusterIndex;
205 template <
typename DynVectorType,
typename VectorType>
208 typedef typename VectorType::Index
Index;
209 DynVectorType indexNextEntry = blockStart;
210 permutation.resize(eivalToCluster.rows());
211 for (Index i = 0; i < eivalToCluster.rows(); i++) {
212 Index cluster = eivalToCluster[i];
213 permutation[i] = indexNextEntry[cluster];
214 ++indexNextEntry[cluster];
219 template <
typename VectorType,
typename MatrixType>
222 typedef typename VectorType::Index
Index;
223 for (Index i = 0; i < permutation.rows() - 1; i++) {
225 for (j = i; j < permutation.rows(); j++) {
226 if (permutation(j) == i)
break;
228 eigen_assert(permutation(j) == i);
229 for (Index k = j-1; k >= i; k--) {
231 rotation.
makeGivens(T(k, k+1), T(k+1, k+1) - T(k, k));
232 T.applyOnTheLeft(k, k+1, rotation.
adjoint());
233 T.applyOnTheRight(k, k+1, rotation);
234 U.applyOnTheRight(k, k+1, rotation);
235 std::swap(permutation.coeffRef(k), permutation.coeffRef(k+1));
246 template <
typename MatrixType,
typename AtomicType,
typename VectorType>
249 fT.setZero(T.rows(), T.cols());
250 for (
typename VectorType::Index i = 0; i < clusterSize.rows(); ++i) {
251 fT.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i))
252 = atomic.compute(T.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i)));
278 template <
typename MatrixType>
281 eigen_assert(A.rows() == A.cols());
282 eigen_assert(A.isUpperTriangular());
283 eigen_assert(B.rows() == B.cols());
284 eigen_assert(B.isUpperTriangular());
285 eigen_assert(C.rows() == A.rows());
286 eigen_assert(C.cols() == B.rows());
288 typedef typename MatrixType::Index
Index;
289 typedef typename MatrixType::Scalar Scalar;
295 for (Index i = m - 1; i >= 0; --i) {
296 for (Index j = 0; j < n; ++j) {
316 X(i,j) = (C(i,j) - AX - XB) / (A(i,i) + B(j,j));
328 template <
typename MatrixType,
typename VectorType>
332 typedef typename MatrixType::Scalar Scalar;
333 typedef typename MatrixType::Index
Index;
334 static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
335 static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
336 static const int Options = MatrixType::Options;
339 for (Index k = 1; k < clusterSize.rows(); k++) {
340 for (Index i = 0; i < clusterSize.rows() - k; i++) {
342 DynMatrixType A = T.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i));
343 DynMatrixType
B = -T.block(blockStart(i+k), blockStart(i+k), clusterSize(i+k), clusterSize(i+k));
344 DynMatrixType
C = fT.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i))
345 * T.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k));
346 C -= T.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k))
347 * fT.block(blockStart(i+k), blockStart(i+k), clusterSize(i+k), clusterSize(i+k));
348 for (Index m = i + 1; m < i + k; m++) {
349 C += fT.block(blockStart(i), blockStart(m), clusterSize(i), clusterSize(m))
350 * T.block(blockStart(m), blockStart(i+k), clusterSize(m), clusterSize(i+k));
351 C -= T.block(blockStart(i), blockStart(m), clusterSize(i), clusterSize(m))
352 * fT.block(blockStart(m), blockStart(i+k), clusterSize(m), clusterSize(i+k));
354 fT.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k))
375 template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>
388 template <
typename AtomicType,
typename ResultType>
389 static void run(
const MatrixType& A, AtomicType& atomic, ResultType &result);
398 template <
typename MatrixType>
401 template <
typename AtomicType,
typename ResultType>
402 static void run(
const MatrixType& A, AtomicType& atomic, ResultType &result)
405 typedef typename Traits::Scalar Scalar;
406 static const int Rows = Traits::RowsAtCompileTime, Cols = Traits::ColsAtCompileTime;
407 static const int MaxRows = Traits::MaxRowsAtCompileTime, MaxCols = Traits::MaxColsAtCompileTime;
409 typedef std::complex<Scalar> ComplexScalar;
412 ComplexMatrix CA = A.template cast<ComplexScalar>();
413 ComplexMatrix Cresult;
415 result = Cresult.real();
422 template <
typename MatrixType>
425 template <
typename AtomicType,
typename ResultType>
426 static void run(
const MatrixType& A, AtomicType& atomic, ResultType &result)
429 typedef typename MatrixType::Index
Index;
434 MatrixType U = schurOfA.
matrixU();
437 std::list<std::list<Index> > clusters;
463 result = U * (fT.template triangularView<Upper>() * U.adjoint());
483 typedef typename Derived::Scalar Scalar;
484 typedef typename Derived::Index
Index;
503 template <
typename ResultType>
504 inline void evalTo(ResultType& result)
const 509 static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
510 static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
511 typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
515 AtomicType atomic(m_f);
520 Index rows()
const {
return m_A.rows(); }
521 Index cols()
const {
return m_A.cols(); }
524 const DerivedNested m_A;
529 template<
typename Derived>
532 typedef typename Derived::PlainObject ReturnType;
540 template <
typename Derived>
543 eigen_assert(rows() == cols());
547 template <
typename Derived>
550 eigen_assert(rows() == cols());
551 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
555 template <
typename Derived>
558 eigen_assert(rows() == cols());
559 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
563 template <
typename Derived>
566 eigen_assert(rows() == cols());
567 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
571 template <
typename Derived>
574 eigen_assert(rows() == cols());
575 typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
581 #endif // EIGEN_MATRIX_FUNCTION void matrix_function_compute_permutation(const DynVectorType &blockStart, const DynVectorType &eivalToCluster, VectorType &permutation)
Compute permutation which groups ei'vals in same cluster together.
Definition: MatrixFunction.h:206
void matrix_function_compute_map(const EivalsType &eivals, const ListOfClusters &clusters, VectorType &eivalToCluster)
Compute mapping of eigenvalue indices to cluster indices.
Definition: MatrixFunction.h:189
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:149
MatrixType compute(const MatrixType &A)
Compute matrix function of atomic matrix.
Definition: MatrixFunction.h:64
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:85
Definition: ForwardDeclarations.h:263
Holds information about the various numeric (i.e.
Definition: NumTraits.h:150
Proxy for the matrix function of some matrix (expression).
Definition: ForwardDeclarations.h:285
Definition: ReturnByValue.h:50
void matrix_function_compute_block_start(const VectorType &clusterSize, VectorType &blockStart)
Compute start of each block using clusterSize.
Definition: MatrixFunction.h:178
MatrixFunctionReturnValue(const Derived &A, StemFunction f)
Constructor.
Definition: MatrixFunction.h:497
void matrix_function_compute_block_atomic(const MatrixType &T, AtomicType &atomic, const VectorType &blockStart, const VectorType &clusterSize, MatrixType &fT)
Compute block diagonal part of matrix function.
Definition: MatrixFunction.h:247
void matrix_function_partition_eigenvalues(const EivalsType &eivals, std::list< Cluster > &clusters)
Partition eigenvalues in clusters of ei'vals close to each other.
Definition: MatrixFunction.h:132
ListOfClusters::iterator matrix_function_find_cluster(Index key, ListOfClusters &clusters)
Find cluster in clusters containing some value.
Definition: MatrixFunction.h:109
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
Class for computing matrix functions.
Definition: MatrixFunction.h:376
Definition: ForwardDeclarations.h:293
void matrix_function_compute_cluster_size(const ListOfClusters &clusters, Matrix< Index, Dynamic, 1 > &clusterSize)
Compute size of each cluster given a partitioning.
Definition: MatrixFunction.h:165
EIGEN_DEVICE_FUNC Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > & setZero(Index size)
Resizes to the given size, and sets all coefficients in this expression to zero.
Definition: CwiseNullaryOp.h:515
MatrixFunctionAtomic(StemFunction f)
Constructor.
Definition: MatrixFunction.h:40
void matrix_function_permute_schur(VectorType &permutation, MatrixType &U, MatrixType &T)
Permute Schur decomposition in U and T according to permutation.
Definition: MatrixFunction.h:220
A small structure to hold a non zero as a triplet (i,j,value).
Definition: SparseUtil.h:154
Definition: BandTriangularSolver.h:13
Definition: XprHelper.h:585
const ComplexMatrixType & matrixU() const
Returns the unitary matrix in the Schur decomposition.
Definition: ComplexSchur.h:138
void matrix_function_compute_above_diagonal(const MatrixType &T, const VectorType &blockStart, const VectorType &clusterSize, MatrixType &fT)
Compute part of matrix function above block diagonal.
Definition: MatrixFunction.h:329
static void run(const MatrixType &A, AtomicType &atomic, ResultType &result)
Compute the matrix function.
Helper class for computing matrix functions of atomic matrices.
Definition: MatrixFunction.h:30
void evalTo(ResultType &result) const
Compute the matrix function.
Definition: MatrixFunction.h:504
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:55
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:178
MatrixType matrix_function_solve_triangular_sylvester(const MatrixType &A, const MatrixType &B, const MatrixType &C)
Solve a triangular Sylvester equation AX + XB = C.
Definition: MatrixFunction.h:279
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:162
JacobiRotation adjoint() const
Returns the adjoint transformation.
Definition: Jacobi.h:62