mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
Add absolute_difference coefficient-wise binary Array function
This commit is contained in:
parent
6ff5a14091
commit
d5c665742b
@ -52,6 +52,7 @@ struct default_packet_traits
|
||||
HasAbs = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasAbsDiff = 0,
|
||||
HasMin = 1,
|
||||
HasMax = 1,
|
||||
HasConj = 1,
|
||||
@ -322,6 +323,10 @@ pcmp_eq(const Packet& a, const Packet& b) { return a==b ? ptrue(a) : pzero(a); }
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pcmp_lt_or_nan(const Packet& a, const Packet& b) { return pnot(pcmp_le(b,a)); }
|
||||
|
||||
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pabsdiff(const Packet& a, const Packet& b) { return pselect(pcmp_lt(a, b), psub(b, a), psub(a, b)); }
|
||||
|
||||
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
@ -1181,6 +1181,36 @@ inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline bool abs2(bool x) { return x; }
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE T absdiff(const T& x, const T& y)
|
||||
{
|
||||
return x > y ? x - y : y - x;
|
||||
}
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE float absdiff(const float& x, const float& y)
|
||||
{
|
||||
return fabsf(x - y);
|
||||
}
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE double absdiff(const double& x, const double& y)
|
||||
{
|
||||
return fabs(x - y);
|
||||
}
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE long double absdiff(const long double& x, const long double& y)
|
||||
{
|
||||
#if defined(EIGEN_HIPCC)
|
||||
// no "fabsl" on HIP yet
|
||||
return (x > y) ? x : y;
|
||||
#else
|
||||
return fabsl(x - y);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
|
||||
|
@ -145,6 +145,7 @@ struct packet_traits<float> : default_packet_traits
|
||||
HasAbs = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasAbsDiff = 1,
|
||||
HasMin = 1,
|
||||
HasMax = 1,
|
||||
HasConj = 1,
|
||||
@ -183,6 +184,7 @@ struct packet_traits<int8_t> : default_packet_traits
|
||||
HasMul = 1,
|
||||
HasNegate = 1,
|
||||
HasAbs = 1,
|
||||
HasAbsDiff = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasMin = 1,
|
||||
@ -212,6 +214,7 @@ struct packet_traits<uint8_t> : default_packet_traits
|
||||
HasMul = 1,
|
||||
HasNegate = 0,
|
||||
HasAbs = 1,
|
||||
HasAbsDiff = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasMin = 1,
|
||||
@ -243,6 +246,7 @@ struct packet_traits<int16_t> : default_packet_traits
|
||||
HasMul = 1,
|
||||
HasNegate = 1,
|
||||
HasAbs = 1,
|
||||
HasAbsDiff = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasMin = 1,
|
||||
@ -272,6 +276,7 @@ struct packet_traits<uint16_t> : default_packet_traits
|
||||
HasMul = 1,
|
||||
HasNegate = 0,
|
||||
HasAbs = 0,
|
||||
HasAbsDiff = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasMin = 1,
|
||||
@ -305,6 +310,7 @@ struct packet_traits<int32_t> : default_packet_traits
|
||||
HasAbs = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasAbsDiff = 1,
|
||||
HasMin = 1,
|
||||
HasMax = 1,
|
||||
HasConj = 1,
|
||||
@ -334,6 +340,7 @@ struct packet_traits<uint32_t> : default_packet_traits
|
||||
HasAbs = 0,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasAbsDiff = 1,
|
||||
HasMin = 1,
|
||||
HasMax = 1,
|
||||
HasConj = 1,
|
||||
@ -1101,6 +1108,47 @@ template<> EIGEN_STRONG_INLINE Packet2ui pmadd(const Packet2ui& a, const Packet2
|
||||
template<> EIGEN_STRONG_INLINE Packet4ui pmadd(const Packet4ui& a, const Packet4ui& b, const Packet4ui& c)
|
||||
{ return vmlaq_u32(c,a,b); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pabsdiff<Packet2f>(const Packet2f& a, const Packet2f& b)
|
||||
{ return vabd_f32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pabsdiff<Packet4f>(const Packet4f& a, const Packet4f& b)
|
||||
{ return vabdq_f32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4c pabsdiff<Packet4c>(const Packet4c& a, const Packet4c& b)
|
||||
{
|
||||
return vget_lane_s32(vreinterpret_s32_s8(vabd_s8(
|
||||
vreinterpret_s8_s32(vdup_n_s32(a)),
|
||||
vreinterpret_s8_s32(vdup_n_s32(b)))), 0);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet8c pabsdiff<Packet8c>(const Packet8c& a, const Packet8c& b)
|
||||
{ return vabd_s8(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet16c pabsdiff<Packet16c>(const Packet16c& a, const Packet16c& b)
|
||||
{ return vabdq_s8(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4uc pabsdiff<Packet4uc>(const Packet4uc& a, const Packet4uc& b)
|
||||
{
|
||||
return vget_lane_u32(vreinterpret_u32_u8(vabd_u8(
|
||||
vreinterpret_u8_u32(vdup_n_u32(a)),
|
||||
vreinterpret_u8_u32(vdup_n_u32(b)))), 0);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet8uc pabsdiff<Packet8uc>(const Packet8uc& a, const Packet8uc& b)
|
||||
{ return vabd_u8(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet16uc pabsdiff<Packet16uc>(const Packet16uc& a, const Packet16uc& b)
|
||||
{ return vabdq_u8(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4s pabsdiff<Packet4s>(const Packet4s& a, const Packet4s& b)
|
||||
{ return vabd_s16(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet8s pabsdiff<Packet8s>(const Packet8s& a, const Packet8s& b)
|
||||
{ return vabdq_s16(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4us pabsdiff<Packet4us>(const Packet4us& a, const Packet4us& b)
|
||||
{ return vabd_u16(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet8us pabsdiff<Packet8us>(const Packet8us& a, const Packet8us& b)
|
||||
{ return vabdq_u16(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2i pabsdiff<Packet2i>(const Packet2i& a, const Packet2i& b)
|
||||
{ return vabd_s32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pabsdiff<Packet4i>(const Packet4i& a, const Packet4i& b)
|
||||
{ return vabdq_s32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2ui pabsdiff<Packet2ui>(const Packet2ui& a, const Packet2ui& b)
|
||||
{ return vabd_u32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4ui pabsdiff<Packet4ui>(const Packet4ui& a, const Packet4ui& b)
|
||||
{ return vabdq_u32(a,b); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pmin<Packet2f>(const Packet2f& a, const Packet2f& b) { return vmin_f32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return vminq_f32(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4c pmin<Packet4c>(const Packet4c& a, const Packet4c& b)
|
||||
|
@ -422,6 +422,36 @@ template<> struct functor_traits<scalar_boolean_xor_op> {
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the absolute difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::absolute_difference
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_absolute_difference_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_absolute_difference_op>::ReturnType result_type;
|
||||
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_absolute_difference_op)
|
||||
#else
|
||||
scalar_absolute_difference_op() {
|
||||
EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
|
||||
{ return numext::absdiff(); }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pabsdiff(a,b); }
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_absolute_difference_op<LhsScalar,RhsScalar> > {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
//---------- binary functors bound to a constant, thus appearing as a unary functor ----------
|
||||
|
@ -187,6 +187,7 @@ template<typename Scalar> struct scalar_real_op;
|
||||
template<typename Scalar> struct scalar_imag_op;
|
||||
template<typename Scalar> struct scalar_abs_op;
|
||||
template<typename Scalar> struct scalar_abs2_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_absolute_difference_op;
|
||||
template<typename Scalar> struct scalar_sqrt_op;
|
||||
template<typename Scalar> struct scalar_rsqrt_op;
|
||||
template<typename Scalar> struct scalar_exp_op;
|
||||
|
@ -75,6 +75,32 @@ max
|
||||
return (max)(Derived::PlainObject::Constant(rows(), cols(), other));
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise absdiff of \c *this and \a other
|
||||
*
|
||||
* Example: \include Cwise_absolute_difference.cpp
|
||||
* Output: \verbinclude Cwise_absolute_difference.out
|
||||
*
|
||||
* \sa absolute_difference()
|
||||
*/
|
||||
EIGEN_MAKE_CWISE_BINARY_OP(absolute_difference,absolute_difference)
|
||||
|
||||
/** \returns an expression of the coefficient-wise absolute_difference of \c *this and scalar \a other
|
||||
*
|
||||
* \sa absolute_difference()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_absolute_difference_op<Scalar,Scalar>, const Derived,
|
||||
const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
absolute_difference
|
||||
#else
|
||||
(absolute_difference)
|
||||
#endif
|
||||
(const Scalar &other) const
|
||||
{
|
||||
return (absolute_difference)(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.
|
||||
|
@ -343,6 +343,7 @@ template<typename ArrayType> void array_real(const ArrayType& m)
|
||||
VERIFY_IS_APPROX(inverse(inverse(m1)),m1);
|
||||
VERIFY((abs(m1) == m1 || abs(m1) == -m1).all());
|
||||
VERIFY_IS_APPROX(m3, sqrt(abs2(m1)));
|
||||
VERIFY_IS_APPROX(m1.absolute_difference(m2), (m1 > m2).select(m1 - m2, m2 - m1));
|
||||
VERIFY_IS_APPROX( m1.sign(), -(-m1).sign() );
|
||||
VERIFY_IS_APPROX( m1*m1.sign(),m1.abs());
|
||||
VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define REF_SUB(a,b) ((a)-(b))
|
||||
#define REF_MUL(a,b) ((a)*(b))
|
||||
#define REF_DIV(a,b) ((a)/(b))
|
||||
#define REF_ABS_DIFF(a,b) ((a)>(b)?(a)-(b):(b)-(a))
|
||||
|
||||
template<typename Scalar,typename Packet> void packetmath()
|
||||
{
|
||||
@ -557,6 +558,7 @@ template<typename Scalar,typename Packet> void packetmath_notcomplex()
|
||||
CHECK_CWISE2_IF(PacketTraits::HasMin, (std::min), internal::pmin);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasMax, (std::max), internal::pmax);
|
||||
CHECK_CWISE1(numext::abs, internal::pabs);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasAbsDiff, REF_ABS_DIFF, internal::pabsdiff);
|
||||
|
||||
ref[0] = data1[0];
|
||||
for (int i=0; i<PacketSize; ++i)
|
||||
|
Loading…
Reference in New Issue
Block a user