ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cgamdev.cpp
Go to the documentation of this file.
1 
15 #include <fvar.hpp>
16 #define ITMAX 200
17 #define EPS 1.e-9
18 //#define EPS 3.0e-7
19 #define FPMIN 1.0e-30
20 void gcf(double& gammcf,double a,double x,double &gln);
21 void gser(double& gamser,double a,double x,double& gln);
22 
23 double gammp(double a,double x)
24 {
25  double gamser,gammcf,gln;
26 
27  if (x < 0.0 || a <= 0.0)
28  cerr << "Invalid arguments in routine gammp" << endl;
29  if (x < (a+1.0)) {
30  gser(gamser,a,x,gln);
31  return gamser;
32  } else {
33  gcf(gammcf,a,x,gln);
34  return 1.0-gammcf;
35  }
36 }
37 
38 double cumd_gamma(double x,double a)
39 {
40  double gamser,gammcf,gln;
41 
42  if (x < 0.0 || a <= 0.0)
43  cerr << "Invalid arguments in routine gammp" << endl;
44  if (x < (a+1.0)) {
45  gser(gamser,a,x,gln);
46  return gamser;
47  } else {
48  gcf(gammcf,a,x,gln);
49  return 1.0-gammcf;
50  }
51 }
52 
59 void gcf(double& gammcf,double a,double x,double &gln)
60 {
61  int i;
62  double an,b,c,d,del,h;
63 
64  gln=gammln(a);
65  b=x+1.0-a;
66  c=1.0/FPMIN;
67  d=1.0/b;
68  h=d;
69  for (i=1;i<=ITMAX;i++) {
70  an = -i*(i-a);
71  b += 2.0;
72  d=an*d+b;
73  if (fabs(d) < FPMIN) d=FPMIN;
74  c=b+an/c;
75  if (fabs(c) < FPMIN) c=FPMIN;
76  d=1.0/d;
77  del=d*c;
78  h *= del;
79  if (fabs(del-1.0) < EPS) break;
80  }
81  if (i > ITMAX)
82  cerr << "a too large, ITMAX too small in gcf" << endl;
83  gammcf=exp(-x+a*log(x)-(gln))*h;
84 }
85 
92 void gser(double& gamser,double a,double x,double& gln)
93 {
94  int n;
95  double sum,del,ap;
96 
97  gln=gammln(a);
98  if (x <= 0.0) {
99  if (x < 0.0)
100  cerr << "x less than 0 in routine gser" << endl;
101  gamser=0.0;
102  return;
103  } else {
104  ap=a;
105  del=sum=1.0/a;
106  for (n=1;n<=ITMAX;n++) {
107  ++ap;
108  del *= x/ap;
109  sum += del;
110  if (fabs(del) < fabs(sum)*EPS) {
111  gamser=sum*exp(-x+a*log(x)-(gln));
112  return;
113  }
114  }
115  cerr << "a too large, ITMAX too small in routine gser" << endl;
116  return;
117  }
118 }
119 
120 double get_initial_u(double a,double y);
121 
122 double Sn(double x,double a);
123 
124 double inv_cumd_gamma(double y,double a)
125 {
126  if (a<0.05)
127  {
128  cerr << "a musdt be > 0.1" << endl;
129  ad_exit(1);
130  }
131  double u=get_initial_u(a,y);
132  double h;
133  do
134  {
135  double z=gammp(a,a*exp(u));
136  double d=y-z;
137  //cout << d << endl;
138  double log_fprime=a*log(a)+a*(u-exp(u)) -gammln(a);
139  double fprime=exp(log_fprime);
140  h=d/fprime;
141  u+=h;
142  }
143  while(fabs(h)>1.e-12);
144  double x=a*exp(u);
145  return x;
146 }
147 
148 #undef ITMAX
149 #undef EPS
150 
151 double get_initial_u(double a,double y)
152 {
153  const double c=0.57721;
154  // note that P = y;
155  double logP=log(y);
156  double logQ=log(1-y);
157  double logB=logQ+gammln(a);
158  double x0=1.e+100;
159  double log_x0=1.e+100;
160 
161  if (a<1.0)
162  {
163  if ( logB>log(.6) || (logB > log(.45) && a>=.3) )
164  {
165  double logu;
166  if (logB+logQ > log(1.e-8))
167  {
168  logu=(logP+gammln(1.0+a))/a;
169  }
170  else
171  {
172  logu=-exp(logQ)/a -c;
173  }
174  double u=exp(logu);
175  x0=u/(1-u/(1.0+a));
176  double tmp=log(1-u/(1.0+a));
177  log_x0=logu;
178  log_x0-=tmp;
179  }
180  else if ( a<.3 && log(.35) <= logB && logB <= log(.6) )
181  {
182  double t=exp(-c-exp(logB));
183  double logt=-c-exp(logB);
184  double u=t*exp(t);
185  x0=t*exp(u);
186  log_x0=logt+u;
187  }
188  else if ( (log(.15)<=logB && logB <=log(.35)) ||
189  ((log(.15)<=logB && logB <=log(.45)) && a>=.3) )
190  {
191  double y=-logB;
192  double v=y-(1-a)*log(y);
193  x0=y-(1-a)*log(v)-log(1+(1.0-a)/(1.0+v));
194  log_x0=log(x0);
195  }
196  else if (log(.01)<logB && logB < log(.15))
197  {
198  double y=-logB;
199  double v=y-(1-a)*log(y);
200  x0=y-(1-a)*log(v)-log((v*v+2*(3-a)*v+(2-a)*(3-a))/(v*v +(5-a)*v+2));
201  log_x0=log(x0);
202  }
203  else if (logB < log(.01))
204  {
205  double y=-logB;
206  double v=y-(1-a)*log(y);
207  x0=y-(1-a)*log(v)-log((v*v+2*(3-a)*v+(2-a)*(3-a))/(v*v +(5-a)*v+2));
208  log_x0=log(x0);
209  }
210  else
211  {
212  cerr << "this can't happen" << endl;
213  ad_exit(1);
214  }
215  }
216  else if (a>=1.0)
217  {
218  const double a0 = 3.31125922108741;
219  const double b1 = 6.61053765625462;
220  const double a1 = 11.6616720288968;
221  const double b2 = 6.40691597760039;
222  const double a2 = 4.28342155967104;
223  const double b3 = 1.27364489782223;
224  const double a3 = .213623493715853;
225  const double b4 = .03611708101884203;
226 
227  int sgn=1;
228  double logtau;
229  if (logP< log(0.5))
230  {
231  logtau=logP;
232  sgn=-1;
233  }
234  else
235  {
236  logtau=logQ;
237  sgn=1;
238  }
239 
240  double t=sqrt(-2.0*logtau);
241 
242  double num = (((a3*t+a2)*t+a1)*t)+a0;
243  double den = ((((b4*t+b3)*t+b2)*t)+b1)*t+1;
244  double s=sgn*(t-num/den);
245  double s2=s*s;
246  double s3=s2*s;
247  double s4=s3*s;
248  double s5=s4*s;
249  double roota=sqrt(a);
250  double w=a+s*roota+(s2-1)/3.0+(s3-7.0*s)/(36.*roota)
251  -(3.0*s4+7.0*s2-16)/(810.0*a)
252  +(9.0*s5+256.0*s3-433.0*s)/(38880.0*a*roota);
253  if (logP< log(0.5))
254  {
255  if (w>.15*(a+1))
256  {
257  x0=w;
258  }
259  else
260  {
261  double v=logP+gammln(a+1);
262  double u1=exp(v+w)/a;
263  double S1=1+u1/(a+1);
264  double u2=exp((v+u1-log(S1))/a);
265  double S2=1+u2/(a+1)+u2*u2/((a+1)*(a+2));
266  double u3=exp((v+u2-log(S2))/a);
267  double S3=1+u3/(a+1)+u3*u3/((a+1)*(a+2))
268  + u3*u3*u3/((a+1)*(a+2)*(a+3));
269  double z=exp((v+u3-log(S3))/a);
270  if (z<.002*(a+1.0))
271  {
272  x0=z;
273  }
274  else
275  {
276  double sn=Sn(z,a);
277  double zbar=exp((v+z-log(sn))/a);
278  x0=zbar*(1.0-(a*log(zbar)-zbar-v+log(sn))/(a-zbar));
279  }
280  }
281  log_x0=log(x0);
282  }
283  else
284  {
285  double u = -logB +(a-1.0)*log(w)-log(1.0+(1.0-a)/(1+w));
286  x0=u;
287  log_x0=log(x0);
288  }
289  }
290  if (a==1.0)
291  {
292  x0=-log(1.0-y);
293  log_x0=log(x0);
294  }
295  return log_x0-log(a);
296 }
double gammln(double xx)
Log gamma function.
Definition: combc.cpp:52
#define EPS
Definition: betacf_val.hpp:10
#define x
double inv_cumd_gamma(double y, double a)
Definition: cgamdev.cpp:124
double cumd_gamma(double x, double a)
Definition: cgamdev.cpp:38
double sum(const d3_array &darray)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr.cpp:21
exitptr ad_exit
Definition: gradstrc.cpp:53
df1_two_variable fabs(const df1_two_variable &x)
Definition: df12fun.cpp:891
#define ITMAX
Definition: cgamdev.cpp:16
ivector sgn(const dvector &v)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dvect24.cpp:11
prnstream & endl(prnstream &)
d3_array sqrt(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2c.cpp:11
double get_initial_u(double a, double y)
Definition: cgamdev.cpp:151
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
double gammp(double a, double x)
Definition: cgamdev.cpp:23
d3_array exp(const d3_array &arr3)
Returns d3_array results with computed exp from elements in arr3.
Definition: d3arr2a.cpp:28
void gcf(double &gammcf, double a, double x, double &gln)
Incomplete gamma function.
Definition: cgamdev.cpp:59
void gser(double &gamser, double a, double x, double &gln)
Incomplete gamma function.
Definition: cgamdev.cpp:92
#define w
double Sn(double x, double a)
Definition: vgamdev.cpp:178
#define FPMIN
Definition: cgamdev.cpp:19
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13