Add erf
and erfc
to f32
and f64
· Issue #89 · rust-lang/libs-team (original) (raw)
Proposal
Problem statement
The Gauss error function erf
occurs relatively frequently in statistics and physics and is part of the C99 standard library. Currently the erf
function and the related erfc
are only accessible in Rust via external crates (e.g. libm).
Motivation, use-cases
The error function erf
on a real number xxx is defined as:
mathrmerfx=frac2sqrtpiint0xe−t2dt\mathrm{erf} x = \frac{2}{\sqrt\pi}\int_0^x e^{-t^2} dtmathrmerfx=frac2sqrtpiint0xe−t2dt
Specific cases for erf
:
- erf(±0) returns ±0
- erf(±∞) returns ±1
- erf(NaN) returns NaN
The related complementary error function erfc
is defined as:
mathrmerfcx=1−mathrmerfx\mathrm{erfc} x = 1 - \mathrm{erf} xmathrmerfcx=1−mathrmerfx
Specific cases for erfc
:
- erfc(∞) returns 0
- erfc(-∞) returns 2
- erfc(NaN) returns NaN
These functions cannot be simply expressed in terms of the other Rust std library floating-point functions. The function is available in the standard libraries of C since C99 and Python since Python 3.2.
The primary use case for erf
is its relation to the cumulative distribution function Phi\PhiPhi of the normal (Gaussian) distribution, which occurs frequently in statistics. The relationship, expressed in terms of erf
on f64 is:
fn phi(x: f64) -> f64 { 0.5 * (1.0 + (x * f64::consts::FRAC_1_SQRT_2).erf()) }
or in terms of erfc
as:
fn phi(x: f64) -> f64 { 0.5 * (-x * f64::consts::FRAC_1_SQRT_2).erfc() }
This link to the normal distribution results in erf
(and functions derived from erf
) occurring fairly often in mathematical/statistical code. Together with the ongoing proposal for implementing the gamma function (rust-lang/rfcs#864), this brings Rust's standard library closer to implementing the full range of mathematical functions in C99.
Solution sketches
For C99-compatible implementations of the C standard library, the process would involve exposing the library functions erf
and erfc
(for f64
), and erff
and erfcf
(for f32
).
Otherwise there exists a Rust implementation in the libm crate, which would provide a basis in case of any future plans to move the floating point mathematical functions into core
.
An alternative approach might be to stabilise the cumulative normal distribution function Phi\PhiPhi directly, though this would require additional processing of the C standard library output and possibly be less familiar than having erf
available directly given its inclusion in the standard libraries of other languages.
Links and related work
- Wikipedia page on the Error function: https://en.wikipedia.org/wiki/Error_function
- Wolfram Mathworld page on Erf: https://mathworld.wolfram.com/Erf.html
- cppreference for C99 library
erf
,erff
,erfl
: https://en.cppreference.com/w/c/numeric/math/erf - cppreference for C99 library
erfc
,erfcf
,erfcl
: https://en.cppreference.com/w/c/numeric/math/erfc - Python reference for
erf
,erfc
: https://docs.python.org/3/library/math.html#special-functions - libm implementation of
erf
/erfc
: https://github.com/rust-lang/libm/blob/master/src/math/erf.rs - libm implementation of
erff
/erfcf
: https://github.com/rust-lang/libm/blob/master/src/math/erff.rs
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.