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