aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/functors
diff options
context:
space:
mode:
Diffstat (limited to 'Eigen/src/Core/functors')
-rw-r--r--Eigen/src/Core/functors/BinaryFunctors.h4
-rw-r--r--Eigen/src/Core/functors/CMakeLists.txt6
-rw-r--r--Eigen/src/Core/functors/NullaryFunctors.h71
-rw-r--r--Eigen/src/Core/functors/UnaryFunctors.h126
4 files changed, 38 insertions, 169 deletions
diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h
index dc3690444..d82ffed02 100644
--- a/Eigen/src/Core/functors/BinaryFunctors.h
+++ b/Eigen/src/Core/functors/BinaryFunctors.h
@@ -287,7 +287,7 @@ struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
{
Cost = 3 * NumTraits<Scalar>::AddCost +
2 * NumTraits<Scalar>::MulCost +
- 2 * NumTraits<Scalar>::template Div<false>::Cost,
+ 2 * scalar_div_cost<Scalar,false>::value,
PacketAccess = false
};
};
@@ -375,7 +375,7 @@ struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
enum {
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
- Cost = NumTraits<result_type>::template Div<PacketAccess>::Cost
+ Cost = scalar_div_cost<result_type,PacketAccess>::value
};
};
diff --git a/Eigen/src/Core/functors/CMakeLists.txt b/Eigen/src/Core/functors/CMakeLists.txt
deleted file mode 100644
index f4b99a9c3..000000000
--- a/Eigen/src/Core/functors/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-FILE(GLOB Eigen_Core_Functor_SRCS "*.h")
-
-INSTALL(FILES
- ${Eigen_Core_Functor_SRCS}
- DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/functors COMPONENT Devel
- )
diff --git a/Eigen/src/Core/functors/NullaryFunctors.h b/Eigen/src/Core/functors/NullaryFunctors.h
index eaa582f23..a2154d3b5 100644
--- a/Eigen/src/Core/functors/NullaryFunctors.h
+++ b/Eigen/src/Core/functors/NullaryFunctors.h
@@ -18,10 +18,9 @@ template<typename Scalar>
struct scalar_constant_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
- template<typename Index, typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp(Index, Index = 0) const { return internal::pset1<PacketType>(m_other); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() () const { return m_other; }
+ template<typename PacketType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const { return internal::pset1<PacketType>(m_other); }
const Scalar m_other;
};
template<typename Scalar>
@@ -31,8 +30,8 @@ struct functor_traits<scalar_constant_op<Scalar> >
template<typename Scalar> struct scalar_identity_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
+ template<typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType row, IndexType col) const { return row==col ? Scalar(1) : Scalar(0); }
};
template<typename Scalar>
struct functor_traits<scalar_identity_op<Scalar> >
@@ -56,15 +55,15 @@ struct linspaced_op_impl<Scalar,Packet,/*RandomAccess*/false,/*IsInteger*/false>
m_packetStep(pset1<Packet>(unpacket_traits<Packet>::size*m_step)),
m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(m_step),plset<Packet>(-unpacket_traits<Packet>::size)))) {}
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
+ template<typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const
{
m_base = padd(m_base, pset1<Packet>(m_step));
return m_low+Scalar(i)*m_step;
}
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
+ template<typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType) const { return m_base = padd(m_base,m_packetStep); }
const Scalar m_low;
const Scalar m_step;
@@ -82,11 +81,11 @@ struct linspaced_op_impl<Scalar,Packet,/*RandomAccess*/true,/*IsInteger*/false>
m_low(low), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)),
m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Packet>(0)) {}
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
+ template<typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return m_low+i*m_step; }
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
+ template<typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const
{ return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(Scalar(i)),m_interPacket))); }
const Scalar m_low;
@@ -103,15 +102,15 @@ struct linspaced_op_impl<Scalar,Packet,/*RandomAccess*/true,/*IsInteger*/true>
m_low(low), m_length(high-low), m_divisor(convert_index<Scalar>(num_steps==1?1:num_steps-1)), m_interPacket(plset<Packet>(0))
{}
- template<typename Index>
+ template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const Scalar operator() (Index i) const {
+ const Scalar operator() (IndexType i) const {
return m_low + (m_length*Scalar(i))/m_divisor;
}
- template<typename Index>
+ template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const Packet packetOp(Index i) const {
+ const Packet packetOp(IndexType i) const {
return internal::padd(pset1<Packet>(m_low), pdiv(pmul(pset1<Packet>(m_length), padd(pset1<Packet>(Scalar(i)),m_interPacket)),
pset1<Packet>(m_divisor))); }
@@ -143,29 +142,11 @@ template <typename Scalar, typename PacketType, bool RandomAccess> struct linspa
: impl((num_steps==1 ? high : low),high,num_steps)
{}
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
+ template<typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return impl(i); }
- // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
- // there row==0 and col is used for the actual iteration.
- template<typename Index>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
- {
- eigen_assert(col==0 || row==0);
- return impl(col + row);
- }
-
- template<typename Index, typename Packet>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
-
- // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
- // there row==0 and col is used for the actual iteration.
- template<typename Index, typename Packet>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
- {
- eigen_assert(col==0 || row==0);
- return impl.packetOp(col + row);
- }
+ template<typename Packet,typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.packetOp(i); }
// This proxy object handles the actual required temporaries, the different
// implementations (random vs. sequential access) as well as the
@@ -175,11 +156,11 @@ template <typename Scalar, typename PacketType, bool RandomAccess> struct linspa
const linspaced_op_impl<Scalar,PacketType,(NumTraits<Scalar>::IsInteger?true:RandomAccess),NumTraits<Scalar>::IsInteger> impl;
};
-// all functors allow linear access, except scalar_identity_op. So we fix here a quick meta
-// to indicate whether a functor allows linear access, just always answering 'yes' except for
-// scalar_identity_op.
-template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
-template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
+// Linear access is automatically determined from the operator() prototypes available for the given functor.
+// If it exposes an operator()(i,j), then we assume the i and j coefficients are required independently
+// and linear access is not possible. In all other cases, linear access is enabled.
+// Users should not have to deal with this struture.
+template<typename Functor> struct functor_has_linear_access { enum { ret = !has_binary_operator<Functor>::value }; };
} // end namespace internal
diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h
index e2f3d869f..2009f8e57 100644
--- a/Eigen/src/Core/functors/UnaryFunctors.h
+++ b/Eigen/src/Core/functors/UnaryFunctors.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -248,7 +248,7 @@ struct functor_traits<scalar_exp_op<Scalar> > {
// double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div, 13 other
: (14 * NumTraits<Scalar>::AddCost +
6 * NumTraits<Scalar>::MulCost +
- NumTraits<Scalar>::template Div<packet_traits<Scalar>::HasDiv>::Cost))
+ scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value))
#else
Cost =
(sizeof(Scalar) == 4
@@ -257,7 +257,7 @@ struct functor_traits<scalar_exp_op<Scalar> > {
// double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div, 13 other
: (23 * NumTraits<Scalar>::AddCost +
12 * NumTraits<Scalar>::MulCost +
- NumTraits<Scalar>::template Div<packet_traits<Scalar>::HasDiv>::Cost))
+ scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value))
#endif
};
};
@@ -498,138 +498,32 @@ struct functor_traits<scalar_atan_op<Scalar> >
template <typename Scalar>
struct scalar_tanh_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_tanh_op)
- EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const {
- /** \internal \returns the hyperbolic tan of \a a (coeff-wise)
- Doesn't do anything fancy, just a 13/6-degree rational interpolant
- which
- is accurate up to a couple of ulp in the range [-9, 9], outside of
- which
- the fl(tanh(x)) = +/-1. */
-
- // Clamp the inputs to the range [-9, 9] since anything outside
- // this range is +/-1.0f in single-precision.
- const Scalar plus_9 = static_cast<Scalar>(9.0);
- const Scalar minus_9 = static_cast<Scalar>(-9.0);
- const Scalar x = numext::maxi(minus_9, numext::mini(plus_9, a));
- // Scalarhe monomial coefficients of the numerator polynomial (odd).
- const Scalar alpha_1 = static_cast<Scalar>(4.89352455891786e-03);
- const Scalar alpha_3 = static_cast<Scalar>(6.37261928875436e-04);
- const Scalar alpha_5 = static_cast<Scalar>(1.48572235717979e-05);
- const Scalar alpha_7 = static_cast<Scalar>(5.12229709037114e-08);
- const Scalar alpha_9 = static_cast<Scalar>(-8.60467152213735e-11);
- const Scalar alpha_11 = static_cast<Scalar>(2.00018790482477e-13);
- const Scalar alpha_13 = static_cast<Scalar>(-2.76076847742355e-16);
- // Scalarhe monomial coefficients of the denominator polynomial (even).
- const Scalar beta_0 = static_cast<Scalar>(4.89352518554385e-03);
- const Scalar beta_2 = static_cast<Scalar>(2.26843463243900e-03);
- const Scalar beta_4 = static_cast<Scalar>(1.18534705686654e-04);
- const Scalar beta_6 = static_cast<Scalar>(1.19825839466702e-06);
- // Since the polynomials are odd/even, we need x^2.
- const Scalar x2 = x * x;
- // Evaluate the numerator polynomial p.
- Scalar p = x2 * alpha_13 + alpha_11;
- p = x2 * p + alpha_9;
- p = x2 * p + alpha_7;
- p = x2 * p + alpha_5;
- p = x2 * p + alpha_3;
- p = x2 * p + alpha_1;
- p = x * p;
- // Evaluate the denominator polynomial p.
- Scalar q = x2 * beta_6 + beta_4;
- q = x2 * q + beta_2;
- q = x2 * q + beta_0;
- // Divide the numerator by the denominator.
- return p / q;
- }
+ EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::tanh(a); }
template <typename Packet>
- EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& _x) const {
- /** \internal \returns the hyperbolic tan of \a a (coeff-wise)
- Doesn't do anything fancy, just a 13/6-degree rational interpolant which
- is accurate up to a couple of ulp in the range [-9, 9], outside of which
- the
- fl(tanh(x)) = +/-1. */
-
- // Clamp the inputs to the range [-9, 9] since anything outside
- // this range is +/-1.0f in single-precision.
- const Packet plus_9 = pset1<Packet>(9.0);
- const Packet minus_9 = pset1<Packet>(-9.0);
- const Packet x = pmax(minus_9, pmin(plus_9, _x));
-
- // The monomial coefficients of the numerator polynomial (odd).
- const Packet alpha_1 = pset1<Packet>(4.89352455891786e-03);
- const Packet alpha_3 = pset1<Packet>(6.37261928875436e-04);
- const Packet alpha_5 = pset1<Packet>(1.48572235717979e-05);
- const Packet alpha_7 = pset1<Packet>(5.12229709037114e-08);
- const Packet alpha_9 = pset1<Packet>(-8.60467152213735e-11);
- const Packet alpha_11 = pset1<Packet>(2.00018790482477e-13);
- const Packet alpha_13 = pset1<Packet>(-2.76076847742355e-16);
-
- // The monomial coefficients of the denominator polynomial (even).
- const Packet beta_0 = pset1<Packet>(4.89352518554385e-03);
- const Packet beta_2 = pset1<Packet>(2.26843463243900e-03);
- const Packet beta_4 = pset1<Packet>(1.18534705686654e-04);
- const Packet beta_6 = pset1<Packet>(1.19825839466702e-06);
-
- // Since the polynomials are odd/even, we need x^2.
- const Packet x2 = pmul(x, x);
-
- // Evaluate the numerator polynomial p.
- Packet p = pmadd(x2, alpha_13, alpha_11);
- p = pmadd(x2, p, alpha_9);
- p = pmadd(x2, p, alpha_7);
- p = pmadd(x2, p, alpha_5);
- p = pmadd(x2, p, alpha_3);
- p = pmadd(x2, p, alpha_1);
- p = pmul(x, p);
-
- // Evaluate the denominator polynomial p.
- Packet q = pmadd(x2, beta_6, beta_4);
- q = pmadd(x2, q, beta_2);
- q = pmadd(x2, q, beta_0);
-
- // Divide the numerator by the denominator.
- return pdiv(p, q);
- }
-};
-template <>
-struct scalar_tanh_op<std::complex<double> > {
- EIGEN_DEVICE_FUNC inline const std::complex<double> operator()(
- const std::complex<double>& a) const {
- return numext::tanh(a);
- }
-};
-template <>
-struct scalar_tanh_op<std::complex<float> > {
- EIGEN_DEVICE_FUNC inline const std::complex<float> operator()(
- const std::complex<float>& a) const {
- return numext::tanh(a);
- }
+ EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& x) const { return ptanh(x); }
};
+
template <typename Scalar>
struct functor_traits<scalar_tanh_op<Scalar> > {
enum {
PacketAccess = packet_traits<Scalar>::HasTanh,
- Cost = (PacketAccess && (!is_same<Scalar, std::complex<float> >::value) &&
- (!is_same<Scalar, std::complex<double> >::value)
+ Cost = ( (EIGEN_FAST_MATH && is_same<Scalar,float>::value)
// The following numbers are based on the AVX implementation,
#ifdef EIGEN_VECTORIZE_FMA
// Haswell can issue 2 add/mul/madd per cycle.
// 9 pmadd, 2 pmul, 1 div, 2 other
? (2 * NumTraits<Scalar>::AddCost +
6 * NumTraits<Scalar>::MulCost +
- NumTraits<Scalar>::template Div<
- packet_traits<Scalar>::HasDiv>::Cost)
+ scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)
#else
? (11 * NumTraits<Scalar>::AddCost +
11 * NumTraits<Scalar>::MulCost +
- NumTraits<Scalar>::template Div<
- packet_traits<Scalar>::HasDiv>::Cost)
+ scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)
#endif
// This number assumes a naive implementation of tanh
: (6 * NumTraits<Scalar>::AddCost +
3 * NumTraits<Scalar>::MulCost +
- 2 * NumTraits<Scalar>::template Div<
- packet_traits<Scalar>::HasDiv>::Cost +
+ 2 * scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value +
functor_traits<scalar_exp_op<Scalar> >::Cost))
};
};