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