mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
Bug #1777: make the scalar and packet path consistent for the logistic function + respective unit test
This commit is contained in:
parent
99b7f7cb9c
commit
029a76e115
@ -951,8 +951,7 @@ template <typename T>
|
|||||||
struct scalar_logistic_op {
|
struct scalar_logistic_op {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T operator()(const T& x) const {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T operator()(const T& x) const {
|
||||||
const T one = T(1);
|
return packetOp(x);
|
||||||
return one / (one + numext::exp(-x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
template <typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
@ -978,17 +977,7 @@ template <>
|
|||||||
struct scalar_logistic_op<float> {
|
struct scalar_logistic_op<float> {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float operator()(const float& x) const {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float operator()(const float& x) const {
|
||||||
// The upper cut-off is the smallest x for which the rational approximation evaluates to 1.
|
return packetOp(x);
|
||||||
// Choosing this value saves us a few instructions clamping the results at the end.
|
|
||||||
#ifdef EIGEN_VECTORIZE_FMA
|
|
||||||
const float cutoff_upper = 15.7243833541870117f;
|
|
||||||
#else
|
|
||||||
const float cutoff_upper = 15.6437711715698242f;
|
|
||||||
#endif
|
|
||||||
const float cutoff_lower = -9.f;
|
|
||||||
if (x > cutoff_upper) return 1.0f;
|
|
||||||
else if (x < cutoff_lower) return numext::exp(x);
|
|
||||||
else return 1.0f / (1.0f + numext::exp(-x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
template <typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
@ -997,7 +986,8 @@ struct scalar_logistic_op<float> {
|
|||||||
const Packet lt_mask = pcmp_lt<Packet>(_x, cutoff_lower);
|
const Packet lt_mask = pcmp_lt<Packet>(_x, cutoff_lower);
|
||||||
const bool any_small = predux(lt_mask);
|
const bool any_small = predux(lt_mask);
|
||||||
|
|
||||||
// Clamp the input to be at most 'cutoff_upper'.
|
// The upper cut-off is the smallest x for which the rational approximation evaluates to 1.
|
||||||
|
// Choosing this value saves us a few instructions clamping the results at the end.
|
||||||
#ifdef EIGEN_VECTORIZE_FMA
|
#ifdef EIGEN_VECTORIZE_FMA
|
||||||
const Packet cutoff_upper = pset1<Packet>(15.7243833541870117f);
|
const Packet cutoff_upper = pset1<Packet>(15.7243833541870117f);
|
||||||
#else
|
#else
|
||||||
|
@ -447,6 +447,21 @@ template<typename Scalar,typename Packet> void packetmath_real()
|
|||||||
VERIFY((numext::isnan)(data2[0]));
|
VERIFY((numext::isnan)(data2[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
internal::scalar_logistic_op<Scalar> logistic;
|
||||||
|
for (int i=0; i<size; ++i)
|
||||||
|
{
|
||||||
|
data1[i] = internal::random<Scalar>(-20,20);
|
||||||
|
}
|
||||||
|
internal::pstore(data2, logistic.packetOp(internal::pload<Packet>(data1)));
|
||||||
|
for (int i=0; i<PacketSize; ++i) {
|
||||||
|
VERIFY_IS_APPROX(data2[i],logistic(data1[i]));
|
||||||
|
#ifdef EIGEN_VECTORIZE // don't check for exactness when using the i387 FPU
|
||||||
|
VERIFY_IS_EQUAL(data2[i],logistic(data1[i]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L)
|
#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L)
|
||||||
data1[0] = std::numeric_limits<Scalar>::infinity();
|
data1[0] = std::numeric_limits<Scalar>::infinity();
|
||||||
data1[1] = Scalar(-1);
|
data1[1] = Scalar(-1);
|
||||||
|
Loading…
Reference in New Issue
Block a user