annotate PsiCLASS-1.0.2/stats.cpp @ 0:903fc43d6227 draft default tip

Uploaded
author lsong10
date Fri, 26 Mar 2021 16:52:45 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
1 #include "stats.hpp"
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
2
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
3 /** The digamma function in long double precision.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
4 * @param x the real value of the argument
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
5 * @return the value of the digamma (psi) function at that point
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
6 * @author Richard J. Mathar
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
7 * @since 2005-11-24
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
8 */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
9 long double digammal(long double x)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
10 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
11 /* force into the interval 1..3 */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
12 if( x < 0.0L )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
13 return digammal(1.0L-x)+M_PIl/tanl(M_PIl*(1.0L-x)) ; /* reflection formula */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
14 else if( x < 1.0L )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
15 return digammal(1.0L+x)-1.0L/x ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
16 else if ( x == 1.0L)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
17 return -M_GAMMAl ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
18 else if ( x == 2.0L)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
19 return 1.0L-M_GAMMAl ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
20 else if ( x == 3.0L)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
21 return 1.5L-M_GAMMAl ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
22 else if ( x > 3.0L)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
23 /* duplication formula */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
24 return 0.5L*(digammal(x/2.0L)+digammal((x+1.0L)/2.0L))+M_LN2l ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
25 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
26 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
27 /* Just for your information, the following lines contain
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
28 * the Maple source code to re-generate the table that is
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
29 * eventually becoming the Kncoe[] array below
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
30 * interface(prettyprint=0) :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
31 * Digits := 63 :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
32 * r := 0 :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
33 *
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
34 * for l from 1 to 60 do
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
35 * d := binomial(-1/2,l) :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
36 * r := r+d*(-1)^l*(Zeta(2*l+1) -1) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
37 * evalf(r) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
38 * print(%,evalf(1+Psi(1)-r)) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
39 *o d :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
40 *
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
41 * for N from 1 to 28 do
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
42 * r := 0 :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
43 * n := N-1 :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
44 *
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
45 * for l from iquo(n+3,2) to 70 do
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
46 * d := 0 :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
47 * for s from 0 to n+1 do
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
48 * d := d+(-1)^s*binomial(n+1,s)*binomial((s-1)/2,l) :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
49 * od :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
50 * if 2*l-n > 1 then
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
51 * r := r+d*(-1)^l*(Zeta(2*l-n) -1) :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
52 * fi :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
53 * od :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
54 * print(evalf((-1)^n*2*r)) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
55 *od :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
56 *quit :
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
57 */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
58 static long double Kncoe[] = { .30459198558715155634315638246624251L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
59 .72037977439182833573548891941219706L, -.12454959243861367729528855995001087L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
60 .27769457331927827002810119567456810e-1L, -.67762371439822456447373550186163070e-2L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
61 .17238755142247705209823876688592170e-2L, -.44817699064252933515310345718960928e-3L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
62 .11793660000155572716272710617753373e-3L, -.31253894280980134452125172274246963e-4L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
63 .83173997012173283398932708991137488e-5L, -.22191427643780045431149221890172210e-5L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
64 .59302266729329346291029599913617915e-6L, -.15863051191470655433559920279603632e-6L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
65 .42459203983193603241777510648681429e-7L, -.11369129616951114238848106591780146e-7L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
66 .304502217295931698401459168423403510e-8L, -.81568455080753152802915013641723686e-9L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
67 .21852324749975455125936715817306383e-9L, -.58546491441689515680751900276454407e-10L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
68 .15686348450871204869813586459513648e-10L, -.42029496273143231373796179302482033e-11L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
69 .11261435719264907097227520956710754e-11L, -.30174353636860279765375177200637590e-12L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
70 .80850955256389526647406571868193768e-13L, -.21663779809421233144009565199997351e-13L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
71 .58047634271339391495076374966835526e-14L, -.15553767189204733561108869588173845e-14L,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
72 .41676108598040807753707828039353330e-15L, -.11167065064221317094734023242188463e-15L } ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
73
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
74 register long double Tn_1 = 1.0L ; /* T_{n-1}(x), started at n=1 */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
75 register long double Tn = x-2.0L ; /* T_{n}(x) , started at n=1 */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
76 register long double resul = Kncoe[0] + Kncoe[1]*Tn ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
77
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
78 x -= 2.0L ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
79 int n ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
80
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
81 for( n = 2 ; n < int( sizeof(Kncoe)/sizeof(long double) ) ; n++)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
82 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
83 const long double Tn1 = 2.0L * x * Tn - Tn_1 ; /* Chebyshev recursion, Eq. 22.7.4 Abramowitz-Stegun */
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
84 resul += Kncoe[n]*Tn1 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
85 Tn_1 = Tn ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
86 Tn = Tn1 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
87 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
88 return resul ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
89 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
90 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
91
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
92
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
93
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
94 double trigamma ( double x, int *ifault )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
95
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
96 //****************************************************************************
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
97 // purpose:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
98 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
99 // trigamma calculates trigamma(x) = d**2 log(gamma(x)) / dx**2
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
100 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
101 // licensing:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
102 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
103 // this code is distributed under the gnu lgpl license.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
104 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
105 // modified:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
106 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
107 // 19 january 2008
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
108 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
109 // author:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
110 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
111 // original fortran77 version by be schneider.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
112 // c++ version by john burkardt.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
113 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
114 // reference:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
115 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
116 // be schneider,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
117 // algorithm as 121:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
118 // trigamma function,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
119 // applied statistics,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
120 // volume 27, number 1, pages 97-99, 1978.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
121 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
122 // parameters:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
123 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
124 // input, double x, the argument of the trigamma function.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
125 // 0 < x.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
126 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
127 // output, int *ifault, error flag.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
128 // 0, no error.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
129 // 1, x <= 0.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
130 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
131 // output, double trigamma, the value of the trigamma function at x.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
132 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
133 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
134 double a = 0.0001;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
135 double b = 5.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
136 double b2 = 0.1666666667;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
137 double b4 = -0.03333333333;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
138 double b6 = 0.02380952381;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
139 double b8 = -0.03333333333;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
140 double value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
141 double y;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
142 double z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
143 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
144 // check the input.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
145 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
146 if ( x <= 0.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
147 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
148 *ifault = 1;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
149 value = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
150 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
151 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
152
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
153 *ifault = 0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
154 z = x;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
155 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
156 // use small value approximation if x <= a.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
157 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
158 if ( x <= a )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
159 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
160 value = 1.0 / x / x;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
161 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
162 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
163 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
164 // increase argument to ( x + i ) >= b.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
165 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
166 value = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
167
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
168 while ( z < b )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
169 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
170 value = value + 1.0 / z / z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
171 z = z + 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
172 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
173 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
174 // apply asymptotic formula if argument is b or greater.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
175 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
176 y = 1.0 / z / z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
177
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
178 value = value + 0.5 *
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
179 y + ( 1.0 + y * ( b2+ y * ( b4 + y * ( b6+ y * b8 )))) / z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
180
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
181 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
182 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
183
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
184
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
185 double LogGammaDensity( double x, double k, double theta )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
186 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
187 return -k * log( theta ) + ( k - 1 ) * log( x ) - x / theta - lgamma( k ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
188 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
189
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
190 double MixtureGammaAssignment( double x, double pi, double* k, double *theta )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
191 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
192 if ( pi == 1 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
193 return 1 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
194 else if ( pi == 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
195 return 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
196
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
197 double lf0 = LogGammaDensity( x, k[0], theta[0] ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
198 double lf1 = LogGammaDensity( x, k[1], theta[1] ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
199 return (double)1.0 / ( 1.0 + exp( lf1 + log( 1 - pi ) - lf0 - log( pi ) ) ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
200 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
201
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
202 //****************************************************************************80
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
203
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
204 double alnorm ( double x, bool upper )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
205
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
206 //****************************************************************************80
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
207 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
208 // Purpose:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
209 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
210 // ALNORM computes the cumulative density of the standard normal distribution.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
211 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
212 // Licensing:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
213 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
214 // This code is distributed under the GNU LGPL license.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
215 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
216 // Modified:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
217 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
218 // 17 January 2008
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
219 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
220 // Author:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
221 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
222 // Original FORTRAN77 version by David Hill.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
223 // C++ version by John Burkardt.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
224 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
225 // Reference:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
226 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
227 // David Hill,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
228 // Algorithm AS 66:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
229 // The Normal Integral,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
230 // Applied Statistics,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
231 // Volume 22, Number 3, 1973, pages 424-427.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
232 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
233 // Parameters:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
234 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
235 // Input, double X, is one endpoint of the semi-infinite interval
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
236 // over which the integration takes place.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
237 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
238 // Input, bool UPPER, determines whether the upper or lower
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
239 // interval is to be integrated:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
240 // .TRUE. => integrate from X to + Infinity;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
241 // .FALSE. => integrate from - Infinity to X.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
242 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
243 // Output, double ALNORM, the integral of the standard normal
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
244 // distribution over the desired interval.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
245 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
246 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
247 double a1 = 5.75885480458;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
248 double a2 = 2.62433121679;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
249 double a3 = 5.92885724438;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
250 double b1 = -29.8213557807;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
251 double b2 = 48.6959930692;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
252 double c1 = -0.000000038052;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
253 double c2 = 0.000398064794;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
254 double c3 = -0.151679116635;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
255 double c4 = 4.8385912808;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
256 double c5 = 0.742380924027;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
257 double c6 = 3.99019417011;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
258 double con = 1.28;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
259 double d1 = 1.00000615302;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
260 double d2 = 1.98615381364;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
261 double d3 = 5.29330324926;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
262 double d4 = -15.1508972451;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
263 double d5 = 30.789933034;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
264 double ltone = 7.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
265 double p = 0.398942280444;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
266 double q = 0.39990348504;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
267 double r = 0.398942280385;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
268 bool up;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
269 double utzero = 18.66;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
270 double value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
271 double y;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
272 double z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
273
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
274 up = upper;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
275 z = x;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
276
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
277 if ( z < 0.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
278 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
279 up = !up;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
280 z = - z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
281 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
282
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
283 if ( ltone < z && ( ( !up ) || utzero < z ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
284 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
285 if ( up )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
286 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
287 value = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
288 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
289 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
290 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
291 value = 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
292 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
293 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
294 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
295
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
296 y = 0.5 * z * z;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
297
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
298 if ( z <= con )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
299 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
300 value = 0.5 - z * ( p - q * y
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
301 / ( y + a1 + b1
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
302 / ( y + a2 + b2
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
303 / ( y + a3 ))));
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
304 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
305 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
306 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
307 value = r * exp ( - y )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
308 / ( z + c1 + d1
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
309 / ( z + c2 + d2
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
310 / ( z + c3 + d3
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
311 / ( z + c4 + d4
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
312 / ( z + c5 + d5
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
313 / ( z + c6 ))))));
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
314 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
315
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
316 if ( !up )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
317 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
318 value = 1.0 - value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
319 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
320
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
321 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
322 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
323
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
324 //****************************************************************************80
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
325
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
326 double gammad ( double x, double p, int *ifault )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
327
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
328 //****************************************************************************80
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
329 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
330 // Purpose:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
331 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
332 // GAMMAD computes the Incomplete Gamma Integral
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
333 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
334 // Licensing:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
335 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
336 // This code is distributed under the GNU LGPL license.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
337 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
338 // Modified:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
339 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
340 // 20 January 2008
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
341 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
342 // Author:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
343 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
344 // Original FORTRAN77 version by B Shea.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
345 // C++ version by John Burkardt.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
346 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
347 // Reference:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
348 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
349 // B Shea,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
350 // Algorithm AS 239:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
351 // Chi-squared and Incomplete Gamma Integral,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
352 // Applied Statistics,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
353 // Volume 37, Number 3, 1988, pages 466-473.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
354 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
355 // Parameters:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
356 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
357 // Input, double X, P, the parameters of the incomplete
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
358 // gamma ratio. 0 <= X, and 0 < P.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
359 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
360 // Output, int IFAULT, error flag.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
361 // 0, no error.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
362 // 1, X < 0 or P <= 0.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
363 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
364 // Output, double GAMMAD, the value of the incomplete
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
365 // Gamma integral.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
366 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
367 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
368 double a;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
369 double an;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
370 double arg;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
371 double b;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
372 double c;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
373 double elimit = - 88.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
374 double oflo = 1.0E+37;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
375 double plimit = 1000.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
376 double pn1;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
377 double pn2;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
378 double pn3;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
379 double pn4;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
380 double pn5;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
381 double pn6;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
382 double rn;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
383 double tol = 1.0E-14;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
384 bool upper;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
385 double value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
386 double xbig = 1.0E+08;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
387
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
388 value = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
389 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
390 // Check the input.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
391 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
392 if ( x < 0.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
393 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
394 *ifault = 1;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
395 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
396 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
397
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
398 if ( p <= 0.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
399 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
400 *ifault = 1;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
401 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
402 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
403
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
404 *ifault = 0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
405
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
406 if ( x == 0.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
407 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
408 value = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
409 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
410 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
411 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
412 // If P is large, use a normal approximation.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
413 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
414 if ( plimit < p )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
415 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
416 pn1 = 3.0 * sqrt ( p ) * ( pow ( x / p, 1.0 / 3.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
417 + 1.0 / ( 9.0 * p ) - 1.0 );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
418
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
419 upper = false;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
420 value = alnorm ( pn1, upper );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
421 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
422 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
423 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
424 // If X is large set value = 1.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
425 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
426 if ( xbig < x )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
427 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
428 value = 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
429 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
430 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
431 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
432 // Use Pearson's series expansion.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
433 // (Note that P is not large enough to force overflow in ALOGAM).
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
434 // No need to test IFAULT on exit since P > 0.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
435 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
436 if ( x <= 1.0 || x < p )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
437 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
438 arg = p * log ( x ) - x - lgamma ( p + 1.0 );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
439 c = 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
440 value = 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
441 a = p;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
442
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
443 for ( ; ; )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
444 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
445 a = a + 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
446 c = c * x / a;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
447 value = value + c;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
448
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
449 if ( c <= tol )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
450 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
451 break;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
452 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
453 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
454
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
455 arg = arg + log ( value );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
456
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
457 if ( elimit <= arg )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
458 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
459 value = exp ( arg );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
460 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
461 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
462 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
463 value = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
464 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
465 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
466 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
467 // Use a continued fraction expansion.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
468 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
469 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
470 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
471 arg = p * log ( x ) - x - lgamma ( p );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
472 a = 1.0 - p;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
473 b = a + x + 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
474 c = 0.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
475 pn1 = 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
476 pn2 = x;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
477 pn3 = x + 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
478 pn4 = x * b;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
479 value = pn3 / pn4;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
480
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
481 for ( ; ; )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
482 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
483 a = a + 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
484 b = b + 2.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
485 c = c + 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
486 an = a * c;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
487 pn5 = b * pn3 - an * pn1;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
488 pn6 = b * pn4 - an * pn2;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
489
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
490 if ( pn6 != 0.0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
491 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
492 rn = pn5 / pn6;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
493
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
494 if ( fabs ( value - rn ) <= r8_min ( tol, tol * rn ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
495 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
496 break;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
497 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
498 value = rn;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
499 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
500
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
501 pn1 = pn3;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
502 pn2 = pn4;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
503 pn3 = pn5;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
504 pn4 = pn6;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
505 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
506 // Re-scale terms in continued fraction if terms are large.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
507 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
508 if ( oflo <= fabs ( pn5 ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
509 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
510 pn1 = pn1 / oflo;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
511 pn2 = pn2 / oflo;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
512 pn3 = pn3 / oflo;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
513 pn4 = pn4 / oflo;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
514 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
515 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
516
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
517 arg = arg + log ( value );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
518
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
519 if ( elimit <= arg )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
520 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
521 value = 1.0 - exp ( arg );
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
522 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
523 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
524 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
525 value = 1.0;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
526 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
527 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
528
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
529 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
530 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
531
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
532 double r8_min ( double x, double y )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
533
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
534 //****************************************************************************80
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
535 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
536 // Purpose:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
537 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
538 // R8_MIN returns the minimum of two R8's.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
539 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
540 // Licensing:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
541 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
542 // This code is distributed under the GNU LGPL license.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
543 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
544 // Modified:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
545 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
546 // 31 August 2004
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
547 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
548 // Author:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
549 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
550 // John Burkardt
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
551 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
552 // Parameters:
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
553 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
554 // Input, double X, Y, the quantities to compare.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
555 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
556 // Output, double R8_MIN, the minimum of X and Y.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
557 //
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
558 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
559 double value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
560
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
561 if ( y < x )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
562 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
563 value = y;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
564 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
565 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
566 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
567 value = x;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
568 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
569 return value;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
570 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
571
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
572 // This function is implemented by Li Song.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
573 // If Y follows (theta, k)=(1/alpha, k)-gamma distribution, then P_Y(Y<t)=gammad(alpha*t, k).
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
574 // Furthurmore, chi-square with d.f. k is gamma distribution (2, k/2)
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
575 double chicdf( double x, double df )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
576 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
577 int ifault ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
578 return gammad( x / 2.0, df / 2.0, &ifault ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
579 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
580