TMB Documentation  v1.9.11
atomic_macro.hpp
1 // Copyright (C) 2013-2015 Kasper Kristensen
2 // License: GPL-2
3 
4 /* Flag to detect if any atomic functions have been created */
5 TMB_EXTERN bool atomicFunctionGenerated CSKIP(= false;)
6 
8 #define TMB_ATOMIC_VECTOR_FUNCTION(ATOMIC_NAME, OUTPUT_DIM, ATOMIC_DOUBLE, \
9  ATOMIC_REVERSE) \
10  \
11  template<class Double> \
12  void ATOMIC_NAME(const CppAD::vector<Double>& tx, \
13  CppAD::vector<Double>& ty) CSKIP_ATOMIC({ \
14  ATOMIC_DOUBLE; \
15  }) \
16  template<class Double> \
17  CppAD::vector<double> \
18  ATOMIC_NAME(const CppAD::vector<Double>& tx) CSKIP_ATOMIC({ \
19  CppAD::vector<double> ty(OUTPUT_DIM); \
20  ATOMIC_NAME(tx, ty); \
21  return ty; \
22  }) \
23  IF_TMB_PRECOMPILE_ATOMICS( \
24  template \
25  void ATOMIC_NAME<double>(const CppAD::vector<double>& tx, \
26  CppAD::vector<double>& ty); \
27  template \
28  CppAD::vector<double> ATOMIC_NAME<double>(const CppAD::vector<double>& tx); \
29  ) \
30  template <class Type> \
31  void ATOMIC_NAME(const CppAD::vector<AD<Type> >& tx, \
32  CppAD::vector<AD<Type> >& ty); \
33  template <class Type> \
34  CppAD::vector<AD<Type> > ATOMIC_NAME(const CppAD::vector<AD<Type> >& tx); \
35  template <class Type> \
36  class atomic##ATOMIC_NAME : public CppAD::atomic_base<Type> { \
37  public: \
38  atomic##ATOMIC_NAME(const char* name) : CppAD::atomic_base<Type>(name) { \
39  atomic::atomicFunctionGenerated = true; \
40  if (config.trace.atomic) \
41  std::cout << "Constructing atomic " << #ATOMIC_NAME << "\n"; \
42  this->option(CppAD::atomic_base<Type>::bool_sparsity_enum); \
43  } \
44  \
45  private: \
46  virtual bool forward(size_t p, size_t q, const CppAD::vector<bool>& vx, \
47  CppAD::vector<bool>& vy, \
48  const CppAD::vector<Type>& tx, \
49  CppAD::vector<Type>& ty) { \
50  if (q > 0) \
51  Rf_error("Atomic '" #ATOMIC_NAME "' order not implemented.\n"); \
52  if (vx.size() > 0) { \
53  bool anyvx = false; \
54  for (size_t i = 0; i < vx.size(); i++) anyvx |= vx[i]; \
55  for (size_t i = 0; i < vy.size(); i++) vy[i] = anyvx; \
56  } \
57  ATOMIC_NAME(tx, ty); \
58  return true; \
59  } \
60  virtual bool reverse(size_t q, const CppAD::vector<Type>& tx, \
61  const CppAD::vector<Type>& ty, \
62  CppAD::vector<Type>& px, \
63  const CppAD::vector<Type>& py) { \
64  if (q > 0) \
65  Rf_error("Atomic '" #ATOMIC_NAME "' order not implemented.\n"); \
66  ATOMIC_REVERSE; \
67  return true; \
68  } \
69  virtual bool rev_sparse_jac(size_t q, const CppAD::vector<bool>& rt, \
70  CppAD::vector<bool>& st) { \
71  bool anyrt = false; \
72  for (size_t i = 0; i < rt.size(); i++) anyrt |= rt[i]; \
73  for (size_t i = 0; i < st.size(); i++) st[i] = anyrt; \
74  return true; \
75  } \
76  virtual bool rev_sparse_jac(size_t q, \
77  const CppAD::vector<std::set<size_t> >& rt, \
78  CppAD::vector<std::set<size_t> >& st) { \
79  Rf_error("Should not be called"); \
80  } \
81  }; \
82  template <class Type> \
83  void ATOMIC_NAME(const CppAD::vector<AD<Type> >& tx, \
84  CppAD::vector<AD<Type> >& ty) { \
85  static atomic##ATOMIC_NAME<Type> afun##ATOMIC_NAME( \
86  "atomic_" #ATOMIC_NAME); \
87  afun##ATOMIC_NAME(tx, ty); \
88  } \
89  template <class Type> \
90  CppAD::vector<AD<Type> > ATOMIC_NAME(const CppAD::vector<AD<Type> >& tx) { \
91  CppAD::vector<AD<Type> > ty(OUTPUT_DIM); \
92  ATOMIC_NAME(tx, ty); \
93  return ty; \
94  }
95 
96 #define TMB_ATOMIC_STATIC_FUNCTION( \
97  ATOMIC_NAME, \
98  INPUT_SIZE, \
99  ATOMIC_DOUBLE, \
100  ATOMIC_REVERSE \
101 ) \
102 template<class dummy=void> \
103 double ATOMIC_NAME (const double *tx) { \
104  double ty[1]; \
105  ATOMIC_DOUBLE; \
106  return ty[0]; \
107 } \
108 template <class Type> \
109 CppAD::vector<AD<Type> > ATOMIC_NAME(const CppAD::vector<AD<Type> >& tx);\
110 template<class Type> \
111 Type ATOMIC_NAME (const Type *tx) { \
112  CppAD::vector<Type> tx_(INPUT_SIZE); \
113  for (size_t i=0; i<INPUT_SIZE; i++) tx_[i]=tx[i]; \
114  return ATOMIC_NAME(tx_)[0]; \
115 } \
116 TMB_ATOMIC_VECTOR_FUNCTION( \
117  ATOMIC_NAME, \
118  1, \
119  ATOMIC_DOUBLE, \
120  ATOMIC_REVERSE \
121 )
122 // Helper to forward declare atomic
123 #define TMB_ATOMIC_VECTOR_FUNCTION_DECLARE(ATOMIC_NAME) \
124 template<class T> \
125 CppAD::vector<AD<T> > ATOMIC_NAME(const CppAD::vector<AD<T> > &x); \
126 template<class Double> \
127 CppAD::vector<double> ATOMIC_NAME(const CppAD::vector<Double > &x);
128 // Helper to forward define atomic
129 #define TMB_ATOMIC_VECTOR_FUNCTION_DEFINE(ATOMIC_NAME, \
130  OUTPUT_DIM, \
131  ATOMIC_DOUBLE, \
132  ATOMIC_REVERSE) \
133 TMB_ATOMIC_VECTOR_FUNCTION(ATOMIC_NAME, \
134  OUTPUT_DIM, \
135  ATOMIC_DOUBLE, \
136  ATOMIC_REVERSE)
Namespace with special functions and derivatives.
Definition: TMB.hpp:136
Type rt(Type df)
Simulate from a Student&#39;s t distribution.
#define TMB_ATOMIC_VECTOR_FUNCTION( ATOMIC_NAME, OUTPUT_DIM, ATOMIC_DOUBLE, ATOMIC_REVERSE)
Construct atomic vector function based on known derivatives.
bool atomic
Trace construction of atomic functions.
Definition: config.hpp:31
License: GPL v2