]> Cypherpunks repositories - gostls13.git/commitdiff
math: implement the erfcinv function
authorLakshay Garg <lakshay.garg.1996@gmail.com>
Fri, 18 Aug 2017 17:34:02 +0000 (23:04 +0530)
committerRobert Griesemer <gri@golang.org>
Tue, 22 Aug 2017 13:13:20 +0000 (13:13 +0000)
Fixes: #6359
Change-Id: I6c697befd681a253e73a7091faa9f20ff3791201
Reviewed-on: https://go-review.googlesource.com/57090
Reviewed-by: Robert Griesemer <gri@golang.org>
src/math/all_test.go
src/math/erfinv.go

index 7c1794f3d7c151fd93c92e592b7708769771248c..89abcf063df0c5a8b5d44ab8a0feb85e85f34cf8 100644 (file)
@@ -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++ {
index 3ea38e0355f29fbe36db8f27c92c6e5d43ede986..21b5578c84f965d8468e39f1ad8ebc16589e29fe 100644 (file)
@@ -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)
+}