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