ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vgamdev.cpp
Go to the documentation of this file.
1 /*
2  $Id$
3 
4  Author: David Fournier
5  Copyright (c) 2008, 2009, 2010 Regents of the University of California
6  */
7 #include <fvar.hpp>
8 #define ITMAX 200
9 //#define EPS 3.0e-7
10 #define EPS 1.0e-9
11 #define FPMIN 1.0e-30
12 static void gcf(double& gammcf,double a,double x,double &gln);
13 static void gser(double& gamser,double a,double x,double& gln);
14 
20  {
21  prevariable& x= (prevariable&)(_x);
22  prevariable& a= (prevariable&)(_a);
23 
24  dvariable y=cumd_norm(x);
25 
26  y=.9999*y+.00005;
27 
29 
30  return z;
31  }
32 
33 
34 static double gammp(double a,double x)
35 {
36  double gamser = 0.0,gammcf,gln;
37 
38  if (x < 0.0 || a <= 0.0)
39  cerr << "Invalid arguments in routine gammp" << endl;
40  if (x < (a+1.0)) {
41  gser(gamser,a,x,gln);
42  return gamser;
43  } else {
44  gcf(gammcf,a,x,gln);
45  return 1.0-gammcf;
46  }
47 }
48 
55 static void gcf(double& gammcf,double a,double x,double &gln)
56 {
57  int i;
58  double an,b,c,d,del,h;
59 
60  gln=gammln(a);
61  b=x+1.0-a;
62  c=1.0/FPMIN;
63  d=1.0/b;
64  h=d;
65  for (i=1;i<=ITMAX;i++) {
66  an = -i*(i-a);
67  b += 2.0;
68  d=an*d+b;
69  if (fabs(d) < FPMIN) d=FPMIN;
70  c=b+an/c;
71  if (fabs(c) < FPMIN) c=FPMIN;
72  d=1.0/d;
73  del=d*c;
74  h *= del;
75  if (fabs(del-1.0) < EPS) break;
76  }
77  if (i > ITMAX)
78  cerr << "a too large, ITMAX too small in gcf" << endl;
79  gammcf=exp(-x+a*log(x)-(gln))*h;
80 }
81 
88 static void gser(double& gamser,double a,double x,double& gln)
89 {
90  int n;
91  double sum,del,ap;
92 
93  gln=gammln(a);
94  if (x <= 0.0) {
95  if (x < 0.0)
96  cerr << "x less than 0 in routine gser" << endl;
97  gamser=0.0;
98  return;
99  } else {
100  ap=a;
101  del=sum=1.0/a;
102  for (n=1;n<=ITMAX;n++) {
103  ++ap;
104  del *= x/ap;
105  sum += del;
106  if (fabs(del) < fabs(sum)*EPS) {
107  gamser=sum*exp(-x+a*log(x)-(gln));
108  return;
109  }
110  }
111  cerr << "a too large, ITMAX too small in routine gser" << endl;
112  return;
113  }
114 }
115 
116 static double get_initial_u(double a,double y);
117 
118 double Sn(double x,double a);
119 
120 #include <df32fun.h>
122  const df3_two_variable& a);
123 
125 {
126  double a=value(_a);
127  double y=value(_y);
128  if (a<0.05)
129  {
130  cerr << "a musdt be > 0.1" << endl;
131  ad_exit(1);
132  }
133  double u=get_initial_u(a,y);
134  double h;
135  int loop_counter=0;
136  do
137  {
138  loop_counter++;
139  double z=gammp(a,a*exp(u));
140  double d=y-z;
141  //cout << d << endl;
142  double log_fprime=a*log(a)+a*(u-exp(u)) -gammln(a);
143  double fprime=exp(log_fprime);
144  h=d/fprime;
145  u+=h;
146  if (loop_counter>1000)
147  {
148  cerr << "Error in inv_cumd_gamma"
149  " maximum number of interations exceeded for values"
150  << endl << " x = " << y << " a = " << a << " h = " << h << endl;
151  }
152  }
153  while(fabs(h)>1.e-12);
154 
155  double x=a*exp(u);
156 
157  init_df3_two_variable xx(x);
158  init_df3_two_variable aa(a);
159  *xx.get_u_x()=1.0;
160  *aa.get_u_y()=1.0;
161 
162  df3_two_variable z=cumd_gamma(xx,aa);
163  double F_x=1.0/(*z.get_u_x());
164  double F_y=-F_x*(*z.get_u_y());
165 
166  dvariable vz=0.0;
167  value(vz)=x;
168 
170  &(vz.v->x),&(_y.v->x),F_x,&(_a.v->x),F_y);
171 
172  return vz;
173 }
174 
175 #undef ITMAX
176 #undef EPS
177 
178 double Sn(double x,double a)
179 {
180  double summ=1.0;
181 
182  const double xp=x;
183  double prod=1.0;
184 
185  int i=1;
186  for (; i <= 50; i++)
187  {
188  prod*=(a+i);
189  double summand=xp/prod;
190  if (summand<1.e-4) break;
191  summ+=summand;
192  }
193  if (i > 50)
194  {
195  cerr << "convergence error" << endl;
196  ad_exit(1);
197  }
198  return summ;
199 }
200 
201 static double get_initial_u(double a,double y)
202 {
203  const double c=0.57721;
204  // note that P = y;
205  double logP=log(y);
206  double logQ=log(1-y);
207  double logB=logQ+gammln(a);
208  double x0=1.e+100;
209  double log_x0=1.e+100;
210 
211  if (a<1.0)
212  {
213  if ( logB>log(.6) || (logB > log(.45) && a>=.3) )
214  {
215  double logu;
216  if (logB+logQ > log(1.e-8))
217  {
218  logu=(logP+gammln(1.0+a))/a;
219  }
220  else
221  {
222  logu=-exp(logQ)/a -c;
223  }
224  double u=exp(logu);
225  x0=u/(1-u/(1.0+a));
226  double tmp=log(1-u/(1.0+a));
227  log_x0=logu;
228  log_x0-=tmp;
229  }
230  else if ( a<.3 && log(.35) <= logB && logB <= log(.6) )
231  {
232  double t=exp(-c-exp(logB));
233  double logt=-c-exp(logB);
234  double u=t*exp(t);
235  x0=t*exp(u);
236  log_x0=logt+u;
237  }
238  else if ( (log(.15)<=logB && logB <=log(.35)) ||
239  ((log(.15)<=logB && logB <=log(.45)) && a>=.3) )
240  {
241  double y=-logB;
242  double v=y-(1-a)*log(y);
243  x0=y-(1-a)*log(v)-log(1+(1.0-a)/(1.0+v));
244  log_x0=log(x0);
245  }
246  else if (log(.01)<logB && logB < log(.15))
247  {
248  double y=-logB;
249  double v=y-(1-a)*log(y);
250  x0=y-(1-a)*log(v)-log((v*v+2*(3-a)*v+(2-a)*(3-a))/(v*v +(5-a)*v+2));
251  log_x0=log(x0);
252  }
253  else if (logB < log(.01))
254  {
255  double y=-logB;
256  double v=y-(1-a)*log(y);
257  x0=y-(1-a)*log(v)-log((v*v+2*(3-a)*v+(2-a)*(3-a))/(v*v +(5-a)*v+2));
258  log_x0=log(x0);
259  }
260  else
261  {
262  cerr << "this can't happen" << endl;
263  ad_exit(1);
264  }
265  }
266  else if (a>=1.0)
267  {
268  const double a0 = 3.31125922108741;
269  const double b1 = 6.61053765625462;
270  const double a1 = 11.6616720288968;
271  const double b2 = 6.40691597760039;
272  const double a2 = 4.28342155967104;
273  const double b3 = 1.27364489782223;
274  const double a3 = .213623493715853;
275  const double b4 = .03611708101884203;
276 
277  int sgn=1;
278  double logtau;
279  if (logP< log(0.5))
280  {
281  logtau=logP;
282  sgn=-1;
283  }
284  else
285  {
286  logtau=logQ;
287  sgn=1;
288  }
289 
290  double t=sqrt(-2.0*logtau);
291 
292  double num = (((a3*t+a2)*t+a1)*t)+a0;
293  double den = ((((b4*t+b3)*t+b2)*t)+b1)*t+1;
294  double s=sgn*(t-num/den);
295  double s2=s*s;
296  double s3=s2*s;
297  double s4=s3*s;
298  double s5=s4*s;
299  double roota=sqrt(a);
300  double w=a+s*roota+(s2-1)/3.0+(s3-7.0*s)/(36.*roota)
301  -(3.0*s4+7.0*s2-16)/(810.0*a)
302  +(9.0*s5+256.0*s3-433.0*s)/(38880.0*a*roota);
303  if (logP< log(0.5))
304  {
305  if (w>.15*(a+1))
306  {
307  x0=w;
308  }
309  else
310  {
311  double v=logP+gammln(a+1);
312  double u1=exp(v+w)/a;
313  double S1=1+u1/(a+1);
314  double u2=exp((v+u1-log(S1))/a);
315  double S2=1+u2/(a+1)+u2*u2/((a+1)*(a+2));
316  double u3=exp((v+u2-log(S2))/a);
317  double S3=1+u3/(a+1)+u3*u3/((a+1)*(a+2))
318  + u3*u3*u3/((a+1)*(a+2)*(a+3));
319  double z=exp((v+u3-log(S3))/a);
320  if (z<.002*(a+1.0))
321  {
322  x0=z;
323  }
324  else
325  {
326  double sn=Sn(z,a);
327  double zbar=exp((v+z-log(sn))/a);
328  x0=zbar*(1.0-(a*log(zbar)-zbar-v+log(sn))/(a-zbar));
329  }
330  }
331  log_x0=log(x0);
332  }
333  else
334  {
335  double u = -logB +(a-1.0)*log(w)-log(1.0+(1.0-a)/(1+w));
336  x0=u;
337  log_x0=log(x0);
338  }
339  }
340  if (a==1.0)
341  {
342  x0=-log(1.0-y);
343  log_x0=log(x0);
344  }
345  return log_x0-log(a);
346 }
Base class for dvariable.
Definition: fvar.hpp:1315
double gammln(double xx)
Log gamma function.
Definition: combc.cpp:52
#define EPS
Definition: betacf_val.hpp:10
Description not yet available.
Definition: df32fun.h:55
#define x
double inv_cumd_gamma(double y, double a)
Definition: cgamdev.cpp:124
Description not yet available.
Definition: df32fun.h:130
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
ivector sgn(const dvector &v)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dvect24.cpp:11
void set_gradient_stack(void(*func)(void), double *dep_addr, double *ind_addr1=NULL, double mult1=0, double *ind_addr2=NULL, double mult2=0)
Description not yet available.
Definition: fvar.hpp:1045
double * get_u_y(void) const
Definition: df32fun.h:74
double * get_u_x(void) const
Definition: df32fun.h:70
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
#define FPMIN
Definition: vgamdev.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 default_evaluation(void)
Description not yet available.
Definition: def_eval.cpp:61
void gcf(double &gammcf, double a, double x, double &gln)
Incomplete gamma function.
Definition: cgamdev.cpp:59
double_and_int * v
pointer to the data
Definition: fvar.hpp:1333
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
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
static _THREAD grad_stack * GRAD_STACK1
double cumd_norm(const double &x)
Culative normal distribution; constant objects.
Definition: cumdist.cpp:90
#define ITMAX
Definition: vgamdev.cpp:8
Description not yet available.
Fundamental data type for reverse mode automatic differentiation.
Definition: fvar.hpp:1518
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13
double x
&lt; value of the variable
Definition: fvar.hpp:195
double gamma_deviate(double _x, double _a)