CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_FUN_CONSTRUCT_INCLUDED 00003 # define CPPAD_FUN_CONSTRUCT_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Eclipse Public License Version 1.0. 00011 00012 A copy of this license is included in the COPYING file of this distribution. 00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00014 -------------------------------------------------------------------------- */ 00015 /* 00016 $begin FunConstruct$$ 00017 $spell 00018 alloc 00019 num 00020 Jac 00021 bool 00022 taylor 00023 var 00024 ADvector 00025 const 00026 Jacobian 00027 $$ 00028 00029 $spell 00030 $$ 00031 00032 $section Construct an ADFun Object and Stop Recording$$ 00033 00034 $index ADFun, construct$$ 00035 $index construct, ADFun$$ 00036 $index tape, stop recording$$ 00037 $index recording, stop tape$$ 00038 00039 $head Syntax$$ 00040 $codei%ADFun<%Base%> %f%, %g% 00041 %$$ 00042 $codei%ADFun<%Base%> %f%(%x%, %y%) 00043 %$$ 00044 $icode%g% = %f% 00045 %$$ 00046 00047 00048 $head Purpose$$ 00049 The $codei%AD<%Base%>%$$ object $icode f$$ can 00050 store an AD of $icode Base$$ 00051 $cref/operation sequence/glossary/Operation/Sequence/$$. 00052 It can then be used to calculate derivatives of the corresponding 00053 $cref/AD function/glossary/AD Function/$$ 00054 $latex \[ 00055 F : B^n \rightarrow B^m 00056 \] $$ 00057 where $latex B$$ is the space corresponding to objects of type $icode Base$$. 00058 00059 $head x$$ 00060 If the argument $icode x$$ is present, it has prototype 00061 $codei% 00062 const %VectorAD% &%x% 00063 %$$ 00064 It must be the vector argument in the previous call to 00065 $cref Independent$$. 00066 Neither its size, or any of its values, are allowed to change 00067 between calling 00068 $codei% 00069 Independent(%x%) 00070 %$$ 00071 and 00072 $codei% 00073 ADFun<%Base%> %f%(%x%, %y%) 00074 %$$ 00075 00076 $head y$$ 00077 If the argument $icode y$$ is present, it has prototype 00078 $codei% 00079 const %VectorAD% &%y% 00080 %$$ 00081 The sequence of operations that map $icode x$$ 00082 to $icode y$$ are stored in the ADFun object $icode f$$. 00083 00084 $head VectorAD$$ 00085 The type $icode VectorAD$$ must be a $cref SimpleVector$$ class with 00086 $cref/elements of type/SimpleVector/Elements of Specified Type/$$ 00087 $codei%AD<%Base%>%$$. 00088 The routine $cref CheckSimpleVector$$ will generate an error message 00089 if this is not the case. 00090 00091 $head Default Constructor$$ 00092 $index default, ADFun constructor$$ 00093 $index ADFun, default constructor$$ 00094 $index constructor, ADFun constructor$$ 00095 The default constructor 00096 $codei% 00097 ADFun<%Base%> %f% 00098 %$$ 00099 creates an 00100 $codei%AD<%Base%>%$$ object with no corresponding operation sequence; i.e., 00101 $codei% 00102 %f%.size_var() 00103 %$$ 00104 returns the value zero (see $cref/size_var/seq_property/size_var/$$). 00105 00106 $head Sequence Constructor$$ 00107 $index sequence, ADFun constructor$$ 00108 $index ADFun, sequence constructor$$ 00109 $index constructor, ADFun sequence$$ 00110 The sequence constructor 00111 $codei% 00112 ADFun<%Base%> %f%(%x%, %y%) 00113 %$$ 00114 creates the $codei%AD<%Base%>%$$ object $icode f$$, 00115 stops the recording of AD of $icode Base$$ operations 00116 corresponding to the call 00117 $codei% 00118 Independent(%x%) 00119 %$$ 00120 and stores the corresponding operation sequence in the object $icode f$$. 00121 It then stores the zero order Taylor coefficients 00122 (corresponding to the value of $icode x$$) in $icode f$$. 00123 This is equivalent to the following steps using the default constructor: 00124 00125 $list number$$ 00126 Create $icode f$$ with the default constructor 00127 $codei% 00128 ADFun<%Base%> %f%; 00129 %$$ 00130 $lnext 00131 Stop the tape and storing the operation sequence using 00132 $codei% 00133 %f%.Dependent(%x%, %y%); 00134 %$$ 00135 (see $cref Dependent$$). 00136 $lnext 00137 Calculate the zero order Taylor coefficients for all 00138 the variables in the operation sequence using 00139 $codei% 00140 %f%.Forward(%p%, %x_p%) 00141 %$$ 00142 with $icode p$$ equal to zero and the elements of $icode x_p$$ 00143 equal to the corresponding elements of $icode x$$ 00144 (see $cref Forward$$). 00145 $lend 00146 00147 $head Copy Constructor$$ 00148 $index copy, ADFun constructor$$ 00149 $index ADFun, copy constructor$$ 00150 $index constructor, ADFun copy$$ 00151 It is an error to attempt to use the $codei%ADFun<%Base%>%$$ copy constructor; 00152 i.e., the following syntax is not allowed: 00153 $codei% 00154 ADFun<%Base%> %g%(%f%) 00155 %$$ 00156 where $icode f$$ is an $codei%ADFun<%Base%>%$$ object. 00157 Use its $cref/default constructor/FunConstruct/Default Constructor/$$ instead 00158 and its assignment operator. 00159 00160 $head Assignment Operator$$ 00161 $index ADFun, assignment operator$$ 00162 $index assignment, ADFun operator$$ 00163 $index operator, ADFun assignment$$ 00164 The $codei%ADFun<%Base%>%$$ assignment operation 00165 $codei% 00166 %g% = %f% 00167 %$$ 00168 makes a copy of the operation sequence currently stored in $icode f$$ 00169 in the object $icode g$$. 00170 The object $icode f$$ is not affected by this operation and 00171 can be $code const$$. 00172 All of information (state) stored in $icode f$$ is copied to $icode g$$ 00173 and any information originally in $icode g$$ is lost. 00174 00175 $subhead Taylor Coefficients$$ 00176 The Taylor coefficient information currently stored in $icode f$$ 00177 (computed by $cref/f.Forward/Forward/$$) is 00178 copied to $icode g$$. 00179 Hence, directly after this operation 00180 $codei% 00181 %g%.size_order() == %f%.size_order() 00182 %$$ 00183 00184 $subhead Sparsity Patterns$$ 00185 The forward Jacobian sparsity pattern currently stored in $icode f$$ 00186 (computed by $cref/f.ForSparseJac/ForSparseJac/$$) is 00187 copied to $icode g$$. 00188 Hence, directly after this operation 00189 $codei% 00190 %g%.size_forward_bool() == %f%.size_forward_bool() 00191 %g%.size_forward_set() == %f%.size_forward_set() 00192 %$$ 00193 00194 $head Parallel Mode$$ 00195 $index parallel, ADFun$$ 00196 $index ADFun, parallel$$ 00197 The call to $code Independent$$, 00198 and the corresponding call to 00199 $codei% 00200 ADFun<%Base%> %f%( %x%, %y%) 00201 %$$ 00202 or 00203 $codei% 00204 %f%.Dependent( %x%, %y%) 00205 %$$ 00206 or $cref abort_recording$$, 00207 must be preformed by the same thread; i.e., 00208 $cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same. 00209 00210 $head Example$$ 00211 00212 $subhead Sequence Constructor$$ 00213 The file 00214 $cref independent.cpp$$ 00215 contains an example and test of the sequence constructor. 00216 It returns true if it succeeds and false otherwise. 00217 00218 $subhead Default Constructor$$ 00219 The files 00220 $cref fun_check.cpp$$ 00221 and 00222 $cref hes_lagrangian.cpp$$ 00223 contain an examples and tests using the default constructor. 00224 They return true if they succeed and false otherwise. 00225 00226 $children% 00227 example/fun_assign.cpp 00228 %$$ 00229 $subhead Assignment Operator$$ 00230 The file 00231 $cref fun_assign.cpp$$ 00232 contains an example and test of the $codei%ADFun<%Base%>%$$ 00233 assignment operator. 00234 It returns true if it succeeds and false otherwise. 00235 00236 $end 00237 ---------------------------------------------------------------------------- 00238 */ 00239 00240 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00241 /*! 00242 \file fun_construct.hpp 00243 ADFun function constructors and assignment operator. 00244 */ 00245 00246 /*! 00247 ADFun default constructor 00248 00249 The C++ syntax for this operation is 00250 \verbatim 00251 ADFun<Base> f 00252 \endverbatim 00253 An empty ADFun object is created. 00254 The Dependent member function, 00255 or the ADFun<Base> assingment operator, 00256 can then be used to put an operation sequence in this ADFun object. 00257 00258 \tparam Base 00259 is the base for the recording that can be stored in this ADFun object; 00260 i.e., operation sequences that were recorded using the type \c AD<Base>. 00261 */ 00262 template <typename Base> 00263 ADFun<Base>::ADFun(void) : 00264 check_for_nan_(true) , 00265 num_var_tape_(0) 00266 { } 00267 00268 /*! 00269 ADFun assignment operator 00270 00271 The C++ syntax for this operation is 00272 \verbatim 00273 g = f 00274 \endverbatim 00275 where \c g and \c f are ADFun<Base> ADFun objects. 00276 A copy of the the operation sequence currently stored in \c f 00277 is placed in this ADFun object (called \c g above). 00278 Any information currently stored in this ADFun object is lost. 00279 00280 \tparam Base 00281 is the base for the recording that can be stored in this ADFun object; 00282 i.e., operation sequences that were recorded using the type \c AD<Base>. 00283 00284 \param f 00285 ADFun object containing the operation sequence to be copied. 00286 */ 00287 template <typename Base> 00288 void ADFun<Base>::operator=(const ADFun<Base>& f) 00289 { size_t m = f.Range(); 00290 size_t n = f.Domain(); 00291 size_t i; 00292 00293 // go through member variables in ad_fun.hpp order 00294 // 00295 // size_t objects 00296 check_for_nan_ = f.check_for_nan_; 00297 compare_change_ = f.compare_change_; 00298 num_order_taylor_ = f.num_order_taylor_; 00299 cap_order_taylor_ = f.cap_order_taylor_; 00300 num_var_tape_ = f.num_var_tape_; 00301 // 00302 // CppAD::vector objects 00303 ind_taddr_.resize(n); 00304 ind_taddr_ = f.ind_taddr_; 00305 dep_taddr_.resize(m); 00306 dep_taddr_ = f.dep_taddr_; 00307 dep_parameter_.resize(m); 00308 dep_parameter_ = f.dep_parameter_; 00309 // 00310 // pod_vector objects 00311 taylor_ = f.taylor_; 00312 cskip_op_ = f.cskip_op_; 00313 load_op_ = f.load_op_; 00314 // 00315 // player 00316 play_ = f.play_; 00317 // 00318 // sparse_pack 00319 for_jac_sparse_pack_.resize(0, 0); 00320 size_t n_set = f.for_jac_sparse_pack_.n_set(); 00321 size_t end = f.for_jac_sparse_pack_.end(); 00322 if( n_set > 0 ) 00323 { CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ ); 00324 CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_set_.n_set() == 0 ); 00325 for_jac_sparse_pack_.resize(n_set, end); 00326 for(i = 0; i < num_var_tape_ ; i++) 00327 { for_jac_sparse_pack_.assignment( 00328 i , 00329 i , 00330 f.for_jac_sparse_pack_ 00331 ); 00332 } 00333 } 00334 // 00335 // sparse_set 00336 for_jac_sparse_set_.resize(0, 0); 00337 n_set = f.for_jac_sparse_set_.n_set(); 00338 end = f.for_jac_sparse_set_.end(); 00339 if( n_set > 0 ) 00340 { CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ ); 00341 CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_pack_.n_set() == 0 ); 00342 for_jac_sparse_set_.resize(n_set, end); 00343 for(i = 0; i < num_var_tape_; i++) 00344 { for_jac_sparse_set_.assignment( 00345 i , 00346 i , 00347 f.for_jac_sparse_set_ 00348 ); 00349 } 00350 } 00351 } 00352 00353 /*! 00354 ADFun constructor from an operation sequence. 00355 00356 The C++ syntax for this operation is 00357 \verbatim 00358 ADFun<Base> f(x, y) 00359 \endverbatim 00360 The operation sequence that started with the previous call 00361 \c Independent(x), and that ends with this operation, is stored 00362 in this \c ADFun<Base> object \c f. 00363 00364 \tparam Base 00365 is the base for the recording that will be stored in the object \c f; 00366 i.e., the operations were recorded using the type \c AD<Base>. 00367 00368 \tparam VectorAD 00369 is a simple vector class with elements of typea \c AD<Base>. 00370 00371 \param x 00372 is the independent variable vector for this ADFun object. 00373 The domain dimension of this object will be the size of \a x. 00374 00375 \param y 00376 is the dependent variable vector for this ADFun object. 00377 The range dimension of this object will be the size of \a y. 00378 00379 \par Taylor Coefficients 00380 A zero order forward mode sweep is done, 00381 and if NDEBUG is not defined the resulting values for the 00382 depenedent variables are checked against the values in \a y. 00383 Thus, the zero order Taylor coefficients 00384 corresponding to the value of the \a x vector 00385 are stored in this ADFun object. 00386 */ 00387 template <typename Base> 00388 template <typename VectorAD> 00389 ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y) 00390 { 00391 CPPAD_ASSERT_KNOWN( 00392 x.size() > 0, 00393 "ADFun<Base>: independent variable vector has size zero." 00394 ); 00395 CPPAD_ASSERT_KNOWN( 00396 Variable(x[0]), 00397 "ADFun<Base>: independent variable vector has been changed." 00398 ); 00399 ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_); 00400 CPPAD_ASSERT_KNOWN( 00401 tape->size_independent_ == size_t ( x.size() ), 00402 "ADFun<Base>: independent variable vector has been changed." 00403 ); 00404 size_t j, n = x.size(); 00405 # ifndef NDEBUG 00406 size_t i, m = y.size(); 00407 for(j = 0; j < n; j++) 00408 { CPPAD_ASSERT_KNOWN( 00409 size_t(x[j].taddr_) == (j+1), 00410 "ADFun<Base>: independent variable vector has been changed." 00411 ); 00412 CPPAD_ASSERT_KNOWN( 00413 x[j].tape_id_ == x[0].tape_id_, 00414 "ADFun<Base>: independent variable vector has been changed." 00415 ); 00416 } 00417 for(i = 0; i < m; i++) 00418 { CPPAD_ASSERT_KNOWN( 00419 CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) , 00420 "ADFun<Base>: dependent vector contains variables for" 00421 "\na different tape than the independent variables." 00422 ); 00423 } 00424 # endif 00425 00426 // stop the tape and store the operation sequence 00427 Dependent(tape, y); 00428 00429 // ad_fun.hpp member values not set by dependent 00430 check_for_nan_ = true; 00431 00432 // allocate memory for one zero order taylor_ coefficient 00433 CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 ); 00434 size_t c = 1; 00435 capacity_order(c); 00436 CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ == c ); 00437 00438 // set zero order coefficients corresponding to indpendent variables 00439 CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() ); 00440 for(j = 0; j < n; j++) 00441 { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) ); 00442 CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) ); 00443 taylor_[ ind_taddr_[j] ] = x[j].value_; 00444 } 00445 00446 // use independent variable values to fill in values for others 00447 CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() ); 00448 CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() ); 00449 compare_change_ = forward0sweep(std::cout, false, 00450 n, num_var_tape_, &play_, cap_order_taylor_, taylor_.data(), 00451 cskip_op_.data(), load_op_ 00452 ); 00453 CPPAD_ASSERT_UNKNOWN( compare_change_ == 0 ); 00454 00455 // now set the number of orders stored 00456 num_order_taylor_ = 1; 00457 00458 # ifndef NDEBUG 00459 // on MS Visual Studio 2012, CppAD required in front of isnan ? 00460 for(i = 0; i < m; i++) 00461 if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) ) 00462 { using std::endl; 00463 std::ostringstream buf; 00464 buf << "A dependent variable value is not equal to " 00465 << "its tape evaluation value," << endl 00466 << "perhaps it is nan." << endl 00467 << "Dependent variable value = " 00468 << y[i].value_ << endl 00469 << "Tape evaluation value = " 00470 << taylor_[dep_taddr_[i]] << endl 00471 << "Difference = " 00472 << y[i].value_ - taylor_[dep_taddr_[i]] << endl 00473 ; 00474 CPPAD_ASSERT_KNOWN( 00475 0, 00476 buf.str().c_str() 00477 ); 00478 } 00479 # endif 00480 } 00481 00482 } // END_CPPAD_NAMESPACE 00483 # endif