From 4c0bba158e28384e7f58938b5b2930e3230220dc Mon Sep 17 00:00:00 2001 From: Lakshay Garg Date: Fri, 18 Aug 2017 23:04:02 +0530 Subject: [PATCH] math: implement the erfcinv function Fixes: #6359 Change-Id: I6c697befd681a253e73a7091faa9f20ff3791201 Reviewed-on: https://go-review.googlesource.com/57090 Reviewed-by: Robert Griesemer --- src/math/all_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ src/math/erfinv.go | 11 ++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/math/all_test.go b/src/math/all_test.go index 7c1794f3d7..89abcf063d 100644 --- a/src/math/all_test.go +++ b/src/math/all_test.go @@ -971,6 +971,23 @@ var erfinvSC = []float64{ NaN(), } +var vferfcinvSC = []float64{ + 0, + 2, + 1, + Inf(1), + Inf(-1), + NaN(), +} +var erfcinvSC = []float64{ + Inf(+1), + Inf(-1), + 0, + NaN(), + NaN(), + NaN(), +} + var vfexpSC = []float64{ Inf(-1), -2000, @@ -2175,6 +2192,30 @@ func TestErfinv(t *testing.T) { } } +func TestErfcinv(t *testing.T) { + for i := 0; i < len(vf); i++ { + a := 1.0 - (vf[i] / 10) + if f := Erfcinv(a); !veryclose(erfinv[i], f) { + t.Errorf("Erfcinv(%g) = %g, want %g", a, f, erfinv[i]) + } + } + for i := 0; i < len(vferfcinvSC); i++ { + if f := Erfcinv(vferfcinvSC[i]); !alike(erfcinvSC[i], f) { + t.Errorf("Erfcinv(%g) = %g, want %g", vferfcinvSC[i], f, erfcinvSC[i]) + } + } + for x := 0.1; x <= 1.9; x += 1e-2 { + if f := Erfc(Erfcinv(x)); !close(x, f) { + t.Errorf("Erfc(Erfcinv(%g)) = %g, want %g", x, f, x) + } + } + for x := 0.1; x <= 1.9; x += 1e-2 { + if f := Erfcinv(Erfc(x)); !close(x, f) { + t.Errorf("Erfcinv(Erfc(%g)) = %g, want %g", x, f, x) + } + } +} + func TestExp(t *testing.T) { testExp(t, Exp, "Exp") testExp(t, ExpGo, "ExpGo") @@ -3036,6 +3077,14 @@ func BenchmarkErfinv(b *testing.B) { GlobalF = x } +func BenchmarkErfcinv(b *testing.B) { + x := 0.0 + for i := 0; i < b.N; i++ { + x = Erfcinv(.5) + } + GlobalF = x +} + func BenchmarkExp(b *testing.B) { x := 0.0 for i := 0; i < b.N; i++ { diff --git a/src/math/erfinv.go b/src/math/erfinv.go index 3ea38e0355..21b5578c84 100644 --- a/src/math/erfinv.go +++ b/src/math/erfinv.go @@ -114,3 +114,14 @@ func Erfinv(x float64) float64 { } return ans } + +// Erfcinv returns the inverse of Erfc(x). +// +// Special cases are: +// Erfcinv(0) = +Inf +// Erfcinv(2) = -Inf +// Erfcinv(x) = NaN if x < 0 or x > 2 +// Erfcinv(NaN) = NaN +func Erfcinv(x float64) float64 { + return Erfinv(1 - x) +} -- 2.50.0