diff options
author | 2018-04-04 15:12:43 +0200 | |
---|---|---|
committer | 2018-04-04 15:12:43 +0200 | |
commit | 4213b63f5ce33d3f904674ee7b0cabd6934dda6b (patch) | |
tree | bec403caddef6f4cb62a20d213e8e6851d4671e7 /Eigen | |
parent | 368dd4cd9d18cf904b2ce3c4de18020269dcbba1 (diff) |
Factories code between numext::hypot and scalar_hyot_op functor.
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/MathFunctionsImpl.h | 20 | ||||
-rw-r--r-- | Eigen/src/Core/functors/BinaryFunctors.h | 25 |
2 files changed, 21 insertions, 24 deletions
diff --git a/Eigen/src/Core/MathFunctionsImpl.h b/Eigen/src/Core/MathFunctionsImpl.h index 034cfad7b..cc2ac0700 100644 --- a/Eigen/src/Core/MathFunctionsImpl.h +++ b/Eigen/src/Core/MathFunctionsImpl.h @@ -66,6 +66,17 @@ T generic_fast_tanh_float(const T& a_x) return pdiv(p, q); } +template<typename RealScalar> +EIGEN_STRONG_INLINE +RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y) +{ + EIGEN_USING_STD_MATH(sqrt); + RealScalar p, qp; + p = numext::maxi(x,y); + if(p==RealScalar(0)) return RealScalar(0); + qp = numext::mini(y,x) / p; + return p * sqrt(RealScalar(1) + qp*qp); +} template<typename Scalar> struct hypot_impl @@ -74,14 +85,7 @@ struct hypot_impl static inline RealScalar run(const Scalar& x, const Scalar& y) { EIGEN_USING_STD_MATH(abs); - EIGEN_USING_STD_MATH(sqrt); - RealScalar _x = abs(x); - RealScalar _y = abs(y); - RealScalar p, qp; - p = numext::maxi(_x,_y); - if(p==RealScalar(0)) return RealScalar(0); - qp = numext::mini(_y,_x) / p; - return p * sqrt(RealScalar(1) + qp*qp); + return positive_real_hypot(abs(x), abs(y)); } }; diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h index 96747bac7..3eae6b8ca 100644 --- a/Eigen/src/Core/functors/BinaryFunctors.h +++ b/Eigen/src/Core/functors/BinaryFunctors.h @@ -255,7 +255,7 @@ struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,Rh /** \internal - * \brief Template functor to compute the hypot of two scalars + * \brief Template functor to compute the hypot of two \b positive \b and \b real scalars * * \sa MatrixBase::stableNorm(), class Redux */ @@ -263,22 +263,15 @@ template<typename Scalar> struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar> { EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) -// typedef typename NumTraits<Scalar>::Real result_type; - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const { - EIGEN_USING_STD_MATH(sqrt) - Scalar p, qp; - if(_x>_y) - { - p = _x; - qp = _y / p; - } - else - { - p = _y; - qp = _x / p; - } - return p * sqrt(Scalar(1) + qp*qp); + // This functor is used by hypotNorm only for which it is faster to first apply abs + // on all coefficients prior to reduction through hypot. + // This way we avoid calling abs on positive and real entries, and this also permits + // to seamlessly handle complexes. Otherwise we would have to handle both real and complexes + // through the same functor... + return internal::positive_real_hypot(x,y); } }; template<typename Scalar> |