-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add FRAC_1_SQRT_2PI
constant
#383
Comments
I'm wondering if it'd be possible have some macro that evaluates things infinite precision and spits out a float constant. E.g. |
@the8472 you don't need infinite precision, doing the computation in a higher precision than But please don't make |
I'm fine with this constant, although the hill I will die on (for my corpse to rot away and be ignored) is that it should be I mean this in the sense of, I would like this change in naming, but absolutely will not block it over this. |
@clarfonthey I see your point. What's your take on (renaming and) adding |
One big reason why And practically everyone used |
(Speaking for myself here.) |
We discussed this in today's @rust-lang/libs-api meeting. We observed that this constant doesn't currently exist among C's constants, but we were still sympathetic to adding this. We're inclined to add this, but we'd like a second opinion. I think @m-ou-se has worked with the C constants before. Do you have an opinion on this? |
Two existing alternatives: // You could just define the const locally
const FRAC_1_SQRT_2PI: f32 = FRAC_1_SQRT_2 * FRAC_1_SQRT_PI;
// Or write the obvious thing; LLVM will optimize it just as well
(2.0 * PI).sqrt().recip() / sigma All of That's partially by chance, since for different real values In principle, I'm mildly against adding more constants that are just simple expressions, since it clutters (even if only slightly) the library and only helps the cases that need that specific constant. Once you want to further map that constant, the benefit over just writing the expression mostly disappears. We have a language for composing expressions already, so I'd rather see and work with something like |
Proposal
Problem statement
Statistical calculations, image and signal processing applications commonly need to calculate a scaling factor of
1/√(2π)
for the Gaussian probability distribution (specifically,1/(σ√(2π))
where sigma is application specific).The standard normal distribution is the same with trivially
σ=1
(andx=y
):With the current constants, the calculation of the scaling term requires$\frac{1}{\sqrt{2}} \times \frac{1}{\sqrt{\pi}}$ , i.e.:
I propose to add
FRAC_1_SQRT_2PI
(as1/√(2π)
) in order to simplify this toFRAC_1_SQRT_2PI / sigma
reducing clutter and keeping mathematical precision.
This would go in line with #103883 and rust-lang/rust#123850 which add the
FRAC_1_SQRT_PI
constant (1/√π
).Motivating examples or use cases
The image processing library
imgproc
uses this code for calculating a blur filter:This example is less about the choice of a functional implementation style, but it showcases the need for this particular calculation. (Do note that since this is an image processing application, the parameter
sigma
must be freely settable and at least parts of the scaling term must be determined ad-hoc.)The Normal Distribution (Gaussian PDF), Bayesian Statistics as a whole, Error Function calculation and Fourier Transformations are all centered around the same fundamental calculation.
In financial applications, the Black-Scholes model comes up. As an example, the
black_scholes_rust
crate implements it like this.In physics, the Maxwell-Boltzmann equation has the term as$(\bullet)^\frac{3}{2}$ (
.powf(1.5)
).Solution sketch
Trivially, adding
FRAC_1_SQRT_2PI
as1/√(2π) = 0.3989422804014326779399460599343818684758586311649346576659258296…
(from here). I went ahead and drafted it in rust-lang/rust#125253.Alternatives
A combination of
FRAC_1_SQRT_PI
andFRAC_1_SQRT_2
can be used, however at more visual clutter. Applications can make use ofconst
evaluation and reuse their own constant, but this may be subject to floating point processing on the individual machine (arguably; I did not analyze the error potential here).In some cases (e.g. signal processing) the entire calculation can be done "on paper", e.g. when the standard deviation parameter sigma will never change in signal processing applications or image filtering.
Bivariate normal distributions do not have this problem, so this focuses on the most common Gaussians.
Links and related work
Implementation of the above:
FRAC_1_SQRT_2PI
constant to f16/f32/f64/f128 rust#125253Related proposals:
erf
,erfc
) to thef32
/f64
API. #352Previous work on constants:
more_float_constants
rust#103883What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution:
The text was updated successfully, but these errors were encountered: