Open avhz opened 8 months ago
IMO the only reason to add erf
and erfc
is matching the content of math.h
in C99 / C++11. The implementation should just defer to the build environment's libm.a
or compiler-builtins
i.e.
extern "C" {
fn erf(x: f64) -> f64;
}
...
impl f64 {
pub fn erf(self) -> Self {
unsafe { cmath::erf(self) }
}
}
POSIX also defined the Bessel functions (j0
, j1
, jn
, y0
, y1
, yn
), but these are not part of any C standard. That being said lgamma_r
referred in cmath.rs
is also not part of C99 either, not even POSIX.
The gamma functions (rust-lang/rust#99842) are still not stable yet. But rust-lang/rust#26350 explicitly mentioned tgamma
as something that should not be part of standard library. Certainly the same argument applies to erf
.
What is this? Is it relevant?
@kennytm all valid points. Is there anyone else worth checking with? I can close the issue if not.
Cc @workingjubilee, since you usually have useful opinions on floating point stuff. :)
Can someone offer a clarifying explanation of why f32::erf
, f64::erf
, f32::erfc
, and f64::erfc
should not be added to std
? It appears that on Rust 1.77, std
provides methods for logarithms, cube root, trig functions, and Gamma functions on floating point primatives. Is there a reason why these functions should be provided by std
but erf
and erfc
should not? What is different about erf
and erfc
relative to these functions that justifies their exclusion from std
?
I admit that I agree that std
should probably not provide methods for every single named function of the Reals, as doing so could cause users to face low SNR in the documentation and could pose unwanted maintenance burden for the maintainers, but the line drawn as it currently is seems pretty arbitrary to me.
@pezcore
Elementary functions like log
and sin
/cos
can be lowered to LLVM intrinsics so the core
library can stay not explicitly relying on libm
thus avoiding rust-lang/rust#26350.
gamma
is not yet stable, and could be removed because of the libm
dependency (see my comment above https://github.com/rust-lang/libs-team/issues/352#issuecomment-1992094858).
IMO if we accept (stabilize) gamma
we should also accept erf
, and if we remove gamma
there is no reason for erf
in std either.
Proposal
Problem statement
The
f32
/f64
APIs are missing some useful functions, namelyerf
anderfc
, such as inlibm
(where the currentgamma
function is from I believe) or the C++ Faddeeva library.Motivating examples or use cases
The error function is used in numerous areas of scientific computing, such as statistics where the CDF of the Normal Distribution can be written in terms of it:
$$ \mathbb{P}(X \leq x) = F_X(x) = \Phi\left(\frac{x-\mu}{\sigma}\right) = \frac{1}{2} \left[ 1 + \text{erf}\left( \frac{x-\mu}{\sigma\sqrt{2}} \right) \right] $$
Solution sketch
As far as I can tell, the float functions are already from the libm crate, and
erf
,erfc
have just been skipped for some reason.Alternatives
There are obviously multiple ways to implement integrals numerically, but if the gamma function from libm was good enough, I don't see why the error function wouldn't be.
Another alternative is to port the Faddeeva library from C++ (released under an MIT licence).
Links and related work
f32
andf64
libm
cratelibm
error function