ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tweedie_logW.cpp
Go to the documentation of this file.
1 // Re-structured version of tweedie density function from 'cplm' package.
2 
3 /* the threshold used in finding the bounds of the series */
4 #define TWEEDIE_DROP 37.0
5 /* the loop increment used in finding the bounds of the series */
6 #define TWEEDIE_INCRE 5
7 /* the max number of terms allowed in the finite sum approximation*/
8 #define TWEEDIE_NTERM 20000
9 
22 template<class Float>
23 Float tweedie_logW(double y, Float& phi, Float& p){
24  bool ok = (0 < y) && (0 < phi) && (1 < p) && (p < 2);
25  if (!ok) return NAN;
26 
27  Float p1 = p - 1.0, p2 = 2.0 - p;
28  Float a = - p2 / p1, a1 = 1.0 / p1;
29  Float cc, w, sum_ww = 0.0;
30  double ww_max = -INFINITY ;
31 
32  /* only need the lower bound and the # terms to be stored */
33  double jmax = 0;
34  Float logz = 0;
35 
36  /* compute jmax for the given y > 0*/
37  cc = a * log(p1) - log(p2);
38  jmax = asDouble( fmax2(1.0, pow(y, p2) / (phi * p2)) );
39  logz = - a * log(y) - a1 * log(phi) + cc;
40 
41  /* find bounds in the summation */
42  /* locate upper bound */
43  cc = logz + a1 + a * log(-a);
44  double j = jmax ;
45  w = a1 * j ;
46  while (1) {
47  j += TWEEDIE_INCRE ;
48  if (j * (cc - a1 * log(j)) < (w - TWEEDIE_DROP))
49  break ;
50  }
51  int jh = static_cast<int>(ceil(j));
52  /* locate lower bound */
53  j = jmax;
54  while (1) {
55  j -= TWEEDIE_INCRE ;
56  if (j < 1 || j * (cc - a1 * log(j)) < w - TWEEDIE_DROP)
57  break ;
58  }
59  int jl = imax2(1, floor(j)) ;
60  int jd = jh - jl + 1;
61 
62  /* set limit for # terms in the sum */
63  int nterms = imin2(jd, TWEEDIE_NTERM) ;
64  //std::vector<Float> ww(nterms);
65  /* evaluate series using the finite sum*/
66  /* y > 0 */
67  sum_ww = 0.0 ;
68  int iterm = imin2(jd, nterms) ;
69  std::vector<Float> ww(iterm);
70  for (int k = 0; k < iterm; k++) {
71  j = k + jl ;
72  ww[k] = j * logz - lgamma(1 + j) - lgamma(-a * j);
73  ww_max = fmax2( ww_max, asDouble(ww[k]) );
74  }
75  for (int k = 0; k < iterm; k++)
76  sum_ww += exp(ww[k] - ww_max);
77  Float ans = log(sum_ww) + ww_max ;
78 
79  return ans;
80 }
#define TWEEDIE_INCRE
Definition: tweedie_logW.cpp:6
int imax2(int a, double v)
Definition: dtweedie.cpp:5
dvariable lgamma(const prevariable &v)
Definition: dtweedie.cpp:23
double fmax2(double a, const dvariable &v)
Definition: dtweedie.cpp:14
#define TWEEDIE_NTERM
Definition: tweedie_logW.cpp:8
d3_array exp(const d3_array &arr3)
Returns d3_array results with computed exp from elements in arr3.
Definition: d3arr2a.cpp:28
#define w
double asDouble(const dvariable &v)
Definition: dtweedie.cpp:19
int imin2(int a, int b)
Definition: dtweedie.cpp:10
#define TWEEDIE_DROP
Definition: tweedie_logW.cpp:4
static double cc
Definition: cnorlogmix.cpp:13
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13
d3_array pow(const d3_array &m, int e)
Description not yet available.
Definition: d3arr6.cpp:17