00001 # ifndef CPPAD_FUN_CONSTRUCT_INCLUDED 00002 # define CPPAD_FUN_CONSTRUCT_INCLUDED 00003 00004 /* -------------------------------------------------------------------------- 00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell 00006 00007 CppAD is distributed under multiple licenses. This distribution is under 00008 the terms of the 00009 Common Public License Version 1.0. 00010 00011 A copy of this license is included in the COPYING file of this distribution. 00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00013 -------------------------------------------------------------------------- */ 00014 /* 00015 $begin FunConstruct$$ 00016 $spell 00017 Taylor 00018 var 00019 ADvector 00020 const 00021 $$ 00022 00023 $spell 00024 $$ 00025 00026 $section Construct an ADFun Object and Stop Recording$$ 00027 00028 $index ADFun, construct$$ 00029 $index construct, ADFun$$ 00030 $index tape, stop recording$$ 00031 $index recording, stop tape$$ 00032 00033 $head Syntax$$ 00034 $syntax%ADFun<%Base%> %f% 00035 %$$ 00036 $syntax%ADFun<%Base%> %f%(%x%, %y%) 00037 %$$ 00038 00039 00040 $head Purpose$$ 00041 The $syntax%AD<%Base%>%$$ object $italic f$$ can 00042 store an AD of $italic Base$$ 00043 $xref/glossary/Operation/Sequence/operation sequence/1/$$. 00044 It can then be used to calculate derivatives of the corresponding 00045 $xref/glossary/AD Function/AD function/$$ 00046 $latex \[ 00047 F : B^n \rightarrow B^m 00048 \] $$ 00049 where $latex B$$ is the space corresponding to objects of type $italic Base$$. 00050 00051 $head x$$ 00052 If the argument $italic x$$ is present, 00053 it must be the vector argument in the previous call to 00054 $cref/Independent/$$. 00055 Neither its size, or any of its values, are allowed to change 00056 between calling 00057 $syntax% 00058 Independent(%x%) 00059 %$$ 00060 and 00061 $syntax% 00062 ADFun<%Base%> %f%(%x%, %y%) 00063 %$$. 00064 00065 $head y$$ 00066 The sequence of operations that map $italic x$$ 00067 to $italic y$$ are stored in the AD function object $italic f$$. 00068 00069 00070 $head Default Constructor$$ 00071 The default constructor 00072 $syntax% 00073 ADFun<%Base%> %f% 00074 %$$ 00075 creates an 00076 $syntax%AD<%Base%>%$$ object with no corresponding operation sequence; i.e., 00077 $syntax% 00078 %f%.size_var() 00079 %$$ 00080 returns the value zero (see $xref/SeqProperty/size_var/size_var/$$). 00081 00082 $head Sequence Constructor$$ 00083 The sequence constructor 00084 $syntax% 00085 ADFun<%Base%> %f%(%x%, %y%) 00086 %$$ 00087 creates the $syntax%AD<%Base%>%$$ object $italic f$$, 00088 stops the recording of AD of $italic Base$$ operations 00089 corresponding to the call 00090 $syntax% 00091 Independent(%x%) 00092 %$$ 00093 and stores the corresponding operation sequence in the object $italic f$$. 00094 It then stores the first order Taylor coefficients 00095 (corresponding to the value of $italic x$$) in $italic f$$. 00096 This is equivalent to the following steps using the default constructor: 00097 $list number$$ 00098 Create $italic f$$ with the default constructor 00099 $syntax% 00100 ADFun<%Base%> %f%; 00101 %$$ 00102 $lnext 00103 Stop the tape and storing the operation sequence using 00104 $syntax% 00105 %f%.Dependent(%x%, %y%); 00106 %$$ 00107 (see $xref/Dependent/$$). 00108 $lnext 00109 Calculating the first order Taylor coefficients for all 00110 the variables in the operation sequence using 00111 $syntax% 00112 %f%.Forward(%p%, %x_p%) 00113 %$$ 00114 with $italic p$$ equal to zero and the elements of $italic x_p$$ 00115 equal to the corresponding elements of $italic x$$ 00116 (see $xref/Forward/$$). 00117 $lend 00118 00119 $head OpenMP$$ 00120 $index OpenMP, Dependent$$ 00121 $index Dependent, OpenMP$$ 00122 $index OpenMP, ADFun$$ 00123 $index ADFun, OpenMP$$ 00124 In the case of multi-threading with OpenMP, 00125 the call to $code Independent$$ 00126 and the corresponding call to 00127 $syntax% 00128 ADFun<%Base%> %f%( %x%, %y%) 00129 %$$ 00130 or 00131 $syntax% 00132 %f%.Dependent( %x%, %y%) 00133 %$$ 00134 must be preformed by the same thread. 00135 00136 00137 $head Example$$ 00138 00139 $subhead Sequence Constructor$$ 00140 The file 00141 $xref/Independent.cpp/$$ 00142 contains an example and test of the sequence constructor. 00143 It returns true if it succeeds and false otherwise. 00144 00145 $subhead Default Constructor$$ 00146 The files 00147 $xref/FunCheck.cpp/$$ 00148 and 00149 $xref/HesLagrangian.cpp/$$ 00150 contain an examples and tests using the default constructor. 00151 They return true if they succeed and false otherwise. 00152 00153 $end 00154 */ 00155 00156 00157 // BEGIN CppAD namespace 00158 namespace CppAD { 00159 00160 template <typename Base> 00161 template <typename VectorAD> 00162 ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y) 00163 : totalNumVar(0), Taylor(CPPAD_NULL), ForJac(CPPAD_NULL) 00164 { size_t i, j, m, n; 00165 00166 CPPAD_ASSERT_KNOWN( 00167 x.size() > 0, 00168 "ADFun<Base>: independent variable vector has size zero." 00169 ); 00170 CPPAD_ASSERT_KNOWN( 00171 Variable(x[0]), 00172 "ADFun<Base>: independent variable vector has been changed." 00173 ); 00174 ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].id_); 00175 CPPAD_ASSERT_KNOWN( 00176 tape->size_independent == x.size(), 00177 "ADFun<Base>: independent variable vector has been changed." 00178 ); 00179 # ifndef NDEBUG 00180 for(j = 0; j < x.size(); j++) 00181 { CPPAD_ASSERT_KNOWN( 00182 x[j].taddr_ == (j+1), 00183 "ADFun<Base>: independent variable vector has been changed." 00184 ); 00185 CPPAD_ASSERT_KNOWN( 00186 x[j].id_ == x[0].id_, 00187 "ADFun<Base>: independent variable vector has been changed." 00188 ); 00189 } 00190 for(i = 0; i < y.size(); i++) 00191 { CPPAD_ASSERT_KNOWN( 00192 CppAD::Parameter( y[i] ) | (y[i].id_ == x[0].id_) , 00193 "ADFun<Base>: dependent vector contains variables for" 00194 "\na different tape than the independent variables." 00195 ); 00196 } 00197 # endif 00198 00199 // stop the tape and store the operation sequence 00200 Dependent(tape, y); 00201 00202 // allocate memory for one zero order Taylor coefficient 00203 taylor_per_var= 1; 00204 TaylorColDim = 1; 00205 Taylor = CPPAD_TRACK_NEW_VEC(totalNumVar, Taylor); 00206 00207 // set zero order coefficients corresponding to indpendent variables 00208 n = ind_taddr.size(); 00209 CPPAD_ASSERT_UNKNOWN( n == x.size() ); 00210 for(j = 0; j < n; j++) 00211 { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) ); 00212 CPPAD_ASSERT_UNKNOWN( x[j].taddr_ == (j+1) ); 00213 Taylor[ ind_taddr[j] ] = x[j].value_; 00214 } 00215 00216 // use independent variable values to fill in values for others 00217 compareChange = ForwardSweep( 00218 false, 0, totalNumVar, &Rec, TaylorColDim, Taylor 00219 ); 00220 CPPAD_ASSERT_UNKNOWN( compareChange == 0 ); 00221 00222 // check the dependent variable values 00223 m = dep_taddr.size(); 00224 for(i = 0; i < m; i++) CPPAD_ASSERT_KNOWN( 00225 Taylor[dep_taddr[i]] == y[i].value_, 00226 "An independent variable is not equal its tape evaluation" 00227 ", it may be nan." 00228 ); 00229 } 00230 00231 } // END CppAD namespace 00232 00233 # endif