TMB Documentation  v1.9.11
lambert.cpp
1 
2 #include <TMB.hpp>
3 
4 // Double version of Lambert W function
5 double LambertW(double x) {
6  double logx = log(x);
7  double y = (logx > 0 ? logx : 0);
8  int niter = 100, i=0;
9  for (; i < niter; i++) {
10  if ( fabs( logx - log(y) - y) < 1e-9) break;
11  y -= (y - exp(logx - y)) / (1 + y);
12  }
13  if (i == niter) Rf_warning("W: failed convergence");
14  return y;
15 }
16 
18  // ATOMIC_NAME
19  LambertW
20  ,
21  // OUTPUT_DIM
22  1,
23  // ATOMIC_DOUBLE
24  ty[0] = LambertW(tx[0]); // Call the 'double' version
25  ,
26  // ATOMIC_REVERSE
27  Type W = ty[0]; // Function value from forward pass
28  Type DW = 1. / (exp(W) * (1. + W)); // Derivative
29  px[0] = DW * py[0]; // Reverse mode chain rule
30 )
31 
32 // Scalar version
33 template<class Type>
34 Type LambertW(Type x){
35  CppAD::vector<Type> tx(1);
36  tx[0] = x;
37  return LambertW(tx)[0];
38 }
39 
40 // Vectorized version
41 VECTORIZE1_t(LambertW)
42 
43 template<class Type>
44 Type objective_function<Type>::operator() ()
45 {
47  Type f = LambertW(x).sum();
48  return f;
49 }
50 
#define VECTORIZE1_t(FUN)
Vectorize 1-argument functions.
Definition: Vectorize.hpp:63
Includes and sets all stuff needed to compile the user defined objective function.
#define PARAMETER_VECTOR(name)
Get parameter vector from R and declare it as vector<Type>
Definition: tmb_core.hpp:220
#define TMB_ATOMIC_VECTOR_FUNCTION( ATOMIC_NAME, OUTPUT_DIM, ATOMIC_DOUBLE, ATOMIC_REVERSE)
Construct atomic vector function based on known derivatives.
License: GPL v2