Add signbit function

This commit is contained in:
Charles Schlosser
2022-11-04 00:31:20 +00:00
committed by Rasmus Munk Larsen
parent 8f8e36458f
commit 82b152dbe7
12 changed files with 332 additions and 9 deletions

View File

@@ -563,13 +563,13 @@ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
parg(const Packet& a) { using numext::arg; return arg(a); }
/** \internal \returns \a a logically shifted by N bits to the right */
/** \internal \returns \a a arithmetically shifted by N bits to the right */
template<int N> EIGEN_DEVICE_FUNC inline int
parithmetic_shift_right(const int& a) { return a >> N; }
template<int N> EIGEN_DEVICE_FUNC inline long int
parithmetic_shift_right(const long int& a) { return a >> N; }
/** \internal \returns \a a arithmetically shifted by N bits to the right */
/** \internal \returns \a a logically shifted by N bits to the right */
template<int N> EIGEN_DEVICE_FUNC inline int
plogical_shift_right(const int& a) { return static_cast<int>(static_cast<unsigned int>(a) >> N); }
template<int N> EIGEN_DEVICE_FUNC inline long int
@@ -1191,6 +1191,34 @@ Packet prsqrt(const Packet& a) {
return preciprocal<Packet>(psqrt(a));
}
template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
struct psignbit_impl;
template <typename Packet, bool IsInteger>
struct psignbit_impl<Packet, true, IsInteger> {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Packet run(const Packet& a) { return numext::signbit(a); }
};
template <typename Packet>
struct psignbit_impl<Packet, false, false> {
// generic implementation if not specialized in PacketMath.h
// slower than arithmetic shift
typedef typename unpacket_traits<Packet>::type Scalar;
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static Packet run(const Packet& a) {
const Packet cst_pos_one = pset1<Packet>(Scalar(1));
const Packet cst_neg_one = pset1<Packet>(Scalar(-1));
return pcmp_eq(por(pand(a, cst_neg_one), cst_pos_one), cst_neg_one);
}
};
template <typename Packet>
struct psignbit_impl<Packet, false, true> {
// generic implementation for integer packets
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Packet run(const Packet& a) { return pcmp_lt(a, pzero(a)); }
};
/** \internal \returns the sign bit of \a a as a bitmask*/
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE constexpr Packet
psignbit(const Packet& a) { return psignbit_impl<Packet>::run(a); }
} // end namespace internal
} // end namespace Eigen