1
0
mirror of https://github.com/golang/go synced 2024-10-02 14:28:38 -06:00

math: implement the erfcinv function

Fixes: #6359

Change-Id: I6c697befd681a253e73a7091faa9f20ff3791201
Reviewed-on: https://go-review.googlesource.com/57090
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Lakshay Garg 2017-08-18 23:04:02 +05:30 committed by Robert Griesemer
parent bdd7c01b55
commit 4c0bba158e
2 changed files with 60 additions and 0 deletions

View File

@ -971,6 +971,23 @@ var erfinvSC = []float64{
NaN(), 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{ var vfexpSC = []float64{
Inf(-1), Inf(-1),
-2000, -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) { func TestExp(t *testing.T) {
testExp(t, Exp, "Exp") testExp(t, Exp, "Exp")
testExp(t, ExpGo, "ExpGo") testExp(t, ExpGo, "ExpGo")
@ -3036,6 +3077,14 @@ func BenchmarkErfinv(b *testing.B) {
GlobalF = x 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) { func BenchmarkExp(b *testing.B) {
x := 0.0 x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {

View File

@ -114,3 +114,14 @@ func Erfinv(x float64) float64 {
} }
return ans 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)
}