CppAD: A C++ Algorithmic Differentiation Package 20110419
discrete.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_DISCRETE_INCLUDED
00003 # define CPPAD_DISCRETE_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 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 $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 Example$$
00123 $children%
00124         example/tape_index.cpp%
00125         example/interp_onetape.cpp%
00126         example/interp_retape.cpp
00127 %$$
00128 The file
00129 $cref/TapeIndex.cpp/$$
00130 contains an example and test that uses a discrete function 
00131 to vary an array index during $cref/Forward/$$ mode calculations.
00132 The file
00133 $cref/interp_onetape.cpp/$$
00134 contains an example and test that uses discrete
00135 functions to avoid retaping a calculation that requires interpolation.
00136 (The file
00137 $cref/interp_retape.cpp/$$
00138 shows how interpolation can be done with retaping.)
00139 
00140 $head Deprecated$$
00141 $index CppADCreateDiscrete, deprecated$$
00142 $index deprecated, CppADCreateDiscrete$$
00143 The preprocessor symbol $code CppADCreateDiscrete$$
00144 is defined to be the same as $code CPPAD_DISCRETE_FUNCTION$$
00145 but its use is deprecated.
00146 
00147 $end
00148 ------------------------------------------------------------------------------
00149 */
00150 # include <vector>
00151 
00152 CPPAD_BEGIN_NAMESPACE
00153 /*!
00154 \file discrete.hpp
00155 user define discrete functions
00156 */
00157 
00158 /*!
00159 \def CPPAD_DISCRETE_FUNCTION(Base, name)
00160 Defines the function <code>name(ax, ay)</code>  
00161 where \c ax and \c ay are vectors with <code>AD<Base></code> elements.
00162 
00163 \par Base
00164 is the base type for the discrete function.
00165 
00166 \par name 
00167 is the name of the user defined function that corresponding to this operation.
00168 */
00169 
00170 # define CPPAD_DISCRETE_FUNCTION(Base, name)            \
00171 inline CppAD::AD<Base> name (const CppAD::AD<Base>& ax) \
00172 {                                                       \
00173      static CppAD::discrete<Base> fun(#name, name);     \
00174                                                         \
00175      return fun.ad(ax);                                 \
00176 }                                      
00177 # define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION
00178 
00179 
00180 /*
00181 Class that acutally implemnets the <code>ay = name(ax)</code> call.
00182 
00183 A new discrete function is generated for ech time the user invokes
00184 the CPPAD_DISCRETE_FUNCTION macro; see static object in that macro.
00185 */
00186 template <class Base>
00187 class discrete {
00188         /// type for the uer routine that computes function values
00189         typedef Base (*F) (const Base& x);
00190 private:
00191         /// name of this user defined function
00192         const std::string name_;
00193         /// user's implementation of the function for Base operations
00194         const F              f_;
00195         /// index of this objec in the vector of all objects for this class
00196         const size_t     index_;
00197 
00198         /*!
00199         List of all objects in this class.
00200 
00201         Can use CppAD::vector for debugging, but it will appear that 
00202         there is a memory leak because this list is not distroyed before
00203         CPPAD_TRACK_COUNT is called by the test routines.
00204         */
00205         static std::vector<discrete *>& List(void)
00206         {       static std::vector<discrete *> list;
00207                 return list;
00208         }
00209 public:
00210         /*!
00211         Constructor called for each invocation of CPPAD_DISCRETE_FUNCTION.
00212 
00213         Put this objec in the list of all objects for this class and set
00214         the constant private data name_, f_, and index_.
00215 
00216         \param Name
00217         is the user's name for this discrete function.
00218 
00219         \param f
00220         user routine that implements this function for \c Base class.
00221         */
00222         discrete(const char* Name, F f) : 
00223         name_(Name)
00224         , f_(f) 
00225         , index_( List().size() )
00226         {       List().push_back(this); }
00227 
00228         /*!
00229         Implement the user call to <code>ay = name(ax)</code>.
00230 
00231         \param ax
00232         is the argument for this call.
00233 
00234         \return
00235         the return value is called \c ay above.
00236         */
00237         AD<Base> ad(const AD<Base> &ax) const
00238         {       AD<Base> ay;
00239 
00240                 ay.value_ = f_(ax.value_);
00241                 if( Variable(ax) )
00242                 {       ADTape<Base> *tape = ax.tape_this();
00243                         CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 );
00244                         CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 );
00245 
00246                         // put operand addresses in the tape
00247                         tape->Rec_.PutArg(index_, ax.taddr_);
00248                         // put operator in the tape
00249                         ay.taddr_ = tape->Rec_.PutOp(DisOp);
00250                         // make result a variable
00251                         ay.id_    = tape->id_;
00252 
00253                         CPPAD_ASSERT_UNKNOWN( Variable(ay) );
00254                 } 
00255                 return ay;
00256         }
00257 
00258         /// Name corresponding to a discrete object
00259         static const char* name(size_t index)
00260         {       return List()[index]->name_.c_str(); }
00261 
00262         /*!
00263         Link from forward mode sweep to users routine
00264 
00265         \param index
00266         index for this function in the list of all discrete object 
00267 
00268         \param x
00269         argument value at which to evaluate this function
00270         */
00271         static Base eval(size_t index, const Base& x)
00272         {
00273                 CPPAD_ASSERT_UNKNOWN(index < List().size() );
00274 
00275                 return List()[index]->f_(x);
00276         }
00277 };
00278 
00279 CPPAD_END_NAMESPACE
00280 # endif