1 # ifndef CPPAD_CORE_FUN_CONSTRUCT_HPP
2 # define CPPAD_CORE_FUN_CONSTRUCT_HPP
3 /* --------------------------------------------------------------------------
4 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell
5
6 CppAD is distributed under the terms of the
7 Eclipse Public License Version 2.0.
8
9 This Source Code may also be made available under the following
10 Secondary License when the conditions for such availability set forth
11 in the Eclipse Public License, Version 2.0 are satisfied:
12 GNU General Public License, Version 2.0 or later.
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
33
34 $head Syntax$$
35 $codei%ADFun<%Base%> %f%(%x%, %y%);
36 %$$
37 $codei%ADFun<%Base%> %f%
38 %$$
39 $icode%f%.swap(%g%)
40 %$$
41 $icode%f% = %g
42 %$$
43
44 $head Purpose$$
45 The $codei%ADFun<%Base%>%$$ object $icode f$$
46 stores 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{R}^n \rightarrow \B{R}^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 %ADVector% &%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 %ADVector% &%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 ADVector$$
81 The type $icode ADVector$$ 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%> %g%
91 %$$
92 creates an
93 $codei%AD<%Base%>%$$ object with no corresponding operation sequence; i.e.,
94 $codei%
95 %g%.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 swap$$
148 The swap operation $code%f%.swap(%g%)%$$ exchanges the contents of
149 the two $codei%ADFun<%Base%>%$$ functions; i.e.,
150 $icode f$$ ($icode g$$) before the swap is identical to
151 $icode g$$ ($icode f$$) after the swap.
152
153 $head Assignment Operator$$
154 The $codei%ADFun<%Base%>%$$ assignment operation
155 $codei%
156 %g% = %f%
157 %$$
158 makes a copy of the operation sequence currently stored in $icode f$$
159 in the object $icode g$$.
160 The object $icode f$$ is not affected by this operation and
161 can be $code const$$.
162 All of information (state) stored in $icode f$$ is copied to $icode g$$
163 and any information originally in $icode g$$ is lost.
164
165 $subhead Move Semantics$$
166 In the special case where $icode f$$ is a temporary object
167 (and enough C++11 features are supported by the compiler)
168 this assignment will use move semantics.
169 This avoids the overhead of the copying all the information from
170 $icode f$$ to $icode g$$.
171
172 $subhead Taylor Coefficients$$
173 The Taylor coefficient information currently stored in $icode f$$
174 (computed by $cref/f.Forward/Forward/$$) is
175 copied to $icode g$$.
176 Hence, directly after this operation
177 $codei%
178 %g%.size_order() == %f%.size_order()
179 %$$
180
181 $subhead Sparsity Patterns$$
182 The forward Jacobian sparsity pattern currently stored in $icode f$$
183 (computed by $cref/f.ForSparseJac/ForSparseJac/$$) is
184 copied to $icode g$$.
185 Hence, directly after this operation
186 $codei%
187 %g%.size_forward_bool() == %f%.size_forward_bool()
188 %g%.size_forward_set() == %f%.size_forward_set()
189 %$$
190
191 $head Parallel Mode$$
192 The call to $code Independent$$,
193 and the corresponding call to
194 $codei%
195 ADFun<%Base%> %f%( %x%, %y%)
196 %$$
197 or
198 $codei%
199 %f%.Dependent( %x%, %y%)
200 %$$
201 or $cref abort_recording$$,
202 must be preformed by the same thread; i.e.,
203 $cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same.
204
205 $head Example$$
206
207 $subhead Sequence Constructor$$
208 The file
209 $cref independent.cpp$$
210 contains an example and test of the sequence constructor.
211
212 $subhead Default Constructor$$
213 The files
214 $cref fun_check.cpp$$
215 and
216 $cref hes_lagrangian.cpp$$
217 contain an examples and tests using the default constructor.
218 They return true if they succeed and false otherwise.
219
220 $children%
221 example/general/fun_assign.cpp
222 %$$
223 $subhead Assignment Operator$$
224 The file
225 $cref fun_assign.cpp$$
226 contains an example and test of the $codei%ADFun<%Base%>%$$
227 assignment operator.
228
229 $end
230 ----------------------------------------------------------------------------
231 */
232
233 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
234 /*!
235 \file fun_construct.hpp
236 ADFun function constructors and assignment operator.
237 */
238
239 /*!
240 ADFun default constructor
241
242 The C++ syntax for this operation is
243 \verbatim
244 ADFun<Base> f
245 \endverbatim
246 An empty ADFun object is created.
247 The Dependent member function,
248 or the ADFun<Base> assingment operator,
249 can then be used to put an operation sequence in this ADFun object.
250
251 \tparam Base
252 is the base for the recording that can be stored in this ADFun object;
253 i.e., operation sequences that were recorded using the type AD<Base>.
254 */
255 template <class Base, class RecBase>
ADFun(void)256 ADFun<Base,RecBase>::ADFun(void) :
257 function_name_(""),
258 exceed_collision_limit_(false),
259 has_been_optimized_(false),
260 check_for_nan_(true) ,
261 compare_change_count_(0),
262 compare_change_number_(0),
263 compare_change_op_index_(0),
264 num_order_taylor_(0),
265 cap_order_taylor_(0),
266 num_direction_taylor_(0),
267 num_var_tape_(0)
268 { }
269 //
270 // move semantics version of constructor
271 // (none of the defualt constructor values matter to the destructor)
272 template <class Base, class RecBase>
ADFun(ADFun && f)273 ADFun<Base,RecBase>::ADFun(ADFun&& f)
274 { swap(f); }
275 //
276 // destructor
277 template <class Base, class RecBase>
~ADFun(void)278 ADFun<Base,RecBase>::~ADFun(void)
279 { }
280 /*!
281 ADFun assignment operator
282
283 The C++ syntax for this operation is
284 \verbatim
285 g = f
286 \endverbatim
287 where g and f are ADFun<Base> ADFun objects.
288 A copy of the the operation sequence currently stored in f
289 is placed in this ADFun object (called g above).
290 Any information currently stored in this ADFun object is lost.
291
292 \tparam Base
293 is the base for the recording that can be stored in this ADFun object;
294 i.e., operation sequences that were recorded using the type AD<Base>.
295
296 \param f
297 ADFun object containing the operation sequence to be copied.
298 */
299 template <class Base, class RecBase>
operator =(const ADFun & f)300 void ADFun<Base,RecBase>::operator=(const ADFun& f)
301 {
302 // go through member variables in ad_fun.hpp order
303 //
304 // string objects
305 function_name_ = f.function_name_;
306 //
307 // bool objects
308 exceed_collision_limit_ = f.exceed_collision_limit_;
309 has_been_optimized_ = f.has_been_optimized_;
310 check_for_nan_ = f.check_for_nan_;
311 //
312 // size_t objects
313 compare_change_count_ = f.compare_change_count_;
314 compare_change_number_ = f.compare_change_number_;
315 compare_change_op_index_ = f.compare_change_op_index_;
316 num_order_taylor_ = f.num_order_taylor_;
317 cap_order_taylor_ = f.cap_order_taylor_;
318 num_direction_taylor_ = f.num_direction_taylor_;
319 num_var_tape_ = f.num_var_tape_;
320 //
321 // pod_vector objects
322 ind_taddr_ = f.ind_taddr_;
323 dep_taddr_ = f.dep_taddr_;
324 dep_parameter_ = f.dep_parameter_;
325 cskip_op_ = f.cskip_op_;
326 load_op2var_ = f.load_op2var_;
327 //
328 // pod_vector_maybe_vectors
329 taylor_ = f.taylor_;
330 subgraph_partial_ = f.subgraph_partial_;
331 //
332 // player
333 play_ = f.play_;
334 //
335 // subgraph
336 subgraph_info_ = f.subgraph_info_;
337 //
338 // sparse_pack
339 for_jac_sparse_pack_ = f.for_jac_sparse_pack_;
340 //
341 // sparse_list
342 for_jac_sparse_set_ = f.for_jac_sparse_set_;
343 }
344 /// swap
345 template <class Base, class RecBase>
swap(ADFun & f)346 void ADFun<Base,RecBase>::swap(ADFun& f)
347 {
348 // string objects
349 function_name_.swap( f.function_name_ );
350 //
351 // bool objects
352 std::swap( exceed_collision_limit_ , f.exceed_collision_limit_);
353 std::swap( has_been_optimized_ , f.has_been_optimized_);
354 std::swap( check_for_nan_ , f.check_for_nan_);
355 //
356 // size_t objects
357 std::swap( compare_change_count_ , f.compare_change_count_);
358 std::swap( compare_change_number_ , f.compare_change_number_);
359 std::swap( compare_change_op_index_ , f.compare_change_op_index_);
360 std::swap( num_order_taylor_ , f.num_order_taylor_);
361 std::swap( cap_order_taylor_ , f.cap_order_taylor_);
362 std::swap( num_direction_taylor_ , f.num_direction_taylor_);
363 std::swap( num_var_tape_ , f.num_var_tape_);
364 //
365 // pod_vector objects
366 ind_taddr_.swap( f.ind_taddr_);
367 dep_taddr_.swap( f.dep_taddr_);
368 dep_parameter_.swap( f.dep_parameter_);
369 taylor_.swap( f.taylor_);
370 cskip_op_.swap( f.cskip_op_);
371 load_op2var_.swap( f.load_op2var_);
372 //
373 // player
374 play_.swap(f.play_);
375 //
376 // subgraph_info
377 subgraph_info_.swap(f.subgraph_info_);
378 //
379 // sparse_pack
380 for_jac_sparse_pack_.swap( f.for_jac_sparse_pack_);
381 //
382 // sparse_list
383 for_jac_sparse_set_.swap( f.for_jac_sparse_set_);
384 }
385 /// Move semantics version of constructor and assignment
386 template <class Base, class RecBase>
operator =(ADFun && f)387 void ADFun<Base,RecBase>::operator=(ADFun&& f)
388 { swap(f); }
389
390
391 /*!
392 ADFun constructor from an operation sequence.
393
394 The C++ syntax for this operation is
395 \verbatim
396 ADFun<Base> f(x, y)
397 \endverbatim
398 The operation sequence that started with the previous call
399 Independent(x), and that ends with this operation, is stored
400 in this ADFun<Base> object f.
401
402 \tparam Base
403 is the base for the recording that will be stored in the object f;
404 i.e., the operations were recorded using the type AD<Base>.
405
406 \tparam ADVector
407 is a simple vector class with elements of typea AD<Base>.
408
409 \param x
410 is the independent variable vector for this ADFun object.
411 The domain dimension of this object will be the size of x.
412
413 \param y
414 is the dependent variable vector for this ADFun object.
415 The range dimension of this object will be the size of y.
416
417 \par Taylor Coefficients
418 A zero order forward mode sweep is done,
419 and if NDEBUG is not defined the resulting values for the
420 depenedent variables are checked against the values in y.
421 Thus, the zero order Taylor coefficients
422 corresponding to the value of the x vector
423 are stored in this ADFun object.
424 */
425 template <class Base, class RecBase>
426 template <class ADVector>
ADFun(const ADVector & x,const ADVector & y)427 ADFun<Base,RecBase>::ADFun(const ADVector &x, const ADVector &y)
428 {
429 // used to identify the RecBase type in calls to sweeps
430 RecBase not_used_rec_base(0.0);
431
432 CPPAD_ASSERT_KNOWN(
433 x.size() > 0,
434 "ADFun<Base>: independent variable vector has size zero."
435 );
436 CPPAD_ASSERT_KNOWN(
437 Variable(x[0]),
438 "ADFun<Base>: independent variable vector has been changed."
439 );
440 local::ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_);
441 CPPAD_ASSERT_KNOWN(
442 tape->size_independent_ == size_t ( x.size() ),
443 "ADFun<Base>: independent variable vector has been changed."
444 );
445 size_t j, n = x.size();
446 # ifndef NDEBUG
447 size_t i, m = y.size();
448 for(j = 0; j < n; j++)
449 { CPPAD_ASSERT_KNOWN(
450 size_t(x[j].taddr_) == (j+1),
451 "ADFun<Base>: independent variable vector has been changed."
452 );
453 CPPAD_ASSERT_KNOWN(
454 x[j].tape_id_ == x[0].tape_id_,
455 "ADFun<Base>: independent variable vector has been changed."
456 );
457 }
458 for(i = 0; i < m; i++)
459 { CPPAD_ASSERT_KNOWN(
460 CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) ,
461 "ADFun<Base>: dependent vector contains variables for"
462 "\na different tape than the independent variables."
463 );
464 }
465 # endif
466
467 // stop the tape and store the operation sequence
468 Dependent(tape, y);
469
470 // This function has not yet been optimized
471 exceed_collision_limit_ = false;
472
473 // ad_fun.hpp member values not set by dependent
474 check_for_nan_ = true;
475
476 // allocate memory for one zero order taylor_ coefficient
477 CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 );
478 CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 0 );
479 size_t c = 1;
480 size_t r = 1;
481 capacity_order(c, r);
482 CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ == c );
483 CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r );
484
485 // set zero order coefficients corresponding to indpendent variables
486 CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() );
487 for(j = 0; j < n; j++)
488 { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
489 CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) );
490 taylor_[ ind_taddr_[j] ] = x[j].value_;
491 }
492
493 // use independent variable values to fill in values for others
494 CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
495 CPPAD_ASSERT_UNKNOWN( load_op2var_.size() == play_.num_var_load_rec() );
496 local::sweep::forward0(&play_, std::cout, false,
497 n, num_var_tape_, cap_order_taylor_, taylor_.data(),
498 cskip_op_.data(), load_op2var_,
499 compare_change_count_,
500 compare_change_number_,
501 compare_change_op_index_,
502 not_used_rec_base
503 );
504 CPPAD_ASSERT_UNKNOWN( compare_change_count_ == 1 );
505 CPPAD_ASSERT_UNKNOWN( compare_change_number_ == 0 );
506 CPPAD_ASSERT_UNKNOWN( compare_change_op_index_ == 0 );
507
508 // now set the number of orders stored
509 num_order_taylor_ = 1;
510
511 # ifndef NDEBUG
512 // on MS Visual Studio 2012, CppAD required in front of isnan ?
513 for(i = 0; i < m; i++)
514 if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) )
515 { using std::endl;
516 std::ostringstream buf;
517 buf << "A dependent variable value is not equal to "
518 << "its tape evaluation value," << endl
519 << "perhaps it is nan." << endl
520 << "Dependent variable value = "
521 << y[i].value_ << endl
522 << "Tape evaluation value = "
523 << taylor_[dep_taddr_[i]] << endl
524 << "Difference = "
525 << y[i].value_ - taylor_[dep_taddr_[i]] << endl
526 ;
527 // buf.str() returns a string object with a copy of the current
528 // contents in the stream buffer.
529 std::string msg_str = buf.str();
530 // msg_str.c_str() returns a pointer to the c-string
531 // representation of the string object's value.
532 const char* msg_char_star = msg_str.c_str();
533 CPPAD_ASSERT_KNOWN(
534 0,
535 msg_char_star
536 );
537 }
538 # endif
539 }
540
541 } // END_CPPAD_NAMESPACE
542 # endif
543