View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *     https://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.hipparchus.special;
19  
20  import org.hipparchus.Field;
21  import org.hipparchus.UnitTestUtils;
22  import org.hipparchus.util.Binary64;
23  import org.hipparchus.util.Binary64Field;
24  import org.hipparchus.util.FastMath;
25  import org.junit.Assert;
26  import org.junit.Test;
27  
28  /**
29   */
30  public class ErfTest {
31      final Field<Binary64> field = Binary64Field.getInstance();
32      final Binary64 zero = field.getZero();
33      final Binary64 one = field.getOne();
34  
35      @Test
36      public void testErf0() {
37          double actual = Erf.erf(0.0);
38          double expected = 0.0;
39          Assert.assertEquals(expected, actual, 1.0e-15);
40          Assert.assertEquals(1 - expected, Erf.erfc(0.0), 1.0e-15);
41      }
42  
43      @Test
44      public void testErf0Field() {
45          Binary64 actual   = Erf.erf(zero);
46          Binary64 expected = zero;
47          Assert.assertEquals(zero.getReal(), actual.getReal(), 1.0e-15);
48          Assert.assertEquals(one.subtract(expected).getReal(), Erf.erfc(zero).getReal(), 1.0e-15);
49      }
50  
51      @Test
52      public void testErf1960() {
53          double x = 1.960 / FastMath.sqrt(2.0);
54          double actual = Erf.erf(x);
55          double expected = 0.95;
56          Assert.assertEquals(expected, actual, 1.0e-5);
57          Assert.assertEquals(1 - actual, Erf.erfc(x), 1.0e-15);
58  
59          actual = Erf.erf(-x);
60          expected = -expected;
61          Assert.assertEquals(expected, actual, 1.0e-5);
62          Assert.assertEquals(1 - actual, Erf.erfc(-x), 1.0e-15);
63      }
64  
65      @Test
66      public void testErf1960Field() {
67          Binary64 x = one.multiply(1.960).divide(FastMath.sqrt(2.0));
68          Binary64 actual = Erf.erf(x);
69          Binary64 expected = one.multiply(0.95);
70          Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
71          Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x).getReal(), 1.0e-15);
72  
73          actual = Erf.erf(x.negate());
74          expected = expected.negate();
75          Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
76          Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x.negate()).getReal(), 1.0e-15);
77      }
78  
79      @Test
80      public void testErf2576() {
81          double x = 2.576 / FastMath.sqrt(2.0);
82          double actual = Erf.erf(x);
83          double expected = 0.99;
84          Assert.assertEquals(expected, actual, 1.0e-5);
85          Assert.assertEquals(1 - actual, Erf.erfc(x), 1e-15);
86  
87          actual = Erf.erf(-x);
88          expected = -expected;
89          Assert.assertEquals(expected, actual, 1.0e-5);
90          Assert.assertEquals(1 - actual, Erf.erfc(-x), 1.0e-15);
91      }
92  
93      @Test
94      public void testErf2576Field() {
95          Binary64 x = one.multiply(2.576).divide(FastMath.sqrt(2.0));
96          Binary64 actual = Erf.erf(x);
97          Binary64 expected = one.multiply(0.99);
98          Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
99          Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x).getReal(), 1.0e-15);
100 
101         actual = Erf.erf(x.negate());
102         expected = expected.negate();
103         Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
104         Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x.negate()).getReal(), 1.0e-15);
105     }
106 
107     @Test
108     public void testErf2807() {
109         double x = 2.807 / FastMath.sqrt(2.0);
110         double actual = Erf.erf(x);
111         double expected = 0.995;
112         Assert.assertEquals(expected, actual, 1.0e-5);
113         Assert.assertEquals(1 - actual, Erf.erfc(x), 1.0e-15);
114 
115         actual = Erf.erf(-x);
116         expected = -expected;
117         Assert.assertEquals(expected, actual, 1.0e-5);
118         Assert.assertEquals(1 - actual, Erf.erfc(-x), 1.0e-15);
119     }
120 
121     @Test
122     public void testErf2807Field() {
123         Binary64 x = one.multiply(2.807).divide(FastMath.sqrt(2.0));
124         Binary64 actual = Erf.erf(x);
125         Binary64 expected = one.multiply(0.995);
126         Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
127         Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x).getReal(), 1.0e-15);
128 
129         actual = Erf.erf(x.negate());
130         expected = expected.negate();
131         Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
132         Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x.negate()).getReal(), 1.0e-15);
133     }
134 
135     @Test
136     public void testErf3291() {
137         double x = 3.291 / FastMath.sqrt(2.0);
138         double actual = Erf.erf(x);
139         double expected = 0.999;
140         Assert.assertEquals(expected, actual, 1.0e-5);
141         Assert.assertEquals(1 - expected, Erf.erfc(x), 1.0e-5);
142 
143         actual = Erf.erf(-x);
144         expected = -expected;
145         Assert.assertEquals(expected, actual, 1.0e-5);
146         Assert.assertEquals(1 - expected, Erf.erfc(-x), 1.0e-5);
147     }
148 
149     @Test
150     public void testErf3291Field() {
151         Binary64 x = one.multiply(3.291).divide(FastMath.sqrt(2.0));
152         Binary64 actual = Erf.erf(x);
153         Binary64 expected = one.multiply(0.999);
154         Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
155         Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x).getReal(), 1.0e-15);
156 
157         actual = Erf.erf(x.negate());
158         expected = expected.negate();
159         Assert.assertEquals(expected.getReal(), actual.getReal(), 1.0e-5);
160         Assert.assertEquals(one.subtract(actual).getReal(), Erf.erfc(x.negate()).getReal(), 1.0e-15);
161     }
162 
163     /**
164      * MATH-301, MATH-456
165      */
166     @Test
167     public void testLargeValues() {
168         for (int i = 1; i < 200; i*=10) {
169             double result = Erf.erf(i);
170             Assert.assertFalse(Double.isNaN(result));
171             Assert.assertTrue(result > 0 && result <= 1);
172             result = Erf.erf(-i);
173             Assert.assertFalse(Double.isNaN(result));
174             Assert.assertTrue(result >= -1 && result < 0);
175             result = Erf.erfc(i);
176             Assert.assertFalse(Double.isNaN(result));
177             Assert.assertTrue(result >= 0 && result < 1);
178             result = Erf.erfc(-i);
179             Assert.assertFalse(Double.isNaN(result));
180             Assert.assertTrue(result >= 1 && result <= 2);
181         }
182         Assert.assertEquals(-1, Erf.erf(Double.NEGATIVE_INFINITY), 0);
183         Assert.assertEquals(1, Erf.erf(Double.POSITIVE_INFINITY), 0);
184         Assert.assertEquals(2, Erf.erfc(Double.NEGATIVE_INFINITY), 0);
185         Assert.assertEquals(0, Erf.erfc(Double.POSITIVE_INFINITY), 0);
186     }
187 
188     /**
189      * MATH-301, MATH-456
190      */
191     @Test
192     public void testLargeValuesField() {
193         for (int i = 1; i < 200; i*=10) {
194             final Binary64 iField = new Binary64(i);
195             Binary64 result = Erf.erf(iField);
196             Assert.assertFalse(result.isNaN());
197             Assert.assertTrue(result.getReal() > 0 && result.getReal() <= 1);
198             result = Erf.erf(iField.negate());
199             Assert.assertFalse(result.isNaN());
200             Assert.assertTrue(result.getReal() >= -1 && result.getReal() < 0);
201             result = Erf.erfc(iField);
202             Assert.assertFalse(result.isNaN());
203             Assert.assertTrue(result.getReal() >= 0 && result.getReal() < 1);
204             result = Erf.erfc(iField.negate());
205             Assert.assertFalse(result.isNaN());
206             Assert.assertTrue(result.getReal() >= 1 && result.getReal() <= 2);
207         }
208         Assert.assertEquals(one.negate().getReal(), Erf.erf(new Binary64(Double.NEGATIVE_INFINITY)).getReal(), 0);
209         Assert.assertEquals(one.getReal(), Erf.erf(new Binary64(Double.POSITIVE_INFINITY)).getReal(), 0);
210         Assert.assertEquals(one.multiply(2).getReal(), new Binary64(Erf.erfc(Double.NEGATIVE_INFINITY)).getReal(), 0);
211         Assert.assertEquals(zero.getReal(), Erf.erfc(new Binary64(Double.POSITIVE_INFINITY)).getReal(), 0);
212     }
213 
214     /**
215      * Compare Erf.erf against reference values computed using GCC 4.2.1 (Apple OSX packaged version)
216      * erfl (extended precision erf).
217      */
218     @Test
219     public void testErfGnu() {
220         final double tol = 1E-15;
221         final double[] gnuValues = new double[] {-1, -1, -1, -1, -1,
222         -1, -1, -1, -0.99999999999999997848,
223         -0.99999999999999264217, -0.99999999999846254017, -0.99999999980338395581, -0.99999998458274209971,
224         -0.9999992569016276586, -0.99997790950300141459, -0.99959304798255504108, -0.99532226501895273415,
225         -0.96610514647531072711, -0.84270079294971486948, -0.52049987781304653809,  0,
226          0.52049987781304653809, 0.84270079294971486948, 0.96610514647531072711, 0.99532226501895273415,
227          0.99959304798255504108, 0.99997790950300141459, 0.9999992569016276586, 0.99999998458274209971,
228          0.99999999980338395581, 0.99999999999846254017, 0.99999999999999264217, 0.99999999999999997848,
229          1,  1,  1,  1,
230          1,  1,  1,  1};
231         double x = -10d;
232         for (int i = 0; i < 41; i++) {
233             Assert.assertEquals(gnuValues[i], Erf.erf(x), tol);
234             x += 0.5d;
235         }
236     }
237 
238     /**
239      * Compare Erf.erf against reference values computed using GCC 4.2.1 (Apple OSX packaged version)
240      * erfl (extended precision erf).
241      */
242     @Test
243     public void testErfGnuField() {
244         final double tol = 1E-15;
245         final Binary64[] gnuValues = new Binary64[] {one.negate(), one.negate(), one.negate(), one.negate(), one.negate(),
246         one.negate(), one.negate(), one.negate(), new Binary64(-0.99999999999999997848),
247         new Binary64(-0.99999999999999264217), new Binary64(-0.99999999999846254017), new Binary64(-0.99999999980338395581), new Binary64(-0.99999998458274209971),
248         new Binary64(-0.9999992569016276586), new Binary64(-0.99997790950300141459), new Binary64(-0.99959304798255504108), new Binary64(-0.99532226501895273415),
249         new Binary64(-0.96610514647531072711), new Binary64(-0.84270079294971486948), new Binary64(-0.52049987781304653809),  zero,
250          new Binary64(0.52049987781304653809), new Binary64(0.84270079294971486948), new Binary64(0.96610514647531072711), new Binary64(0.99532226501895273415),
251          new Binary64(0.99959304798255504108), new Binary64(0.99997790950300141459), new Binary64(0.9999992569016276586), new Binary64(0.99999998458274209971),
252          new Binary64(0.99999999980338395581), new Binary64(0.99999999999846254017), new Binary64(0.99999999999999264217), new Binary64(0.99999999999999997848),
253          one,  one,  one,  one,
254          one,  one,  one,  one};
255         Binary64 x = one.multiply(-10d);
256         for (int i = 0; i < 41; i++) {
257             Assert.assertEquals(gnuValues[i].getReal(), Erf.erf(x).getReal(), tol);
258             x = x.add(0.5d);
259         }
260     }
261 
262     /**
263      * Compare Erf.erfc against reference values computed using GCC 4.2.1 (Apple OSX packaged version)
264      * erfcl (extended precision erfc).
265      */
266     @Test
267     public void testErfcGnu() {
268         final double tol = 1E-15;
269         final double[] gnuValues = new double[] { 2,  2,  2,  2,  2,
270         2,  2,  2, 1.9999999999999999785,
271         1.9999999999999926422, 1.9999999999984625402, 1.9999999998033839558, 1.9999999845827420998,
272         1.9999992569016276586, 1.9999779095030014146, 1.9995930479825550411, 1.9953222650189527342,
273         1.9661051464753107271, 1.8427007929497148695, 1.5204998778130465381,  1,
274         0.47950012218695346194, 0.15729920705028513051, 0.033894853524689272893, 0.0046777349810472658333,
275         0.00040695201744495893941, 2.2090496998585441366E-05, 7.4309837234141274516E-07, 1.5417257900280018858E-08,
276         1.966160441542887477E-10, 1.5374597944280348501E-12, 7.3578479179743980661E-15, 2.1519736712498913103E-17,
277         3.8421483271206474691E-20, 4.1838256077794144006E-23, 2.7766493860305691016E-26, 1.1224297172982927079E-29,
278         2.7623240713337714448E-33, 4.1370317465138102353E-37, 3.7692144856548799402E-41, 2.0884875837625447567E-45};
279         double x = -10d;
280         for (int i = 0; i < 41; i++) {
281             Assert.assertEquals(gnuValues[i], Erf.erfc(x), tol);
282             x += 0.5d;
283         }
284     }
285 
286     /**
287      * Compare Erf.erfc against reference values computed using GCC 4.2.1 (Apple OSX packaged version)
288      * erfcl (extended precision erfc).
289      */
290     @Test
291     public void testErfcGnuField() {
292         final double tol = 1E-15;
293         final Binary64[] gnuValues = new Binary64[] { new Binary64(2),  new Binary64(2),  new Binary64(2),  new Binary64(2),  new Binary64(2),
294         new Binary64(2),  new Binary64(2),  new Binary64(2), new Binary64(1.9999999999999999785),
295         new Binary64(1.9999999999999926422), new Binary64(1.9999999999984625402), new Binary64(1.9999999998033839558), new Binary64(1.9999999845827420998),
296         new Binary64(1.9999992569016276586), new Binary64(1.9999779095030014146), new Binary64(1.9995930479825550411), new Binary64(1.9953222650189527342),
297         new Binary64(1.9661051464753107271), new Binary64(1.8427007929497148695), new Binary64(1.5204998778130465381),  one,
298         new Binary64(0.47950012218695346194), new Binary64(0.15729920705028513051), new Binary64(0.033894853524689272893), new Binary64(0.0046777349810472658333),
299         new Binary64(0.00040695201744495893941), new Binary64(2.2090496998585441366E-05), new Binary64(7.4309837234141274516E-07), new Binary64(1.5417257900280018858E-08),
300         new Binary64(1.966160441542887477E-10), new Binary64(1.5374597944280348501E-12), new Binary64(7.3578479179743980661E-15), new Binary64(2.1519736712498913103E-17),
301         new Binary64(3.8421483271206474691E-20), new Binary64(4.1838256077794144006E-23), new Binary64(2.7766493860305691016E-26), new Binary64(1.1224297172982927079E-29),
302         new Binary64(2.7623240713337714448E-33), new Binary64(4.1370317465138102353E-37), new Binary64(3.7692144856548799402E-41),new Binary64( 2.0884875837625447567E-45)};
303         Binary64 x = new Binary64(-10d);
304         for (int i = 0; i < 41; i++) {
305             Assert.assertEquals(gnuValues[i].getReal(), Erf.erfc(x).getReal(), tol);
306             x = x.add(0.5d);
307         }
308     }
309 
310     /**
311      * Tests erfc against reference data computed using Maple reported in Marsaglia, G,,
312      * "Evaluating the Normal Distribution," Journal of Statistical Software, July, 2004.
313      * http//www.jstatsoft.org/v11/a05/paper
314      */
315     @Test
316     public void testErfcMaple() {
317         double[][] ref = new double[][]
318                         {{0.1, 4.60172162722971e-01},
319                          {1.2, 1.15069670221708e-01},
320                          {2.3, 1.07241100216758e-02},
321                          {3.4, 3.36929265676881e-04},
322                          {4.5, 3.39767312473006e-06},
323                          {5.6, 1.07175902583109e-08},
324                          {6.7, 1.04209769879652e-11},
325                          {7.8, 3.09535877195870e-15},
326                          {8.9, 2.79233437493966e-19},
327                          {10.0, 7.61985302416053e-24},
328                          {11.1, 6.27219439321703e-29},
329                          {12.2, 1.55411978638959e-34},
330                          {13.3, 1.15734162836904e-40},
331                          {14.4, 2.58717592540226e-47},
332                          {15.5, 1.73446079179387e-54},
333                          {16.6, 3.48454651995041e-62}
334         };
335         for (int i = 0; i < 15; i++) {
336             final double result = 0.5*Erf.erfc(ref[i][0]/FastMath.sqrt(2));
337             Assert.assertEquals(ref[i][1], result, 1E-15);
338             UnitTestUtils.assertRelativelyEquals(ref[i][1], result, 1E-13);
339         }
340     }
341 
342     /**
343      * Tests erfc against reference data computed using Maple reported in Marsaglia, G,,
344      * "Evaluating the Normal Distribution," Journal of Statistical Software, July, 2004.
345      * http//www.jstatsoft.org/v11/a05/paper
346      */
347     @Test
348     public void testErfcMapleField() {
349         Binary64[][] ref = new Binary64[][]
350                 {{new Binary64(0.1), new Binary64(4.60172162722971e-01)},
351                  {new Binary64(1.2), new Binary64(1.15069670221708e-01)},
352                  {new Binary64(2.3), new Binary64(1.07241100216758e-02)},
353                  {new Binary64(3.4), new Binary64(3.36929265676881e-04)},
354                  {new Binary64(4.5), new Binary64(3.39767312473006e-06)},
355                  {new Binary64(5.6), new Binary64(1.07175902583109e-08)},
356                  {new Binary64(6.7), new Binary64(1.04209769879652e-11)},
357                  {new Binary64(7.8), new Binary64(3.09535877195870e-15)},
358                  {new Binary64(8.9), new Binary64(2.79233437493966e-19)},
359                  {new Binary64(10.0), new Binary64(7.61985302416053e-24)},
360                  {new Binary64(11.1), new Binary64(6.27219439321703e-29)},
361                  {new Binary64(12.2), new Binary64(1.55411978638959e-34)},
362                  {new Binary64(13.3), new Binary64(1.15734162836904e-40)},
363                  {new Binary64(14.4), new Binary64(2.58717592540226e-47)},
364                  {new Binary64(15.5), new Binary64(1.73446079179387e-54)},
365                  {new Binary64(16.6), new Binary64(3.48454651995041e-62)}
366                 };
367         for (int i = 0; i < 15; i++) {
368             final Binary64 result = Erf.erfc(ref[i][0].divide(FastMath.sqrt(2))).multiply(0.5);
369             Assert.assertEquals(ref[i][1].getReal(), result.getReal(), 1E-15);
370             UnitTestUtils.assertRelativelyEquals(ref[i][1].getReal(), result.getReal(), 1E-13);
371         }
372     }
373 
374     /**
375      * Test the implementation of Erf.erf(double, double) for consistency with results
376      * obtained from Erf.erf(double) and Erf.erfc(double).
377      */
378     @Test
379     public void testTwoArgumentErf() {
380         double[] xi = new double[]{-2.0, -1.0, -0.9, -0.1, 0.0, 0.1, 0.9, 1.0, 2.0};
381         for(double x1 : xi) {
382             for(double x2 : xi) {
383                 double a = Erf.erf(x1, x2);
384                 double b = Erf.erf(x2) - Erf.erf(x1);
385                 double c = Erf.erfc(x1) - Erf.erfc(x2);
386                 Assert.assertEquals(a, b, 1E-15);
387                 Assert.assertEquals(a, c, 1E-15);
388             }
389         }
390     }
391 
392     /**
393      * Test the implementation of Erf.erf(double, double) for consistency with results
394      * obtained from Erf.erf(double) and Erf.erfc(double).
395      */
396     @Test
397     public void testTwoArgumentErfField() {
398         Binary64[] xi = new Binary64[]{new Binary64(-2.0), new Binary64(-1.0), new Binary64(-0.9), new Binary64(-0.1), new Binary64(0.0), new Binary64(0.1), new Binary64(0.9), new Binary64(1.0), new Binary64(2.0)};
399         for(Binary64 x1 : xi) {
400             for(Binary64 x2 : xi) {
401                 Binary64 a = Erf.erf(x1, x2);
402                 Binary64 b = Erf.erf(x2).subtract(Erf.erf(x1));
403                 Binary64 c = Erf.erfc(x1).subtract(Erf.erfc(x2));
404                 Assert.assertEquals(a.getReal(), b.getReal(), 1E-15);
405                 Assert.assertEquals(a.getReal(), c.getReal(), 1E-15);
406             }
407         }
408     }
409 
410     @Test
411     public void testErfInvNaN() {
412         Assert.assertTrue(Double.isNaN(Erf.erfInv(-1.001)));
413         Assert.assertTrue(Double.isNaN(Erf.erfInv(+1.001)));
414     }
415 
416     @Test
417     public void testErfInvNaNField() {
418         Assert.assertTrue((Erf.erfInv(new Binary64(-1.001))).isNaN());
419         Assert.assertTrue(Erf.erfInv(new Binary64(+1.001)).isNaN());
420     }
421 
422     @Test
423     public void testErfInvInfinite() {
424         Assert.assertTrue(Double.isInfinite(Erf.erfInv(-1)));
425         Assert.assertTrue(Erf.erfInv(-1) < 0);
426         Assert.assertTrue(Double.isInfinite(Erf.erfInv(+1)));
427         Assert.assertTrue(Erf.erfInv(+1) > 0);
428     }
429 
430     @Test
431     public void testErfInvInfiniteField() {
432         Assert.assertTrue(Double.isInfinite(Erf.erfInv(-1)));
433         Assert.assertTrue(Erf.erfInv(-1) < 0);
434         Assert.assertTrue(Double.isInfinite(Erf.erfInv(+1)));
435         Assert.assertTrue(Erf.erfInv(+1) > 0);
436     }
437 
438     @Test
439     public void testErfInv() {
440         for (double x = -5.9; x < 5.9; x += 0.01) {
441             final double y = Erf.erf(x);
442             final double dydx = 2 * FastMath.exp(-x * x) / FastMath.sqrt(FastMath.PI);
443             Assert.assertEquals(x, Erf.erfInv(y), 1.0e-15 / dydx);
444         }
445     }
446 
447     @Test
448     public void testErfInvField() {
449         for (Binary64 x = new Binary64(-5.9); x.getReal() < 5.9; x = x.add(0.01)) {
450             final Binary64 y = Erf.erf(x);
451             final Binary64 dydx = x.square().negate().exp().multiply(2/FastMath.sqrt(FastMath.PI));
452             Assert.assertEquals(x.getReal(), Erf.erfInv(y).getReal(), 1.0e-15 / dydx.getReal());
453         }
454     }
455 
456     @Test
457     public void testErfcInvNaN() {
458         Assert.assertTrue(Double.isNaN(Erf.erfcInv(-0.001)));
459         Assert.assertTrue(Double.isNaN(Erf.erfcInv(+2.001)));
460     }
461 
462     @Test
463     public void testErfcInvNaNField() {
464         Assert.assertTrue(Erf.erfcInv(new Binary64(-0.001)).isNaN());
465         Assert.assertTrue(Erf.erfcInv(new Binary64(+2.001)).isNaN());
466     }
467 
468     @Test
469     public void testErfcInvInfinite() {
470         Assert.assertTrue(Double.isInfinite(Erf.erfcInv(-0)));
471         Assert.assertTrue(Erf.erfcInv( 0) > 0);
472         Assert.assertTrue(Double.isInfinite(Erf.erfcInv(+2)));
473         Assert.assertTrue(Erf.erfcInv(+2) < 0);
474     }
475 
476     @Test
477     public void testErfcInvInfiniteField() {
478         Assert.assertTrue(Erf.erfcInv(new Binary64(-0)).isInfinite());
479         Assert.assertTrue(Erf.erfcInv( zero).getReal() > 0);
480         Assert.assertTrue(Erf.erfcInv(new Binary64(+2)).isInfinite());
481         Assert.assertTrue(Erf.erfcInv(new Binary64(+2)).getReal() < 0);
482     }
483 
484     @Test
485     public void testErfcInv() {
486         for (double x = -5.85; x < 5.9; x += 0.01) {
487             final double y = Erf.erfc(x);
488             final double dydxAbs = 2 * FastMath.exp(-x * x) / FastMath.sqrt(FastMath.PI);
489             Assert.assertEquals(x, Erf.erfcInv(y), 1.0e-15 / dydxAbs);
490         }
491     }
492 
493     @Test
494     public void testErfcInvField() {
495         for (Binary64 x = new Binary64(-5.85); x.getReal() < 5.9; x = x.add(0.01)) {
496             final Binary64 y = Erf.erfc(x);
497             final Binary64 dydxAbs = x.square().negate().exp().multiply(2/FastMath.sqrt(FastMath.PI));
498             Assert.assertEquals(x.getReal(), Erf.erfcInv(y).getReal(), 1.0e-15 / dydxAbs.getReal());
499         }
500     }
501 }