10#ifndef EIGEN_MATRIX_FUNCTION_H
11#define EIGEN_MATRIX_FUNCTION_H
29template <
typename MatrixType>
34 typedef typename MatrixType::Scalar
Scalar;
46 MatrixType
compute(
const MatrixType& A);
52template <
typename MatrixType>
56 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();
63template <
typename MatrixType>
68 Index rows = A.rows();
70 MatrixType Ashifted = A - avgEival * MatrixType::Identity(rows, rows);
72 MatrixType
F = m_f(avgEival, 0) * MatrixType::Identity(rows, rows);
73 MatrixType P = Ashifted;
75 for (
Index s = 1; double(s) < 1.1 * double(rows) + 10.0; s++) {
76 Fincr = m_f(avgEival,
static_cast<int>(s)) * P;
78 P =
Scalar(RealScalar(1)/RealScalar(s + 1)) * P * Ashifted;
81 const RealScalar F_norm =
F.cwiseAbs().rowwise().sum().maxCoeff();
82 const RealScalar Fincr_norm = Fincr.cwiseAbs().rowwise().sum().maxCoeff();
85 RealScalar rfactorial = 1;
86 for (
Index r = 0; r < rows; r++) {
88 for (
Index i = 0; i < rows; i++)
89 mx = (
std::max)(mx,
std::abs(m_f(Ashifted(i, i) + avgEival,
static_cast<int>(s+r))));
91 rfactorial *= RealScalar(r);
92 delta = (
std::max)(delta, mx / rfactorial);
94 const RealScalar P_norm = P.cwiseAbs().rowwise().sum().maxCoeff();
107template <
typename Index,
typename ListOfClusters>
110 typename std::list<Index>::iterator j;
111 for (
typename ListOfClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
112 j =
std::find(i->begin(), i->end(), key);
116 return clusters.end();
130template <
typename EivalsType,
typename Cluster>
133 typedef typename EivalsType::RealScalar RealScalar;
134 for (
Index i=0; i<eivals.rows(); ++i) {
137 if (qi == clusters.end()) {
140 clusters.push_back(l);
146 for (
Index j=i+1; j<eivals.rows(); ++j) {
148 &&
std::find(qi->begin(), qi->end(), j) == qi->end()) {
150 if (qj == clusters.end()) {
153 qi->insert(qi->end(), qj->begin(), qj->end());
162template <
typename ListOfClusters,
typename Index>
165 const Index numClusters =
static_cast<Index>(clusters.size());
166 clusterSize.
setZero(numClusters);
167 Index clusterIndex = 0;
168 for (
typename ListOfClusters::const_iterator cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
169 clusterSize[clusterIndex] = cluster->size();
175template <
typename VectorType>
178 blockStart.resize(clusterSize.rows());
180 for (
Index i = 1; i < clusterSize.rows(); i++) {
181 blockStart(i) = blockStart(i-1) + clusterSize(i-1);
186template <
typename EivalsType,
typename ListOfClusters,
typename VectorType>
189 eivalToCluster.resize(eivals.rows());
190 Index clusterIndex = 0;
191 for (
typename ListOfClusters::const_iterator cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
192 for (
Index i = 0; i < eivals.rows(); ++i) {
193 if (
std::find(cluster->begin(), cluster->end(), i) != cluster->end()) {
194 eivalToCluster[i] = clusterIndex;
202template <
typename DynVectorType,
typename VectorType>
205 DynVectorType indexNextEntry = blockStart;
206 permutation.resize(eivalToCluster.rows());
207 for (
Index i = 0; i < eivalToCluster.rows(); i++) {
208 Index cluster = eivalToCluster[i];
209 permutation[i] = indexNextEntry[cluster];
210 ++indexNextEntry[cluster];
215template <
typename VectorType,
typename MatrixType>
218 for (
Index i = 0; i < permutation.rows() - 1; i++) {
220 for (j = i; j < permutation.rows(); j++) {
221 if (permutation(j) == i)
break;
224 for (
Index k = j-1; k >= i; k--) {
226 rotation.
makeGivens(T(k, k+1), T(k+1, k+1) - T(k, k));
227 T.applyOnTheLeft(k, k+1, rotation.
adjoint());
228 T.applyOnTheRight(k, k+1, rotation);
229 U.applyOnTheRight(k, k+1, rotation);
230 std::swap(permutation.coeffRef(k), permutation.coeffRef(k+1));
241template <
typename MatrixType,
typename AtomicType,
typename VectorType>
244 fT.setZero(T.rows(), T.cols());
245 for (
Index i = 0; i < clusterSize.rows(); ++i) {
246 fT.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i))
247 = atomic.compute(T.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i)));
273template <
typename MatrixType>
283 typedef typename MatrixType::Scalar Scalar;
289 for (
Index i = m - 1; i >= 0; --i) {
290 for (
Index j = 0; j < n; ++j) {
310 X(i,j) = (C(i,j) - AX - XB) / (A(i,i) + B(j,j));
322template <
typename MatrixType,
typename VectorType>
326 typedef typename MatrixType::Scalar Scalar;
327 static const int Options = MatrixType::Options;
330 for (
Index k = 1; k < clusterSize.rows(); k++) {
331 for (
Index i = 0; i < clusterSize.rows() - k; i++) {
333 DynMatrixType A = T.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i));
334 DynMatrixType B = -T.block(blockStart(i+k), blockStart(i+k), clusterSize(i+k), clusterSize(i+k));
335 DynMatrixType C = fT.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i))
336 * T.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k));
337 C -= T.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k))
338 * fT.block(blockStart(i+k), blockStart(i+k), clusterSize(i+k), clusterSize(i+k));
339 for (
Index m = i + 1; m < i + k; m++) {
340 C += fT.block(blockStart(i), blockStart(m), clusterSize(i), clusterSize(m))
341 * T.block(blockStart(m), blockStart(i+k), clusterSize(m), clusterSize(i+k));
342 C -= T.block(blockStart(i), blockStart(m), clusterSize(i), clusterSize(m))
343 * fT.block(blockStart(m), blockStart(i+k), clusterSize(m), clusterSize(i+k));
345 fT.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k))
366template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>
379 template <
typename AtomicType,
typename ResultType>
380 static void run(
const MatrixType& A, AtomicType& atomic, ResultType &
result);
389template <
typename MatrixType>
392 template <
typename MatA,
typename AtomicType,
typename ResultType>
393 static void run(
const MatA& A, AtomicType& atomic, ResultType &
result)
396 typedef typename Traits::Scalar Scalar;
397 static const int Rows = Traits::RowsAtCompileTime, Cols = Traits::ColsAtCompileTime;
398 static const int MaxRows = Traits::MaxRowsAtCompileTime, MaxCols = Traits::MaxColsAtCompileTime;
400 typedef std::complex<Scalar> ComplexScalar;
403 ComplexMatrix CA = A.template cast<ComplexScalar>();
404 ComplexMatrix Cresult;
413template <
typename MatrixType>
416 template <
typename MatA,
typename AtomicType,
typename ResultType>
417 static void run(
const MatA& A, AtomicType& atomic, ResultType &
result)
424 MatrixType T = schurOfA.
matrixT();
425 MatrixType U = schurOfA.
matrixU();
428 std::list<std::list<Index> > clusters;
454 result = U * (fT.template triangularView<Upper>() * U.adjoint());
493 template <
typename ResultType>
499 typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
503 AtomicType atomic(m_f);
517template<
typename Derived>
528template <
typename Derived>
535template <
typename Derived>
543template <
typename Derived>
548 return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_cos<ComplexScalar>);
551template <
typename Derived>
556 return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_sinh<ComplexScalar>);
559template <
typename Derived>
564 return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_cosh<ComplexScalar>);
#define eigen_assert(x)
Definition: Macros.h:1047
const ComplexMatrixType & matrixT() const
Returns the triangular matrix in the Schur decomposition.
Definition: ComplexSchur.h:162
const ComplexMatrixType & matrixU() const
Returns the unitary matrix in the Schur decomposition.
Definition: ComplexSchur.h:138
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: ComplexSchur.h:217
\jacobi_module
Definition: Jacobi.h:35
EIGEN_DEVICE_FUNC void makeGivens(const Scalar &p, const Scalar &q, Scalar *r=0)
Makes *this as a Givens rotation G such that applying to the left of the vector yields: .
Definition: Jacobi.h:162
EIGEN_DEVICE_FUNC JacobiRotation adjoint() const
Returns the adjoint transformation.
Definition: Jacobi.h:67
const MatrixFunctionReturnValue< Derived > matrixFunction(StemFunction f) const
Helper function for the unsupported MatrixFunctions module.
Definition: MatrixFunction.h:529
Proxy for the matrix function of some matrix (expression).
Definition: MatrixFunction.h:472
internal::ref_selector< Derived >::type DerivedNested
Definition: MatrixFunction.h:478
Index rows() const
Definition: MatrixFunction.h:508
internal::stem_function< Scalar >::type StemFunction
Definition: MatrixFunction.h:475
void evalTo(ResultType &result) const
Compute the matrix function.
Definition: MatrixFunction.h:494
Index cols() const
Definition: MatrixFunction.h:509
Derived::Scalar Scalar
Definition: MatrixFunction.h:474
MatrixFunctionReturnValue(const Derived &A, StemFunction f)
Constructor.
Definition: MatrixFunction.h:487
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:180
EIGEN_DEVICE_FUNC Derived & setZero(Index size)
Resizes to the given size, and sets all coefficients in this expression to zero.
Definition: CwiseNullaryOp.h:562
Definition: ReturnByValue.h:52
Helper class for computing matrix functions of atomic matrices.
Definition: MatrixFunction.h:31
MatrixFunctionAtomic(StemFunction f)
Constructor.
Definition: MatrixFunction.h:40
MatrixType::Scalar Scalar
Definition: MatrixFunction.h:34
MatrixType compute(const MatrixType &A)
Compute matrix function of atomic matrix.
Definition: MatrixFunction.h:64
stem_function< Scalar >::type StemFunction
Definition: MatrixFunction.h:35
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2325
type
Definition: core.h:575
UnitType abs(const UnitType x) noexcept
Compute absolute value.
Definition: math.h:721
dimensionless::scalar_t sinh(const AngleUnit angle) noexcept
Compute hyperbolic sine.
Definition: math.h:226
dimensionless::scalar_t cosh(const AngleUnit angle) noexcept
Compute hyperbolic cosine.
Definition: math.h:206
dimensionless::scalar_t cos(const AngleUnit angle) noexcept
Compute cosine.
Definition: math.h:61
dimensionless::scalar_t sin(const AngleUnit angle) noexcept
Compute sine.
Definition: math.h:81
@ Success
Computation was successful.
Definition: Constants.h:442
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
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:203
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:163
void matrix_function_compute_block_start(const VectorType &clusterSize, VectorType &blockStart)
Compute start of each block using clusterSize.
Definition: MatrixFunction.h:176
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:242
void matrix_function_permute_schur(VectorType &permutation, MatrixType &U, MatrixType &T)
Permute Schur decomposition in U and T according to permutation.
Definition: MatrixFunction.h:216
static const float matrix_function_separation
Maximum distance allowed between eigenvalues to be considered "close".
Definition: MatrixFunction.h:21
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:323
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:131
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:274
void matrix_function_compute_map(const EivalsType &eivals, const ListOfClusters &clusters, VectorType &eivalToCluster)
Compute mapping of eigenvalue indices to cluster indices.
Definition: MatrixFunction.h:187
NumTraits< typenameMatrixType::Scalar >::Real matrix_function_compute_mu(const MatrixType &A)
Definition: MatrixFunction.h:53
ListOfClusters::iterator matrix_function_find_cluster(Index key, ListOfClusters &clusters)
Find cluster in clusters containing some value.
Definition: MatrixFunction.h:108
Namespace containing all symbols from the Eigen library.
Definition: Core:141
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
result
Definition: format.h:2564
Definition: Eigen_Colamd.h:50
void swap(wpi::SmallPtrSet< T, N > &LHS, wpi::SmallPtrSet< T, N > &RHS)
Implement std::swap in terms of SmallPtrSet swap.
Definition: SmallPtrSet.h:512
static constexpr const unit_t< compound_unit< charge::coulomb, inverse< substance::mol > > > F(N_A *e)
Faraday constant.
static constexpr const charge::coulomb_t e(1.6021766208e-19)
elementary charge.
T Real
Definition: NumTraits.h:164
Holds information about the various numeric (i.e.
Definition: NumTraits.h:233
static void run(const MatA &A, AtomicType &atomic, ResultType &result)
Definition: MatrixFunction.h:393
static void run(const MatA &A, AtomicType &atomic, ResultType &result)
Definition: MatrixFunction.h:417
Class for computing matrix functions.
Definition: MatrixFunction.h:368
static void run(const MatrixType &A, AtomicType &atomic, ResultType &result)
Compute the matrix function.
Definition: XprHelper.h:615
T type
Definition: Meta.h:126
Definition: ForwardDeclarations.h:314
std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
Definition: ForwardDeclarations.h:315
Derived::PlainObject ReturnType
Definition: MatrixFunction.h:520