CppAD: A C++ Algorithmic Differentiation Package  20130918
fun_construct.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines