CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_DISCRETE_INCLUDED 00003 # define CPPAD_DISCRETE_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 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 $begin Discrete$$ 00018 $spell 00019 retaping 00020 namespace 00021 std 00022 Eq 00023 Cpp 00024 const 00025 inline 00026 Geq 00027 $$ 00028 00029 $section Discrete AD Functions$$ 00030 00031 $index discrete, AD function$$ 00032 $index function, discrete AD$$ 00033 00034 $head Syntax$$ 00035 $codei%CPPAD_DISCRETE_FUNCTION(%Base%, %name%) 00036 %$$ 00037 $icode%y% = %name%(%x%) 00038 %$$ 00039 $icode%ay% = %name%(%ax%) 00040 %$$ 00041 00042 00043 $head Purpose$$ 00044 Record the evaluation of a discrete function as part 00045 of an $codei%AD<%Base%>%$$ 00046 $cref/operation sequence/glossary/Operation/Sequence/$$. 00047 The value of a discrete function can depend on the 00048 $cref/independent variables/glossary/Tape/Independent Variable/$$, 00049 but its derivative is identically zero. 00050 For example, suppose that the integer part of 00051 a $cref/variable/glossary/Variable/$$ $icode x$$ is the 00052 index into an array of values. 00053 00054 $head Base$$ 00055 This is the 00056 $cref/base type/base_require/$$ 00057 corresponding to the operations sequence; 00058 i.e., use of the $icode name$$ with arguments of type 00059 $codei%AD<%Base%>%$$ can be recorded in an operation sequence. 00060 00061 $head name$$ 00062 This is the name of the function (as it is used in the source code). 00063 The user must provide a version of $icode name$$ 00064 where the argument has type $icode Base$$. 00065 CppAD uses this to create a version of $icode name$$ 00066 where the argument has type $codei%AD<%Base%>%$$. 00067 00068 $head x$$ 00069 The argument $icode x$$ has prototype 00070 $codei% 00071 const %Base%& %x% 00072 %$$ 00073 It is the value at which the user provided version of $icode name$$ 00074 is to be evaluated. 00075 00076 $head y$$ 00077 The result $icode y$$ has prototype 00078 $codei% 00079 %Base% %y% 00080 %$$ 00081 It is the return value for the user provided version of $icode name$$. 00082 00083 $head ax$$ 00084 The argument $icode ax$$ has prototype 00085 $codei% 00086 const AD<%Base%>& %ax% 00087 %$$ 00088 It is the value at which the CppAD provided version of $icode name$$ 00089 is to be evaluated. 00090 00091 $head ay$$ 00092 The result $icode ay$$ has prototype 00093 $codei% 00094 AD<%Base%> %ay% 00095 %$$ 00096 It is the return value for the CppAD provided version of $icode name$$. 00097 00098 00099 $head Create AD Version$$ 00100 $index CPPAD_DISCRETE_FUNCTION$$ 00101 The preprocessor macro invocation 00102 $codei% 00103 CPPAD_DISCRETE_FUNCTION(%Base%, %name%) 00104 %$$ 00105 defines the $codei%AD<%Base%>%$$ version of $icode name$$. 00106 This can be with in a namespace (not the $code CppAD$$ namespace) 00107 but must be outside of any routine. 00108 00109 $head Operation Sequence$$ 00110 This is an AD of $icode Base$$ 00111 $cref/atomic operation/glossary/Operation/Atomic/$$ 00112 and hence is part of the current 00113 AD of $icode Base$$ 00114 $cref/operation sequence/glossary/Operation/Sequence/$$. 00115 00116 $head Derivatives$$ 00117 During a zero order $cref Forward$$ operation, 00118 an $cref ADFun$$ object will compute the value of $icode name$$ 00119 using the user provided $icode Base$$ version of this routine. 00120 All the derivatives of $icode name$$ will be evaluated as zero. 00121 00122 $head Parallel Mode$$ 00123 $index discrete, parallel$$ 00124 $index parallel, discrete$$ 00125 The first call to 00126 $codei% 00127 %ay% = %name%(%ax%) 00128 %$$ 00129 must not be in $cref/parallel/ta_in_parallel/$$ execution mode. 00130 00131 00132 $head Example$$ 00133 $children% 00134 example/tape_index.cpp% 00135 example/interp_onetape.cpp% 00136 example/interp_retape.cpp 00137 %$$ 00138 The file 00139 $cref tape_index.cpp$$ 00140 contains an example and test that uses a discrete function 00141 to vary an array index during $cref Forward$$ mode calculations. 00142 The file 00143 $cref interp_onetape.cpp$$ 00144 contains an example and test that uses discrete 00145 functions to avoid retaping a calculation that requires interpolation. 00146 (The file 00147 $cref interp_retape.cpp$$ 00148 shows how interpolation can be done with retaping.) 00149 00150 $head Deprecated$$ 00151 $index CppADCreateDiscrete, deprecated$$ 00152 $index deprecated, CppADCreateDiscrete$$ 00153 The preprocessor symbol $code CppADCreateDiscrete$$ 00154 is defined to be the same as $code CPPAD_DISCRETE_FUNCTION$$ 00155 but its use is deprecated. 00156 00157 $end 00158 ------------------------------------------------------------------------------ 00159 */ 00160 # include <vector> 00161 # include <cppad/local/cppad_assert.hpp> 00162 00163 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL 00164 # include <cppad/thread_alloc.hpp> 00165 00166 CPPAD_BEGIN_NAMESPACE 00167 /*! 00168 \defgroup discrete_hpp discrete.hpp 00169 \{ 00170 \file discrete.hpp 00171 user define discrete functions 00172 */ 00173 00174 /*! 00175 \def CPPAD_DISCRETE_FUNCTION(Base, name) 00176 Defines the function <code>name(ax, ay)</code> 00177 where \c ax and \c ay are vectors with <code>AD<Base></code> elements. 00178 00179 \par Base 00180 is the base type for the discrete function. 00181 00182 \par name 00183 is the name of the user defined function that corresponding to this operation. 00184 */ 00185 00186 # define CPPAD_DISCRETE_FUNCTION(Base, name) \ 00187 inline CppAD::AD<Base> name (const CppAD::AD<Base>& ax) \ 00188 { \ 00189 static CppAD::discrete<Base> fun(#name, name); \ 00190 \ 00191 return fun.ad(ax); \ 00192 } 00193 # define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION 00194 00195 00196 /* 00197 Class that acutally implemnets the <code>ay = name(ax)</code> call. 00198 00199 A new discrete function is generated for ech time the user invokes 00200 the CPPAD_DISCRETE_FUNCTION macro; see static object in that macro. 00201 */ 00202 template <class Base> 00203 class discrete { 00204 /// parallel_ad needs to call List to initialize static 00205 template <class Type> 00206 friend void parallel_ad(void); 00207 00208 /// type for the user routine that computes function values 00209 typedef Base (*F) (const Base& x); 00210 private: 00211 /// name of this user defined function 00212 const std::string name_; 00213 /// user's implementation of the function for Base operations 00214 const F f_; 00215 /// index of this objec in the vector of all objects for this class 00216 const size_t index_; 00217 00218 /*! 00219 List of all objects in this class. 00220 00221 If we use CppAD::vector for this vector, it will appear that 00222 there is a memory leak because this list is not distroyed before 00223 thread_alloc::free_available(thread) is called by the testing routines. 00224 */ 00225 static std::vector<discrete *>& List(void) 00226 { CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; 00227 static std::vector<discrete *> list; 00228 return list; 00229 } 00230 public: 00231 /*! 00232 Constructor called for each invocation of CPPAD_DISCRETE_FUNCTION. 00233 00234 Put this objec in the list of all objects for this class and set 00235 the constant private data name_, f_, and index_. 00236 00237 \param Name 00238 is the user's name for this discrete function. 00239 00240 \param f 00241 user routine that implements this function for \c Base class. 00242 00243 \par 00244 This constructor can ont be used in parallel mode because it changes 00245 the static object \c List. 00246 */ 00247 discrete(const char* Name, F f) : 00248 name_(Name) 00249 , f_(f) 00250 , index_( List().size() ) 00251 { 00252 CPPAD_ASSERT_KNOWN( 00253 ! thread_alloc::in_parallel() , 00254 "discrete: First call the function *Name is in parallel mode." 00255 ); 00256 List().push_back(this); 00257 } 00258 00259 /*! 00260 Implement the user call to <code>ay = name(ax)</code>. 00261 00262 \param ax 00263 is the argument for this call. 00264 00265 \return 00266 the return value is called \c ay above. 00267 */ 00268 AD<Base> ad(const AD<Base> &ax) const 00269 { AD<Base> ay; 00270 00271 ay.value_ = f_(ax.value_); 00272 if( Variable(ax) ) 00273 { ADTape<Base> *tape = ax.tape_this(); 00274 CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 ); 00275 CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 ); 00276 00277 // put operand addresses in the tape 00278 tape->Rec_.PutArg(index_, ax.taddr_); 00279 // put operator in the tape 00280 ay.taddr_ = tape->Rec_.PutOp(DisOp); 00281 // make result a variable 00282 ay.tape_id_ = tape->id_; 00283 00284 CPPAD_ASSERT_UNKNOWN( Variable(ay) ); 00285 } 00286 return ay; 00287 } 00288 00289 /// Name corresponding to a discrete object 00290 static const char* name(size_t index) 00291 { return List()[index]->name_.c_str(); } 00292 00293 /*! 00294 Link from forward mode sweep to users routine 00295 00296 \param index 00297 index for this function in the list of all discrete object 00298 00299 \param x 00300 argument value at which to evaluate this function 00301 */ 00302 static Base eval(size_t index, const Base& x) 00303 { 00304 CPPAD_ASSERT_UNKNOWN(index < List().size() ); 00305 00306 return List()[index]->f_(x); 00307 } 00308 }; 00309 00310 /*! \} */ 00311 CPPAD_END_NAMESPACE 00312 # endif