Eigen::MatrixPowerAtomic< MatrixType > Class Template Reference

Class for computing matrix powers. More...

#include <MatrixPower.h>

+ Inheritance diagram for Eigen::MatrixPowerAtomic< MatrixType >:

Public Member Functions

 MatrixPowerAtomic (const MatrixType &T, RealScalar p)
 Constructor. More...
 
void compute (ResultType &res) const
 Compute the matrix power. More...
 

Private Types

enum  { RowsAtCompileTime = MatrixType::RowsAtCompileTime , MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime }
 
typedef MatrixType::Scalar Scalar
 
typedef MatrixType::RealScalar RealScalar
 
typedef std::complex< RealScalarComplexScalar
 
typedef Block< MatrixType, Dynamic, DynamicResultType
 

Private Member Functions

void computePade (int degree, const MatrixType &IminusT, ResultType &res) const
 
void compute2x2 (ResultType &res, RealScalar p) const
 
void computeBig (ResultType &res) const
 
- Private Member Functions inherited from Eigen::internal::noncopyable
EIGEN_DEVICE_FUNC noncopyable ()
 
EIGEN_DEVICE_FUNC ~noncopyable ()
 

Static Private Member Functions

static int getPadeDegree (float normIminusT)
 
static int getPadeDegree (double normIminusT)
 
static int getPadeDegree (long double normIminusT)
 
static ComplexScalar computeSuperDiag (const ComplexScalar &, const ComplexScalar &, RealScalar p)
 
static RealScalar computeSuperDiag (RealScalar, RealScalar, RealScalar p)
 

Private Attributes

const MatrixTypem_A
 
RealScalar m_p
 

Detailed Description

template<typename MatrixType>
class Eigen::MatrixPowerAtomic< MatrixType >

Class for computing matrix powers.

Template Parameters
MatrixTypetype of the base, expected to be an instantiation of the Matrix class template.

This class is capable of computing triangular real/complex matrices raised to a power in the interval \( (-1, 1) \).

Note
Currently this class is only used by MatrixPower. One may insist that this be nested into MatrixPower. This class is here to facilitate future development of triangular matrix functions.

Member Typedef Documentation

◆ ComplexScalar

template<typename MatrixType >
typedef std::complex<RealScalar> Eigen::MatrixPowerAtomic< MatrixType >::ComplexScalar
private

◆ RealScalar

template<typename MatrixType >
typedef MatrixType::RealScalar Eigen::MatrixPowerAtomic< MatrixType >::RealScalar
private

◆ ResultType

template<typename MatrixType >
typedef Block<MatrixType, Dynamic, Dynamic> Eigen::MatrixPowerAtomic< MatrixType >::ResultType
private

◆ Scalar

template<typename MatrixType >
typedef MatrixType::Scalar Eigen::MatrixPowerAtomic< MatrixType >::Scalar
private

Member Enumeration Documentation

◆ anonymous enum

template<typename MatrixType >
anonymous enum
private
Enumerator
RowsAtCompileTime 
MaxRowsAtCompileTime 
91 { RowsAtCompileTime = MatrixType::RowsAtCompileTime, MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime };
@ RowsAtCompileTime
Definition: MatrixPower.h:91
@ MaxRowsAtCompileTime
Definition: MatrixPower.h:91

Constructor & Destructor Documentation

◆ MatrixPowerAtomic()

template<typename MatrixType >
Eigen::MatrixPowerAtomic< MatrixType >::MatrixPowerAtomic ( const MatrixType T,
RealScalar  p 
)

Constructor.

Parameters
[in]Tthe base of the matrix power.
[in]pthe exponent of the matrix power, should be in \( (-1, 1) \).

The class stores a reference to T, so it should not be changed (or destroyed) before evaluation. Only the upper triangular part of T is read.

133  : m_A(T), m_p(p) {
134  eigen_assert(T.rows() == T.cols());
135  eigen_assert(p > -1 && p < 1);
136 }
#define eigen_assert(x)
Definition: Macros.h:910
float * p
Definition: Tutorial_Map_using.cpp:9
RealScalar m_p
Definition: MatrixPower.h:98
const MatrixType & m_A
Definition: MatrixPower.h:97

References eigen_assert, and p.

Member Function Documentation

