diff options
Diffstat (limited to 'Eigen/src/Core/functors/NullaryFunctors.h')
-rw-r--r-- | Eigen/src/Core/functors/NullaryFunctors.h | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/Eigen/src/Core/functors/NullaryFunctors.h b/Eigen/src/Core/functors/NullaryFunctors.h index b03be0269..192f225dd 100644 --- a/Eigen/src/Core/functors/NullaryFunctors.h +++ b/Eigen/src/Core/functors/NullaryFunctors.h @@ -37,26 +37,27 @@ template<typename Scalar> struct functor_traits<scalar_identity_op<Scalar> > { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; }; -template <typename Scalar, typename Packet, bool IsInteger> struct linspaced_op_impl; +template <typename Scalar, bool IsInteger> struct linspaced_op_impl; -template <typename Scalar, typename Packet> -struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false> +template <typename Scalar> +struct linspaced_op_impl<Scalar,/*IsInteger*/false> { - linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) : - m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)), + typedef typename NumTraits<Scalar>::Real RealScalar; + + EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) : + m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : Scalar((high-low)/RealScalar(num_steps-1))), m_flip(numext::abs(high)<numext::abs(low)) {} template<typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { - typedef typename NumTraits<Scalar>::Real RealScalar; if(m_flip) - return (i==0)? m_low : (m_high - RealScalar(m_size1-i)*m_step); + return (i==0)? m_low : Scalar(m_high - RealScalar(m_size1-i)*m_step); else - return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step); + return (i==m_size1)? m_high : Scalar(m_low + RealScalar(i)*m_step); } - template<typename IndexType> + template<typename Packet, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { // Principle: @@ -65,17 +66,17 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false> { Packet pi = plset<Packet>(Scalar(i-m_size1)); Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi)); - if(i==0) - res = pinsertfirst(res, m_low); - return res; + if (EIGEN_PREDICT_TRUE(i != 0)) return res; + Packet mask = pcmp_lt(pset1<Packet>(0), plset<Packet>(0)); + return pselect<Packet>(mask, res, pset1<Packet>(m_low)); } else { Packet pi = plset<Packet>(Scalar(i)); Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi)); - if(i==m_size1-unpacket_traits<Packet>::size+1) - res = pinsertlast(res, m_high); - return res; + if(EIGEN_PREDICT_TRUE(i != m_size1-unpacket_traits<Packet>::size+1)) return res; + Packet mask = pcmp_lt(plset<Packet>(0), pset1<Packet>(unpacket_traits<Packet>::size-1)); + return pselect<Packet>(mask, res, pset1<Packet>(m_high)); } } @@ -86,10 +87,10 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false> const bool m_flip; }; -template <typename Scalar, typename Packet> -struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/true> +template <typename Scalar> +struct linspaced_op_impl<Scalar,/*IsInteger*/true> { - linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) : + EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) : m_low(low), m_multiplier((high-low)/convert_index<Scalar>(num_steps<=1 ? 1 : num_steps-1)), m_divisor(convert_index<Scalar>((high>=low?num_steps:-num_steps)+(high-low))/((numext::abs(high-low)+1)==0?1:(numext::abs(high-low)+1))), @@ -115,8 +116,8 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/true> // Forward declaration (we default to random access which does not really give // us a speed gain when using packet access but it allows to use the functor in // nested expressions). -template <typename Scalar, typename PacketType> struct linspaced_op; -template <typename Scalar, typename PacketType> struct functor_traits< linspaced_op<Scalar,PacketType> > +template <typename Scalar> struct linspaced_op; +template <typename Scalar> struct functor_traits< linspaced_op<Scalar> > { enum { @@ -126,9 +127,9 @@ template <typename Scalar, typename PacketType> struct functor_traits< linspaced IsRepeatable = true }; }; -template <typename Scalar, typename PacketType> struct linspaced_op +template <typename Scalar> struct linspaced_op { - linspaced_op(const Scalar& low, const Scalar& high, Index num_steps) + EIGEN_DEVICE_FUNC linspaced_op(const Scalar& low, const Scalar& high, Index num_steps) : impl((num_steps==1 ? high : low),high,num_steps) {} @@ -136,11 +137,11 @@ template <typename Scalar, typename PacketType> struct linspaced_op EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return impl(i); } template<typename Packet,typename IndexType> - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.packetOp(i); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.template packetOp<Packet>(i); } // This proxy object handles the actual required temporaries and the different // implementations (integer vs. floating point). - const linspaced_op_impl<Scalar,PacketType,NumTraits<Scalar>::IsInteger> impl; + const linspaced_op_impl<Scalar,NumTraits<Scalar>::IsInteger> impl; }; // Linear access is automatically determined from the operator() prototypes available for the given functor. @@ -166,12 +167,12 @@ struct has_unary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = template<typename Scalar,typename IndexType> struct has_binary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 1}; }; -template<typename Scalar, typename PacketType,typename IndexType> -struct has_nullary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; }; -template<typename Scalar, typename PacketType,typename IndexType> -struct has_unary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 1}; }; -template<typename Scalar, typename PacketType,typename IndexType> -struct has_binary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; }; +template<typename Scalar,typename IndexType> +struct has_nullary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; }; +template<typename Scalar,typename IndexType> +struct has_unary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 1}; }; +template<typename Scalar,typename IndexType> +struct has_binary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; }; template<typename Scalar,typename IndexType> struct has_nullary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 1}; }; |