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