TMB Documentation  v1.9.11
dynamic_data.hpp
1 namespace atomic {
2 namespace dynamic_data {
3  /* Represent SEXP as double so it can be put on the tape. Same for
4  char pointers.
5 
6  FIXME: Portability.
7  Currently assuming sizeof(double) >= sizeof(pointer) which should
8  be OK for most common 32/64 bit operating systems.
9  */
10 
11 #ifdef WITH_LIBTMB
12  double sexp_to_double(SEXP x);
13  SEXP double_to_sexp(double x);
14  double charptr_to_double(const char *x);
15  const char* double_to_charptr(double x);
16 #else
17  double sexp_to_double(SEXP x) {
18  SEXP* px = &x;
19  double* py = (double*) px;
20  return py[0];
21  }
22  SEXP double_to_sexp(double x) {
23  double* px = &x;
24  SEXP* py = (SEXP*) px;
25  return py[0];
26  }
27  double charptr_to_double(const char *x) {
28  const char** px = &x;
29  double* py = (double*) px;
30  return py[0];
31  }
32  const char* double_to_charptr(double x) {
33  double* px = &x;
34  const char** py = (const char**) px;
35  return py[0];
36  }
37 #endif // #ifdef WITH_LIBTMB
38 
40  // atomic name
41  list_lookup_by_index
42  ,
43  // output dim
44  1
45  ,
46  // forward double
47  SEXP data = double_to_sexp( tx[0] );
48  int index = (int) tx[1];
49  ty[0] = sexp_to_double( VECTOR_ELT(data, index) );
50  ,
51  // reverse
52  px[0] = 0; px[1] = 0;
53  )
54 
56  // atomic name
57  list_lookup_by_name
58  ,
59  // output dim
60  1
61  ,
62  // forward double
63  SEXP list = double_to_sexp( tx[0] );
64  const char* str = double_to_charptr( tx[1] );
65  SEXP elmt = R_NilValue;
66  SEXP names = Rf_getAttrib(list, R_NamesSymbol);
67  int i;
68  for (i = 0; i < Rf_length(list); i++) {
69  if(strcmp(CHAR(STRING_ELT(names, i)), str) == 0) {
70  elmt = VECTOR_ELT(list, i);
71  break;
72  }
73  }
74  ty[0] = sexp_to_double( elmt );
75  ,
76  // reverse
77  px[0] = 0; px[1] = 0;
78  )
79 
81  // atomic name
82  envir_lookup_by_name
83  ,
84  // output dim
85  1
86  ,
87  // forward double
88  SEXP envir = double_to_sexp( tx[0] );
89  const char* nam = double_to_charptr( tx[1] );
90  SEXP res = Rf_findVar(Rf_install(nam), envir);
91  ty[0] = sexp_to_double( res );
92  ,
93  // reverse
94  px[0] = 0; px[1] = 0;
95  )
96 
97  // Convert SEXP to vector
99  // atomic name
100  sexp_to_vector
101  ,
102  // output dim
103  LENGTH( double_to_sexp( asDouble(tx[0]) ))
104  ,
105  // forward double
106  SEXP data = double_to_sexp( tx[0] );
107  int n = LENGTH( data );
108  if (n != (int) ty.size())
109  Rf_error("Data update: "
110  "number of items to replace (%i) "
111  "does not match replacement length (%i)",
112  (int) ty.size(), n);
113  double* pdata = REAL(data);
114  for (int i = 0; i<n; i++) ty[i] = pdata[i];
115  ,
116  // reverse
117  px[0] = 0;
118  )
119 
120 
121  // Input: double x, Type y
122  // Output double x (now with fake dependence on y)
124  // atomic name
125  set_dependent
126  ,
127  // output dim
128  1
129  ,
130  // forward double
131  ty[0] = tx[0];
132  ,
133  // reverse
134  px[0] = 0; px[1] = 0;
135  )
136 
137 
138  /* Interfaces */
139  template<class Type>
140  Type set_dependent(double x, Type fake_parameter) {
141  CppAD::vector<Type> tx(2);
142  tx[0] = x;
143  tx[1] = fake_parameter;
144  return set_dependent(tx)[0];
145  }
146 
147  template<class Type>
148  vector<Type> sexp_to_vector(Type sexp) {
149  CppAD::vector<Type> tx(1);
150  tx[0] = sexp;
151  CppAD::vector<Type> ty(sexp_to_vector(tx));
152  return ty;
153  }
154 
155  // Output: SEXP represented by Type
156  template<class Type>
157  Type envir_lookup_by_name(Type envir, const char* name) {
158  CppAD::vector<Type> tx(2);
159  tx[0] = envir;
160  tx[1] = charptr_to_double( name );
161  return envir_lookup_by_name(tx)[0];
162  }
163 
164  // Output: SEXP represented by Type
165  template<class Type>
166  Type list_lookup_by_name(Type list, const char* name) {
167  CppAD::vector<Type> tx(2);
168  tx[0] = list;
169  tx[1] = charptr_to_double( name );
170  return list_lookup_by_name(tx)[0];
171  }
172 
173  // Output: SEXP represented by Type
174  template<class Type>
175  Type list_lookup_by_index(Type list, Type index) {
176  CppAD::vector<Type> tx(2);
177  tx[0] = list;
178  tx[1] = index;
179  return list_lookup_by_index(tx)[0];
180  }
181 
182  // Fill elements from y into x
183  template<class T1, class T2>
184  void cpy(T1 &x, T2 y) {
185  for (int i=0; i<y.size(); i++) {
186  x.coeffRef(i) = y.coeffRef(i);
187  }
188  }
189 
190  // Scalar case
191  template<class Type>
192  void cpy(Type &x, vector<Type> y) {
193  x = y[0];
194  }
195 
196 }
197 }
198 
221 #define DATA_UPDATE(name) \
222 atomic::dynamic_data::cpy(name, \
223  atomic::dynamic_data::sexp_to_vector( \
224  atomic::dynamic_data::list_lookup_by_name( \
225  atomic::dynamic_data::envir_lookup_by_name( \
226  atomic::dynamic_data::set_dependent( \
227  atomic::dynamic_data::sexp_to_double( \
228  ENCLOS(TMB_OBJECTIVE_PTR -> report) \
229  ), \
230  TMB_OBJECTIVE_PTR -> theta[0] \
231  ), \
232  "data" \
233  ), \
234  #name \
235  ) \
236  ) \
237 );
Vector class used by TMB.
Definition: vector.hpp:17
Namespace with special functions and derivatives.
#define TMB_ATOMIC_VECTOR_FUNCTION( ATOMIC_NAME, OUTPUT_DIM, ATOMIC_DOUBLE, ATOMIC_REVERSE)
Construct atomic vector function based on known derivatives.
License: GPL v2