ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
integrate.hpp
Go to the documentation of this file.
1 #ifndef TINY_AD_INTEGRATE_H
2 #define TINY_AD_INTEGRATE_H
3 
4 /* Standalone ? */
5 #ifndef R_RCONFIG_H
6 #include <vector>
7 using std::vector;
8 #include <float.h> // INFINITY etc
9 #endif
10 
11 namespace gauss_kronrod {
12 // Fake that Rmath.h is included - and take explicitly what we need
13 // #ifndef RMATH_H
14 // #define RMATH_H
15 // #endif
16 // *** Update: Rmath.h inclusion now disabled in integrate.cpp
17 
18 /*
19  These fmin2 and fmax2 assume that derivatives are not required. This
20  is OK for integrate since these functions are used to calculate
21  error bounds - nothing else.
22 
23  FIXME: Put all helper functions for integrate in its own namespace
24  to ensure that fmin2, fmax2 etc, are never used elsewhere.
25 */
26 template<class T>
27 double value(T x){ return ((double*) &x)[0]; }
28 template<class S, class T> // FIXME: Would imin2(int,int) conflict with Rf_imin2 ?
29 int imin2(S x, T y) {return (x < y) ? x : y;}
30 template<class S, class T>
31 double fmin2(S x, T y) {return (value(x) < value(y)) ? value(x) : value(y);}
32 template<class S, class T>
33 double fmax2(S x, T y) {return (value(x) < value(y)) ? value(y) : value(x);}
34 
35 #include "integrate.cpp"
36 
44 struct control {
46  double reltol;
47  double abstol;
48  control(int subdivisions_ = 100,
49  double reltol_ = 1e-4,
50  double abstol_ = 1e-4) :
51  subdivisions(subdivisions_),
52  reltol(reltol_),
53  abstol(abstol_) {}
54 };
55 
70 template<class Integrand>
71 struct Integral {
72  typedef typename Integrand::Scalar Type;
73  // R's integrators require a vectorized integrand
75  Integrand f;
76  vectorized_integrand(Integrand f_) : f(f_) {}
77  void operator() (Type *x, int n, void *ex) {
78  for(int i=0; i<n; i++) x[i] = f(x[i]);
79  }
80  } fn;
82  Integrand& integrand(){return fn.f;}
83  // Input to R's integrators
85  int neval, ier, limit, lenw, last;
86  vector<int> iwork;
87  vector<Type> work;
88  void setAccuracy(double epsrel_ = 1e-4, double epsabs_ = 1e-4) {
89  epsabs = epsabs_; epsrel = epsrel_; result = 0; abserr = 1e4;
90  neval = 0; ier = 0; last=0;
91  }
92  void setWorkspace(int subdivisions = 100) {
93  limit = subdivisions; lenw = 4 * limit;
94  iwork.resize(limit);
95  work.resize(lenw);
96  }
98  int inf;
99  void setBounds(Type a_, Type b_) {
100  int a_finite = (a_ != -INFINITY) && (a_ != INFINITY);
101  int b_finite = (b_ != -INFINITY) && (b_ != INFINITY);
102  if ( a_finite && b_finite) { inf = 0; a = a_; b = b_; }
103  else if ( a_finite && !b_finite) { inf = 1; bound = a_; }
104  else if (!a_finite && b_finite) { inf = -1; bound = b_; }
105  else { inf = 2; }
106  }
113  Integral(Integrand f_, Type a_, Type b_,
114  control c = control()
115  ) : fn(f_) {
116  setAccuracy(c.reltol, c.abstol);
117  setWorkspace(c.subdivisions);
118  setBounds(a_, b_);
119  }
121  if (inf)
122  Rdqagi(fn, NULL, &bound, &inf, &epsabs, &epsrel, &result, &abserr,
123  &neval, &ier, &limit, &lenw, &last, &iwork[0], &work[0]);
124  else
125  Rdqags(fn, NULL, &a, &b, &epsabs, &epsrel, &result, &abserr,
126  &neval, &ier, &limit, &lenw, &last, &iwork[0], &work[0]);
127  return result;
128  }
129 };
130 
157 template<class Integrand>
158 typename Integrand::Scalar integrate(Integrand f,
159  typename Integrand::Scalar a = -INFINITY,
160  typename Integrand::Scalar b = INFINITY,
161  control c = control() ) {
162  Integral< Integrand > I(f, a, b, c);
163  return I();
164 }
165 
180 template<class Integrand>
181 struct mvIntegral {
182  typedef typename Integrand::Scalar Scalar;
183  struct evaluator {
184  typedef typename Integrand::Scalar Scalar;
185  Integrand &f;
186  Scalar &x; // Integration variable
187  evaluator(Integrand &f_,
188  Scalar &x_ ) : f(f_), x(x_) {}
189  Scalar operator()(const Scalar &x_) {
190  x = x_;
191  return f();
192  }
193  } ev;
196  mvIntegral(Integrand &f_,
197  Scalar &x_,
198  Scalar a= -INFINITY,
199  Scalar b= INFINITY,
200  control c_ = control()) :
201  ev(f_, x_), c(c_), I(ev, a, b, c_) {}
202  Scalar operator()() { return I(); }
205  Scalar a= -INFINITY,
206  Scalar b= INFINITY) {
207  return mvIntegral<mvIntegral>(*this, x, a, b, c);
208  }
209 };
210 
211 
212 template<class Integrand>
213 struct mvIntegral0 {
214  typedef typename Integrand::Scalar Scalar;
215  Integrand &f;
217  mvIntegral0(Integrand &f_,
218  control c_) : f(f_), c(c_) {}
221  Scalar a= -INFINITY,
222  Scalar b= INFINITY) {
223  return mvIntegral<Integrand>(f, x, a, b, c);
224  }
225 };
253 template<class Integrand>
255  control c = control() ) {
256  return mvIntegral0<Integrand> (f, c);
257 }
258 
259 } // End namespace gauss_kronrod
260 
261 // using gauss_kronrod::Integral;
262 // using gauss_kronrod::integrate;
263 // using gauss_kronrod::mvIntegrate;
264 
265 #endif
Integrand::Scalar Scalar
Definition: integrate.hpp:214
mvIntegral< Integrand > wrt(Scalar &x, Scalar a=-INFINITY, Scalar b=INFINITY)
With respect to.
Definition: integrate.hpp:220
mvIntegral< mvIntegral > wrt(Scalar &x, Scalar a=-INFINITY, Scalar b=INFINITY)
With respect to.
Definition: integrate.hpp:204
int imin2(S x, T y)
Definition: integrate.hpp:29
Integral(Integrand f_, Type a_, Type b_, control c=control())
Constructor.
Definition: integrate.hpp:113
void operator()(Type *x, int n, void *ex)
Definition: integrate.hpp:77
evaluator(Integrand &f_, Scalar &x_)
Definition: integrate.hpp:187
User control parameters for R&#39;s integrate.
Definition: integrate.hpp:44
Integrand::Scalar Scalar
Definition: integrate.hpp:182
#define x
Integrand::Scalar integrate(Integrand f, typename Integrand::Scalar a=-INFINITY, typename Integrand::Scalar b=INFINITY, control c=control())
Integrate function over finite or infinite interval.
Definition: integrate.hpp:158
mvIntegral0< Integrand > mvIntegrate(Integrand &f, control c=control())
Multivariate integration.
Definition: integrate.hpp:254
double fmin2(S x, T y)
Definition: integrate.hpp:31
struct gauss_kronrod::mvIntegral::evaluator ev
Interface to R&#39;s adaptive integrate routine.
Definition: integrate.hpp:71
Scalar operator()(const Scalar &x_)
Definition: integrate.hpp:189
Integrand::Scalar Type
Definition: integrate.hpp:72
struct gauss_kronrod::Integral::vectorized_integrand fn
double fmax2(S x, T y)
Definition: integrate.hpp:33
void Rdqagi(integr_fn f, void *ex, Float *bound, int *inf, Float *epsabs, Float *epsrel, Float *result, Float *abserr, int *neval, int *ier, int *limit, int *lenw, int *last, int *iwork, Float *work)
Definition: integrate.hpp:72
vector< Type > work
Definition: integrate.hpp:87
Multivariate integral class.
Definition: integrate.hpp:181
control(int subdivisions_=100, double reltol_=1e-4, double abstol_=1e-4)
Definition: integrate.hpp:48
vector< int > iwork
Definition: integrate.hpp:86
void setAccuracy(double epsrel_=1e-4, double epsabs_=1e-4)
Definition: integrate.hpp:88
mvIntegral0(Integrand &f_, control c_)
Definition: integrate.hpp:217
void setBounds(Type a_, Type b_)
Definition: integrate.hpp:99
Integral< evaluator > I
Definition: integrate.hpp:195
void setWorkspace(int subdivisions=100)
Definition: integrate.hpp:92
double value(T x)
Definition: integrate.hpp:27
void Rdqags(integr_fn f, void *ex, Float *a, Float *b, Float *epsabs, Float *epsrel, Float *result, Float *abserr, int *neval, int *ier, int *limit, int *lenw, int *last, int *iwork, Float *work)
Definition: integrate.hpp:806
mvIntegral(Integrand &f_, Scalar &x_, Scalar a=-INFINITY, Scalar b=INFINITY, control c_=control())
Definition: integrate.hpp:196
Integrand & integrand()
Return reference to integrand so the user can change parameters.
Definition: integrate.hpp:82