You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First and foremost, thanks for all the works in statrs! It's really nice to work with it!
Recently, I have been using it to build a polars expression plugin, which I hope to open source soon enough. One last bit before doing so was to stress test tail accuracy.
Important
Mandatory disclaimer: this is my first experience writing rust code
The issue
Beta::sf(x) forms the complement before the call:
beta::beta_reg(self.shape_b,self.shape_a,1.0 - x)
For small values of x (< 1.1e-16) the argument 1.0 - x rounds to exactly 1.0, so sf returns 1.0 regardless of the shapes.
With shape_a < 1 the lower tail carries real mass and the answer is gone: Beta(0.05, 0.05).sf(1e-16) returns 1.0 where the value is 0.92045095674306394, a relative error of 8.6e-2.
1.0 - cdf(x) on the same object is accurate to 16 digits, because on that side of the split beta_reg never sees a rounded argument. Only the routing is wrong.
Premise
First and foremost, thanks for all the works in statrs! It's really nice to work with it!
Recently, I have been using it to build a polars expression plugin, which I hope to open source soon enough. One last bit before doing so was to stress test tail accuracy.
Important
Mandatory disclaimer: this is my first experience writing rust code
The issue
Beta::sf(x)forms the complement before the call:For small values of
x(< 1.1e-16) the argument1.0 - xrounds to exactly1.0, sosfreturns1.0regardless of the shapes.With
shape_a < 1the lower tail carries real mass and the answer is gone:Beta(0.05, 0.05).sf(1e-16)returns1.0where the value is0.92045095674306394, a relative error of8.6e-2.1.0 - cdf(x)on the same object is accurate to 16 digits, because on that side of the splitbeta_regnever sees a rounded argument. Only the routing is wrong.Environment: statrs
0.19.0(default-features = false, features = ["std"]), rustc 1.97.1, aarch64-apple-darwin,--release.Reproducer
x = 1e-16 (1-x) = 9.999999999999999e-1 sf = 1.00000000000000000 1 - cdf = 0.84216163834910041 x = 1e-18 (1-x) = 1e0 sf = 1.00000000000000000 1 - cdf = 0.87462453281806818 x = 1e-20 (1-x) = 1e0 sf = 1.00000000000000000 1 - cdf = 0.90041072647564402 x = 1e-30 (1-x) = 1e0 sf = 1.00000000000000000 1 - cdf = 0.96850710651415306 x = 1e-100 (1-x) = 1e0 sf = 1.00000000000000000 1 - cdf = 0.99999004107264755```Expected
Reference from
mpmathatmp.dps = 60(same asscipy.stats.beta(0.05, 0.05).sf(values)):xsf1 - cdfsf1e-161.00.920450956743063940.920450956743063998.6e-21e-181.00.936811948895712470.936811948895712516.8e-21e-201.00.949807946910663600.949807946910663615.3e-21e-301.00.984127879179760620.984127879179760631.6e-21e-1001.00.999994980794691070.999994980794691075.0e-6Script for the reference column
Suggested fix (Claude assisted, due to above disclaimer)
FYI I would be interested in trying opening a PR