CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
fun_construct.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_FUN_CONSTRUCT_HPP
2 # define CPPAD_CORE_FUN_CONSTRUCT_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 $begin FunConstruct$$
16 $spell
17  alloc
18  num
19  Jac
20  bool
21  taylor
22  var
23  ADvector
24  const
25  Jacobian
26 $$
27 
28 $spell
29 $$
30 
31 $section Construct an ADFun Object and Stop Recording$$
32 $mindex tape$$
33 
34 
35 $head Syntax$$
36 $codei%ADFun<%Base%> %f%, %g%
37 %$$
38 $codei%ADFun<%Base%> %f%(%x%, %y%)
39 %$$
40 $icode%g% = %f%
41 %$$
42 
43 
44 $head Purpose$$
45 The $codei%AD<%Base%>%$$ object $icode f$$ can
46 store an AD of $icode Base$$
47 $cref/operation sequence/glossary/Operation/Sequence/$$.
48 It can then be used to calculate derivatives of the corresponding
49 $cref/AD function/glossary/AD Function/$$
50 $latex \[
51  F : B^n \rightarrow B^m
52 \] $$
53 where $latex B$$ is the space corresponding to objects of type $icode Base$$.
54 
55 $head x$$
56 If the argument $icode x$$ is present, it has prototype
57 $codei%
58  const %VectorAD% &%x%
59 %$$
60 It must be the vector argument in the previous call to
61 $cref Independent$$.
62 Neither its size, or any of its values, are allowed to change
63 between calling
64 $codei%
65  Independent(%x%)
66 %$$
67 and
68 $codei%
69  ADFun<%Base%> %f%(%x%, %y%)
70 %$$
71 
72 $head y$$
73 If the argument $icode y$$ is present, it has prototype
74 $codei%
75  const %VectorAD% &%y%
76 %$$
77 The sequence of operations that map $icode x$$
78 to $icode y$$ are stored in the ADFun object $icode f$$.
79 
80 $head VectorAD$$
81 The type $icode VectorAD$$ must be a $cref SimpleVector$$ class with
82 $cref/elements of type/SimpleVector/Elements of Specified Type/$$
83 $codei%AD<%Base%>%$$.
84 The routine $cref CheckSimpleVector$$ will generate an error message
85 if this is not the case.
86 
87 $head Default Constructor$$
88 The default constructor
89 $codei%
90  ADFun<%Base%> %f%
91 %$$
92 creates an
93 $codei%AD<%Base%>%$$ object with no corresponding operation sequence; i.e.,
94 $codei%
95  %f%.size_var()
96 %$$
97 returns the value zero (see $cref/size_var/seq_property/size_var/$$).
98 
99 $head Sequence Constructor$$
100 The sequence constructor
101 $codei%
102  ADFun<%Base%> %f%(%x%, %y%)
103 %$$
104 creates the $codei%AD<%Base%>%$$ object $icode f$$,
105 stops the recording of AD of $icode Base$$ operations
106 corresponding to the call
107 $codei%
108  Independent(%x%)
109 %$$
110 and stores the corresponding operation sequence in the object $icode f$$.
111 It then stores the zero order Taylor coefficients
112 (corresponding to the value of $icode x$$) in $icode f$$.
113 This is equivalent to the following steps using the default constructor:
114 
115 $list number$$
116 Create $icode f$$ with the default constructor
117 $codei%
118  ADFun<%Base%> %f%;
119 %$$
120 $lnext
121 Stop the tape and storing the operation sequence using
122 $codei%
123  %f%.Dependent(%x%, %y%);
124 %$$
125 (see $cref Dependent$$).
126 $lnext
127 Calculate the zero order Taylor coefficients for all
128 the variables in the operation sequence using
129 $codei%
130  %f%.Forward(%p%, %x_p%)
131 %$$
132 with $icode p$$ equal to zero and the elements of $icode x_p$$
133 equal to the corresponding elements of $icode x$$
134 (see $cref Forward$$).
135 $lend
136 
137 $head Copy Constructor$$
138 It is an error to attempt to use the $codei%ADFun<%Base%>%$$ copy constructor;
139 i.e., the following syntax is not allowed:
140 $codei%
141  ADFun<%Base%> %g%(%f%)
142 %$$
143 where $icode f$$ is an $codei%ADFun<%Base%>%$$ object.
144 Use its $cref/default constructor/FunConstruct/Default Constructor/$$ instead
145 and its assignment operator.
146 
147 $head Assignment Operator$$
148 The $codei%ADFun<%Base%>%$$ assignment operation
149 $codei%
150  %g% = %f%
151 %$$
152 makes a copy of the operation sequence currently stored in $icode f$$
153 in the object $icode g$$.
154 The object $icode f$$ is not affected by this operation and
155 can be $code const$$.
156 All of information (state) stored in $icode f$$ is copied to $icode g$$
157 and any information originally in $icode g$$ is lost.
158 
159 $subhead Taylor Coefficients$$
160 The Taylor coefficient information currently stored in $icode f$$
161 (computed by $cref/f.Forward/Forward/$$) is
162 copied to $icode g$$.
163 Hence, directly after this operation
164 $codei%
165  %g%.size_order() == %f%.size_order()
166 %$$
167 
168 $subhead Sparsity Patterns$$
169 The forward Jacobian sparsity pattern currently stored in $icode f$$
170 (computed by $cref/f.ForSparseJac/ForSparseJac/$$) is
171 copied to $icode g$$.
172 Hence, directly after this operation
173 $codei%
174  %g%.size_forward_bool() == %f%.size_forward_bool()
175  %g%.size_forward_set() == %f%.size_forward_set()
176 %$$
177 
178 $head Parallel Mode$$
179 The call to $code Independent$$,
180 and the corresponding call to
181 $codei%
182  ADFun<%Base%> %f%( %x%, %y%)
183 %$$
184 or
185 $codei%
186  %f%.Dependent( %x%, %y%)
187 %$$
188 or $cref abort_recording$$,
189 must be preformed by the same thread; i.e.,
190 $cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same.
191 
192 $head Example$$
193 
194 $subhead Sequence Constructor$$
195 The file
196 $cref independent.cpp$$
197 contains an example and test of the sequence constructor.
198 It returns true if it succeeds and false otherwise.
199 
200 $subhead Default Constructor$$
201 The files
202 $cref fun_check.cpp$$
203 and
204 $cref hes_lagrangian.cpp$$
205 contain an examples and tests using the default constructor.
206 They return true if they succeed and false otherwise.
207 
208 $children%
209  example/general/fun_assign.cpp
210 %$$
211 $subhead Assignment Operator$$
212 The file
213 $cref fun_assign.cpp$$
214 contains an example and test of the $codei%ADFun<%Base%>%$$
215 assignment operator.
216 It returns true if it succeeds and false otherwise.
217 
218 $end
219 ----------------------------------------------------------------------------
220 */
221 
222 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
223 /*!
224 \file fun_construct.hpp
225 ADFun function constructors and assignment operator.
226 */
227 
228 /*!
229 ADFun default constructor
230 
231 The C++ syntax for this operation is
232 \verbatim
233  ADFun<Base> f
234 \endverbatim
235 An empty ADFun object is created.
236 The Dependent member function,
237 or the ADFun<Base> assingment operator,
238 can then be used to put an operation sequence in this ADFun object.
239 
240 \tparam Base
241 is the base for the recording that can be stored in this ADFun object;
242 i.e., operation sequences that were recorded using the type \c AD<Base>.
243 */
244 template <typename Base>
246 has_been_optimized_(false),
247 check_for_nan_(true) ,
248 compare_change_count_(1),
249 compare_change_number_(0),
250 compare_change_op_index_(0),
251 num_var_tape_(0)
252 { }
253 
254 /*!
255 ADFun assignment operator
256 
257 The C++ syntax for this operation is
258 \verbatim
259  g = f
260 \endverbatim
261 where \c g and \c f are ADFun<Base> ADFun objects.
262 A copy of the the operation sequence currently stored in \c f
263 is placed in this ADFun object (called \c g above).
264 Any information currently stored in this ADFun object is lost.
265 
266 \tparam Base
267 is the base for the recording that can be stored in this ADFun object;
268 i.e., operation sequences that were recorded using the type \c AD<Base>.
269 
270 \param f
271 ADFun object containing the operation sequence to be copied.
272 */
273 template <typename Base>
275 { size_t m = f.Range();
276  size_t n = f.Domain();
277  size_t i;
278 
279  // go through member variables in ad_fun.hpp order
280  //
281  // size_t objects
282  has_been_optimized_ = f.has_been_optimized_;
283  check_for_nan_ = f.check_for_nan_;
284  compare_change_count_ = f.compare_change_count_;
285  compare_change_number_ = f.compare_change_number_;
286  compare_change_op_index_ = f.compare_change_op_index_;
287  num_order_taylor_ = f.num_order_taylor_;
288  cap_order_taylor_ = f.cap_order_taylor_;
289  num_direction_taylor_ = f.num_direction_taylor_;
290  num_var_tape_ = f.num_var_tape_;
291  //
292  // CppAD::vector objects
293  ind_taddr_.resize(n);
294  ind_taddr_ = f.ind_taddr_;
295  dep_taddr_.resize(m);
296  dep_taddr_ = f.dep_taddr_;
297  dep_parameter_.resize(m);
298  dep_parameter_ = f.dep_parameter_;
299  //
300  // pod_vector objects
301  taylor_ = f.taylor_;
302  cskip_op_ = f.cskip_op_;
303  load_op_ = f.load_op_;
304  subgraph_info_ = f.subgraph_info_;
305  //
306  // player
307  play_ = f.play_;
308  //
309  // sparse_pack
310  for_jac_sparse_pack_.resize(0, 0);
311  size_t n_set = f.for_jac_sparse_pack_.n_set();
312  size_t end = f.for_jac_sparse_pack_.end();
313  if( n_set > 0 )
314  { CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ );
316  for_jac_sparse_pack_.resize(n_set, end);
317  for(i = 0; i < num_var_tape_ ; i++)
318  { for_jac_sparse_pack_.assignment(
319  i ,
320  i ,
322  );
323  }
324  }
325  //
326  // sparse_set
327  for_jac_sparse_set_.resize(0, 0);
328  n_set = f.for_jac_sparse_set_.n_set();
329  end = f.for_jac_sparse_set_.end();
330  if( n_set > 0 )
331  { CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ );
333  for_jac_sparse_set_.resize(n_set, end);
334  for(i = 0; i < num_var_tape_; i++)
335  { for_jac_sparse_set_.assignment(
336  i ,
337  i ,
339  );
340  }
341  }
342 }
343 
344 /*!
345 ADFun constructor from an operation sequence.
346 
347 The C++ syntax for this operation is
348 \verbatim
349  ADFun<Base> f(x, y)
350 \endverbatim
351 The operation sequence that started with the previous call
352 \c Independent(x), and that ends with this operation, is stored
353 in this \c ADFun<Base> object \c f.
354 
355 \tparam Base
356 is the base for the recording that will be stored in the object \c f;
357 i.e., the operations were recorded using the type \c AD<Base>.
358 
359 \tparam VectorAD
360 is a simple vector class with elements of typea \c AD<Base>.
361 
362 \param x
363 is the independent variable vector for this ADFun object.
364 The domain dimension of this object will be the size of \a x.
365 
366 \param y
367 is the dependent variable vector for this ADFun object.
368 The range dimension of this object will be the size of \a y.
369 
370 \par Taylor Coefficients
371 A zero order forward mode sweep is done,
372 and if NDEBUG is not defined the resulting values for the
373 depenedent variables are checked against the values in \a y.
374 Thus, the zero order Taylor coefficients
375 corresponding to the value of the \a x vector
376 are stored in this ADFun object.
377 */
378 template <typename Base>
379 template <typename VectorAD>
380 ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y)
381 {
383  x.size() > 0,
384  "ADFun<Base>: independent variable vector has size zero."
385  );
387  Variable(x[0]),
388  "ADFun<Base>: independent variable vector has been changed."
389  );
390  local::ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_);
392  tape->size_independent_ == size_t ( x.size() ),
393  "ADFun<Base>: independent variable vector has been changed."
394  );
395  size_t j, n = x.size();
396 # ifndef NDEBUG
397  size_t i, m = y.size();
398  for(j = 0; j < n; j++)
400  size_t(x[j].taddr_) == (j+1),
401  "ADFun<Base>: independent variable vector has been changed."
402  );
404  x[j].tape_id_ == x[0].tape_id_,
405  "ADFun<Base>: independent variable vector has been changed."
406  );
407  }
408  for(i = 0; i < m; i++)
410  CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) ,
411  "ADFun<Base>: dependent vector contains variables for"
412  "\na different tape than the independent variables."
413  );
414  }
415 # endif
416 
417  // stop the tape and store the operation sequence
418  Dependent(tape, y);
419 
420 
421  // ad_fun.hpp member values not set by dependent
422  check_for_nan_ = true;
423 
424  // allocate memory for one zero order taylor_ coefficient
425  CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 );
426  CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 0 );
427  size_t c = 1;
428  size_t r = 1;
429  capacity_order(c, r);
430  CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ == c );
431  CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r );
432 
433  // set zero order coefficients corresponding to indpendent variables
434  CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() );
435  for(j = 0; j < n; j++)
436  { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
437  CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) );
438  taylor_[ ind_taddr_[j] ] = x[j].value_;
439  }
440 
441  // use independent variable values to fill in values for others
442  CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
443  CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() );
444  local::forward0sweep(&play_, std::cout, false,
445  n, num_var_tape_, cap_order_taylor_, taylor_.data(),
446  cskip_op_.data(), load_op_,
447  compare_change_count_,
448  compare_change_number_,
449  compare_change_op_index_
450  );
451  CPPAD_ASSERT_UNKNOWN( compare_change_count_ == 1 );
452  CPPAD_ASSERT_UNKNOWN( compare_change_number_ == 0 );
453  CPPAD_ASSERT_UNKNOWN( compare_change_op_index_ == 0 );
454 
455  // now set the number of orders stored
456  num_order_taylor_ = 1;
457 
458 # ifndef NDEBUG
459  // on MS Visual Studio 2012, CppAD required in front of isnan ?
460  for(i = 0; i < m; i++)
461  if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) )
462  { using std::endl;
463  std::ostringstream buf;
464  buf << "A dependent variable value is not equal to "
465  << "its tape evaluation value," << endl
466  << "perhaps it is nan." << endl
467  << "Dependent variable value = "
468  << y[i].value_ << endl
469  << "Tape evaluation value = "
470  << taylor_[dep_taddr_[i]] << endl
471  << "Difference = "
472  << y[i].value_ - taylor_[dep_taddr_[i]] << endl
473  ;
474  // buf.str() returns a string object with a copy of the current
475  // contents in the stream buffer.
476  std::string msg_str = buf.str();
477  // msg_str.c_str() returns a pointer to the c-string
478  // representation of the string object's value.
479  const char* msg_char_star = msg_str.c_str();
481  0,
482  msg_char_star
483  );
484  }
485 # endif
486 }
487 
488 } // END_CPPAD_NAMESPACE
489 # endif
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
size_t end(void) const
Fetch end for this vector of sets object.
local::sparse_list for_jac_sparse_set_
Set results of the forward mode Jacobian sparsity calculations for_jac_sparse_set_.n_set() != 0 implies for_sparse_pack_ is empty.
Definition: ad_fun.hpp:140
bool has_been_optimized_
Has this ADFun object been optmized.
Definition: ad_fun.hpp:74
size_t Range(void) const
number of dependent variables
Definition: ad_fun.hpp:552
Class used to hold function objects.
Definition: ad_fun.hpp:69
size_t num_order_taylor_
number of orders stored in taylor_
Definition: ad_fun.hpp:94
size_t n_set(void) const
Fetch n_set for vector of sets object.
size_t cap_order_taylor_
maximum number of orders that will fit in taylor_
Definition: ad_fun.hpp:97
local::sparse_pack for_jac_sparse_pack_
Packed results of the forward mode Jacobian sparsity calculations. for_jac_sparse_pack_.n_set() != 0 implies other sparsity results are empty.
Definition: ad_fun.hpp:136
size_t size_independent_
Number of independent variables in this tapes reconding. Set by Independent and effectively const...
Definition: ad_tape.hpp:104
CppAD::vector< size_t > ind_taddr_
tape address for the independent variables
Definition: ad_fun.hpp:106
size_t end(void) const
Fetch end for this vector of sets object.
void resize(size_t n)
change the number of elements in this vector.
Definition: vector.hpp:399
void forward0sweep(const local::player< Base > *play, std::ostream &s_out, bool print, size_t n, size_t numvar, size_t J, Base *taylor, bool *cskip_op, pod_vector< addr_t > &var_by_load_op, size_t compare_change_count, size_t &compare_change_number, size_t &compare_change_op_index)
Compute zero order forward mode Taylor coefficients.
local::player< Base > play_
the operation sequence corresponding to this object
Definition: ad_fun.hpp:131
bool isnan(const Scalar &s)
Definition: nan.hpp:169
static local::ADTape< Base > * tape_ptr(void)
Pointer for the tape for this AD&lt;Base&gt; class and the current thread.
Definition: tape_link.hpp:130
size_t num_var_tape_
number of variables in the recording (play_)
Definition: ad_fun.hpp:103
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Variable(const AD< Base > &x)
Definition: par_var.hpp:99
local::pod_vector< bool > cskip_op_
which operations can be conditionally skipped Set during forward pass of order zero ...
Definition: ad_fun.hpp:124
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
bool check_for_nan_
Check for nan&#39;s and report message to user (default value is true).
Definition: ad_fun.hpp:77
void operator=(const ADFun &f)
ADFun assignment operator.
ADFun(void)
default constructor
size_t compare_change_count_
If zero, ignoring comparison operators. Otherwise is the compare change count at which to store the o...
Definition: ad_fun.hpp:81
size_t num_direction_taylor_
number of directions stored in taylor_
Definition: ad_fun.hpp:100
Class used to hold tape that records AD&lt;Base&gt; operations.
Definition: ad_tape.hpp:26
size_t Domain(void) const
number of independent variables
Definition: ad_fun.hpp:548
size_t n_set(void) const
Fetch n_set for vector of sets object.
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Parameter(const AD< Base > &x)
Definition: par_var.hpp:80
CppAD::vector< bool > dep_parameter_
which dependent variables are actually parameters
Definition: ad_fun.hpp:112
size_t compare_change_op_index_
If compare_change_count is zero, compare_change_op_index_ is also zero. Otherwise it is the operator...
Definition: ad_fun.hpp:91
local::pod_vector< addr_t > load_op_
Variable on the tape corresponding to each vecad load operation (if zero, the operation corresponds t...
Definition: ad_fun.hpp:128
CppAD::vector< size_t > dep_taddr_
tape address and parameter flag for the dependent variables
Definition: ad_fun.hpp:109
local::pod_vector< Base > taylor_
results of the forward mode calculations
Definition: ad_fun.hpp:115
local::subgraph::subgraph_info subgraph_info_
subgraph information for this object
Definition: ad_fun.hpp:143
size_t compare_change_number_
If compare_change_count_ is zero, compare_change_number_ is also zero. Otherwise, it is set to the nu...
Definition: ad_fun.hpp:86