CppAD: A C++ Algorithmic Differentiation Package 20110419
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_INDEPENDENT_INCLUDED 00003 # define CPPAD_INDEPENDENT_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Common 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 --------------------------------------------------------------------------- 00017 00018 $begin Independent$$ 00019 $spell 00020 Cpp 00021 bool 00022 const 00023 var 00024 typename 00025 $$ 00026 00027 $index Independent$$ 00028 $index start, recording$$ 00029 $index recording, start$$ 00030 $index variable, independent$$ 00031 00032 $section Declare Independent Variables and Start Recording$$ 00033 00034 $head Syntax$$ 00035 $syntax%Independent(%x%)%$$ 00036 00037 00038 $head Purpose$$ 00039 Start a recording the 00040 $xref/glossary/AD of Base/AD of Base/$$ operations 00041 with $italic x$$ as the vector of independent variables. 00042 Once the 00043 AD of $italic Base$$ 00044 $xref/glossary/Operation/Sequence/operation sequence/1/$$ is completed, 00045 it must be transferred to a function object; see below. 00046 00047 $head Variables for a Tape$$ 00048 A tape is create by the call 00049 $syntax% 00050 Independent(%x%) 00051 %$$ 00052 The corresponding operation sequence is transferred to a function object, 00053 and the tape is deleted, 00054 using either (see $cref/ADFun<Base> f(x, y)/FunConstruct/$$) 00055 $syntax% 00056 ADFun<%Base%> %f%( %x%, %y%) 00057 %$$ 00058 or using (see $cref/f.Dependent(x, y)/Dependent/$$) 00059 $syntax% 00060 %f%.Dependent( %x%, %y%) 00061 %$$ 00062 Between when the tape is created and when it is destroyed, 00063 we refer to the elements of $italic x$$, 00064 and the values that depend on the elements of $italic x$$, 00065 as variables for the tape created by the call to $code Independent$$. 00066 00067 $head x$$ 00068 The vector $italic x$$ has prototype 00069 $syntax% 00070 %VectorAD% &%x% 00071 %$$ 00072 (see $italic VectorAD$$ below). 00073 The size of the vector $italic x$$, must be greater than zero, 00074 and is the number of independent variables for this 00075 AD operation sequence. 00076 00077 $head VectorAD$$ 00078 The type $italic VectorAD$$ must be a $xref/SimpleVector/$$ class with 00079 $xref/SimpleVector/Elements of Specified Type/elements of type/$$ 00080 $syntax%AD<%Base%>%$$. 00081 The routine $xref/CheckSimpleVector/$$ will generate an error message 00082 if this is not the case. 00083 00084 $head Memory Leak$$ 00085 A memory leak will result if 00086 a tape is create by a call to $code Independent$$ 00087 and not deleted by a corresponding call to 00088 $syntax% 00089 ADFun<%Base%> %f%( %x%, %y%) 00090 %$$ 00091 or using 00092 $syntax% 00093 %f%.Dependent( %x%, %y%) 00094 %$$ 00095 00096 $head OpenMP$$ 00097 $index OpenMP, Independent$$ 00098 $index Independent, OpenMP$$ 00099 In the case of multi-threading with OpenMP, 00100 the call to $code Independent$$ 00101 and the corresponding call to 00102 $syntax% 00103 ADFun<%Base%> %f%( %x%, %y%) 00104 %$$ 00105 or 00106 $syntax% 00107 %f%.Dependent( %x%, %y%) 00108 %$$ 00109 must be preformed by the same thread. 00110 00111 $head Example$$ 00112 $children% 00113 example/independent.cpp 00114 %$$ 00115 The file 00116 $xref/Independent.cpp/$$ 00117 contains an example and test of this operation. 00118 It returns true if it succeeds and false otherwise. 00119 00120 $end 00121 ----------------------------------------------------------------------------- 00122 */ 00123 00124 // BEGIN CppAD namespace 00125 namespace CppAD { 00126 // --------------------------------------------------------------------------- 00127 00128 template <typename Base> 00129 template <typename VectorAD> 00130 void ADTape<Base>::Independent(VectorAD &x) 00131 { 00132 // check VectorAD is Simple Vector class with AD<Base> elements 00133 CheckSimpleVector< AD<Base>, VectorAD>(); 00134 00135 // dimension of the domain space 00136 size_t n = x.size(); 00137 CPPAD_ASSERT_KNOWN( 00138 n > 0, 00139 "Indepdendent: the argument vector x has zero size" 00140 ); 00141 CPPAD_ASSERT_UNKNOWN( Rec_.num_rec_var() == 0 ); 00142 00143 // mark the beginning of the tape and skip the first variable index 00144 // (zero) because parameters use taddr zero 00145 CPPAD_ASSERT_NARG_NRES(BeginOp, 0, 1); 00146 Rec_.PutOp(BeginOp); 00147 00148 // place each of the independent variables in the tape 00149 CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1); 00150 size_t j; 00151 for(j = 0; j < n; j++) 00152 { // tape address for this independent variable 00153 x[j].taddr_ = Rec_.PutOp(InvOp); 00154 x[j].id_ = id_; 00155 CPPAD_ASSERT_UNKNOWN( x[j].taddr_ == j+1 ); 00156 CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) ); 00157 } 00158 00159 // done specifying all of the independent variables 00160 size_independent_ = n; 00161 } 00162 00163 template <typename VectorAD> 00164 inline void Independent(VectorAD &x) 00165 { typedef typename VectorAD::value_type ADBase; 00166 typedef typename ADBase::value_type Base; 00167 CPPAD_ASSERT_KNOWN( 00168 ADBase::tape_ptr() == CPPAD_NULL, 00169 "Independent: cannot create a new tape because\n" 00170 "a previous tape is still active (for this thread).\n" 00171 "AD<Base>::abort_recording() would abort this previous recording." 00172 ); 00173 size_t id = ADBase::tape_new(); 00174 00175 ADBase::tape_ptr(id)->Independent(x); 00176 } 00177 00178 00179 } 00180 // END CppAD namespace 00181 00182 # endif