CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
discrete.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_DISCRETE_HPP
2 # define CPPAD_CORE_DISCRETE_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 /*
16 $begin Discrete$$
17 $spell
18  retaping
19  namespace
20  std
21  Eq
22  Cpp
23  const
24  inline
25  Geq
26 $$
27 
28 $section Discrete AD Functions$$
29 $mindex CPPAD_DISCRETE_FUNCTION$$
30 
31 
32 $head Syntax$$
33 $codei%CPPAD_DISCRETE_FUNCTION(%Base%, %name%)
34 %$$
35 $icode%y% = %name%(%x%)
36 %$$
37 $icode%ay% = %name%(%ax%)
38 %$$
39 
40 
41 $head Purpose$$
42 Record the evaluation of a discrete function as part
43 of an $codei%AD<%Base%>%$$
44 $cref/operation sequence/glossary/Operation/Sequence/$$.
45 The value of a discrete function can depend on the
46 $cref/independent variables/glossary/Tape/Independent Variable/$$,
47 but its derivative is identically zero.
48 For example, suppose that the integer part of
49 a $cref/variable/glossary/Variable/$$ $icode x$$ is the
50 index into an array of values.
51 
52 $head Base$$
53 This is the
54 $cref/base type/base_require/$$
55 corresponding to the operations sequence;
56 i.e., use of the $icode name$$ with arguments of type
57 $codei%AD<%Base%>%$$ can be recorded in an operation sequence.
58 
59 $head name$$
60 This is the name of the function (as it is used in the source code).
61 The user must provide a version of $icode name$$
62 where the argument has type $icode Base$$.
63 CppAD uses this to create a version of $icode name$$
64 where the argument has type $codei%AD<%Base%>%$$.
65 
66 $head x$$
67 The argument $icode x$$ has prototype
68 $codei%
69  const %Base%& %x%
70 %$$
71 It is the value at which the user provided version of $icode name$$
72 is to be evaluated.
73 
74 $head y$$
75 The result $icode y$$ has prototype
76 $codei%
77  %Base% %y%
78 %$$
79 It is the return value for the user provided version of $icode name$$.
80 
81 $head ax$$
82 The argument $icode ax$$ has prototype
83 $codei%
84  const AD<%Base%>& %ax%
85 %$$
86 It is the value at which the CppAD provided version of $icode name$$
87 is to be evaluated.
88 
89 $head ay$$
90 The result $icode ay$$ has prototype
91 $codei%
92  AD<%Base%> %ay%
93 %$$
94 It is the return value for the CppAD provided version of $icode name$$.
95 
96 
97 $head Create AD Version$$
98 The preprocessor macro invocation
99 $codei%
100  CPPAD_DISCRETE_FUNCTION(%Base%, %name%)
101 %$$
102 defines the $codei%AD<%Base%>%$$ version of $icode name$$.
103 This can be with in a namespace (not the $code CppAD$$ namespace)
104 but must be outside of any routine.
105 
106 $head Operation Sequence$$
107 This is an AD of $icode Base$$
108 $cref/atomic operation/glossary/Operation/Atomic/$$
109 and hence is part of the current
110 AD of $icode Base$$
111 $cref/operation sequence/glossary/Operation/Sequence/$$.
112 
113 $head Derivatives$$
114 During a zero order $cref Forward$$ operation,
115 an $cref ADFun$$ object will compute the value of $icode name$$
116 using the user provided $icode Base$$ version of this routine.
117 All the derivatives of $icode name$$ will be evaluated as zero.
118 
119 $head Parallel Mode$$
120 The first call to
121 $codei%
122  %ay% = %name%(%ax%)
123 %$$
124 must not be in $cref/parallel/ta_in_parallel/$$ execution mode.
125 
126 
127 $head Example$$
128 $children%
129  example/general/tape_index.cpp%
130  example/general/interp_onetape.cpp%
131  example/general/interp_retape.cpp
132 %$$
133 The file
134 $cref tape_index.cpp$$
135 contains an example and test that uses a discrete function
136 to vary an array index during $cref Forward$$ mode calculations.
137 The file
138 $cref interp_onetape.cpp$$
139 contains an example and test that uses discrete
140 functions to avoid retaping a calculation that requires interpolation.
141 (The file
142 $cref interp_retape.cpp$$
143 shows how interpolation can be done with retaping.)
144 
145 $head CppADCreateDiscrete Deprecated 2007-07-28$$
146 The preprocessor symbol $code CppADCreateDiscrete$$
147 is defined to be the same as $code CPPAD_DISCRETE_FUNCTION$$
148 but its use is deprecated.
149 
150 $end
151 ------------------------------------------------------------------------------
152 */
153 # include <vector>
154 # include <cppad/core/cppad_assert.hpp>
155 
156 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
158 
159 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
160 /*!
161 \file discrete.hpp
162 user define discrete functions
163 */
164 
165 /*!
166 \def CPPAD_DISCRETE_FUNCTION(Base, name)
167 Defines the function <code>name(ax, ay)</code>
168 where \c ax and \c ay are vectors with <code>AD<Base></code> elements.
169 
170 \par Base
171 is the base type for the discrete function.
172 
173 \par name
174 is the name of the user defined function that corresponding to this operation.
175 */
176 
177 # define CPPAD_DISCRETE_FUNCTION(Base, name) \
178 inline CppAD::AD<Base> name (const CppAD::AD<Base>& ax) \
179 { \
180  static CppAD::discrete<Base> fun(#name, name); \
181  \
182  return fun.ad(ax); \
183 }
184 # define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION
185 
186 
187 /*
188 Class that acutally implemnets the <code>ay = name(ax)</code> call.
189 
190 A new discrete function is generated for ech time the user invokes
191 the CPPAD_DISCRETE_FUNCTION macro; see static object in that macro.
192 */
193 template <class Base>
194 class discrete {
195  /// parallel_ad needs to call List to initialize static
196  template <class Type>
197  friend void parallel_ad(void);
198 
199  /// type for the user routine that computes function values
200  typedef Base (*F) (const Base& x);
201 private:
202  /// name of this user defined function
203  const std::string name_;
204  /// user's implementation of the function for Base operations
205  const F f_;
206  /// index of this objec in the vector of all objects for this class
207  const size_t index_;
208 
209  /*!
210  List of all objects in this class.
211 
212  If we use CppAD::vector for this vector, it will appear that
213  there is a memory leak because this list is not distroyed before
214  thread_alloc::free_available(thread) is called by the testing routines.
215  */
216  static std::vector<discrete *>& List(void)
218  static std::vector<discrete *> list;
219  return list;
220  }
221 public:
222  /*!
223  Constructor called for each invocation of CPPAD_DISCRETE_FUNCTION.
224 
225  Put this object in the list of all objects for this class and set
226  the constant private data name_, f_, and index_.
227 
228  \param Name
229  is the user's name for this discrete function.
230 
231  \param f
232  user routine that implements this function for \c Base class.
233 
234  \par
235  This constructor can ont be used in parallel mode because it changes
236  the static object \c List.
237  */
238  discrete(const char* Name, F f) :
239  name_(Name)
240  , f_(f)
241  , index_( List().size() )
242  {
245  "discrete: First call the function *Name is in parallel mode."
246  );
247  List().push_back(this);
248  }
249 
250  /*!
251  Implement the user call to <code>ay = name(ax)</code>.
252 
253  \param ax
254  is the argument for this call.
255 
256  \return
257  the return value is called \c ay above.
258  */
259  AD<Base> ad(const AD<Base> &ax) const
260  { AD<Base> ay;
261 
262  ay.value_ = f_(ax.value_);
263  if( Variable(ax) )
264  { local::ADTape<Base> *tape = ax.tape_this();
267 
268  // put operand addresses in the tape
270  std::numeric_limits<addr_t>::max() >= index_,
271  "discrete: cppad_tape_addr_type maximum not large enough"
272  );
273  tape->Rec_.PutArg(addr_t(index_), ax.taddr_);
274  // put operator in the tape
275  ay.taddr_ = tape->Rec_.PutOp(local::DisOp);
276  // make result a variable
277  ay.tape_id_ = tape->id_;
278 
280  }
281  return ay;
282  }
283 
284  /// Name corresponding to a discrete object
285  static const char* name(size_t index)
286  { return List()[index]->name_.c_str(); }
287 
288  /*!
289  Link from forward mode sweep to users routine
290 
291  \param index
292  index for this function in the list of all discrete object
293 
294  \param x
295  argument value at which to evaluate this function
296  */
297  static Base eval(size_t index, const Base& x)
298  {
299  CPPAD_ASSERT_UNKNOWN(index < List().size() );
300 
301  return List()[index]->f_(x);
302  }
303 };
304 
305 } // END_CPPAD_NAMESPACE
306 # endif
friend void parallel_ad(void)
parallel_ad needs to call List to initialize static
Definition: parallel_ad.hpp:79
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
Base value_
Definition: ad.hpp:38
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
Definition: ad.hpp:34
static bool in_parallel(void)
Are we in a parallel execution state; i.e., is it possible that other threads are currently executing...
static const char * name(size_t index)
Name corresponding to a discrete object.
Definition: discrete.hpp:285
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
#define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode.
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
static Base eval(size_t index, const Base &x)
Link from forward mode sweep to users routine.
Definition: discrete.hpp:297
Base(* F)(const Base &x)
type for the user routine that computes function values
Definition: discrete.hpp:200
discrete(const char *Name, F f)
Constructor called for each invocation of CPPAD_DISCRETE_FUNCTION.
Definition: discrete.hpp:238
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Variable(const AD< Base > &x)
Definition: par_var.hpp:99
static std::vector< discrete * > & List(void)
List of all objects in this class.
Definition: discrete.hpp:216
const F f_
user&#39;s implementation of the function for Base operations
Definition: discrete.hpp:205
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
AD< Base > ad(const AD< Base > &ax) const
Implement the user call to ay = name(ax).
Definition: discrete.hpp:259
local::recorder< Base > Rec_
This is where the information is recorded.
Definition: ad_tape.hpp:106
tape_id_t tape_id_
Definition: ad.hpp:41
Class used to hold tape that records AD&lt;Base&gt; operations.
Definition: ad_tape.hpp:26
File used to define the CppAD multi-threading allocator class.
const std::string name_
name of this user defined function
Definition: discrete.hpp:203
const size_t index_
index of this objec in the vector of all objects for this class
Definition: discrete.hpp:207
addr_t taddr_
Definition: ad.hpp:44
tape_id_t id_
Unique identifier for this tape.
Definition: ad_tape.hpp:101
local::ADTape< Base > * tape_this(void) const
Get a pointer to tape that records AD&lt;Base&gt; operations for the current thread.
Definition: tape_link.hpp:335