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