pub trait SpecializedComplexSpecialMath<E>: ComplexVector<Element = E> {
// Required methods
fn complex_tgamma<P: Policy>(self) -> Self;
fn complex_lgamma<P: Policy>(self) -> Self;
fn complex_digamma<P: Policy>(self) -> Self;
fn complex_trigamma<P: Policy>(self) -> Self;
fn complex_lambert_w<P: Policy>(self) -> (Self, Self);
fn faddeeva_w<P: Policy>(self) -> Self;
// Provided methods
fn erfcx<P: Policy>(self) -> Self { ... }
fn voigt<P: Policy>(self) -> Self::Real { ... }
fn complex_beta<P: Policy>(self, b: Self) -> Self { ... }
}special only.Expand description
The complex special functions whose algorithms carry element-specific coefficient tables.
SpecializedSpecialMath for Complex<V> is one blanket impl that forwards here,
so the f32 and f64 cases can diverge exactly the way thermite-special’s own
ps.rs/pd.rs do. The shared bodies are free functions in this module that take
their coefficients as slices; an impl supplies the table and little else.
Self is the complex vector, so these are ordinary self methods and the
per-element dispatch is in the impl header (for Complex<V> where V::Element = f64).
That shape is what lets decl_complex_math! generate
ComplexSpecialMath from it, exactly as it generates
ComplexMath from SpecializedComplexMath.
A type only reaches SpecialMath over C by implementing this, which is why the
element-agnostic members (erf, logistic_sigmoid, …) are not on it: they stay
in the blanket impl and cost an implementor nothing. The Gamma members keep their
complex_ prefix because SpecialMath already exposes tgamma/lgamma/… on the
same types, and two traits offering one name makes every call ambiguous.
Required Methods§
fn complex_tgamma<P: Policy>(self) -> Self
fn complex_lgamma<P: Policy>(self) -> Self
fn complex_digamma<P: Policy>(self) -> Self
fn complex_trigamma<P: Policy>(self) -> Self
fn complex_lambert_w<P: Policy>(self) -> (Self, Self)
Sourcefn faddeeva_w<P: Policy>(self) -> Self
fn faddeeva_w<P: Policy>(self) -> Self
The Faddeeva function $w(z) = e^{-z^2}\operatorname{erfc}(-iz)$.
Carries the Weideman coefficient table, hence its place here. See
faddeeva for the algorithm and the accuracy ladder.
Provided Methods§
Sourcefn erfcx<P: Policy>(self) -> Self
fn erfcx<P: Policy>(self) -> Self
$\operatorname{erfcx}(z) = e^{z^2}\operatorname{erfc}(z) = w(iz)$.
The scaled complementary error function: erfc without the exponential
underflow, so it stays meaningful where erfc itself has flushed to zero.
Sourcefn voigt<P: Policy>(self) -> Self::Real
fn voigt<P: Policy>(self) -> Self::Real
The Voigt function $K(x, y) = \operatorname{Re} w(x + iy)$, the convolution of
a Gaussian and a Lorentzian in normalized coordinates, as a real value.
The one consumer that wants the real part alone, and so the one that depends on
the near-real-axis correction. Use Best or above; that is where it is enabled.
Normalization is left to the caller: physical line shapes want an additional
$1/(\sigma\sqrt{2\pi})$ and a scaling of x and y by the Doppler width.
Sourcefn complex_beta<P: Policy>(self, b: Self) -> Self
fn complex_beta<P: Policy>(self, b: Self) -> Self
$B(a, b) = \frac{\Gamma(a)\Gamma(b)}{\Gamma(a+b)}$
Deliberately not exp(lgamma(a) + lgamma(b) - lgamma(a+b)): over C the
principal log-gamma branches do not add, so the exponentiated form is correct
only up to a factor of $e^{2\pi i k}$. The quotient of gammas has no branch
to get wrong, at the cost of overflowing where the log form would not.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl<E, V: FloatVector<Element = E>, const N: usize> SpecializedComplexSpecialMath<Complex<Dual<E, N>>> for Complex<Dual<V, N>>
dual only.