Source code: com/hartmath/expression/HDoubleSpecial.java
1 /*
2 * HDoubleSpecial.java
3 * Copyright (C) 2000 Klaus Hartlage
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 package com.hartmath.expression;
20
21 import java.lang.*;
22 import java.io.*;
23 import java.math.*;
24 import java.io.Serializable;
25
26 /**
27 * The special function math library.
28 * This class cannot be subclassed or instantiated because all methods are static.
29 * @version 1.0
30 * @author Mark Hale (modified for hartmath by Klaus Hartlage)
31 *
32 */
33 public class HDoubleSpecial {
34
35 /**
36 * Class Constructor.
37 *
38 *
39 * @see
40 */
41 private HDoubleSpecial() {
42 }
43
44 // CHEBYSHEV SERIES
45 // series for ai0 on the interval 1.25000d-01 to 3.33333d-01
46 // with weighted error 7.87e-17
47 // log weighted error 16.10
48 // significant figures required 14.69
49 // decimal places required 16.76
50
51 private final static double ai0cs[] = {
52 0.07575994494023796, 0.00759138081082334, 0.00041531313389237,
53 0.00001070076463439, -0.00000790117997921, -0.00000078261435014,
54 0.00000027838499429, 0.00000000825247260, -0.00000001204463945,
55 0.00000000155964859, 0.00000000022925563, -0.00000000011916228,
56 0.00000000001757854, 0.00000000000112822, -0.00000000000114684,
57 0.00000000000027155, -0.00000000000002415, -0.00000000000000608,
58 0.00000000000000314, -0.00000000000000071, 0.00000000000000007
59 };
60
61 // series for ai02 on the interval 0. to 1.25000d-01
62 // with weighted error 3.79e-17
63 // log weighted error 16.42
64 // significant figures required 14.86
65 // decimal places required 17.09
66
67 private final static double ai02cs[] = {
68 0.05449041101410882, 0.00336911647825569, 0.00006889758346918,
69 0.00000289137052082, 0.00000020489185893, 0.00000002266668991,
70 0.00000000339623203, 0.00000000049406022, 0.00000000001188914,
71 -0.00000000003149915, -0.00000000001321580, -0.00000000000179419,
72 0.00000000000071801, 0.00000000000038529, 0.00000000000001539,
73 -0.00000000000004151, -0.00000000000000954, 0.00000000000000382,
74 0.00000000000000176, -0.00000000000000034, -0.00000000000000027,
75 0.00000000000000003
76 };
77
78 // series for ai1 on the interval 1.25000d-01 to 3.33333d-01
79 // with weighted error 6.98e-17
80 // log weighted error 16.16
81 // significant figures required 14.53
82 // decimal places required 16.82
83
84 private final static double ai1cs[] = {
85 -0.02846744181881479, -0.01922953231443221, -0.00061151858579437,
86 -0.00002069971253350, 0.00000858561914581, 0.00000104949824671,
87 -0.00000029183389184, -0.00000001559378146, 0.00000001318012367,
88 -0.00000000144842341, -0.00000000029085122, 0.00000000012663889,
89 -0.00000000001664947, -0.00000000000166665, 0.00000000000124260,
90 -0.00000000000027315, 0.00000000000002023, 0.00000000000000730,
91 -0.00000000000000333, 0.00000000000000071, -0.00000000000000006
92 };
93
94 // series for ai12 on the interval 0. to 1.25000d-01
95 // with weighted error 3.55e-17
96 // log weighted error 16.45
97 // significant figures required 14.69
98 // decimal places required 17.12
99
100 private final static double ai12cs[] = {
101 0.02857623501828014, -0.00976109749136147, -0.00011058893876263,
102 -0.00000388256480887, -0.00000025122362377, -0.00000002631468847,
103 -0.00000000383538039, -0.00000000055897433, -0.00000000001897495,
104 0.00000000003252602, 0.00000000001412580, 0.00000000000203564,
105 -0.00000000000071985, -0.00000000000040836, -0.00000000000002101,
106 0.00000000000004273, 0.00000000000001041, -0.00000000000000382,
107 -0.00000000000000186, 0.00000000000000033, 0.00000000000000028,
108 -0.00000000000000003
109 };
110
111 // series for aif on the interval -1.00000d+00 to 1.00000d+00
112 // with weighted error 1.09e-19
113 // log weighted error 18.96
114 // significant figures required 17.76
115 // decimal places required 19.44
116
117 private final static double aifcs[] = {
118 -0.03797135849666999750, 0.05919188853726363857,
119 0.00098629280577279975, 0.00000684884381907656, 0.00000002594202596219,
120 0.00000000006176612774, 0.00000000000010092454, 0.00000000000000012014,
121 0.00000000000000000010
122 };
123
124 // series for aig on the interval -1.00000d+00 to 1.00000d+00
125 // with weighted error 1.51e-17
126 // log weighted error 16.82
127 // significant figures required 15.19
128 // decimal places required 17.27
129
130 private final static double aigcs[] = {
131 0.01815236558116127, 0.02157256316601076, 0.00025678356987483,
132 0.00000142652141197, 0.00000000457211492, 0.00000000000952517,
133 0.00000000000001392, 0.00000000000000001
134 };
135
136 // series for aip on the interval 0. to 1.00000d+00
137 // with weighted error 5.10e-17
138 // log weighted error 16.29
139 // significant figures required 14.41
140 // decimal places required 17.06
141
142 private final static double aipcs[] = {
143 -0.0187519297793868, -0.0091443848250055, 0.0009010457337825,
144 -0.0001394184127221, 0.0000273815815785, -0.0000062750421119,
145 0.0000016064844184, -0.0000004476392158, 0.0000001334635874,
146 -0.0000000420735334, 0.0000000139021990, -0.0000000047831848,
147 0.0000000017047897, -0.0000000006268389, 0.0000000002369824,
148 -0.0000000000918641, 0.0000000000364278, -0.0000000000147475,
149 0.0000000000060851, -0.0000000000025552, 0.0000000000010906,
150 -0.0000000000004725, 0.0000000000002076, -0.0000000000000924,
151 0.0000000000000417, -0.0000000000000190, 0.0000000000000087,
152 -0.0000000000000040, 0.0000000000000019, -0.0000000000000009,
153 0.0000000000000004, -0.0000000000000002, 0.0000000000000001,
154 -0.0000000000000000
155 };
156
157 // series for am21 on the interval -1.25000d-01 to 0.
158 // with weighted error 2.89e-17
159 // log weighted error 16.54
160 // significant figures required 14.15
161 // decimal places required 17.34
162
163 private final static double am21cs[] = {
164 0.0065809191761485, 0.0023675984685722, 0.0001324741670371,
165 0.0000157600904043, 0.0000027529702663, 0.0000006102679017,
166 0.0000001595088468, 0.0000000471033947, 0.0000000152933871,
167 0.0000000053590722, 0.0000000020000910, 0.0000000007872292,
168 0.0000000003243103, 0.0000000001390106, 0.0000000000617011,
169 0.0000000000282491, 0.0000000000132979, 0.0000000000064188,
170 0.0000000000031697, 0.0000000000015981, 0.0000000000008213,
171 0.0000000000004296, 0.0000000000002284, 0.0000000000001232,
172 0.0000000000000675, 0.0000000000000374, 0.0000000000000210,
173 0.0000000000000119, 0.0000000000000068, 0.0000000000000039,
174 0.0000000000000023, 0.0000000000000013, 0.0000000000000008,
175 0.0000000000000005, 0.0000000000000003, 0.0000000000000001,
176 0.0000000000000001, 0.0000000000000000, 0.0000000000000000,
177 0.0000000000000000
178 };
179
180 // series for ath1 on the interval -1.25000d-01 to 0.
181 // with weighted error 2.53e-17
182 // log weighted error 16.60
183 // significant figures required 15.15
184 // decimal places required 17.38
185
186 private final static double ath1cs[] = {
187 -0.07125837815669365, -0.00590471979831451, -0.00012114544069499,
188 -0.00000988608542270, -0.00000138084097352, -0.00000026142640172,
189 -0.00000006050432589, -0.00000001618436223, -0.00000000483464911,
190 -0.00000000157655272, -0.00000000055231518, -0.00000000020545441,
191 -0.00000000008043412, -0.00000000003291252, -0.00000000001399875,
192 -0.00000000000616151, -0.00000000000279614, -0.00000000000130428,
193 -0.00000000000062373, -0.00000000000030512, -0.00000000000015239,
194 -0.00000000000007758, -0.00000000000004020, -0.00000000000002117,
195 -0.00000000000001132, -0.00000000000000614, -0.00000000000000337,
196 -0.00000000000000188, -0.00000000000000105, -0.00000000000000060,
197 -0.00000000000000034, -0.00000000000000020, -0.00000000000000011,
198 -0.00000000000000007, -0.00000000000000004, -0.00000000000000002
199 };
200
201 // series for am22 on the interval -1.00000d+00 to -1.25000d-01
202 // with weighted error 2.99e-17
203 // log weighted error 16.52
204 // significant figures required 14.57
205 // decimal places required 17.28
206
207 private final static double am22cs[] = {
208 -0.01562844480625341, 0.00778336445239681, 0.00086705777047718,
209 0.00015696627315611, 0.00003563962571432, 0.00000924598335425,
210 0.00000262110161850, 0.00000079188221651, 0.00000025104152792,
211 0.00000008265223206, 0.00000002805711662, 0.00000000976821090,
212 0.00000000347407923, 0.00000000125828132, 0.00000000046298826,
213 0.00000000017272825, 0.00000000006523192, 0.00000000002490471,
214 0.00000000000960156, 0.00000000000373448, 0.00000000000146417,
215 0.00000000000057826, 0.00000000000022991, 0.00000000000009197,
216 0.00000000000003700, 0.00000000000001496, 0.00000000000000608,
217 0.00000000000000248, 0.00000000000000101, 0.00000000000000041,
218 0.00000000000000017, 0.00000000000000007, 0.00000000000000002
219 };
220
221 // series for ath2 on the interval -1.00000d+00 to -1.25000d-01
222 // with weighted error 2.57e-17
223 // log weighted error 16.59
224 // significant figures required 15.07
225 // decimal places required 17.34
226
227 private final static double ath2cs[] = {
228 0.00440527345871877, -0.03042919452318455, -0.00138565328377179,
229 -0.00018044439089549, -0.00003380847108327, -0.00000767818353522,
230 -0.00000196783944371, -0.00000054837271158, -0.00000016254615505,
231 -0.00000005053049981, -0.00000001631580701, -0.00000000543420411,
232 -0.00000000185739855, -0.00000000064895120, -0.00000000023105948,
233 -0.00000000008363282, -0.00000000003071196, -0.00000000001142367,
234 -0.00000000000429811, -0.00000000000163389, -0.00000000000062693,
235 -0.00000000000024260, -0.00000000000009461, -0.00000000000003716,
236 -0.00000000000001469, -0.00000000000000584, -0.00000000000000233,
237 -0.00000000000000093, -0.00000000000000037, -0.00000000000000015,
238 -0.00000000000000006, -0.00000000000000002
239 };
240
241 // series for bi0 on the interval 0. to 9.00000d+00
242 // with weighted error 2.46e-18
243 // log weighted error 17.61
244 // significant figures required 17.90
245 // decimal places required 18.15
246
247 private final static double bi0cs[] = {
248 -0.07660547252839144951, 1.927337953993808270, 0.2282644586920301339,
249 0.01304891466707290428, 0.00043442709008164874, 0.00000942265768600193,
250 0.00000014340062895106, 0.00000000161384906966, 0.00000000001396650044,
251 0.00000000000009579451, 0.00000000000000053339, 0.00000000000000000245
252 };
253
254 // series for bj0 on the interval 0. to 1.60000d+01
255 // with weighted error 7.47e-18
256 // log weighted error 17.13
257 // significant figures required 16.98
258 // decimal places required 17.68
259
260 private final static double bj0cs[] = {
261 0.100254161968939137, -0.665223007764405132, 0.248983703498281314,
262 -0.0332527231700357697, 0.0023114179304694015, -0.0000991127741995080,
263 0.0000028916708643998, -0.0000000612108586630, 0.0000000009838650793,
264 -0.0000000000124235515, 0.0000000000001265433, -0.0000000000000010619,
265 0.0000000000000000074
266 };
267
268 // series for bm0 on the interval 0. to 6.25000d-02
269 // with weighted error 4.98e-17
270 // log weighted error 16.30
271 // significant figures required 14.97
272 // decimal places required 16.96
273
274 private final static double bm0cs[] = {
275 0.09284961637381644, -0.00142987707403484, 0.00002830579271257,
276 -0.00000143300611424, 0.00000012028628046, -0.00000001397113013,
277 0.00000000204076188, -0.00000000035399669, 0.00000000007024759,
278 -0.00000000001554107, 0.00000000000376226, -0.00000000000098282,
279 0.00000000000027408, -0.00000000000008091, 0.00000000000002511,
280 -0.00000000000000814, 0.00000000000000275, -0.00000000000000096,
281 0.00000000000000034, -0.00000000000000012, 0.00000000000000004
282 };
283
284 // series for bth0 on the interval 0. to 6.25000d-02
285 // with weighted error 3.67e-17
286 // log weighted error 16.44
287 // significant figures required 15.53
288 // decimal places required 17.13
289
290 private final static double bth0cs[] = {
291 -0.24639163774300119, 0.001737098307508963, -0.000062183633402968,
292 0.000004368050165742, -0.000000456093019869, 0.000000062197400101,
293 -0.000000010300442889, 0.000000001979526776, -0.000000000428198396,
294 0.000000000102035840, -0.000000000026363898, 0.000000000007297935,
295 -0.000000000002144188, 0.000000000000663693, -0.000000000000215126,
296 0.000000000000072659, -0.000000000000025465, 0.000000000000009229,
297 -0.000000000000003448, 0.000000000000001325, -0.000000000000000522,
298 0.000000000000000210, -0.000000000000000087, 0.000000000000000036
299 };
300
301 // series for by0 on the interval 0. to 1.60000d+01
302 // with weighted error 1.20e-17
303 // log weighted error 16.92
304 // significant figures required 16.15
305 // decimal places required 17.48
306
307 private final static double by0cs[] = {
308 -0.011277839392865573, -0.12834523756042035, -0.10437884799794249,
309 0.023662749183969695, -0.002090391647700486, 0.000103975453939057,
310 -0.000003369747162423, 0.000000077293842676, -0.000000001324976772,
311 0.000000000017648232, -0.000000000000188105, 0.000000000000001641,
312 -0.000000000000000011
313 };
314
315 // series for bi1 on the interval 0. to 9.00000d+00
316 // with weighted error 2.40e-17
317 // log weighted error 16.62
318 // significant figures required 16.23
319 // decimal places required 17.14
320
321 private final static double bi1cs[] = {
322 -0.001971713261099859, 0.40734887667546481, 0.034838994299959456,
323 0.001545394556300123, 0.000041888521098377, 0.000000764902676483,
324 0.000000010042493924, 0.000000000099322077, 0.000000000000766380,
325 0.000000000000004741, 0.000000000000000024
326 };
327
328 // series for bj1 on the interval 0. to 1.60000d+01
329 // with weighted error 4.48e-17
330 // log weighted error 16.35
331 // significant figures required 15.77
332 // decimal places required 16.89
333
334 private final static double bj1cs[] = {
335 -0.11726141513332787, -0.25361521830790640, 0.050127080984469569,
336 -0.004631514809625081, 0.000247996229415914, -0.000008678948686278,
337 0.000000214293917143, -0.000000003936093079, 0.000000000055911823,
338 -0.000000000000632761, 0.000000000000005840, -0.000000000000000044
339 };
340
341 // series for bm1 on the interval 0. to 6.25000d-02
342 // with weighted error 5.61e-17
343 // log weighted error 16.25
344 // significant figures required 14.97
345 // decimal places required 16.91
346
347 private final static double bm1cs[] = {
348 0.1047362510931285, 0.00442443893702345, -0.00005661639504035,
349 0.00000231349417339, -0.00000017377182007, 0.00000001893209930,
350 -0.00000000265416023, 0.00000000044740209, -0.00000000008691795,
351 0.00000000001891492, -0.00000000000451884, 0.00000000000116765,
352 -0.00000000000032265, 0.00000000000009450, -0.00000000000002913,
353 0.00000000000000939, -0.00000000000000315, 0.00000000000000109,
354 -0.00000000000000039, 0.00000000000000014, -0.00000000000000005
355 };
356
357 // series for bth1 on the interval 0. to 6.25000d-02
358 // with weighted error 4.10e-17
359 // log weighted error 16.39
360 // significant figures required 15.96
361 // decimal places required 17.08
362
363 private final static double bth1cs[] = {
364 0.74060141026313850, -0.004571755659637690, 0.000119818510964326,
365 -0.000006964561891648, 0.000000655495621447, -0.000000084066228945,
366 0.000000013376886564, -0.000000002499565654, 0.000000000529495100,
367 -0.000000000124135944, 0.000000000031656485, -0.000000000008668640,
368 0.000000000002523758, -0.000000000000775085, 0.000000000000249527,
369 -0.000000000000083773, 0.000000000000029205, -0.000000000000010534,
370 0.000000000000003919, -0.000000000000001500, 0.000000000000000589,
371 -0.000000000000000237, 0.000000000000000097, -0.000000000000000040
372 };
373
374 // series for by1 on the interval 0. to 1.60000d+01
375 // with weighted error 1.87e-18
376 // log weighted error 17.73
377 // significant figures required 17.83
378 // decimal places required 18.30
379
380 private final static double by1cs[] = {
381 0.03208047100611908629, 1.262707897433500450, 0.00649996189992317500,
382 -0.08936164528860504117, 0.01325088122175709545,
383 -0.00089790591196483523, 0.00003647361487958306,
384 -0.00000100137438166600, 0.00000001994539657390,
385 -0.00000000030230656018, 0.00000000000360987815,
386 -0.00000000000003487488, 0.00000000000000027838, -0.00000000000000000186
387 };
388
389 /**
390 * Evaluates a Chebyshev series.
391 * @param x value at which to evaluate series
392 * @param series the coefficients of the series
393 */
394 public static double chebyshev(double x, double series[]) {
395 double twox, b0 = 0.0, b1 = 0.0, b2 = 0.0;
396
397 twox = 2 * x;
398
399 for (int i = series.length - 1; i > -1; i--) {
400 b2 = b1;
401 b1 = b0;
402 b0 = twox * b1 - b2 + series[i];
403 }
404
405 return 0.5 * (b0 - b2);
406 }
407
408 /**
409 * Airy function.
410 * Based on the NETLIB Fortran function ai written by W. Fullerton.
411 */
412 public static double airy(double x) {
413 if (x < -1.0) {
414 double mp[] = airyModPhase(x);
415
416 return mp[0] * Math.cos(mp[1]);
417 } else if (x > 1.0) {
418 return expAiry(x) * Math.exp(-2.0 * x * Math.sqrt(x) / 3.0);
419 } else {
420 final double z = x * x * x;
421
422 return 0.375
423 + (chebyshev(z, aifcs) - x * (0.25 + chebyshev(z, aigcs)));
424 }
425 }
426
427 /**
428 * Airy modulus and phase.
429 * Based on the NETLIB Fortran subroutine r9aimp written by W. Fullerton.
430 * @return an array with [0] containing the modulus and [1] containing the phase.
431 */
432 private static double[] airyModPhase(double x) {
433 double z, mp[] = new double[2];
434
435 if (x < -2.0) {
436 z = 16.0 / (x * x * x) + 1.0;
437 mp[0] = 0.3125 + chebyshev(z, am21cs);
438 mp[1] = -0.625 + chebyshev(z, ath1cs);
439 } else {
440 z = (16.0 / (x * x * x) + 9.0) / 7.0;
441 mp[0] = 0.3125 + chebyshev(z, am22cs);
442 mp[1] = -0.625 + chebyshev(z, ath2cs);
443 }
444
445 final double sqrtx = Math.sqrt(-x);
446
447 mp[0] = Math.sqrt(mp[0] / sqrtx);
448 mp[1] = Math.PI / 4.0 - x * sqrtx * mp[1];
449
450 return mp;
451 }
452
453 /**
454 * Exponential scaled Airy function.
455 * Based on the NETLIB Fortran function aie written by W. Fullerton.
456 */
457 private static double expAiry(double x) {
458 if (x < -1.0) {
459 double mp[] = airyModPhase(x);
460
461 return mp[0] * Math.cos(mp[1]);
462 } else if (x <= 1.0) {
463 final double z = x * x * x;
464
465 return 0.375
466 + (chebyshev(z, aifcs) - x * (0.25 + chebyshev(z, aigcs)))
467 * Math.exp(2.0 * x * Math.sqrt(x) / 3.0);
468 } else {
469 final double sqrtx = Math.sqrt(x);
470 final double z = 2.0 / (x * sqrtx) - 1.0;
471
472 return (0.28125 + chebyshev(z, aipcs)) / Math.sqrt(sqrtx);
473 }
474 }
475
476 /**
477 * Bessel function of first kind, order zero.
478 * Based on the NETLIB Fortran function besj0 written by W. Fullerton.
479 */
480 public static double besselFirstZero(double x) {
481 double y = Math.abs(x);
482
483 if (y > 4.0) {
484 final double z = 32 / (y * y) - 1;
485 final double amplitude = (0.75 + chebyshev(z, bm0cs))
486 / Math.sqrt(y);
487 final double theta = y - Math.PI / 4.0 + chebyshev(z, bth0cs) / y;
488
489 return amplitude * Math.cos(theta);
490 } else if (y == 0.0) {
491 return 1.0;
492 } else {
493 return chebyshev(0.125 * y * y - 1, bj0cs);
494 }
495 }
496
497 /**
498 * Modified Bessel function of first kind, order zero.
499 * Based on the NETLIB Fortran function besi0 written by W. Fullerton.
500 */
501 public static double modBesselFirstZero(double x) {
502 double y = Math.abs(x);
503
504 if (y > 3.0) {
505 return Math.exp(y) * expModBesselFirstZero(x);
506 } else {
507 return 2.75 + chebyshev(y * y / 4.5 - 1.0, bi0cs);
508 }
509 }
510
511 /**
512 * Exponential scaled modified Bessel function of first kind, order zero.
513 * Based on the NETLIB Fortran function besi0e written by W. Fullerton.
514 */
515 private static double expModBesselFirstZero(double x) {
516 final double y = Math.abs(x);
517
518 if (y > 3.0) {
519 if (y > 8.0) {
520 return (0.375 + chebyshev(16.0 / y - 1.0, ai02cs)) / Math.sqrt(y);
521 } else {
522 return (0.375 + chebyshev((48.0 / y - 11.0) / 5.0, ai0cs))
523 / Math.sqrt(y);
524 }
525 } else {
526 return Math.exp(-y) * (2.75 + chebyshev(y * y / 4.5 - 1.0, bi0cs));
527 }
528 }
529
530 /**
531 * Bessel function of first kind, order one.
532 * Based on the NETLIB Fortran function besj1 written by W. Fullerton.
533 */
534 public static double besselFirstOne(double x) {
535 double y = Math.abs(x);
536
537 if (y > 4.0) {
538 final double z = 32.0 / (y * y) - 1.0;
539 final double amplitude = (0.75 + chebyshev(z, bm1cs))
540 / Math.sqrt(y);
541 final double theta = y - 3.0 * Math.PI / 4.0
542 + chebyshev(z, bth1cs) / y;
543
544 return Math.abs(amplitude) * x * Math.cos(theta) / Math.abs(x);
545 } else if (y == 0.0) {
546 return 0.0;
547 } else {
548 return x * (0.25 + chebyshev(0.125 * y * y - 1.0, bj1cs));
549 }
550 }
551
552 /**
553 * Modified Bessel function of first kind, order one.
554 * Based on the NETLIB Fortran function besi1 written by W. Fullerton.
555 */
556 public static double modBesselFirstOne(double x) {
557 final double y = Math.abs(x);
558
559 if (y > 3.0) {
560 return Math.exp(y) * expModBesselFirstOne(x);
561 } else if (y == 0.0) {
562 return 0.0;
563 } else {
564 return x * (0.875 + chebyshev(y * y / 4.5 - 1.0, bi1cs));
565 }
566 }
567
568 /**
569 * Exponential scaled modified Bessel function of first kind, order one.
570 * Based on the NETLIB Fortran function besi1e written by W. Fullerton.
571 */
572 private static double expModBesselFirstOne(double x) {
573 final double y = Math.abs(x);
574
575 if (y > 3.0) {
576 if (y > 8.0) {
577 return x / y * (0.375 + chebyshev(16.0 / y - 1.0, ai12cs))
578 / Math.sqrt(y);
579 } else {
580 return x / y
581 * (0.375 + chebyshev((48.0 / y - 11.0) / 5.0, ai1cs))
582 / Math.sqrt(y);
583 }
584 } else if (y == 0.0) {
585 return 0.0;
586 } else {
587 return Math.exp(-y) * x
588 * (0.875 + chebyshev(y * y / 4.5 - 1.0, bi1cs));
589 }
590 }
591
592 /**
593 * Bessel function of second kind, order zero.
594 * Based on the NETLIB Fortran function besy0 written by W. Fullerton.
595 */
596 public static double besselSecondZero(double x) {
597 if (x > 4.0) {
598 final double z = 32.0 / (x * x) - 1.0;
599 final double amplitude = (0.75 + chebyshev(z, bm0cs))
600 / Math.sqrt(x);
601 final double theta = x - Math.PI / 4 + chebyshev(z, bth0cs) / x;
602
603 return amplitude * Math.sin(theta);
604 } else {
605 return (Math.log(0.5) + Math.log(x)) * besselFirstZero(x) + 0.375
606 + chebyshev(0.125 * x * x - 1.0, by0cs) * 2.0 / Math.PI;
607 }
608 }
609
610 /**
611 * Bessel function of second kind, order one.
612 * Based on the NETLIB Fortran function besy1 written by W. Fullerton.
613 */
614 public static double besselSecondOne(double x) {
615 if (x > 4.0) {
616 final double z = 32.0 / (x * x) - 1.0;
617 final double amplitude = (0.75 + chebyshev(z, bm1cs))
618 / Math.sqrt(x);
619 final double theta = x - 3.0 * Math.PI / 4.0
620 + chebyshev(z, bth1cs) / x;
621
622 return amplitude * Math.sin(theta);
623 } else {
624 return 2.0 * Math.log(0.5 * x) * besselFirstOne(x) / Math.PI
625 + (0.5 + chebyshev(0.125 * x * x - 1.0, by1cs)) / x;
626 }
627 }
628
629 private final static double LOGSQRT2PI = Math.log(Math.sqrt(HDouble.TWO_PI));
630
631 /**
632 * Gamma function.
633 * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz<BR>
634 * Applied Mathematics Division<BR>
635 * Argonne National Laboratory<BR>
636 * Argonne, IL 60439<BR>
637 * <P>
638 * References:
639 * <OL>
640 * <LI>"An Overview of Software Development for Special Functions", W. J. Cody, Lecture Notes in Mathematics, 506, Numerical Analysis Dundee, 1975, G. A. Watson (ed.), Springer Verlag, Berlin, 1976.
641 * <LI>Computer Approximations, Hart, Et. Al., Wiley and sons, New York, 1968.
642 * </OL></P><P>
643 * From the original documentation:
644 * </P><P>
645 * This routine calculates the GAMMA function for a real argument X.
646 * Computation is based on an algorithm outlined in reference 1.
647 * The program uses rational functions that approximate the GAMMA
648 * function to at least 20 significant decimal digits. Coefficients
649 * for the approximation over the interval (1,2) are unpublished.
650 * Those for the approximation for X .GE. 12 are from reference 2.
651 * The accuracy achieved depends on the arithmetic system, the
652 * compiler, the intrinsic functions, and proper selection of the
653 * machine-dependent constants.
654 * </P><P>
655 * Error returns:<BR>
656 * The program returns the value XINF for singularities or when overflow would occur.
657 * The computation is believed to be free of underflow and overflow.
658 * </P>
659 * @return Double.MAX_VALUE if overflow would occur, i.e. if abs(x) > 171.624
660 * @author Jaco van Kooten
661 */
662 public static double gamma(double x) {
663
664 // Gamma function related constants
665
666 final double g_p[] = {
667 -1.71618513886549492533811, 24.7656508055759199108314,
668 -379.804256470945635097577, 629.331155312818442661052,
669 866.966202790413211295064, -31451.2729688483675254357,
670 -36144.4134186911729807069, 66456.1438202405440627855
671 };
672 final double g_q[] = {
673 -30.8402300119738975254353, 315.350626979604161529144,
674 -1015.15636749021914166146, -3107.77167157231109440444,
675 22538.1184209801510330112, 4755.84627752788110767815,
676 -134659.959864969306392456, -115132.259675553483497211
677 };
678 final double g_c[] = {
679 -.001910444077728, 8.4171387781295e-4, -5.952379913043012e-4,
680 7.93650793500350248e-4, -.002777777777777681622553,
681 .08333333333333333331554247, .0057083835261
682 };
683 final double g_xbig = 171.624;
684 double fact = 1.0, xden, xnum;
685 int i, n = 0;
686 double y = x, z, y1;
687 boolean parity = false;
688 double res, sum, ysq;
689
690 if (y <= 0.0) {
691
692 // ----------------------------------------------------------------------
693 // Argument is negative
694 // ----------------------------------------------------------------------
695
696 y = -(x);
697 y1 = (int) y;
698 res = y - y1;
699
700 if (res != 0.0) {
701 if (y1 != (((int) (y1 * 0.5)) * 2.0)) {
702 parity = true;
703 }
704
705 fact = -Math.PI / Math.sin(Math.PI * res);
706 y++;
707 } else {
708 return Double.MAX_VALUE;
709 }
710 }
711
712 // ----------------------------------------------------------------------
713 // Argument is positive
714 // ----------------------------------------------------------------------
715
716 if (y < HDouble.EPS) {
717
718 // ----------------------------------------------------------------------
719 // Argument .LT. HDouble.EPS
720 // ----------------------------------------------------------------------
721
722 if (y >= HDouble.XMININ) {
723 res = 1.0 / y;
724 } else {
725 return Double.MAX_VALUE;
726 }
727 } else if (y < 12.0) {
728 y1 = y;
729
730 if (y < 1.0) {
731
732 // ----------------------------------------------------------------------
733 // 0.0 .LT. argument .LT. 1.0
734 // ----------------------------------------------------------------------
735
736 z = y;
737 y++;
738 } else {
739
740 // ----------------------------------------------------------------------
741 // 1.0 .LT. argument .LT. 12.0, reduce argument if necessary
742 // ----------------------------------------------------------------------
743
744 n = (int) y - 1;
745 y -= (double) n;
746 z = y - 1.0;
747 }
748
749 // ----------------------------------------------------------------------
750 // Evaluate approximation for 1.0 .LT. argument .LT. 2.0
751 // ----------------------------------------------------------------------
752
753 xnum = 0.0;
754 xden = 1.0;
755
756 for (i = 0; i < 8; ++i) {
757 xnum = (xnum + g_p[i]) * z;
758 xden = xden * z + g_q[i];
759 }
760
761 res = xnum / xden + 1.0;
762
763 if (y1 < y) {
764
765 // ----------------------------------------------------------------------
766 // Adjust result for case 0.0 .LT. argument .LT. 1.0
767 // ----------------------------------------------------------------------
768
769 res /= y1;
770 } else if (y1 > y) {
771
772 // ----------------------------------------------------------------------
773 // Adjust result for case 2.0 .LT. argument .LT. 12.0
774 // ----------------------------------------------------------------------
775
776 for (i = 0; i < n; ++i) {
777 res *= y;
778 y++;
779 }
780 }
781 } else {
782
783 // ----------------------------------------------------------------------
784 // Evaluate for argument .GE. 12.0
785 // ----------------------------------------------------------------------
786
787 if (y <= g_xbig) {
788 ysq = y * y;
789 sum = g_c[6];
790
791 for (i = 0; i < 6; ++i) {
792 sum = sum / ysq + g_c[i];
793 }
794
795 sum = sum / y - y + LOGSQRT2PI;
796 sum += (y - 0.5) * Math.log(y);
797 res = Math.exp(sum);
798 } else {
799 return Double.MAX_VALUE;
800 }
801 }
802
803 // ----------------------------------------------------------------------
804 // Final adjustments and return
805 // ----------------------------------------------------------------------
806
807 if (parity) {
808 res = -res;
809 }
810 if (fact != 1.0) {
811 res = fact / res;
812 }
813
814 return res;
815 }
816
817 /**
818 * The largest argument for which logGamma(x) is representable in the machine.
819 */
820 private final static double logGamma_xBig = 2.55e305;
821
822 // Function cache for logGamma
823
824 private static double logGammaCache_res = 0.0;
825 private static double logGammaCache_x = 0.0;
826
827 /**
828 * The natural logarithm of the gamma function.
829 * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz<BR>
830 * Applied Mathematics Division<BR>
831 * Argonne National Laboratory<BR>
832 * Argonne, IL 60439<BR>
833 * <P>
834 * References:
835 * <OL>
836 * <LI>W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.
837 * <LI>K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.
838 * <LI>Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.
839 * </OL></P><P>
840 * From the original documentation:
841 * </P><P>
842 * This routine calculates the LOG(GAMMA) function for a positive real argument X.
843 * Computation is based on an algorithm outlined in references 1 and 2.
844 * The program uses rational functions that theoretically approximate LOG(GAMMA)
845 * to at least 18 significant decimal digits. The approximation for X > 12 is from reference 3,
846 * while approximations for X < 12.0 are similar to those in reference 1, but are unpublished.
847 * The accuracy achieved depends on the arithmetic system, the compiler, the intrinsic functions,
848 * and proper selection of the machine-dependent constants.
849 * </P><P>
850 * Error returns:<BR>
851 * The program returns the value XINF for X .LE. 0.0 or when overflow would occur.
852 * The computation is believed to be free of underflow and overflow.
853 * </P>
854 * @return Double.MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305
855 * @author Jaco van Kooten
856 */
857 public static double logGamma(double x) {
858
859 // Log Gamma related constants
860
861 final double lg_d1 = -.5772156649015328605195174,
862 lg_d2 = .4227843350984671393993777,
863 lg_d4 = 1.791759469228055000094023;
864 final double lg_p1[] = {
865 4.945235359296727046734888, 201.8112620856775083915565,
866 2290.838373831346393026739, 11319.67205903380828685045,
867 28557.24635671635335736389, 38484.96228443793359990269,
868 26377.48787624195437963534, 7225.813979700288197698961
869 };
870 final double lg_q1[] = {
871 67.48212550303777196073036, 1113.332393857199323513008,
872 7738.757056935398733233834, 27639.87074403340708898585,
873 54993.10206226157329794414, 61611.22180066002127833352,
874 36351.27591501940507276287, 8785.536302431013170870835
875 };
876 final double lg_p2[] = {
877 4.974607845568932035012064, 542.4138599891070494101986,
878 15506.93864978364947665077, 184793.2904445632425417223,
879 1088204.76946882876749847, 3338152.967987029735917223,
880 5106661.678927352456275255, 3074109.054850539556250927
881 };
882 final double lg_q2[] = {
883 183.0328399370592604055942, 7765.049321445005871323047,
884 133190.3827966074194402448, 1136705.821321969608938755,
885 5267964.117437946917577538, 13467014.54311101692290052,
886 17827365.30353274213975932, 9533095.591844353613395747
887 };
888 final double lg_p4[] = {
889 14745.02166059939948905062, 2426813.369486704502836312,
890 121475557.4045093227939592, 2663432449.630976949898078,
891 29403789566.34553899906876, 170266573776.5398868392998,
892 492612579337.743088758812, 560625185622.3951465078242
893 };
894 final double lg_q4[] = {
895 2690.530175870899333379843, 639388.5654300092398984238,
896 41355999.30241388052042842, 1120872109.61614794137657,
897 14886137286.78813811542398, 101680358627.2438228077304,
898 341747634550.7377132798597, 446315818741.9713286462081
899 };
900 final double lg_c[] = {
901 -0.001910444077728, 8.4171387781295e-4, -5.952379913043012e-4,
902 7.93650793500350248e-4, -0.002777777777777681622553,
903 0.08333333333333333331554247, 0.0057083835261
904 };
905
906 // Rough estimate of the fourth root of logGamma_xBig
907
908 final double lg_frtbig = 2.25e76;
909 final double pnt68 = 0.6796875;
910 double xden, corr, xnum;
911 int i;
912 double y, xm1, xm2, xm4, res, ysq;
913
914 if (x == logGammaCache_x) {
915 return logGammaCache_res;
916 }
917
918 y = x;
919
920 if (y > 0.0 && y <= logGamma_xBig) {
921 if (y <= HDouble.EPS) {
922 res = -Math.log(y);
923 } else if (y <= 1.5) {
924
925 // ----------------------------------------------------------------------
926 // HDouble.EPS .LT. X .LE. 1.5
927 // ----------------------------------------------------------------------
928
929 if (y < pnt68) {
930 corr = -Math.log(y);
931 xm1 = y;
932 } else {
933 corr = 0.0;
934 xm1 = y - 1.0;
935 }
936 if (y <= 0.5 || y >= pnt68) {
937 xden = 1.0;
938 xnum = 0.0;
939
940 for (i = 0; i < 8; i++) {
941 xnum = xnum * xm1 + lg_p1[i];
942 xden = xden * xm1 + lg_q1[i];
943 }
944
945 res = corr + xm1 * (lg_d1 + xm1 * (xnum / xden));
946 } else {
947 xm2 = y - 1.0;
948 xden = 1.0;
949 xnum = 0.0;
950
951 for (i = 0; i < 8; i++) {
952 xnum = xnum * xm2 + lg_p2[i];
953 xden = xden * xm2 + lg_q2[i];
954 }
955
956 res = corr + xm2 * (lg_d2 + xm2 * (xnum / xden));
957 }
958 } else if (y <= 4.0) {
959
960 // ----------------------------------------------------------------------
961 // 1.5 .LT. X .LE. 4.0
962 // ----------------------------------------------------------------------
963
964 xm2 = y - 2.0;
965 xden = 1.0;
966 xnum = 0.0;
967
968 for (i = 0; i < 8; i++) {
969 xnum = xnum * xm2 + lg_p2[i];
970 xden = xden * xm2 + lg_q2[i];
971 }
972
973 res = xm2 * (lg_d2 + xm2 * (xnum / xden));
974 } else if (y <= 12.0) {
975
976 // ----------------------------------------------------------------------
977 // 4.0 .LT. X .LE. 12.0
978 // ----------------------------------------------------------------------
979
980 xm4 = y - 4.0;
981 xden = -1.0;
982 xnum = 0.0;
983
984 for (i = 0; i < 8; i++) {
985 xnum = xnum * xm4 + lg_p4[i];
986 xden = xden * xm4 + lg_q4[i];
987 }
988
989 res = lg_d4 + xm4 * (xnum / xden);
990 } else {
991
992 // ----------------------------------------------------------------------
993 // Evaluate for argument .GE. 12.0
994 // ----------------------------------------------------------------------
995
996 res = 0.0;
997
998 if (y <= lg_frtbig) {
999 res = lg_c[6];
1000 ysq = y * y;
1001
1002 for (i = 0; i < 6; i++) {
1003 res = res / ysq + lg_c[i];
1004 }
1005 }
1006
1007 res /= y;
1008 corr = Math.log(y);
1009 res = res + LOGSQRT2PI - 0.5 * corr;
1010 res += y * (corr - 1.0);
1011 }
1012 } else {
1013
1014 // ----------------------------------------------------------------------
1015 // Return for bad arguments
1016 // ----------------------------------------------------------------------
1017
1018 res = Double.MAX_VALUE;
1019 }
1020
1021 // ----------------------------------------------------------------------
1022 // Final adjustments and return
1023 // ----------------------------------------------------------------------
1024
1025 logGammaCache_x = x;
1026 logGammaCache_res = res;
1027
1028 return res;
1029 }
1030
1031 private final static int MAX_ITERATIONS = 150;
1032 private final static double PRECISION = 4.0 * HDouble.EPS;
1033
1034 /**
1035 * Incomplete gamma function.
1036 * The computation is based on approximations presented in Numerical Recipes, Chapter 6.2 (W.H. Press et al, 1992).
1037 * @param a require a>=0
1038 * @param x require x>=0
1039 * @return 0 if x<0, a<=0 or a>2.55E305 to avoid errors and over/underflow
1040 * @author Jaco van Kooten
1041 */
1042 public static double incompleteGamma(double a, double x) {
1043 if (x <= 0.0 || a <= 0.0 || a > logGamma_xBig) {
1044 return 0.0;
1045 }
1046 if (x < (a + 1.0)) {
1047 return gammaSeriesExpansion(a, x);
1048 } else {
1049 return 1.0 - gammaFraction(a, x);
1050 }
1051 }
1052
1053 /**
1054 * @author Jaco van Kooten
1055 */
1056 private static double gammaSeriesExpansion(double a, double x) {
1057 double ap = a;
1058 double del = 1.0 / a;
1059 double sum = del;
1060
1061 for (int n = 1; n < MAX_ITERATIONS; n++) {
1062 ++ap;
1063 del *= x / ap;
1064 sum += del;
1065
1066 if (del < sum * PRECISION) {
1067 return sum * Math.exp(-x + a * Math.log(x) - logGamma(a));
1068 }
1069 }
1070
1071 return 0.0;
1072 }
1073
1074 /**
1075 * @author Jaco van Kooten
1076 */
1077 private static double gammaFraction(double a, double x) {
1078 double b = x + 1.0 - a;
1079 double c = 1.0 / HDouble.XMININ;
1080 double d = 1.0 / b;
1081 double h = d;
1082 double del = 0.0;
1083 double an;
1084
1085 for (int i = 1; i < MAX_ITERATIONS && Math.abs(del - 1.0) > PRECISION;
1086 i++) {
1087 an = -i * (i - a);
1088 b += 2.0;
1089 d = an * d + b;
1090 c = b + an / c;
1091
1092 if (Math.abs(c) < HDouble.XMININ) {
1093 c = HDouble.XMININ;
1094 }
1095 if (Math.abs(d) < HDouble.XMININ) {
1096 c = HDouble.XMININ;
1097 }
1098
1099 d = 1.0 / d;
1100 del = d * c;
1101 h *= del;
1102 }
1103
1104 return Math.exp(-x + a * Math.log(x) - logGamma(a)) * h;
1105 }
1106
1107 /**
1108 * Beta function.
1109 * @param p require p>0
1110 * @param q require q>0
1111 * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow
1112 * @author Jaco van Kooten
1113 */
1114 public static double beta(double p, double q) {
1115 if (p <= 0.0 || q <= 0.0 || (p + q) > logGamma_xBig) {
1116 return 0.0;
1117 } else {
1118 return Math.exp(logBeta(p, q));
1119 }
1120 }
1121
1122 // Function cache for logBeta
1123
1124 private static double logBetaCache_res = 0.0;
1125 private static double logBetaCache_p = 0.0;
1126 private static double logBetaCache_q = 0.0;
1127
1128 /**
1129 * The natural logarithm of the beta function.
1130 * @param p require p>0
1131 * @param q require q>0
1132 * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow
1133 * @author Jaco van Kooten
1134 */
1135 public static double logBeta(double p, double q) {
1136 if (p != logBetaCache_p || q != logBetaCache_q) {
1137 logBetaCache_p = p;
1138 logBetaCache_q = q;
1139
1140 if (p <= 0.0 || q <= 0.0 || (p + q) > logGamma_xBig) {
1141 logBetaCache_res = 0.0;
1142 } else {
1143 logBetaCache_res = logGamma(p) + logGamma(q) - logGamma(p + q);
1144 }
1145 }
1146
1147 return logBetaCache_res;
1148 }
1149
1150 /**
1151 * Incomplete beta function.
1152 * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992).
1153 * @param x require 0<=x<=1
1154 * @param p require p>0
1155 * @param q require q>0
1156 * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow
1157 * @author Jaco van Kooten
1158 */
1159 public static double incompleteBeta(double x, double p, double q) {
1160 if (x <= 0.0) {
1161 return 0.0;
1162 } else if (x >= 1.0) {
1163 return 1.0;
1164 } else if (p <= 0.0 || q <= 0.0 || (p + q) > logGamma_xBig) {
1165 return 0.0;
1166 } else {
1167 final double beta_gam = Math.exp(-logBeta(p, q) + p * Math.log(x)
1168 + q * Math.log(1.0 - x));
1169
1170 if (x < (p + 1.0) / (p + q + 2.0)) {
1171 return beta_gam * betaFraction(x, p, q) / p;
1172 } else {
1173 return 1.0 - (beta_gam * betaFraction(1.0 - x, q, p) / q);
1174 }
1175 }
1176 }
1177
1178 /**
1179 * Evaluates of continued fraction part of incomplete beta function.
1180 * Based on an idea from Numerical Recipes (W.H. Press et al, 1992).
1181 * @author Jaco van Kooten
1182 */
1183 private static double betaFraction(double x, double p, double q) {
1184 int m, m2;
1185 double sum_pq, p_plus, p_minus, c = 1.0, d, delta, h, frac;
1186
1187 sum_pq = p + q;
1188 p_plus = p + 1.0;
1189 p_minus = p - 1.0;
1190 h = 1.0 - sum_pq * x / p_plus;
1191
1192 if (Math.abs(h) < HDouble.XMININ) {
1193 h = HDouble.XMININ;
1194 }
1195
1196 h = 1.0 / h;
1197 frac = h;
1198 m = 1;
1199 delta = 0.0;
1200
1201 while (m <= MAX_ITERATIONS && Math.abs(delta - 1.0) > PRECISION) {
1202 m2 = 2 * m;
1203
1204 // even index for d
1205
1206 d = m * (q - m) * x / ((p_minus + m2) * (p + m2));
1207 h = 1.0 + d * h;
1208
1209 if (Math.abs(h) < HDouble.XMININ) {
1210 h = HDouble.XMININ;
1211 }
1212
1213 h = 1.0 / h;
1214 c = 1.0 + d / c;
1215
1216 if (Math.abs(c) < HDouble.XMININ) {
1217 c = HDouble.XMININ;
1218 }
1219
1220 frac *= h * c;
1221
1222 // odd index for d
1223
1224 d = -(p + m) * (sum_pq + m) * x / ((p + m2) * (p_plus + m2));
1225 h = 1.0 + d * h;
1226
1227 if (Math.abs(h) < HDouble.XMININ) {
1228 h = HDouble.XMININ;
1229 }
1230
1231 h = 1.0 / h;
1232 c = 1.0 + d / c;
1233
1234 if (Math.abs(c) < HDouble.XMININ) {
1235 c = HDouble.XMININ;
1236 }
1237
1238 delta = h * c;
1239 frac *= delta;
1240 m++;
1241 }
1242
1243 return frac;
1244 }
1245
1246 // ====================================================
1247 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1248 //
1249 // Developed at SunSoft, a Sun Microsystems, Inc. business.
1250 // Permission to use, copy, modify, and distribute this
1251 // software is freely granted, provided that this notice
1252 // is preserved.
1253 // ====================================================
1254 //
1255 // x
1256 // 2 |\
1257 // erf(x) = --------- | exp(-t*t)dt
1258 // sqrt(pi) \|
1259 // 0
1260 //
1261 // erfc(x) = 1-erf(x)
1262 // Note that
1263 // erf(-x) = -erf(x)
1264 // erfc(-x) = 2 - erfc(x)
1265 //
1266 // Method:
1267 // 1. For |x| in [0, 0.84375]
1268 // erf(x) = x + x*R(x^2)
1269 // erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
1270 // = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
1271 // where R = P/Q where P is an odd poly of degree 8 and
1272 // Q is an odd poly of degree 10.
1273 // -57.90
1274 // | R - (erf(x)-x)/x | <= 2
1275 //
1276 //
1277 // Remark. The formula is derived by noting
1278 // erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
1279 // and that
1280 // 2/sqrt(pi) = 1.128379167095512573896158903121545171688
1281 // is close to one. The interval is chosen because the fix
1282 // point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
1283 // near 0.6174), and by some experiment, 0.84375 is chosen to
1284 // guarantee the error is less than one ulp for erf.
1285 //
1286 // 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
1287 // c = 0.84506291151 rounded to single (24 bits)
1288 // erf(x) = sign(x) * (c + P1(s)/Q1(s))
1289 // erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
1290 // 1+(c+P1(s)/Q1(s)) if x < 0
1291 // |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
1292 // Remark: here we use the taylor series expansion at x=1.
1293 // erf(1+s) = erf(1) + s*Poly(s)
1294 // = 0.845.. + P1(s)/Q1(s)
1295 // That is, we use rational approximation to approximate
1296 // erf(1+s) - (c = (single)0.84506291151)
1297 // Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
1298 // where
1299 // P1(s) = degree 6 poly in s
1300 // Q1(s) = degree 6 poly in s
1301 //
1302 // 3. For x in [1.25,1/0.35(~2.857143)],
1303 // erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
1304 // erf(x) = 1 - erfc(x)
1305 // where
1306 // R1(z) = degree 7 poly in z, (z=1/x^2)
1307 // S1(z) = degree 8 poly in z
1308 //
1309 // 4. For x in [1/0.35,28]
1310 // erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
1311 // = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
1312 // = 2.0 - tiny (if x <= -6)
1313 // erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
1314 // erf(x) = sign(x)*(1.0 - tiny)
1315 // where
1316 // R2(z) = degree 6 poly in z, (z=1/x^2)
1317 // S2(z) = degree 7 poly in z
1318 //
1319 // Note1:
1320 // To compute exp(-x*x-0.5625+R/S), let s be a single
1321 // precision number and s := x; then
1322 // -x*x = -s*s + (s-x)*(s+x)
1323 // exp(-x*x-0.5626+R/S) =
1324 // exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
1325 // Note2:
1326 // Here 4 and 5 make use of the asymptotic series
1327 // exp(-x*x)
1328 // erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
1329 // x*sqrt(pi)
1330 // We use rational approximation to approximate
1331 // g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
1332 // Here is the error bound for R1/S1 and R2/S2
1333 // |R1/S1 - f(x)| < 2**(-62.57)
1334 // |R2/S2 - f(x)| < 2**(-61.52)
1335 //
1336 // 5. For inf > x >= 28
1337 // erf(x) = sign(x) *(1 - tiny) (raise inexact)
1338 // erfc(x) = tiny*tiny (raise underflow) if x > 0
1339 // = 2 - tiny if x<0
1340 //
1341 // 7. Special case:
1342 // erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
1343 // erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
1344 // erfc/erf(NaN) is NaN
1345 //
1346
1347 /**
1348 * Error function.
1349 * Based on C-code for the error function developed at Sun Microsystems.
1350 * @author Jaco van Kooten
1351 */
1352 public static double error(double x) {
1353
1354 // Coefficients for approximation to erf on [0,0.84375]
1355
1356 final double e_efx = 1.28379167095512586316e-01;
1357
1358 // double efx8=1.02703333676410069053e00;
1359
1360 final double ePp[] = {
1361 1.28379167095512558561e-01, -3.25042107247001499370e-01,
1362 -2.84817495755985104766e-02, -5.77027029648944159157e-03,
1363 -2.37630166566501626084e-05
1364 };
1365 final double eQq[] = {
1366 3.97917223959155352819e-01, 6.50222499887672944485e-02,
1367 5.08130628187576562776e-03, 1.32494738004321644526e-04,
1368 -3.96022827877536812320e-06
1369 };
1370
1371 // Coefficients for approximation to erf in [0.84375,1.25]
1372
1373 final double ePa[] = {
1374 -2.36211856075265944077e-03, 4.14856118683748331666e-01,
1375 -3.72207876035701323847e-01, 3.18346619901161753674e-01,
1376 -1.10894694282396677476e-01, 3.54783043256182359371e-02,
1377 -2.16637559486879084300e-03
1378 };
1379 final double eQa[] = {
1380 1.06420880400844228286e-01, 5.40397917702171048937e-01,
1381 7.18286544141962662868e-02, 1.26171219808761642112e-01,
1382 1.36370839120290507362e-02, 1.19844998467991074170e-02
1383 };
1384 final double e_erx = 8.45062911510467529297e-01;
1385 double P, Q, s, retval;
1386 final double abs_x = (x >= 0.0 ? x : -x);
1387
1388 if (abs_x < 0.84375) { // 0 < |x| < 0.84375
1389 if (abs_x < 3.7252902984619141e-9) { // |x| < 2**-28
1390 retval = abs_x + abs_x * e_efx;
1391 } else {
1392 s = x * x;
1393 P = ePp[0]
1394 + s * (ePp[1] + s * (ePp[2] + s * (ePp[3] + s * ePp[4])));
1395 Q = 1.0
1396 + s
1397 * (eQq[0]
1398 + s
1399 * (eQq[1] + s * (eQq[2] + s * (eQq[3] + s * eQq[4]))));
1400 retval = abs_x + abs_x * (P / Q);
1401 }
1402 } else if (abs_x < 1.25) { // 0.84375 < |x| < 1.25
1403 s = abs_x - 1.0;
1404 P = ePa[0]
1405 + s
1406 * (ePa[1]
1407 + s
1408 * (ePa[2]
1409 + s
1410 * (ePa[3]
1411 + s * (ePa[4] + s * (ePa[5] + s * ePa[6])))));
1412 Q = 1.0
1413 + s
1414 * (eQa[0]
1415 + s
1416 * (eQa[1]
1417 + s
1418 * (eQa[2]
1419 + s * (eQa[3] + s * (eQa[4] + s * eQa[5])))));
1420 retval = e_erx + P / Q;
1421 } else if (abs_x >= 6.0) {
1422 retval = 1.0;
1423 } else { // 1.25 < |x| < 6.0
1424 retval = 1.0 - complementaryError(abs_x);
1425 }
1426
1427 return (x >= 0.0) ? retval : -retval;
1428 }
1429
1430 /**
1431 * Complementary error function.
1432 * Based on C-code for the error function developed at Sun Microsystems.
1433 * @author Jaco van Kooten
1434 */
1435 public static double complementaryError(double x) {
1436
1437 // Coefficients for approximation to erfc in [1.25,1/.35]
1438
1439 final double eRa[] = {
1440 -9.86494403484714822705e-03, -6.93858572707181764372e-01,
1441 -1.05586262253232909814e01, -6.23753324503260060396e01,
1442 -1.62396669462573470355e02, -1.84605092906711035994e02,
1443 -8.12874355063065934246e01, -9.81432934416914548592e00
1444 };
1445 final double eSa[] = {
1446 1.96512716674392571292e01, 1.37657754143519042600e02,
1447 4.34565877475229228821e02, 6.45387271733267880336e02,
1448 4.29008140027567833386e02, 1.08635005541779435134e02,
1449 6.57024977031928170135e00, -6.04244152148580987438e-02
1450 };
1451
1452 // Coefficients for approximation to erfc in [1/.35,28]
1453
1454 final double eRb[] = {
1455 -9.86494292470009928597e-03, -7.99283237680523006574e-01,
1456 -1.77579549177547519889e01, -1.60636384855821916062e02,
1457 -6.37566443368389627722e02, -1.02509513161107724954e03,
1458 -4.83519191608651397019e02
1459 };
1460 final double eSb[] = {
1461 3.03380607434824582924e01, 3.25792512996573918826e02,
1462 1.53672958608443695994e03, 3.19985821950859553908e03,
1463 2.55305040643316442583e03, 4.74528541206955367215e02,
1464 -2.24409524465858183362e01
1465 };
1466 double s, retval, R, S;
1467 final double abs_x = (x >= 0.0 ? x : -x);
1468
1469 if (abs_x < 1.25) {
1470 retval = 1.0 - error(abs_x);
1471 } else if (abs_x > 28.0) {
1472 retval = 0.0;
1473 } else { // 1.25 < |x| < 28
1474 s = 1.0 / (abs_x * abs_x);
1475
1476 if (abs_x < 2.8571428) { // ( |x| < 1/0.35 )
1477 R = eRa[0]
1478 + s
1479 * (eRa[1]
1480 + s
1481 * (eRa[2]
1482 + s
1483 * (eRa[3]
1484 + s
1485 * (eRa[4]
1486 + s
1487 * (eRa[5]
1488 + s * (eRa[6] + s * eRa[7]))))));
1489 S = 1.0
1490 + s
1491 * (eSa[0]
1492 + s
1493 * (eSa[1]
1494 + s
1495 * (eSa[2]
1496 + s
1497 * (eSa[3]
1498 + s
1499 * (eSa[4]
1500 + s
1501 * (eSa[5]
1502 + s
1503 * (eSa[6] + s * eSa[7])))))));
1504 } else { // ( |x| > 1/0.35 )
1505 R = eRb[0]
1506 + s
1507 * (eRb[1]
1508 + s
1509 * (eRb[2]
1510 + s
1511 * (eRb[3]
1512 + s * (eRb[4] + s * (eRb[5] + s * eRb[6])))));
1513 S = 1.0
1514 + s
1515 * (eSb[0]
1516 + s
1517 * (eSb[1]
1518 + s
1519 * (eSb[2]
1520 + s
1521 * (eSb[3]
1522 + s
1523 * (eSb[4]
1524 + s * (eSb[5] + s * eSb[6]))))));
1525 }
1526
1527 retval = Math.exp(-x * x - 0.5625 + R / S) / abs_x;
1528 }
1529
1530 return (x >= 0.0) ? retval : 2.0 - retval;
1531 }
1532
1533
1534 // see http://metalab.unc.edu/javafaq/formatter/
1535 /**
1536 *
1537 * This method formats a floating point number to a minimum of 12 characters,
1538 * six decimal places, in decimal format,
1539 * right aligned, without +
1540 * signs on positive numbers. Spaces
1541 * fill out the number to the specified width.
1542 *
1543 * @param d The number to be formatted
1544 * @return A String containing a formatted representation of the number.
1545 */
1546 public static String format(double d) {
1547 return format(d, 12, 6, false