diff options
author | Gael Guennebaud <g.gael@free.fr> | 2015-07-20 13:57:55 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2015-07-20 13:57:55 +0200 |
commit | 6544b49e59f6f43c9183bf0d15d74267f5070137 (patch) | |
tree | 140eff6e3e17fc7681dfefda759ec0a2f3591836 | |
parent | 2d93060291f3373a3325413159062a3b4d1e95e8 (diff) |
Generalize pow(x,e) such that x and e can be a different expression type or a scalar for either x or e. Add x.pow(e) with e an array expression.
-rw-r--r-- | Eigen/src/Core/GlobalFunctions.h | 38 | ||||
-rw-r--r-- | Eigen/src/plugins/ArrayCwiseBinaryOps.h | 18 | ||||
-rw-r--r-- | doc/snippets/Cwise_array_power_array.cpp | 4 | ||||
-rw-r--r-- | doc/snippets/Cwise_scalar_power_array.cpp | 2 | ||||
-rw-r--r-- | test/array.cpp | 9 |
5 files changed, 67 insertions, 4 deletions
diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index 15d92b862..90d6b6e28 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -71,16 +71,46 @@ namespace Eigen return x.derived().pow(exponent); } - template<typename Derived> - inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived> - pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<Derived>& exponents) + /** \returns an expression of the coefficient-wise power of \a x to the given array of \a exponents. + * + * This function computes the coefficient-wise power. + * + * Example: \include Cwise_array_power_array.cpp + * Output: \verbinclude Cwise_array_power_array.out + * + * \sa ArrayBase::pow() + */ + template<typename Derived,typename ExponentDerived> + inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived> + pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<ExponentDerived>& exponents) { - return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>( + return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived>( x.derived(), exponents.derived() ); } + /** \returns an expression of the coefficient-wise power of the scalar \a x to the given array of \a exponents. + * + * This function computes the coefficient-wise power between a scalar and an array of exponents. + * Beaware that the scalar type of the input scalar \a x and the exponents \a exponents must be the same. + * + * Example: \include Cwise_scalar_power_array.cpp + * Output: \verbinclude Cwise_scalar_power_array.out + * + * \sa ArrayBase::pow() + */ + template<typename Derived> + inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const typename Derived::ConstantReturnType, const Derived> + pow(const typename Derived::Scalar& x, const Eigen::ArrayBase<Derived>& exponents) + { + typename Derived::ConstantReturnType constant_x(exponents.rows(), exponents.cols(), x); + return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const typename Derived::ConstantReturnType, const Derived>( + constant_x, + exponents.derived() + ); + } + /** * \brief Component-wise division of a scalar by array elements. **/ diff --git a/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/Eigen/src/plugins/ArrayCwiseBinaryOps.h index 58844800a..9422c40bc 100644 --- a/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -74,6 +74,24 @@ max return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); } +/** \returns an expression of the coefficient-wise power of \c *this to the given array of \a exponents. + * + * This function computes the coefficient-wise power. + * + * Example: \include Cwise_array_power_array.cpp + * Output: \verbinclude Cwise_array_power_array.out + */ +template<typename ExponentDerived> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE +const CwiseBinaryOp<internal::scalar_binary_pow_op<Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived> +pow(const ArrayBase<ExponentDerived>& exponents) const +{ + return CwiseBinaryOp<internal::scalar_binary_pow_op<Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived>( + this->derived(), + exponents.derived() + ); +} + // TODO code generating macros could be moved to Macros.h and could include generation of documentation #define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \ template<typename OtherDerived> \ diff --git a/doc/snippets/Cwise_array_power_array.cpp b/doc/snippets/Cwise_array_power_array.cpp new file mode 100644 index 000000000..432a76ee5 --- /dev/null +++ b/doc/snippets/Cwise_array_power_array.cpp @@ -0,0 +1,4 @@ +Array<double,1,3> x(8,25,3), + e(1./3.,0.5,2.); +cout << "[" << x << "]^[" << e << "] = " << x.pow(e) << endl; // using ArrayBase::pow +cout << "[" << x << "]^[" << e << "] = " << pow(x,e) << endl; // using Eigen::pow diff --git a/doc/snippets/Cwise_scalar_power_array.cpp b/doc/snippets/Cwise_scalar_power_array.cpp new file mode 100644 index 000000000..c968b2c84 --- /dev/null +++ b/doc/snippets/Cwise_scalar_power_array.cpp @@ -0,0 +1,2 @@ +Array<double,1,3> e(2,-3,1./3.); +cout << "10^[" << e << "] = " << pow(10,e) << endl; diff --git a/test/array.cpp b/test/array.cpp index 8cd4fd888..3d00d1d2d 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -273,9 +273,18 @@ template<typename ArrayType> void array_real(const ArrayType& m) VERIFY_IS_APPROX(pow(m1,2), m1.square()); VERIFY_IS_APPROX(m1.pow(3), m1.cube()); VERIFY_IS_APPROX(pow(m1,3), m1.cube()); + VERIFY_IS_APPROX((-m1).pow(3), -m1.cube()); + VERIFY_IS_APPROX(pow(2*m1,3), 8*m1.cube()); ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2)); VERIFY_IS_APPROX(Eigen::pow(m1,exponents), m1.square()); + VERIFY_IS_APPROX(m1.pow(exponents), m1.square()); + VERIFY_IS_APPROX(Eigen::pow(2*m1,exponents), 4*m1.square()); + VERIFY_IS_APPROX((2*m1).pow(exponents), 4*m1.square()); + VERIFY_IS_APPROX(Eigen::pow(m1,2*exponents), m1.square().square()); + VERIFY_IS_APPROX(m1.pow(2*exponents), m1.square().square()); + VERIFY_IS_APPROX(pow(m1(0,0), exponents), ArrayType::Constant(rows,cols,m1(0,0)*m1(0,0))); + VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt()); VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt()); |