◆ compute()

template<typename MatrixType >
void Eigen::MatrixPowerAtomic< MatrixType >::compute ( ResultType res) const

Compute the matrix power.

Parameters
[out]res\( A^p \) where A and p are specified in the constructor.
139  {
140  using std::pow;
141  switch (m_A.rows()) {
142  case 0:
143  break;
144  case 1:
145  res(0, 0) = pow(m_A(0, 0), m_p);
146  break;
147  case 2:
148  compute2x2(res, m_p);
149  break;
150  default:
151  computeBig(res);
152  }
153 }
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
void compute2x2(ResultType &res, RealScalar p) const
Definition: MatrixPower.h:174
void computeBig(ResultType &res) const
Definition: MatrixPower.h:194
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625

References Eigen::bfloat16_impl::pow(), and res.

Referenced by Eigen::MatrixPower< MatrixType >::computeFracPower().

◆ compute2x2()

template<typename MatrixType >
void Eigen::MatrixPowerAtomic< MatrixType >::compute2x2 ( ResultType res,
RealScalar  p 
) const
private
174  {
175  using std::abs;
176  using std::pow;
177  res.coeffRef(0, 0) = pow(m_A.coeff(0, 0), p);
178 
179  for (Index i = 1; i < m_A.cols(); ++i) {
180  res.coeffRef(i, i) = pow(m_A.coeff(i, i), p);
181  if (m_A.coeff(i - 1, i - 1) == m_A.coeff(i, i))
182  res.coeffRef(i - 1, i) = p * pow(m_A.coeff(i, i), p - 1);
183  else if (2 * abs(m_A.coeff(i - 1, i - 1)) < abs(m_A.coeff(i, i)) ||
184  2 * abs(m_A.coeff(i, i)) < abs(m_A.coeff(i - 1, i - 1)))
185  res.coeffRef(i - 1, i) =
186  (res.coeff(i, i) - res.coeff(i - 1, i - 1)) / (m_A.coeff(i, i) - m_A.coeff(i - 1, i - 1));
187  else
188  res.coeffRef(i - 1, i) = computeSuperDiag(m_A.coeff(i, i), m_A.coeff(i - 1, i - 1), p);
189  res.coeffRef(i - 1, i) *= m_A.coeff(i - 1, i);
190  }
191 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
int i
Definition: BiCGSTAB_step_by_step.cpp:9
static ComplexScalar computeSuperDiag(const ComplexScalar &, const ComplexScalar &, RealScalar p)
Definition: MatrixPower.h:293
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83

References abs(), i, p, Eigen::bfloat16_impl::pow(), and res.

◆ computeBig()

template<typename MatrixType >
void Eigen::MatrixPowerAtomic< MatrixType >::computeBig ( ResultType res) const
private
194  {
195  using std::ldexp;
196  const int digits = std::numeric_limits<RealScalar>::digits;
197  const RealScalar maxNormForPade =
198  RealScalar(digits <= 24 ? 4.3386528e-1L // single precision
199  : digits <= 53 ? 2.789358995219730e-1L // double precision
200  : digits <= 64 ? 2.4471944416607995472e-1L // extended precision
201  : digits <= 106 ? 1.1016843812851143391275867258512e-1L // double-double
202  : 9.134603732914548552537150753385375e-2L); // quadruple precision
203  MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();
204  RealScalar normIminusT;
205  int degree, degree2, numberOfSquareRoots = 0;
206  bool hasExtraSquareRoot = false;
207 
208  for (Index i = 0; i < m_A.cols(); ++i) eigen_assert(m_A(i, i) != RealScalar(0));
209 
210  while (true) {
211  IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;
212  normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();
213  if (normIminusT < maxNormForPade) {
214  degree = getPadeDegree(normIminusT);
215  degree2 = getPadeDegree(normIminusT / 2);
216  if (degree - degree2 <= 1 || hasExtraSquareRoot) break;
217  hasExtraSquareRoot = true;
218  }
219  matrix_sqrt_triangular(T, sqrtT);
220  T = sqrtT.template triangularView<Upper>();
221  ++numberOfSquareRoots;
222  }
223  computePade(degree, IminusT, res);
224 
225  for (; numberOfSquareRoots; --numberOfSquareRoots) {
226  compute2x2(res, ldexp(m_p, -numberOfSquareRoots));
227  res = res.template triangularView<Upper>() * res;
228  }
229  compute2x2(res, m_p);
230 }
Eigen::Triplet< double > T
Definition: EigenUnitTest.cpp:11
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
void computePade(int degree, const MatrixType &IminusT, ResultType &res) const
Definition: MatrixPower.h:156
static int getPadeDegree(float normIminusT)
Definition: MatrixPower.h:233
MatrixType::RealScalar RealScalar
Definition: MatrixPower.h:93
void matrix_sqrt_triangular(const MatrixType &arg, ResultType &result)
Compute matrix square root of triangular matrix.
Definition: MatrixSquareRoot.h:194
const Mdouble degree
Definition: ExtendedMath.h:32

References constants::degree, eigen_assert, i, Eigen::matrix_sqrt_triangular(), and res.

◆ computePade()

template<typename MatrixType >
void Eigen::MatrixPowerAtomic< MatrixType >::computePade ( int  degree,
const MatrixType IminusT,
ResultType res 
) const
private
156  {
157  int i = 2 * degree;
158  res = (m_p - RealScalar(degree)) / RealScalar(2 * i - 2) * IminusT;
159 
160  for (--i; i; --i) {
161  res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res)
162  .template triangularView<Upper>()
163  .solve((i == 1 ? -m_p
164  : i & 1 ? (-m_p - RealScalar(i / 2)) / RealScalar(2 * i)
165  : (m_p - RealScalar(i / 2)) / RealScalar(2 * i - 2)) *
166  IminusT)
167  .eval();
168  }
169  res += MatrixType::Identity(IminusT.rows(), IminusT.cols());
170 }
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Definition: sparse_permutations.cpp:47

