pub trait SpecializedRealSpecialMath<E>: SpecializedSpecialMath<E> {
Show 49 methods
// Required methods
fn erfinv<P: Policy>(self) -> Self;
fn probit<P: Policy>(self) -> Self;
fn langevin<P: Policy>(self) -> Self;
fn inv_langevin<P: Policy>(self) -> Self;
fn langevin_1m<P: Policy>(self) -> Self;
fn inv_langevin_1m<P: Policy>(self) -> Self;
fn lgamma_r<P: Policy>(self) -> (Self, Self);
// Provided methods
fn ndtr<P: Policy>(self) -> Self { ... }
fn log_ndtr<P: Policy>(self) -> Self { ... }
fn logerfc<P: Policy>(self) -> Self { ... }
fn log_ndtr_with_deriv<P: Policy>(self) -> (Self, Self) { ... }
fn inv_log_ndtr<P: Policy>(self) -> Self { ... }
fn inv_digamma<P: Policy>(self) -> Self { ... }
fn wright_omega<P: Policy>(self) -> Self { ... }
fn fresnel<P: Policy>(self) -> (Self, Self) { ... }
fn sici<P: Policy>(self) -> (Self, Self) { ... }
fn fresnel_c<P: Policy>(self) -> Self { ... }
fn fresnel_s<P: Policy>(self) -> Self { ... }
fn sinint<P: Policy>(self) -> Self { ... }
fn cosint<P: Policy>(self) -> Self { ... }
fn bessel_i_ratio<P: Policy>(self, _nu: Self) -> Self { ... }
fn inv_bessel_i_ratio<P: Policy>(self, _nu: Self) -> Self { ... }
fn bessel_i_ratio_1m<P: Policy>(self, _nu: Self) -> Self { ... }
fn inv_bessel_i_ratio_1m<P: Policy>(self, _nu: Self) -> Self { ... }
fn bessel_ratio<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self { ... }
fn inv_bessel_ratio<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self { ... }
fn bessel_ratio_1m<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self { ... }
fn inv_bessel_ratio_1m<P: Policy, F: BesselRatioFamily>(
self,
nu: Self,
) -> Self { ... }
fn gauss_legendre<P: Policy>(self, n: u32) -> (Self, Self) { ... }
fn gauss_hermite<P: Policy>(self, n: u32) -> (Self, Self) { ... }
fn gauss_laguerre<P: Policy>(self, alpha: Self, n: u32) -> (Self, Self) { ... }
fn agm<P: Policy>(a: Self, b: Self) -> Self { ... }
fn pochhammer<P: Policy>(z: Self, m: Self) -> Self { ... }
fn jacobi_elliptic<P: Policy>(u: Self, k: Self) -> (Self, Self, Self) { ... }
fn boxcox<P: Policy>(self, lambda: Self) -> Self { ... }
fn boxcox_1p<P: Policy>(self, lambda: Self) -> Self { ... }
fn inv_boxcox<P: Policy>(self, lambda: Self) -> Self { ... }
fn inv_boxcox_1p<P: Policy>(self, lambda: Self) -> Self { ... }
fn yeo_johnson<P: Policy>(self, lambda: Self) -> Self { ... }
fn inv_yeo_johnson<P: Policy>(self, lambda: Self) -> Self { ... }
fn gelu<P: Policy>(self, alpha: Self) -> Self { ... }
fn swish<P: Policy>(self, beta: Self) -> Self { ... }
fn algebraic_sigmoid_n<P: Policy, const N: usize>(self) -> Self { ... }
fn algebraic_sigmoid<P: Policy>(self, n: u32) -> Self { ... }
fn algebraic_swish<P: Policy>(self) -> Self { ... }
fn gaussian_integral<P: Policy>(
x0: Self,
x1: Self,
a: Self,
c: Self,
) -> Self { ... }
fn spherical_harmonics_table<P: Policy, const L: usize, const N: usize, const CS: bool>(
table: &mut ShTable<Self::Primal, N>,
) { ... }
fn spherical_harmonics_with<P: Policy, const L: usize, const N: usize>(
table: &ShTable<Self::Primal, N>,
x: Self,
y: Self,
z: Self,
out: &mut [Self; N],
) { ... }
fn spherical_harmonics<P: Policy, const L: usize, const N: usize, const CS: bool>(
x: Self,
y: Self,
z: Self,
out: &mut [Self; N],
) { ... }
}Expand description
Specialized implementation trait for real-only special math functions.
Extends SpecializedSpecialMath with functions that have no meaningful
complex analogue (e.g. functions using the real absolute value, or functions
that are inverses of real-domain-only operations).
Required Methods§
fn erfinv<P: Policy>(self) -> Self
fn probit<P: Policy>(self) -> Self
fn langevin<P: Policy>(self) -> Self
fn inv_langevin<P: Policy>(self) -> Self
fn langevin_1m<P: Policy>(self) -> Self
fn inv_langevin_1m<P: Policy>(self) -> Self
fn lgamma_r<P: Policy>(self) -> (Self, Self)
Provided Methods§
Sourcefn log_ndtr<P: Policy>(self) -> Self
fn log_ndtr<P: Policy>(self) -> Self
ln(ndtr(x)), finite wherever x is: ln(erfc) in the moderate region, erfcx
with -x^2/2 kept in the log domain in the tail, ln_1p of the complement on the
right. See generic::ndtr. Element types without a Weideman table
(Compensated) inherit their direct erfcx’s range, about |x| < 37.
Sourcefn logerfc<P: Policy>(self) -> Self
fn logerfc<P: Policy>(self) -> Self
ln(erfc(x)) on the same construction as log_ndtr, with the
tail on the right and ln_1p(+-erf(|x|)) on the bounded side.
Sourcefn log_ndtr_with_deriv<P: Policy>(self) -> (Self, Self)
fn log_ndtr_with_deriv<P: Policy>(self) -> (Self, Self)
(ln ndtr(x), phi(x)/ndtr(x)), the value with the inverse Mills ratio, which is its
derivative. What inv_log_ndtr’s Newton and Dual both need.
Sourcefn inv_log_ndtr<P: Policy>(self) -> Self
fn inv_log_ndtr<P: Policy>(self) -> Self
The x with ln ndtr(x) = y. Newton on log_ndtr.
Sourcefn inv_digamma<P: Policy>(self) -> Self
fn inv_digamma<P: Policy>(self) -> Self
The x > 0 with digamma(x) = y. Newton on digamma with trigamma, and the
Stirling fixed point above y = 6.
Sourcefn wright_omega<P: Policy>(self) -> Self
fn wright_omega<P: Policy>(self) -> Self
The w > 0 with w + ln w = x. Newton, and the Lagrange series below x = -7.
Sourcefn fresnel<P: Policy>(self) -> (Self, Self)
fn fresnel<P: Policy>(self) -> (Self, Self)
(S(x), C(x)), the Fresnel integrals. See generic::fresnel.
The coefficient tables are per-element, so the ps/pd impls supply them and
every other type gets this default. Dual overrides it with the closed-form
derivatives C' = cos(pi x^2/2), S' = sin(pi x^2/2).
Sourcefn sici<P: Policy>(self) -> (Self, Self)
fn sici<P: Policy>(self) -> (Self, Self)
(Si(x), Ci(x)), the trigonometric integrals. See generic::sici.
Same shape as fresnel: per-element tables in ps/pd, and
Dual differentiates by Si' = sin(x)/x, Ci' = cos(x)/x.
Sourcefn fresnel_c<P: Policy>(self) -> Self
fn fresnel_c<P: Policy>(self) -> Self
C(x) alone. Unlike the Airy singles this is genuinely the pair with one half
dead: the two share the argument reduction, the phase and both auxiliaries, so
only one Chebyshev series and one reconstruction fall out. They are pure, so
they do fall out.
Sourcefn bessel_i_ratio<P: Policy>(self, _nu: Self) -> Self
fn bessel_i_ratio<P: Policy>(self, _nu: Self) -> Self
I_nu(x) / I_{nu-1}(x), the vMF mean resultant length. See generic::bessel_ratio.
The kernel reaches the Bessel continued fraction, which pins Primal = Self, so the
ps/pd impls supply it at the concrete element the way bessel_iv is. Dual
overrides through its inner vector, and any other composite is a todo!().
Sourcefn inv_bessel_i_ratio<P: Policy>(self, _nu: Self) -> Self
fn inv_bessel_i_ratio<P: Policy>(self, _nu: Self) -> Self
The kappa with I_nu(kappa) / I_{nu-1}(kappa) = r. Newton on the ratio. Same
arrangement as bessel_i_ratio.
Sourcefn bessel_i_ratio_1m<P: Policy>(self, _nu: Self) -> Self
fn bessel_i_ratio_1m<P: Policy>(self, _nu: Self) -> Self
1 - I_nu(x) / I_{nu-1}(x), accurate where the ratio is within an ulp of 1.
Sourcefn inv_bessel_i_ratio_1m<P: Policy>(self, _nu: Self) -> Self
fn inv_bessel_i_ratio_1m<P: Policy>(self, _nu: Self) -> Self
The kappa with 1 - I_nu(kappa) / I_{nu-1}(kappa) = t, the complement form.
Sourcefn bessel_ratio<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
fn bessel_ratio<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
bessel::ratio::<F>(nu): see BesselRatioFamily.
Sourcefn inv_bessel_ratio<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
fn inv_bessel_ratio<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
inv_bessel::ratio::<F>(r).
Sourcefn bessel_ratio_1m<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
fn bessel_ratio_1m<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
bessel_ratio_1m::<F>(nu).
Sourcefn inv_bessel_ratio_1m<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
fn inv_bessel_ratio_1m<P: Policy, F: BesselRatioFamily>(self, nu: Self) -> Self
inv_bessel_ratio_1m::<F>(t).
Sourcefn gauss_legendre<P: Policy>(self, n: u32) -> (Self, Self)
fn gauss_legendre<P: Policy>(self, n: u32) -> (Self, Self)
(x_k, w_k) of the n-point Gauss-Legendre rule, the index k per lane. See
generic::quadrature.
Sourcefn gauss_hermite<P: Policy>(self, n: u32) -> (Self, Self)
fn gauss_hermite<P: Policy>(self, n: u32) -> (Self, Self)
(x_k, w_k) of the n-point Gauss-Hermite rule, the index k per lane.
Sourcefn gauss_laguerre<P: Policy>(self, alpha: Self, n: u32) -> (Self, Self)
fn gauss_laguerre<P: Policy>(self, alpha: Self, n: u32) -> (Self, Self)
(x_k, w_k) of the n-point Gauss-Laguerre rule with weight x^alpha e^{-x}, the
index k and alpha per lane.
Sourcefn agm<P: Policy>(a: Self, b: Self) -> Self
fn agm<P: Policy>(a: Self, b: Self) -> Self
AGM(a, b), sharing its recurrence with the complete elliptic integrals.
Sourcefn pochhammer<P: Policy>(z: Self, m: Self) -> Self
fn pochhammer<P: Policy>(z: Self, m: Self) -> Self
zeta(s) - 1, the primitive of the pair: the Euler-Maclaurin sum’s leading term is
the 1, so omitting it is exact where subtracting it afterwards is not.
The kernel needs E: BernoulliNumbers and its own ZetaConsts, which a generic E on
this trait does not carry, the same bind polygamma is in. The
ps/pd impls override this at the concrete element. The default here is what a
composite gets until it supplies its own.
(z)_m = Gamma(z+m)/Gamma(z), by exact product where m is a small integer and by
the Stirling difference otherwise. Never forms lgamma(z+m) - lgamma(z) except in
the residual region where nothing else applies.
Sourcefn jacobi_elliptic<P: Policy>(u: Self, k: Self) -> (Self, Self, Self)
fn jacobi_elliptic<P: Policy>(u: Self, k: Self) -> (Self, Self, Self)
(sn, cn, dn) by the arithmetic-only descending Landen transformation.
Composite types that carry derivatives override this: the triple is closed under
d/du, so the derivative components are products of the values and there is no
reason to differentiate the ladder itself.
Sourcefn boxcox<P: Policy>(self, lambda: Self) -> Self
fn boxcox<P: Policy>(self, lambda: Self) -> Self
(x^lambda - 1)/lambda, ln x at lambda = 0.
powf_m1 builds x^lambda - 1 without forming x^lambda, so the division by lambda
is the whole algorithm: there is no cancellation left to protect against and hence
no near-zero series, which the obvious (pow(x, l) - 1)/l spelling would need by
l = 1e-8. Verified a few ulp from lambda = 1e-300 outward.
lambda is a fitted parameter, so it is uniform across a vector in every real use and
the two uniform branches are what actually run. The blend is there for correctness on
a mixed vector, not for speed.
The domain edge x = 0 needs no guard here. powf_m1(0, lambda) is -1 for
lambda > 0 and +inf below, so the division delivers the conventional -1/lambda and
-inf on its own, and more accurately than a reciprocal would. The Best-tier Dekker
residual in powf_m1 carries the edge itself, so nothing is patched up here.
Sourcefn boxcox_1p<P: Policy>(self, lambda: Self) -> Self
fn boxcox_1p<P: Policy>(self, lambda: Self) -> Self
((1 + x)^lambda - 1)/lambda, ln(1 + x) at lambda = 0.
Structurally identical to boxcox, over compound_m1 instead of
powf_m1 so that x near zero keeps its low bits, which is the only reason to have
it, and the reason Yeo-Johnson is built on it.
Sourcefn inv_boxcox<P: Policy>(self, lambda: Self) -> Self
fn inv_boxcox<P: Policy>(self, lambda: Self) -> Self
(lambda*y + 1)^(1/lambda), e^y at lambda = 0. The inverse of
boxcox.
Evaluated as exp(ln1p(lambda*y)/lambda) rather than powf:
lambda*y is small exactly where the forward transform’s lambda is, so 1 + lambda*y
would round it away and the whole reason boxcox is accurate near lambda = 0 would
be undone on the way back.
Sourcefn inv_boxcox_1p<P: Policy>(self, lambda: Self) -> Self
fn inv_boxcox_1p<P: Policy>(self, lambda: Self) -> Self
(lambda*y + 1)^(1/lambda) - 1, e^y - 1 at lambda = 0. The inverse of
boxcox_1p.
Same exponent as inv_boxcox with expm1 outside it, so the
result keeps its relative accuracy where it is near zero, which, this being the
inverse of a transform of data centered near zero, is the ordinary case.
Sourcefn yeo_johnson<P: Policy>(self, lambda: Self) -> Self
fn yeo_johnson<P: Policy>(self, lambda: Self) -> Self
The Yeo-Johnson transform of y = self with parameter lambda.
Four cases in the literature, one kernel here: the transform is odd about the origin
in the sense that the y < 0 branch is the y >= 0 branch applied to |y| with
lambda reflected to 2 - lambda and the result negated. Folding the sign out first
collapses both ln special cases (lambda = 0 above zero, lambda = 2 below) into
the single lambda = 0 seam that boxcox_1p already handles.
Sourcefn inv_yeo_johnson<P: Policy>(self, lambda: Self) -> Self
fn inv_yeo_johnson<P: Policy>(self, lambda: Self) -> Self
The inverse Yeo-Johnson transform. The same sign fold as
yeo_johnson, over inv_boxcox_1p.
The transform is monotone increasing and fixes the origin, so the branch condition on
the way back is the sign of the transformed value, which is the sign of y.
fn gelu<P: Policy>(self, alpha: Self) -> Self
fn swish<P: Policy>(self, beta: Self) -> Self
fn algebraic_sigmoid_n<P: Policy, const N: usize>(self) -> Self
Sourcefn algebraic_sigmoid<P: Policy>(self, n: u32) -> Self
fn algebraic_sigmoid<P: Policy>(self, n: u32) -> Self
The runtime twin of algebraic_sigmoid_n, same arithmetic.
fn algebraic_swish<P: Policy>(self) -> Self
fn gaussian_integral<P: Policy>(x0: Self, x1: Self, a: Self, c: Self) -> Self
Sourcefn spherical_harmonics_table<P: Policy, const L: usize, const N: usize, const CS: bool>(
table: &mut ShTable<Self::Primal, N>,
)
fn spherical_harmonics_table<P: Policy, const L: usize, const N: usize, const CS: bool>( table: &mut ShTable<Self::Primal, N>, )
Fills a runtime coefficient table for degree L and phase CS. See
sh_impl for the conventions, layout, and algorithm.
The direction-independent half of the work, split out so a caller sweeping many
directions pays it once: pair it with spherical_harmonics_with.
The table records its own phase, which is why the evaluators take no CS.
The default computes every coefficient from its closed form in l and m
(two sqrt and two divisions apiece) using nothing but FloatVector
arithmetic, so it works at any degree and on any element type. Real f32/f64
vectors override it to splat the compile-time table instead whenever
L <= MAX_DEGREE, which removes the arithmetic entirely.
Sourcefn spherical_harmonics_with<P: Policy, const L: usize, const N: usize>(
table: &ShTable<Self::Primal, N>,
x: Self,
y: Self,
z: Self,
out: &mut [Self; N],
)
fn spherical_harmonics_with<P: Policy, const L: usize, const N: usize>( table: &ShTable<Self::Primal, N>, x: Self, y: Self, z: Self, out: &mut [Self; N], )
Evaluates all harmonics through degree L from a table built by
spherical_harmonics_table.
The default lifts each Self::Primal coefficient through from_primal as it
is read. That is the identity for types that are their own primal, so they
keep the fused single-type kernel. Composites with a cheaper mixed multiply
(Dual) override this.
Sourcefn spherical_harmonics<P: Policy, const L: usize, const N: usize, const CS: bool>(
x: Self,
y: Self,
z: Self,
out: &mut [Self; N],
)
fn spherical_harmonics<P: Policy, const L: usize, const N: usize, const CS: bool>( x: Self, y: Self, z: Self, out: &mut [Self; N], )
The one-shot form: build a table and evaluate it.
This default composes spherical_harmonics_table
with spherical_harmonics_with, so it needs no
compile-time table and works on every element type and at any degree. Real
f32/f64 vectors override it with the fully-unrolled kernel for
L <= MAX_DEGREE.
A caller in a loop over directions should build the table once and call
spherical_harmonics_with instead. This rebuilds it on every invocation, and
the table is the expensive part.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".