Class NDLogAddExpMath
Scalar kernels backing NumSharp's np.logaddexp / np.logaddexp2 /
np.nextafter binary ufuncs. Each entry point reproduces the exact NumPy 2.4.2
algorithm (npy_math_internal.h.src / ieee754 / halffloat.cpp), operation
for operation, so the result matches NumPy on this platform to within the accuracy of the one
primitive NumSharp cannot reproduce bit-for-bit — the CRT's log1p.
nextafter is BIT-EXACT. BitIncrement(double) /
BitDecrement(double) (and the MathF twins) compose to exactly
the ucrtbase nextafter/nextafterf NumPy calls (verified 0-diff over 6M random
pairs). Half is a straight port of npy_half_nextafter on the raw 16-bit pattern.
logaddexp / logaddexp2 are ≤2 ULP. Exp(double),
Exp2(double) and Exp(float) are already bit-identical
to the ucrtbase exp/exp2/expf NumPy calls; the only divergence is
Log1p(double) — an fdlibm port that agrees with the (closed) ucrtbase
log1p to ≤1 ULP. So float64 logaddexp is ≤1 ULP, logaddexp2 ≤2 ULP (the
LOG2E·log1p product), float32 logaddexp is bit-exact and logaddexp2 ≤1 ULP.
The catastrophic small-value case that a naive log(1+exp(-tmp)) loses
(logaddexp(0,-50) = 1.93e-22, not 0) is fully recovered.
Half is computed in float32 ((Half)F((float)x,(float)y)), matching NumPy's
ee->e half loops which promote to float. Decimal (no NumPy analog) bridges through
double.
public static class NDLogAddExpMath
- Inheritance
-
NDLogAddExpMath
- Inherited Members
Methods
CopySign(double, double)
public static double CopySign(double x, double y)
Parameters
Returns
CopySignDecimal(decimal, decimal)
public static decimal CopySignDecimal(decimal x, decimal y)
Parameters
Returns
CopySignF(float, float)
public static float CopySignF(float x, float y)
Parameters
Returns
CopySignHalf(Half, Half)
Half copysign on raw bits: |x|'s magnitude bits ORed with y's sign bit (NaN payload preserved, sign taken from y — matches NumPy).
public static Half CopySignHalf(Half x, Half y)
Parameters
Returns
Log1p(double)
log(1+x), fdlibm port (≤1 ULP vs ucrtbase log1p).
public static double Log1p(double x)
Parameters
xdouble
Returns
Log1pf(float)
log(1+x) at single precision, fdlibm port.
public static float Log1pf(float x)
Parameters
xfloat
Returns
LogAddExp(double, double)
public static double LogAddExp(double x, double y)
Parameters
Returns
LogAddExp2(double, double)
public static double LogAddExp2(double x, double y)
Parameters
Returns
LogAddExp2Decimal(decimal, decimal)
public static decimal LogAddExp2Decimal(decimal x, decimal y)
Parameters
Returns
LogAddExp2F(float, float)
public static float LogAddExp2F(float x, float y)
Parameters
Returns
LogAddExp2Half(Half, Half)
public static Half LogAddExp2Half(Half x, Half y)
Parameters
Returns
LogAddExpDecimal(decimal, decimal)
public static decimal LogAddExpDecimal(decimal x, decimal y)
Parameters
Returns
LogAddExpF(float, float)
public static float LogAddExpF(float x, float y)
Parameters
Returns
LogAddExpHalf(Half, Half)
public static Half LogAddExpHalf(Half x, Half y)
Parameters
Returns
NextAfter(double, double)
public static double NextAfter(double x, double y)
Parameters
Returns
NextAfterDecimal(decimal, decimal)
public static decimal NextAfterDecimal(decimal x, decimal y)
Parameters
Returns
NextAfterF(float, float)
public static float NextAfterF(float x, float y)
Parameters
Returns
NextAfterHalf(Half, Half)
Port of npy_half_nextafter (halffloat.cpp): raw 16-bit stepping.
Note NumPy's half returns x when x==y (incl. signed-zero-equal), unlike the C99
double/float path which returns y.
public static Half NextAfterHalf(Half x, Half y)