References constants::degree, eval(), i, and res.

◆ computeSuperDiag() [1/2]

template<typename MatrixType >
MatrixPowerAtomic< MatrixType >::ComplexScalar Eigen::MatrixPowerAtomic< MatrixType >::computeSuperDiag ( const ComplexScalar curr,
const ComplexScalar prev,
RealScalar  p 
)
inlinestaticprivate
294  {
295  using std::ceil;
296  using std::exp;
297  using std::log;
298  using std::sinh;
299 
300  ComplexScalar logCurr = log(curr);
301  ComplexScalar logPrev = log(prev);
302  RealScalar unwindingNumber =
303  ceil((numext::imag(logCurr - logPrev) - RealScalar(EIGEN_PI)) / RealScalar(2 * EIGEN_PI));
304  ComplexScalar w =
305  numext::log1p((curr - prev) / prev) / RealScalar(2) + ComplexScalar(0, RealScalar(EIGEN_PI) * unwindingNumber);
306  return RealScalar(2) * exp(RealScalar(0.5) * p * (logCurr + logPrev)) * sinh(p * w) / (curr - prev);
307 }
AnnoyingScalar imag(const AnnoyingScalar &)
Definition: AnnoyingScalar.h:132
#define EIGEN_PI
Definition: MathFunctions.h:16
RowVector3d w
Definition: Matrix_resize_int.cpp:3
std::complex< RealScalar > ComplexScalar
Definition: MatrixPower.h:94
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 ceil(const bfloat16 &a)
Definition: BFloat16.h:644
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp(const bfloat16 &a)
Definition: BFloat16.h:615
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log(const bfloat16 &a)
Definition: BFloat16.h:618
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 sinh(const bfloat16 &a)
Definition: BFloat16.h:637
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log1p(const bfloat16 &a)
Definition: BFloat16.h:619

References Eigen::bfloat16_impl::ceil(), EIGEN_PI, Eigen::bfloat16_impl::exp(), imag(), Eigen::bfloat16_impl::log(), Eigen::bfloat16_impl::log1p(), p, Eigen::bfloat16_impl::sinh(), and w.

◆ computeSuperDiag() [2/2]

template<typename MatrixType >
MatrixPowerAtomic< MatrixType >::RealScalar Eigen::MatrixPowerAtomic< MatrixType >::computeSuperDiag ( RealScalar  curr,
RealScalar  prev,
RealScalar  p 
)
inlinestaticprivate
311  {
312  using std::exp;
313  using std::log;
314  using std::sinh;
315 
316  RealScalar w = numext::log1p((curr - prev) / prev) / RealScalar(2);
317  return 2 * exp(p * (log(curr) + log(prev)) / 2) * sinh(p * w) / (curr - prev);
318 }

