CppAD: A C++ Algorithmic Differentiation Package 20110419
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_AD_TAPE_INCLUDED 00003 # define CPPAD_AD_TAPE_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 # include <cppad/local/define.hpp> 00016 00017 CPPAD_BEGIN_NAMESPACE 00018 00019 /*! 00020 Class used to hold tape that records AD<Base> operations. 00021 00022 \tparam Base 00023 An <tt>AD<Base></tt> object is used to recording <tt>AD<Base></tt> operations. 00024 */ 00025 00026 template <class Base> 00027 class ADTape { 00028 // Friends ============================================================= 00029 00030 // classes ------------------------------------------------------------- 00031 friend class AD<Base>; 00032 friend class ADFun<Base>; 00033 friend class discrete<Base>; 00034 friend class user_atomic<Base>; 00035 friend class VecAD<Base>; 00036 friend class VecAD_reference<Base>; 00037 00038 // functions ----------------------------------------------------------- 00039 // PrintFor 00040 friend void PrintFor <Base> 00041 (const char *text, const AD<Base> &x); 00042 // CondExpOp 00043 friend AD<Base> CondExpOp <Base> ( 00044 enum CompareOp cop , 00045 const AD<Base> &left , 00046 const AD<Base> &right , 00047 const AD<Base> &trueCase , 00048 const AD<Base> &falseCase 00049 ); 00050 // pow 00051 friend AD<Base> pow <Base> 00052 (const AD<Base> &x, const AD<Base> &y); 00053 // Parameter 00054 friend bool Parameter <Base> 00055 (const AD<Base> &u); 00056 // Variable 00057 friend bool Variable <Base> 00058 (const AD<Base> &u); 00059 // operators ----------------------------------------------------------- 00060 // arithematic binary operators 00061 friend AD<Base> operator + <Base> 00062 (const AD<Base> &left, const AD<Base> &right); 00063 friend AD<Base> operator - <Base> 00064 (const AD<Base> &left, const AD<Base> &right); 00065 friend AD<Base> operator * <Base> 00066 (const AD<Base> &left, const AD<Base> &right); 00067 friend AD<Base> operator / <Base> 00068 (const AD<Base> &left, const AD<Base> &right); 00069 00070 // comparison operators 00071 friend bool operator < <Base> 00072 (const AD<Base> &left, const AD<Base> &right); 00073 friend bool operator <= <Base> 00074 (const AD<Base> &left, const AD<Base> &right); 00075 friend bool operator > <Base> 00076 (const AD<Base> &left, const AD<Base> &right); 00077 friend bool operator >= <Base> 00078 (const AD<Base> &left, const AD<Base> &right); 00079 friend bool operator == <Base> 00080 (const AD<Base> &left, const AD<Base> &right); 00081 friend bool operator != <Base> 00082 (const AD<Base> &left, const AD<Base> &right); 00083 // ====================================================================== 00084 00085 // -------------------------------------------------------------------------- 00086 private: 00087 // ---------------------------------------------------------------------- 00088 // private data 00089 /*! 00090 Unique identifier for this tape. It is always greater than 00091 CPPAD_MAX_NUM_THREADS, and different for every tape (even ones that have 00092 been deleted). In addition, id_ % CPPAD_MAX_NUM_THREADS is the thread 00093 number for this tape. Set by Independent and effectively const 00094 */ 00095 size_t id_; 00096 /// Number of independent variables in this tapes reconding. 00097 /// Set by Independent and effectively const 00098 size_t size_independent_; 00099 /// This is where the information is recorded. 00100 recorder<Base> Rec_; 00101 // ---------------------------------------------------------------------- 00102 // private functions 00103 // 00104 // add a parameter to the tape 00105 size_t RecordParOp(const Base &x); 00106 00107 // see CondExp.h 00108 void RecordCondExp( 00109 enum CompareOp cop , 00110 AD<Base> &returnValue , 00111 const AD<Base> &left , 00112 const AD<Base> &right , 00113 const AD<Base> &trueCase , 00114 const AD<Base> &falseCase 00115 ); 00116 00117 // see Compare.h 00118 void RecordCompare( 00119 enum CompareOp cop , 00120 bool result , 00121 const AD<Base> &left , 00122 const AD<Base> &right 00123 ); 00124 00125 // place a VecAD object in the tape 00126 size_t AddVec( 00127 size_t length, 00128 const Base *data 00129 ); 00130 00131 public: 00132 // constructor 00133 ADTape(size_t id) : id_(id) 00134 { } 00135 00136 // destructor 00137 ~ADTape(void) 00138 { Rec_.Erase(); } 00139 00140 // public function only used by CppAD::Independent 00141 template <typename VectorADBase> 00142 void Independent(VectorADBase &u); 00143 00144 }; 00145 // --------------------------------------------------------------------------- 00146 // Private functions 00147 // 00148 00149 /*! 00150 Place a parameter in the tape. 00151 00152 On rare occations it is necessary to place a parameter in the tape; e.g., 00153 when it is one of the dependent variabes. 00154 00155 \param z 00156 value of the parameter that we are placing in the tape. 00157 00158 \return 00159 variable index (for this recording) correpsonding to the parameter. 00160 00161 \par Wish List 00162 All these operates are preformed in \c Rec_, so we should 00163 move this routine from <tt>ADTape<Base></tt> to <tt>recorder<Base></tt>. 00164 */ 00165 template <class Base> 00166 size_t ADTape<Base>::RecordParOp(const Base &z) 00167 { size_t z_taddr; 00168 size_t ind; 00169 CPPAD_ASSERT_UNKNOWN( NumRes(ParOp) == 1 ); 00170 CPPAD_ASSERT_UNKNOWN( NumArg(ParOp) == 1 ); 00171 z_taddr = Rec_.PutOp(ParOp); 00172 ind = Rec_.PutPar(z); 00173 Rec_.PutArg(ind); 00174 00175 return z_taddr; 00176 } 00177 00178 /*! 00179 Put initialization for a VecAD<Base> object in the tape. 00180 00181 This routine should be called once for each VecAD object when just 00182 before it changes from a parameter to a variable. 00183 00184 \param length 00185 size of the <tt>VecAD<Base></tt> object. 00186 00187 \param data 00188 initial values for the <tt>VecAD<Base></tt> object 00189 (values before it becomes a variable). 00190 00191 \par Wish List 00192 All these operates are preformed in \c Rec_, so we should 00193 move this routine from <tt>ADTape<Base></tt> to <tt>recorder<Base></tt>. 00194 */ 00195 template <class Base> 00196 size_t ADTape<Base>::AddVec(size_t length, const Base *data) 00197 { CPPAD_ASSERT_UNKNOWN( length > 0 ); 00198 size_t i; 00199 size_t value_index; 00200 00201 // store the length in VecInd 00202 size_t start = Rec_.PutVecInd(length); 00203 00204 // store indices of the values in VecInd 00205 for(i = 0; i < length; i++) 00206 { 00207 value_index = Rec_.PutPar( data[i] ); 00208 Rec_.PutVecInd( value_index ); 00209 } 00210 00211 // return the taddr of the length (where the vector starts) 00212 return start; 00213 } 00214 00215 CPPAD_END_NAMESPACE 00216 00217 # endif