Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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