References Eigen::bfloat16_impl::exp(), Eigen::bfloat16_impl::log(), Eigen::bfloat16_impl::log1p(), p, Eigen::bfloat16_impl::sinh(), and w.

◆ getPadeDegree() [1/3]

template<typename MatrixType >
int Eigen::MatrixPowerAtomic< MatrixType >::getPadeDegree ( double  normIminusT)
inlinestaticprivate
242  {
243  const double maxNormForPade[] = {1.884160592658218e-2 /* degree = 3 */, 6.038881904059573e-2, 1.239917516308172e-1,
244  1.999045567181744e-1, 2.789358995219730e-1};
245  int degree = 3;
246  for (; degree <= 7; ++degree)
247  if (normIminusT <= maxNormForPade[degree - 3]) break;
248  return degree;
249 }

References constants::degree.

◆ getPadeDegree() [2/3]

template<typename MatrixType >
int Eigen::MatrixPowerAtomic< MatrixType >::getPadeDegree ( float  normIminusT)
inlinestaticprivate
233  {
234  const float maxNormForPade[] = {2.8064004e-1f /* degree = 3 */, 4.3386528e-1f};
235  int degree = 3;
236  for (; degree <= 4; ++degree)
237  if (normIminusT <= maxNormForPade[degree - 3]) break;
238  return degree;
239 }

References constants::degree.

◆ getPadeDegree() [3/3]

template<typename MatrixType >
int Eigen::MatrixPowerAtomic< MatrixType >::getPadeDegree ( long double  normIminusT)
inlinestaticprivate
252  {
253 #if LDBL_MANT_DIG == 53
254  const int maxPadeDegree = 7;
255  const double maxNormForPade[] = {1.884160592658218e-2L /* degree = 3 */, 6.038881904059573e-2L, 1.239917516308172e-1L,
256  1.999045567181744e-1L, 2.789358995219730e-1L};
257 #elif LDBL_MANT_DIG <= 64
258  const int maxPadeDegree = 8;
259  const long double maxNormForPade[] = {6.3854693117491799460e-3L /* degree = 3 */,
260  2.6394893435456973676e-2L,
261  6.4216043030404063729e-2L,
262  1.1701165502926694307e-1L,
263  1.7904284231268670284e-1L,
264  2.4471944416607995472e-1L};
265 #elif LDBL_MANT_DIG <= 106
266  const int maxPadeDegree = 10;
267  const double maxNormForPade[] = {1.0007161601787493236741409687186e-4L /* degree = 3 */,
268  1.0007161601787493236741409687186e-3L,
269  4.7069769360887572939882574746264e-3L,
270  1.3220386624169159689406653101695e-2L,
271  2.8063482381631737920612944054906e-2L,
272  4.9625993951953473052385361085058e-2L,
273  7.7367040706027886224557538328171e-2L,
274  1.1016843812851143391275867258512e-1L};
275 #else
276  const int maxPadeDegree = 10;
277  const double maxNormForPade[] = {5.524506147036624377378713555116378e-5L /* degree = 3 */,
278  6.640600568157479679823602193345995e-4L,
279  3.227716520106894279249709728084626e-3L,
280  9.619593944683432960546978734646284e-3L,
281  2.134595382433742403911124458161147e-2L,
282  3.908166513900489428442993794761185e-2L,
283  6.266780814639442865832535460550138e-2L,
284  9.134603732914548552537150753385375e-2L};
285 #endif
286  int degree = 3;
287  for (; degree <= maxPadeDegree; ++degree)
288  if (normIminusT <= static_cast<long double>(maxNormForPade[degree - 3])) break;
289  return degree;
290 }

References constants::degree.

Member Data Documentation

◆ m_A

template<typename MatrixType >
const MatrixType& Eigen::MatrixPowerAtomic< MatrixType >::m_A
private

◆ m_p

template<typename MatrixType >
RealScalar Eigen::MatrixPowerAtomic< MatrixType >::m_p
private

The documentation for this class was generated from the following file: