00001 # ifndef CPPAD_DISCRETE_INCLUDED 00002 # define CPPAD_DISCRETE_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 $begin Discrete$$ 00017 $spell 00018 retaping 00019 namespace 00020 std 00021 Eq 00022 Cpp 00023 const 00024 inline 00025 Geq 00026 $$ 00027 00028 $section Discrete AD Functions$$ 00029 00030 $index discrete, AD function$$ 00031 $index function, discrete AD$$ 00032 00033 $head Syntax$$ 00034 $syntax%CPPAD_DISCRETE_FUNCTION(%Base%, %name%) 00035 %$$ 00036 $syntax%%v% = %name%(%u%) 00037 %$$ 00038 $syntax%%y% = %name%(%x%) 00039 %$$ 00040 00041 00042 $head Purpose$$ 00043 Record the evaluation of a discrete function as part 00044 of an $syntax%AD<%Base%>%$$ 00045 $xref/glossary/Operation/Sequence/operation sequence/1/$$. 00046 The value of a discrete function can depend on the 00047 $cref/independent variables/glossary/Tape/Independent Variable/$$, 00048 but its derivative is identically zero. 00049 For example, suppose that the integer part of 00050 a $cref/variable/glossary/Variable/$$ $italic x$$ is the 00051 index into an array of values. 00052 00053 $head Base$$ 00054 This is the 00055 $cref/base type/base_require/$$ 00056 corresponding to the operations sequence; 00057 i.e., use of the $italic name$$ with arguments of type 00058 $syntax%AD<%Base%>%$$ can be recorded in an operation sequence. 00059 00060 $head name$$ 00061 This is the name of the function (as it is used in the source code). 00062 The user must provide a version of $italic name$$ 00063 where the argument has type $italic Base$$. 00064 CppAD uses this to create a version of $italic name$$ 00065 where the argument has type $syntax%AD<%Base%>%$$. 00066 00067 $head u$$ 00068 The argument $italic u$$ has prototype 00069 $syntax% 00070 const %Base% &%u% 00071 %$$ 00072 It is the value at which the user provided version of $italic name$$ 00073 is to be evaluated. 00074 00075 $head v$$ 00076 The result $italic v$$ has prototype 00077 $syntax% 00078 %Base% %v% 00079 %$$ 00080 It is the return value for the user provided version of $italic name$$. 00081 00082 $head x$$ 00083 The argument $italic x$$ has prototype 00084 $syntax% 00085 const AD<%Base%> &%x% 00086 %$$ 00087 It is the value at which the CppAD provided version of $italic name$$ 00088 is to be evaluated. 00089 00090 $head y$$ 00091 The result $italic y$$ has prototype 00092 $syntax% 00093 AD<%Base%> %v% 00094 %$$ 00095 It is the return value for the CppAD provided version of $italic name$$. 00096 00097 00098 $head Create AD Version$$ 00099 $index CPPAD_DISCRETE_FUNCTION$$ 00100 The preprocessor macro invocation 00101 $syntax% 00102 CPPAD_DISCRETE_FUNCTION(%Base%, %name%) 00103 %$$ 00104 defines the $syntax%AD<%Base%>%$$ version of $italic name$$. 00105 This can be with in a namespace (not the $code CppAD$$ namespace) 00106 but must be outside of any routine. 00107 00108 $head Operation Sequence$$ 00109 This is an AD of $italic Base$$ 00110 $xref/glossary/Operation/Atomic/atomic operation/1/$$ 00111 and hence is part of the current 00112 AD of $italic Base$$ 00113 $xref/glossary/Operation/Sequence/operation sequence/1/$$. 00114 00115 $head Derivatives$$ 00116 During a zero order $xref/Forward//Forward/$$ operation, 00117 an $xref/ADFun/$$ object will compute the value of $italic name$$ 00118 using the user provided $italic Base$$ version of this routine. 00119 All the derivatives of $italic name$$ will be evaluated as zero. 00120 00121 $head Example$$ 00122 $children% 00123 example/tape_index.cpp% 00124 example/interp_onetape.cpp% 00125 example/interp_retape.cpp 00126 %$$ 00127 The file 00128 $xref/TapeIndex.cpp/$$ 00129 contains an example and test that uses a discrete function 00130 to vary an array index during $cref/Forward/$$ mode calculations. 00131 The file 00132 $xref/interp_onetape.cpp/$$ 00133 contains an example and test that uses discrete 00134 functions to avoid retaping a calculation that requires interpolation. 00135 (The file 00136 $xref/interp_retape.cpp/$$ 00137 shows how interpolation can be done with retaping.) 00138 00139 $head Deprecated$$ 00140 $index CppADCreateDiscrete, deprecated$$ 00141 $index deprecated, CppADCreateDiscrete$$ 00142 The preprocessor symbol $code CppADCreateDiscrete$$ 00143 is defined to be the same as $code CPPAD_DISCRETE_FUNCTION$$ 00144 but its use is deprecated. 00145 00146 $end 00147 ------------------------------------------------------------------------------ 00148 */ 00149 00150 # define CPPAD_DISCRETE_FUNCTION(Base, FunName) \ 00151 inline CppAD::AD<Base> FunName (const CppAD::AD<Base> &x) \ 00152 { \ 00153 static CppAD::ADDiscrete<Base> Fun(FunName); \ 00154 \ 00155 return Fun.Eval(x); \ 00156 } 00157 00158 # define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION 00159 00160 # include <vector> 00161 00162 // Begin CppAD namespace 00163 namespace CppAD { 00164 00165 template <class Base> 00166 class ADDiscrete { 00167 typedef Base (*F) (const Base &x); 00168 public: 00169 ADDiscrete(F f_) : f(f_), y_taddr( List()->size() ) 00170 { List()->push_back(this); } 00171 00172 // used during the recording process 00173 AD<Base> Eval(const AD<Base> &x) const 00174 { AD<Base> z; 00175 00176 z.value_ = f(x.value_); 00177 if( Variable(x) ) 00178 { x.tape_this()->RecordDisOp( 00179 z, 00180 x.taddr_, 00181 y_taddr 00182 ); 00183 } 00184 return z; 00185 } 00186 00187 // used to evaluate from the recording 00188 static Base Eval(size_t y_taddr, const Base &x) 00189 { 00190 CPPAD_ASSERT_UNKNOWN(y_taddr < List()->size() ); 00191 00192 return (*List())[y_taddr]->f(x); 00193 } 00194 00195 private: 00196 const F f; 00197 const size_t y_taddr; 00198 00199 static std::vector<ADDiscrete *> *List(void) 00200 { static std::vector<ADDiscrete *> list; 00201 return &list; 00202 } 00203 00204 }; 00205 00206 } // END CppAD namespace 00207 00208 # endif