Eigen-unsupported  3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)
MatrixPower.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2012, 2013 Chen-Pang He <jdh8@ms63.hinet.net>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_MATRIX_POWER
11 #define EIGEN_MATRIX_POWER
12 
13 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 template<typename MatrixType> class MatrixPower;
18 
32 /* TODO This class is only used by MatrixPower, so it should be nested
33  * into MatrixPower, like MatrixPower::ReturnValue. However, my
34  * compiler complained about unused template parameter in the
35  * following declaration in namespace internal.
36  *
37  * template<typename MatrixType>
38  * struct traits<MatrixPower<MatrixType>::ReturnValue>;
39  */
40 template<typename MatrixType>
41 class MatrixPowerParenthesesReturnValue : public ReturnByValue< MatrixPowerParenthesesReturnValue<MatrixType> >
42 {
43  public:
44  typedef typename MatrixType::RealScalar RealScalar;
45 
52  MatrixPowerParenthesesReturnValue(MatrixPower<MatrixType>& pow, RealScalar p) : m_pow(pow), m_p(p)
53  { }
54 
60  template<typename ResultType>
61  inline void evalTo(ResultType& result) const
62  { m_pow.compute(result, m_p); }
63 
64  Index rows() const { return m_pow.rows(); }
65  Index cols() const { return m_pow.cols(); }
66 
67  private:
68  MatrixPower<MatrixType>& m_pow;
69  const RealScalar m_p;
70 };
71 
87 template<typename MatrixType>
88 class MatrixPowerAtomic : internal::noncopyable
89 {
90  private:
91  enum {
92  RowsAtCompileTime = MatrixType::RowsAtCompileTime,
93  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
94  };
95  typedef typename MatrixType::Scalar Scalar;
96  typedef typename MatrixType::RealScalar RealScalar;
97  typedef std::complex<RealScalar> ComplexScalar;
99 
100  const MatrixType& m_A;
101  RealScalar m_p;
102 
103  void computePade(int degree, const MatrixType& IminusT, ResultType& res) const;
104  void compute2x2(ResultType& res, RealScalar p) const;
105  void computeBig(ResultType& res) const;
106  static int getPadeDegree(float normIminusT);
107  static int getPadeDegree(double normIminusT);
108  static int getPadeDegree(long double normIminusT);
109  static ComplexScalar computeSuperDiag(const ComplexScalar&, const ComplexScalar&, RealScalar p);
110  static RealScalar computeSuperDiag(RealScalar, RealScalar, RealScalar p);
111 
112  public:
124  MatrixPowerAtomic(const MatrixType& T, RealScalar p);
125 
132  void compute(ResultType& res) const;
133 };
134 
135 template<typename MatrixType>
136 MatrixPowerAtomic<MatrixType>::MatrixPowerAtomic(const MatrixType& T, RealScalar p) :
137  m_A(T), m_p(p)
138 {
139  eigen_assert(T.rows() == T.cols());
140  eigen_assert(p > -1 && p < 1);
141 }
142 
143 template<typename MatrixType>
145 {
146  using std::pow;
147  switch (m_A.rows()) {
148  case 0:
149  break;
150  case 1:
151  res(0,0) = pow(m_A(0,0), m_p);
152  break;
153  case 2:
154  compute2x2(res, m_p);
155  break;
156  default:
157  computeBig(res);
158  }
159 }
160 
161 template<typename MatrixType>
162 void MatrixPowerAtomic<MatrixType>::computePade(int degree, const MatrixType& IminusT, ResultType& res) const
163 {
164  int i = 2*degree;
165  res = (m_p-RealScalar(degree)) / RealScalar(2*i-2) * IminusT;
166 
167  for (--i; i; --i) {
168  res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res).template triangularView<Upper>()
169  .solve((i==1 ? -m_p : i&1 ? (-m_p-RealScalar(i/2))/RealScalar(2*i) : (m_p-RealScalar(i/2))/RealScalar(2*i-2)) * IminusT).eval();
170  }
171  res += MatrixType::Identity(IminusT.rows(), IminusT.cols());
172 }
173 
174 // This function assumes that res has the correct size (see bug 614)
175 template<typename MatrixType>
176 void MatrixPowerAtomic<MatrixType>::compute2x2(ResultType& res, RealScalar p) const
177 {
178  using std::abs;
179  using std::pow;
180  res.coeffRef(0,0) = pow(m_A.coeff(0,0), p);
181 
182  for (Index i=1; i < m_A.cols(); ++i) {
183  res.coeffRef(i,i) = pow(m_A.coeff(i,i), p);
184  if (m_A.coeff(i-1,i-1) == m_A.coeff(i,i))
185  res.coeffRef(i-1,i) = p * pow(m_A.coeff(i,i), p-1);
186  else if (2*abs(m_A.coeff(i-1,i-1)) < abs(m_A.coeff(i,i)) || 2*abs(m_A.coeff(i,i)) < abs(m_A.coeff(i-1,i-1)))
187  res.coeffRef(i-1,i) = (res.coeff(i,i)-res.coeff(i-1,i-1)) / (m_A.coeff(i,i)-m_A.coeff(i-1,i-1));
188  else
189  res.coeffRef(i-1,i) = computeSuperDiag(m_A.coeff(i,i), m_A.coeff(i-1,i-1), p);
190  res.coeffRef(i-1,i) *= m_A.coeff(i-1,i);
191  }
192 }
193 
194 template<typename MatrixType>
195 void MatrixPowerAtomic<MatrixType>::computeBig(ResultType& res) const
196 {
197  using std::ldexp;
198  const int digits = std::numeric_limits<RealScalar>::digits;
199  const RealScalar maxNormForPade = RealScalar(
200  digits <= 24? 4.3386528e-1L // single precision
201  : digits <= 53? 2.789358995219730e-1L // double precision
202  : digits <= 64? 2.4471944416607995472e-1L // extended precision
203  : digits <= 106? 1.1016843812851143391275867258512e-1L // double-double
204  : 9.134603732914548552537150753385375e-2L); // quadruple precision
205  MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();
206  RealScalar normIminusT;
207  int degree, degree2, numberOfSquareRoots = 0;
208  bool hasExtraSquareRoot = false;
209 
210  for (Index i=0; i < m_A.cols(); ++i)
211  eigen_assert(m_A(i,i) != RealScalar(0));
212 
213  while (true) {
214  IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;
215  normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();
216  if (normIminusT < maxNormForPade) {
217  degree = getPadeDegree(normIminusT);
218  degree2 = getPadeDegree(normIminusT/2);
219  if (degree - degree2 <= 1 || hasExtraSquareRoot)
220  break;
221  hasExtraSquareRoot = true;
222  }
223  matrix_sqrt_triangular(T, sqrtT);
224  T = sqrtT.template triangularView<Upper>();
225  ++numberOfSquareRoots;
226  }
227  computePade(degree, IminusT, res);
228 
229  for (; numberOfSquareRoots; --numberOfSquareRoots) {
230  compute2x2(res, ldexp(m_p, -numberOfSquareRoots));
231  res = res.template triangularView<Upper>() * res;
232  }
233  compute2x2(res, m_p);
234 }
235 
236 template<typename MatrixType>
237 inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(float normIminusT)
238 {
239  const float maxNormForPade[] = { 2.8064004e-1f /* degree = 3 */ , 4.3386528e-1f };
240  int degree = 3;
241  for (; degree <= 4; ++degree)
242  if (normIminusT <= maxNormForPade[degree - 3])
243  break;
244  return degree;
245 }
246 
247 template<typename MatrixType>
248 inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(double normIminusT)
249 {
250  const double maxNormForPade[] = { 1.884160592658218e-2 /* degree = 3 */ , 6.038881904059573e-2, 1.239917516308172e-1,
251  1.999045567181744e-1, 2.789358995219730e-1 };
252  int degree = 3;
253  for (; degree <= 7; ++degree)
254  if (normIminusT <= maxNormForPade[degree - 3])
255  break;
256  return degree;
257 }
258 
259 template<typename MatrixType>
260 inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(long double normIminusT)
261 {
262 #if LDBL_MANT_DIG == 53
263  const int maxPadeDegree = 7;
264  const double maxNormForPade[] = { 1.884160592658218e-2L /* degree = 3 */ , 6.038881904059573e-2L, 1.239917516308172e-1L,
265  1.999045567181744e-1L, 2.789358995219730e-1L };
266 #elif LDBL_MANT_DIG <= 64
267  const int maxPadeDegree = 8;
268  const long double maxNormForPade[] = { 6.3854693117491799460e-3L /* degree = 3 */ , 2.6394893435456973676e-2L,
269  6.4216043030404063729e-2L, 1.1701165502926694307e-1L, 1.7904284231268670284e-1L, 2.4471944416607995472e-1L };
270 #elif LDBL_MANT_DIG <= 106
271  const int maxPadeDegree = 10;
272  const double maxNormForPade[] = { 1.0007161601787493236741409687186e-4L /* degree = 3 */ ,
273  1.0007161601787493236741409687186e-3L, 4.7069769360887572939882574746264e-3L, 1.3220386624169159689406653101695e-2L,
274  2.8063482381631737920612944054906e-2L, 4.9625993951953473052385361085058e-2L, 7.7367040706027886224557538328171e-2L,
275  1.1016843812851143391275867258512e-1L };
276 #else
277  const int maxPadeDegree = 10;
278  const double maxNormForPade[] = { 5.524506147036624377378713555116378e-5L /* degree = 3 */ ,
279  6.640600568157479679823602193345995e-4L, 3.227716520106894279249709728084626e-3L,
280  9.619593944683432960546978734646284e-3L, 2.134595382433742403911124458161147e-2L,
281  3.908166513900489428442993794761185e-2L, 6.266780814639442865832535460550138e-2L,
282  9.134603732914548552537150753385375e-2L };
283 #endif
284  int degree = 3;
285  for (; degree <= maxPadeDegree; ++degree)
286  if (normIminusT <= maxNormForPade[degree - 3])
287  break;
288  return degree;
289 }
290 
291 template<typename MatrixType>
292 inline typename MatrixPowerAtomic<MatrixType>::ComplexScalar
293 MatrixPowerAtomic<MatrixType>::computeSuperDiag(const ComplexScalar& curr, const ComplexScalar& prev, RealScalar p)
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 = ceil((numext::imag(logCurr - logPrev) - RealScalar(EIGEN_PI)) / RealScalar(2*EIGEN_PI));
303  ComplexScalar w = numext::log1p((curr-prev)/prev)/RealScalar(2) + ComplexScalar(0, RealScalar(EIGEN_PI)*unwindingNumber);
304  return RealScalar(2) * exp(RealScalar(0.5) * p * (logCurr + logPrev)) * sinh(p * w) / (curr - prev);
305 }
306 
307 template<typename MatrixType>
308 inline typename MatrixPowerAtomic<MatrixType>::RealScalar
309 MatrixPowerAtomic<MatrixType>::computeSuperDiag(RealScalar curr, RealScalar prev, RealScalar p)
310 {
311  using std::exp;
312  using std::log;
313  using std::sinh;
314 
315  RealScalar w = numext::log1p((curr-prev)/prev)/RealScalar(2);
316  return 2 * exp(p * (log(curr) + log(prev)) / 2) * sinh(p * w) / (curr - prev);
317 }
318 
338 template<typename MatrixType>
339 class MatrixPower : internal::noncopyable
340 {
341  private:
342  typedef typename MatrixType::Scalar Scalar;
343  typedef typename MatrixType::RealScalar RealScalar;
344 
345  public:
354  explicit MatrixPower(const MatrixType& A) :
355  m_A(A),
356  m_conditionNumber(0),
357  m_rank(A.cols()),
358  m_nulls(0)
359  { eigen_assert(A.rows() == A.cols()); }
360 
370 
378  template<typename ResultType>
379  void compute(ResultType& res, RealScalar p);
380 
381  Index rows() const { return m_A.rows(); }
382  Index cols() const { return m_A.cols(); }
383 
384  private:
385  typedef std::complex<RealScalar> ComplexScalar;
386  typedef Matrix<ComplexScalar, Dynamic, Dynamic, 0,
387  MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> ComplexMatrix;
388 
390  typename MatrixType::Nested m_A;
391 
393  MatrixType m_tmp;
394 
396  ComplexMatrix m_T, m_U;
397 
399  ComplexMatrix m_fT;
400 
407  RealScalar m_conditionNumber;
408 
410  Index m_rank;
411 
413  Index m_nulls;
414 
424  void split(RealScalar& p, RealScalar& intpart);
425 
427  void initialize();
428 
429  template<typename ResultType>
430  void computeIntPower(ResultType& res, RealScalar p);
431 
432  template<typename ResultType>
433  void computeFracPower(ResultType& res, RealScalar p);
434 
435  template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
436  static void revertSchur(
437  Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
438  const ComplexMatrix& T,
439  const ComplexMatrix& U);
440 
441  template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
442  static void revertSchur(
443  Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
444  const ComplexMatrix& T,
445  const ComplexMatrix& U);
446 };
447 
448 template<typename MatrixType>
449 template<typename ResultType>
450 void MatrixPower<MatrixType>::compute(ResultType& res, RealScalar p)
451 {
452  using std::pow;
453  switch (cols()) {
454  case 0:
455  break;
456  case 1:
457  res(0,0) = pow(m_A.coeff(0,0), p);
458  break;
459  default:
460  RealScalar intpart;
461  split(p, intpart);
462 
463  res = MatrixType::Identity(rows(), cols());
464  computeIntPower(res, intpart);
465  if (p) computeFracPower(res, p);
466  }
467 }
468 
469 template<typename MatrixType>
470 void MatrixPower<MatrixType>::split(RealScalar& p, RealScalar& intpart)
471 {
472  using std::floor;
473  using std::pow;
474 
475  intpart = floor(p);
476  p -= intpart;
477 
478  // Perform Schur decomposition if it is not yet performed and the power is
479  // not an integer.
480  if (!m_conditionNumber && p)
481  initialize();
482 
483  // Choose the more stable of intpart = floor(p) and intpart = ceil(p).
484  if (p > RealScalar(0.5) && p > (1-p) * pow(m_conditionNumber, p)) {
485  --p;
486  ++intpart;
487  }
488 }
489 
490 template<typename MatrixType>
491 void MatrixPower<MatrixType>::initialize()
492 {
493  const ComplexSchur<MatrixType> schurOfA(m_A);
494  JacobiRotation<ComplexScalar> rot;
495  ComplexScalar eigenvalue;
496 
497  m_fT.resizeLike(m_A);
498  m_T = schurOfA.matrixT();
499  m_U = schurOfA.matrixU();
500  m_conditionNumber = m_T.diagonal().array().abs().maxCoeff() / m_T.diagonal().array().abs().minCoeff();
501 
502  // Move zero eigenvalues to the bottom right corner.
503  for (Index i = cols()-1; i>=0; --i) {
504  if (m_rank <= 2)
505  return;
506  if (m_T.coeff(i,i) == RealScalar(0)) {
507  for (Index j=i+1; j < m_rank; ++j) {
508  eigenvalue = m_T.coeff(j,j);
509  rot.makeGivens(m_T.coeff(j-1,j), eigenvalue);
510  m_T.applyOnTheRight(j-1, j, rot);
511  m_T.applyOnTheLeft(j-1, j, rot.adjoint());
512  m_T.coeffRef(j-1,j-1) = eigenvalue;
513  m_T.coeffRef(j,j) = RealScalar(0);
514  m_U.applyOnTheRight(j-1, j, rot);
515  }
516  --m_rank;
517  }
518  }
519 
520  m_nulls = rows() - m_rank;
521  if (m_nulls) {
522  eigen_assert(m_T.bottomRightCorner(m_nulls, m_nulls).isZero()
523  && "Base of matrix power should be invertible or with a semisimple zero eigenvalue.");
524  m_fT.bottomRows(m_nulls).fill(RealScalar(0));
525  }
526 }
527 
528 template<typename MatrixType>
529 template<typename ResultType>
530 void MatrixPower<MatrixType>::computeIntPower(ResultType& res, RealScalar p)
531 {
532  using std::abs;
533  using std::fmod;
534  RealScalar pp = abs(p);
535 
536  if (p<0)
537  m_tmp = m_A.inverse();
538  else
539  m_tmp = m_A;
540 
541  while (true) {
542  if (fmod(pp, 2) >= 1)
543  res = m_tmp * res;
544  pp /= 2;
545  if (pp < 1)
546  break;
547  m_tmp *= m_tmp;
548  }
549 }
550 
551 template<typename MatrixType>
552 template<typename ResultType>
553 void MatrixPower<MatrixType>::computeFracPower(ResultType& res, RealScalar p)
554 {
555  Block<ComplexMatrix,Dynamic,Dynamic> blockTp(m_fT, 0, 0, m_rank, m_rank);
556  eigen_assert(m_conditionNumber);
557  eigen_assert(m_rank + m_nulls == rows());
558 
559  MatrixPowerAtomic<ComplexMatrix>(m_T.topLeftCorner(m_rank, m_rank), p).compute(blockTp);
560  if (m_nulls) {
561  m_fT.topRightCorner(m_rank, m_nulls) = m_T.topLeftCorner(m_rank, m_rank).template triangularView<Upper>()
562  .solve(blockTp * m_T.topRightCorner(m_rank, m_nulls));
563  }
564  revertSchur(m_tmp, m_fT, m_U);
565  res = m_tmp * res;
566 }
567 
568 template<typename MatrixType>
569 template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
570 inline void MatrixPower<MatrixType>::revertSchur(
571  Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
572  const ComplexMatrix& T,
573  const ComplexMatrix& U)
574 { res.noalias() = U * (T.template triangularView<Upper>() * U.adjoint()); }
575 
576 template<typename MatrixType>
577 template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
578 inline void MatrixPower<MatrixType>::revertSchur(
579  Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
580  const ComplexMatrix& T,
581  const ComplexMatrix& U)
582 { res.noalias() = (U * (T.template triangularView<Upper>() * U.adjoint())).real(); }
583 
597 template<typename Derived>
598 class MatrixPowerReturnValue : public ReturnByValue< MatrixPowerReturnValue<Derived> >
599 {
600  public:
601  typedef typename Derived::PlainObject PlainObject;
602  typedef typename Derived::RealScalar RealScalar;
603 
610  MatrixPowerReturnValue(const Derived& A, RealScalar p) : m_A(A), m_p(p)
611  { }
612 
619  template<typename ResultType>
620  inline void evalTo(ResultType& result) const
621  { MatrixPower<PlainObject>(m_A.eval()).compute(result, m_p); }
622 
623  Index rows() const { return m_A.rows(); }
624  Index cols() const { return m_A.cols(); }
625 
626  private:
627  const Derived& m_A;
628  const RealScalar m_p;
629 };
630 
644 template<typename Derived>
645 class MatrixComplexPowerReturnValue : public ReturnByValue< MatrixComplexPowerReturnValue<Derived> >
646 {
647  public:
648  typedef typename Derived::PlainObject PlainObject;
649  typedef typename std::complex<typename Derived::RealScalar> ComplexScalar;
650 
657  MatrixComplexPowerReturnValue(const Derived& A, const ComplexScalar& p) : m_A(A), m_p(p)
658  { }
659 
669  template<typename ResultType>
670  inline void evalTo(ResultType& result) const
671  { result = (m_p * m_A.log()).exp(); }
672 
673  Index rows() const { return m_A.rows(); }
674  Index cols() const { return m_A.cols(); }
675 
676  private:
677  const Derived& m_A;
678  const ComplexScalar m_p;
679 };
680 
681 namespace internal {
682 
683 template<typename MatrixPowerType>
684 struct traits< MatrixPowerParenthesesReturnValue<MatrixPowerType> >
685 { typedef typename MatrixPowerType::PlainObject ReturnType; };
686 
687 template<typename Derived>
688 struct traits< MatrixPowerReturnValue<Derived> >
689 { typedef typename Derived::PlainObject ReturnType; };
690 
691 template<typename Derived>
692 struct traits< MatrixComplexPowerReturnValue<Derived> >
693 { typedef typename Derived::PlainObject ReturnType; };
694 
695 }
696 
697 template<typename Derived>
698 const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(const RealScalar& p) const
699 { return MatrixPowerReturnValue<Derived>(derived(), p); }
700 
701 template<typename Derived>
702 const MatrixComplexPowerReturnValue<Derived> MatrixBase<Derived>::pow(const std::complex<RealScalar>& p) const
703 { return MatrixComplexPowerReturnValue<Derived>(derived(), p); }
704 
705 } // namespace Eigen
706 
707 #endif // EIGEN_MATRIX_POWER
const MatrixPowerReturnValue< Derived > pow(const RealScalar &p) const
Definition: MatrixPower.h:698
Proxy for the matrix power of some matrix (expression).
Definition: MatrixPower.h:646
MatrixComplexPowerReturnValue(const Derived &A, const ComplexScalar &p)
Constructor.
Definition: MatrixPower.h:657
void evalTo(ResultType &result) const
Compute the matrix power.
Definition: MatrixPower.h:670
Class for computing matrix powers.
Definition: MatrixPower.h:89
MatrixPowerAtomic(const MatrixType &T, RealScalar p)
Constructor.
Definition: MatrixPower.h:136
void compute(ResultType &res) const
Compute the matrix power.
Definition: MatrixPower.h:144
Proxy for the matrix power of some matrix.
Definition: MatrixPower.h:42
MatrixPowerParenthesesReturnValue(MatrixPower< MatrixType > &pow, RealScalar p)
Constructor.
Definition: MatrixPower.h:52
void evalTo(ResultType &result) const
Compute the matrix power.
Definition: MatrixPower.h:61
Proxy for the matrix power of some matrix (expression).
Definition: MatrixPower.h:599
MatrixPowerReturnValue(const Derived &A, RealScalar p)
Constructor.
Definition: MatrixPower.h:610
void evalTo(ResultType &result) const
Compute the matrix power.
Definition: MatrixPower.h:620
Class for computing matrix powers.
Definition: MatrixPower.h:340
const MatrixPowerParenthesesReturnValue< MatrixType > operator()(RealScalar p)
Returns the matrix power.
Definition: MatrixPower.h:368
MatrixPower(const MatrixType &A)
Constructor.
Definition: MatrixPower.h:354
void compute(ResultType &res, RealScalar p)
Compute the matrix power.
Definition: MatrixPower.h:450
void matrix_sqrt_triangular(const MatrixType &arg, ResultType &result)
Compute matrix square root of triangular matrix.
Definition: MatrixSquareRoot.h:206
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ceil_op< typename Derived::Scalar >, const Derived > ceil(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_floor_op< typename Derived::Scalar >, const Derived > floor(const Eigen::ArrayBase< Derived > &x)
const int Dynamic
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)