From 3e5a2f9245007dde62b5e075a02d6dc34c93d218 Mon Sep 17 00:00:00 2001 From: Pavel Guzenfeld Date: Thu, 19 Mar 2026 21:12:15 +0000 Subject: [PATCH] =?UTF-8?q?Fix=20vectorized=20erf=20returning=20NaN=20at?= =?UTF-8?q?=20=C2=B1inf=20instead=20of=20=C2=B11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libeigen/eigen!2306 Closes #3053 --- .../Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h index 83eada37f..6d65c1142 100644 --- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h +++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h @@ -506,7 +506,11 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T generic_fast_erf::run(const T& x) template <> template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T generic_fast_erf::run(const T& x) { +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T generic_fast_erf::run(const T& x_in) { + // Clamp x to [-28:28] beyond which erf(x) is ±1 within double precision. + // This avoids NaN from twoprod and exp operations for infinite inputs. + constexpr double kClamp = 28.0; + const T x = pmin(pmax(x_in, pset1(-kClamp)), pset1(kClamp)); T x2 = pmul(x, x); T erf_small = pmul(x, erf_over_x_double_small(x2));