CppAD: A C++ Algorithmic Differentiation Package  20130102
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-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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines