Fix bug #684: optimize vectorization of array-scalar and scalar-array

This commit is contained in:
Gael Guennebaud 2013-10-18 14:56:36 +02:00
parent a6bff116f9
commit a0e8577b49
2 changed files with 43 additions and 6 deletions

View File

@ -22,6 +22,7 @@ namespace internal {
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
*/
template<typename Scalar> struct scalar_sum_op {
// typedef Scalar result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
template<typename Packet>
@ -45,8 +46,8 @@ struct functor_traits<scalar_sum_op<Scalar> > {
* \sa DenseBase::count(), DenseBase::any(), ArrayBase::cast(), MatrixBase::cast()
*/
template<> struct scalar_sum_op<bool> : scalar_sum_op<int> {
EIGEN_DEPRECATED
scalar_sum_op() {}
EIGEN_DEPRECATED
scalar_sum_op() {}
};
@ -689,6 +690,42 @@ template<typename Scalar>
struct functor_traits<scalar_add_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
/** \internal
* \brief Template functor to subtract a fixed scalar to another one
* \sa class CwiseUnaryOp, Array::operator-, struct scalar_add_op, struct scalar_rsub_op
*/
template<typename Scalar>
struct scalar_sub_op {
typedef typename packet_traits<Scalar>::type Packet;
inline scalar_sub_op(const scalar_sub_op& other) : m_other(other.m_other) { }
inline scalar_sub_op(const Scalar& other) : m_other(other) { }
inline Scalar operator() (const Scalar& a) const { return a - m_other; }
inline const Packet packetOp(const Packet& a) const
{ return internal::psub(a, pset1<Packet>(m_other)); }
const Scalar m_other;
};
template<typename Scalar>
struct functor_traits<scalar_sub_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
/** \internal
* \brief Template functor to subtract a scalar to fixed another one
* \sa class CwiseUnaryOp, Array::operator-, struct scalar_add_op, struct scalar_sub_op
*/
template<typename Scalar>
struct scalar_rsub_op {
typedef typename packet_traits<Scalar>::type Packet;
inline scalar_rsub_op(const scalar_rsub_op& other) : m_other(other.m_other) { }
inline scalar_rsub_op(const Scalar& other) : m_other(other) { }
inline Scalar operator() (const Scalar& a) const { return m_other - a; }
inline const Packet packetOp(const Packet& a) const
{ return internal::psub(pset1<Packet>(m_other), a); }
const Scalar m_other;
};
template<typename Scalar>
struct functor_traits<scalar_rsub_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
/** \internal
* \brief Template functor to compute the square root of a scalar
* \sa class CwiseUnaryOp, Cwise::sqrt()

View File

@ -162,16 +162,16 @@ operator+(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS<Derived>&
*
* \sa operator+(), operator-=()
*/
inline const CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Derived>
inline const CwiseUnaryOp<internal::scalar_sub_op<Scalar>, const Derived>
operator-(const Scalar& scalar) const
{
return *this + (-scalar);
return CwiseUnaryOp<internal::scalar_sub_op<Scalar>, const Derived>(derived(), internal::scalar_sub_op<Scalar>(scalar));;
}
friend inline const CwiseUnaryOp<internal::scalar_add_op<Scalar>, const CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived> >
friend inline const CwiseUnaryOp<internal::scalar_rsub_op<Scalar>, const Derived>
operator-(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS<Derived>& other)
{
return (-other) + scalar;
return CwiseUnaryOp<internal::scalar_rsub_op<Scalar>, const Derived>(other.derived(), internal::scalar_rsub_op<Scalar>(scalar));;
}
/** \returns an expression of the coefficient-wise && operator of *this and \a other