aboutsummaryrefslogtreecommitdiffhomepage
path: root/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
diff options
context:
space:
mode:
Diffstat (limited to 'unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h')
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h44
1 files changed, 28 insertions, 16 deletions
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
index 6825a7882..f8bbd59c1 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
@@ -157,6 +157,24 @@ class MatrixExponential {
/** \brief L1 norm of m_M. */
RealScalar m_l1norm;
+
+ /** \brief Scaling operator. */
+ struct ScalingOp;
+};
+
+template <typename MatrixType>
+struct MatrixExponential<MatrixType>::ScalingOp
+{
+ ScalingOp(int squarings) : m_squarings(squarings) { }
+
+ inline const RealScalar operator() (const RealScalar& x) const
+ { return std::ldexp(x, -m_squarings); }
+
+ inline const ComplexScalar operator() (const ComplexScalar& x) const
+ { return ComplexScalar(std::ldexp(x.real(), -m_squarings), std::ldexp(x.imag(), -m_squarings)); }
+
+ private:
+ int m_squarings;
};
template <typename MatrixType>
@@ -283,17 +301,15 @@ EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade17(const MatrixType
template <typename MatrixType>
void MatrixExponential<MatrixType>::computeUV(float)
{
- using std::frexp;
- using std::pow;
if (m_l1norm < 4.258730016922831e-001) {
pade3(m_M);
} else if (m_l1norm < 1.880152677804762e+000) {
pade5(m_M);
} else {
const float maxnorm = 3.925724783138660f;
- frexp(m_l1norm / maxnorm, &m_squarings);
+ std::frexp(m_l1norm / maxnorm, &m_squarings);
if (m_squarings < 0) m_squarings = 0;
- MatrixType A = m_M / pow(Scalar(2), m_squarings);
+ MatrixType A = CwiseUnaryOp<ScalingOp, MatrixType>(m_M, m_squarings);
pade7(A);
}
}
@@ -301,8 +317,6 @@ void MatrixExponential<MatrixType>::computeUV(float)
template <typename MatrixType>
void MatrixExponential<MatrixType>::computeUV(double)
{
- using std::frexp;
- using std::pow;
if (m_l1norm < 1.495585217958292e-002) {
pade3(m_M);
} else if (m_l1norm < 2.539398330063230e-001) {
@@ -313,9 +327,9 @@ void MatrixExponential<MatrixType>::computeUV(double)
pade9(m_M);
} else {
const double maxnorm = 5.371920351148152;
- frexp(m_l1norm / maxnorm, &m_squarings);
+ std::frexp(m_l1norm / maxnorm, &m_squarings);
if (m_squarings < 0) m_squarings = 0;
- MatrixType A = m_M / pow(Scalar(2), m_squarings);
+ MatrixType A = CwiseUnaryOp<ScalingOp, MatrixType>(m_M, m_squarings);
pade13(A);
}
}
@@ -323,8 +337,6 @@ void MatrixExponential<MatrixType>::computeUV(double)
template <typename MatrixType>
void MatrixExponential<MatrixType>::computeUV(long double)
{
- using std::frexp;
- using std::pow;
#if LDBL_MANT_DIG == 53 // double precision
computeUV(double());
#elif LDBL_MANT_DIG <= 64 // extended precision
@@ -338,9 +350,9 @@ void MatrixExponential<MatrixType>::computeUV(long double)
pade9(m_M);
} else {
const long double maxnorm = 4.0246098906697353063L;
- frexp(m_l1norm / maxnorm, &m_squarings);
+ std::frexp(m_l1norm / maxnorm, &m_squarings);
if (m_squarings < 0) m_squarings = 0;
- MatrixType A = m_M / pow(Scalar(2), m_squarings);
+ MatrixType A = CwiseUnaryOp<ScalingOp, MatrixType>(m_M, m_squarings);
pade13(A);
}
#elif LDBL_MANT_DIG <= 106 // double-double
@@ -356,9 +368,9 @@ void MatrixExponential<MatrixType>::computeUV(long double)
pade13(m_M);
} else {
const long double maxnorm = 3.2579440895405400856599663723517L;
- frexp(m_l1norm / maxnorm, &m_squarings);
+ std::frexp(m_l1norm / maxnorm, &m_squarings);
if (m_squarings < 0) m_squarings = 0;
- MatrixType A = m_M / pow(Scalar(2), m_squarings);
+ MatrixType A = CwiseUnaryOp<ScalingOp, MatrixType>(m_M, m_squarings);
pade17(A);
}
#elif LDBL_MANT_DIG <= 112 // quadruple precison
@@ -374,9 +386,9 @@ void MatrixExponential<MatrixType>::computeUV(long double)
pade13(m_M);
} else {
const long double maxnorm = 2.884233277829519311757165057717815L;
- frexp(m_l1norm / maxnorm, &m_squarings);
+ std::frexp(m_l1norm / maxnorm, &m_squarings);
if (m_squarings < 0) m_squarings = 0;
- MatrixType A = m_M / pow(Scalar(2), m_squarings);
+ MatrixType A = CwiseUnaryOp<ScalingOp, MatrixType>(m_M, m_squarings);
pade17(A);
}
#else