00001 # ifndef CPPAD_AD_TAPE_INCLUDED 00002 # define CPPAD_AD_TAPE_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 $begin ADTape$$ $comment CppAD Developer Documentation$$ 00016 $aindex head$$ 00017 00018 $spell 00019 taddr_ 00020 inline 00021 Var 00022 Prip 00023 Priv 00024 Ldp 00025 Ldv 00026 Stpv 00027 Stvv 00028 Stpp 00029 Stvp 00030 Inv 00031 Vec 00032 Sto 00033 VecInd 00034 Inv 00035 Ind 00036 Num 00037 Op 00038 Cpp 00039 const 00040 bool 00041 Len 00042 xy 00043 xx 00044 yy 00045 $$ 00046 00047 $section ADTape: The CppAD Tape$$ 00048 00049 $head Syntax$$ 00050 $syntax%ADTape<%Base%> %Tape%$$ 00051 00052 00053 $head Description$$ 00054 For each $italic Base$$ that is used in connection with 00055 $syntax%AD<%Base%>%$$, 00056 there must be one and only one $italic id$$ such that 00057 $syntax%ADBase<%Base%>::tape_active(%id%)%$$ is true. 00058 This object is used to record 00059 $syntax%AD<%Base%>%$$ operations and compute derivatives. 00060 00061 $head Rec$$ 00062 the $xref/TapeRec/$$ object $syntax%%Tape%.Rec%$$ contains 00063 the currently recorded information. 00064 This information is recorded using the following functions: 00065 00066 $subhead Empty OpCode$$ 00067 The procedure call 00068 $syntax% 00069 void %Tape%.RecordNonOp() 00070 %$$ 00071 places a NonOp in the next tape location. 00072 This is useful for operations that must reserve extra 00073 calculation space for forward and backward modes. 00074 00075 $subhead Printing OpCode$$ 00076 The procedure call 00077 $syntax% 00078 void %Tape%.RecordPripOp(const char *%text%, const %Base% &%x%) 00079 %$$ 00080 places, in the next tape location, 00081 a PripOp that prints the parameter 00082 value $italic x$$ to standard output. 00083 The procedure call 00084 $syntax% 00085 void %Tape%.RecordPrivOp(const char *%text%, %x_taddr%) 00086 %$$ 00087 places, in the next tape location, 00088 a PrivOp that prints the variable 00089 corresponding to $italic x_taddr$$ to standard output. 00090 These operators enables the user to determine the value of intermediate 00091 variables during forward and reverse mode. 00092 00093 00094 $subhead Parameter$$ 00095 The procedure call 00096 $syntax% 00097 size_t %Tape%.RecordParOp(const %Base% &%z%) 00098 %$$ 00099 creates a $code ParOp$$ record with the value 00100 specified by $italic z$$. 00101 The return value is the taddr of this operation in the tape. 00102 00103 $subhead Independent$$ 00104 The procedure call 00105 $syntax% 00106 void %Tape%.RecordInvOp(AD<%Base%> &%z%) 00107 %$$ 00108 creates a tape record corresponding to a new independent variable. 00109 The field $syntax%%z%.value_%$$ is an input and all the other 00110 fields of $italic z$$ are outputs. 00111 Upon return from $code RecordInvOp$$, 00112 $syntax%%z%.taddr_%$$ 00113 is the taddr of the new tape record. 00114 00115 $subhead Loading Vector Element$$ 00116 The procedure call 00117 $syntax% 00118 void %Tape%.RecordLoadOp( 00119 OpCode %op%, 00120 AD<%Base%> &%z%, 00121 size_t %offset%, 00122 size_t %x_taddr% 00123 ) 00124 %$$ 00125 creates a tape record corresponding to the value of a $code VecAD$$ element. 00126 $syntax% 00127 00128 %op% 00129 %$$ 00130 Must be one of the following values: 00131 $code LdvOp$$, $code LdpOp$$. 00132 $syntax% 00133 00134 %offset% 00135 %$$ 00136 is the offset where this $code VecAD$$ array 00137 starts in the cumulative array containing all the $code VecAD$$ arrays. 00138 It indexes the length of this $code VecAD$$ array 00139 and the rest of the array follows. 00140 $syntax% 00141 00142 %x_taddr% 00143 %$$ 00144 provides the information necessary to retriever the taddr in for this 00145 element within the $code VecAD$$ array. 00146 This has the following meaning depending on the value of $italic op$$: 00147 $table 00148 $bold op$$ 00149 $cnext $bold x_taddr$$ $rnext 00150 $code LdpOp$$ 00151 $cnext location of the index in $syntax%%Rec%.GetPar%$$ $rnext 00152 $code LdvOp$$ 00153 $cnext location of the taddr as a variable in the tape 00154 $tend 00155 $syntax% 00156 00157 %z%.taddr_ 00158 %$$ 00159 is modified so that it corresponds to the new tape record when 00160 $code RecordLoadOp$$ returns. 00161 Upon return from $code RecordLoadOp$$, 00162 $italic z$$ is in the list of variables and 00163 $syntax%%z%.taddr_%$$ 00164 is the taddr in the tape for this $italic op$$ operator. 00165 00166 00167 $subhead Storing Vector Element$$ 00168 The procedure call 00169 $syntax% 00170 void %Tape%.RecordStoreOp( 00171 OpCode %op%, 00172 size_t %offset%, 00173 size_t %x_taddr%, 00174 size_t %y_taddr% 00175 ) 00176 %$$ 00177 creates a tape record corresponding to storing a new value for 00178 a $code VecAD$$ element. 00179 $syntax% 00180 00181 %op% 00182 %$$ 00183 Must be one of the following values: 00184 $code StvvOp$$, $code StpvOp$$. 00185 $syntax% 00186 00187 %offset% 00188 %$$ 00189 is the offset where this $code VecAD$$ array 00190 starts in the cumulative array containing all the $code VecAD$$ arrays. 00191 It indexes the length of this $code VecAD$$ array 00192 and the rest of the array follows. 00193 $syntax% 00194 00195 %x_taddr% 00196 %$$ 00197 provides the information necessary to retrieve the taddr for this 00198 $code VecAD$$ element within this $code VecAD$$ array. 00199 This has the following meaning depending on the value of $italic op$$: 00200 $table 00201 $bold op$$ 00202 $cnext $bold x_taddr$$ $rnext 00203 $code StppOp$$ 00204 $cnext location of the index in $syntax%%Rec%.GetPar%$$ $rnext 00205 $code StpvOp$$ 00206 $cnext location of the index in $syntax%%Rec%.GetPar%$$ $rnext 00207 $code StvpOp$$ 00208 $cnext location of the taddr as a variable in the tape $rnext 00209 $code StvvOp$$ 00210 $cnext location of the taddr as a variable in the tape 00211 $tend 00212 $syntax% 00213 00214 %y_taddr% 00215 %$$ 00216 provides the information necessary to retrieve the value for this 00217 $code VecAD$$ element within this $code VecAD$$ array. 00218 This has the following meaning depending on the value of $italic op$$: 00219 $table 00220 $bold op$$ 00221 $cnext $bold y_taddr$$ $rnext 00222 $code StppOp$$ 00223 $cnext location of the value in $syntax%%Rec%.GetPar%$$ $rnext 00224 $code StvpOp$$ 00225 $cnext location of the value in $syntax%%Rec%.GetPar%$$ $rnext 00226 $code StpvOp$$ 00227 $cnext location of the taddr as a variable in the tape $rnext 00228 $code StvvOp$$ 00229 $cnext location of the taddr as a variable in the tape 00230 $tend 00231 00232 $subhead Op(Variable, Variable)$$ 00233 The procedure call 00234 $syntax% 00235 inline void %Tape%.RecordOp( 00236 OpCode %op%, 00237 AD<%Base%> &%z%, 00238 size_t %x_taddr%, 00239 size_t %y_taddr% 00240 )%$$ 00241 places a new dependent variable $italic z$$ in the tape 00242 and sets $syntax%%z%.taddr_%$$ to the corresponding taddr. 00243 The tape record specifies the operation 00244 $syntax% 00245 %z% = %op%(%x%, %y%) 00246 %$$ 00247 where $italic x_taddr$$ is the taddr of $italic x$$ in the tape 00248 and $italic y_taddr$$ is the taddr of $italic y$$ in the tape 00249 (neither of these indices can be zero). 00250 The field $syntax%%z%.value_%$$ is an input and all the other 00251 fields of $italic z$$ are outputs. 00252 Upon return from $code RecordOp$$, 00253 $italic z$$ is in the list of variables and 00254 $syntax%%z%.taddr_%$$ 00255 is to the taddr of the new tape record. 00256 $pre 00257 00258 $$ 00259 The procedure call 00260 $syntax% 00261 inline void %Tape%.RecordOp( 00262 OpCode %op%, 00263 size_t %x_taddr%, 00264 size_t %y_taddr% 00265 )%$$ 00266 is the same as above except that no variable results from the 00267 tape operation; i.e., $syntax%NumVar(%op%)%$$ is zero. 00268 00269 $subhead Op(Variable, Parameter)$$ 00270 The procedure call 00271 $syntax% 00272 inline void %Tape%.RecordOp( 00273 OpCode %op%, 00274 AD<%Base%> &%z%, 00275 size_t %x_taddr%, 00276 const %Base% &%p% 00277 )%$$ 00278 places a new dependent variable $italic z$$ in the tape 00279 and sets $syntax%%z%.taddr_%$$ to the corresponding taddr. 00280 The tape record specifies the operation 00281 $syntax% 00282 %z% = %op%(%x%, %p%) 00283 %$$ 00284 where $italic x_taddr$$ is the taddr of $italic x$$ in the tape 00285 (this taddr can not be zero). 00286 The field $syntax%%z%.value_%$$ is an input and all the other 00287 fields of $italic z$$ are outputs. 00288 Upon return from $code RecordOp$$, 00289 $italic z$$ is in the list of variables and 00290 $syntax%%z%.taddr_%$$ 00291 is to the taddr of the new tape record. 00292 The value $italic p$$ corresponds to a parameter. 00293 $pre 00294 00295 $$ 00296 The procedure call 00297 $syntax% 00298 inline void %Tape%.RecordOp( 00299 OpCode %op%, 00300 size_t %x_taddr%, 00301 const %Base% &%p% 00302 )%$$ 00303 is the same as above except that no variable results from the 00304 tape operation; i.e., $syntax%NumVar(%op%)%$$ is zero. 00305 00306 $subhead Op(Parameter, Variable)$$ 00307 The procedure call 00308 $syntax% 00309 inline void %Tape%.RecordOp( 00310 OpCode %op%, 00311 AD<%Base%> &%z%, 00312 const %Base% &%p%, 00313 size_t %y_taddr% 00314 )%$$ 00315 places a new dependent variable $italic z$$ in the tape 00316 and sets $syntax%%z%.taddr_%$$ to the corresponding taddr. 00317 The tape record specifies the operation 00318 $syntax% 00319 %z% = %op%(%p%, %y%) 00320 %$$ 00321 where $italic y_taddr$$ is the taddr of $italic y$$ in the tape 00322 (this taddr can not be zero). 00323 The field $syntax%%z%.value_%$$ is an input and all the other 00324 fields of $italic z$$ are outputs. 00325 Upon return from $code RecordOp$$, 00326 $italic z$$ is in the list of variables and 00327 $syntax%%z%.taddr_%$$ 00328 is to the taddr of the new tape record. 00329 The value $italic p$$ corresponds to a parameter. 00330 $pre 00331 00332 $$ 00333 The procedure call 00334 $syntax% 00335 inline void %Tape%.RecordOp( 00336 OpCode %op%, 00337 const %Base% &%p%, 00338 size_t %y_taddr% 00339 )%$$ 00340 is the same as above except that no variable results from the 00341 tape operation; i.e., $syntax%NumVar(%op%)%$$ is zero. 00342 00343 $subhead Op(Parameter, Parameter)$$ 00344 The procedure call 00345 $syntax% 00346 inline void %Tape%.RecordOp( 00347 OpCode %op%, 00348 const %Base% &%x%, 00349 const %Base% &%y% 00350 )%$$ 00351 records an operation between two parameters where 00352 $italic x$$ is the left operand and $italic y$$ is the right operand. 00353 No variable results from the tape operation; 00354 i.e., $syntax%NumVar(%op%)%$$ is zero. 00355 00356 $subhead Op(Variable)$$ 00357 The procedure call 00358 $syntax% 00359 inline void %Tape%.RecordOp( 00360 OpCode %op%, 00361 AD<%Base%> &%z%, 00362 size_t %x_taddr% 00363 )%$$ 00364 places a new dependent variable $italic z$$ in the tape 00365 and sets $syntax%%z%.taddr_%$$ to the corresponding taddr. 00366 The tape record specifies the operation 00367 $syntax% 00368 %z% = %op%(%x%) 00369 %$$ 00370 where $italic x_taddr$$ is the taddr of $italic x$$ in the tape 00371 (this taddr can not be zero) and $italic op$$ specifies the 00372 unary function. 00373 The field $syntax%%z%.value_%$$ is an input and all the other 00374 fields of $italic z$$ are outputs. 00375 Upon return from $code RecordOp$$, 00376 $italic z$$ is in the list of variables and 00377 $syntax%%z%.taddr_%$$ 00378 is to the taddr of the new tape record. 00379 00380 $subhead User Defined Functions$$ 00381 The procedure call 00382 $syntax% 00383 void %Tape%.RecordDisOp( 00384 AD<%Base%> &%z%, 00385 size_t %x_taddr%, 00386 size_t %y_taddr% 00387 )%$$ 00388 places a new dependent variable $italic z$$ in the tape 00389 and sets $syntax%%z%.taddr_%$$ to the corresponding taddr. 00390 The tape record specifies the operation 00391 $syntax% 00392 %z% = %f%(%x%)% 00393 %$$ 00394 where $italic x_taddr$$ is the taddr of $italic x$$ in the tape 00395 and $italic y_taddr$$ is the taddr corresponding to the 00396 Discrete function $italic f$$ 00397 (the value $italic x_taddr$$ cannot be zero). 00398 The field $syntax%%z%.value_%$$ is an input and all the other 00399 fields of $italic z$$ are outputs. 00400 Upon return from $code RecordDisOp$$, 00401 $italic z$$ is in the list of variables and 00402 $syntax%%z%.taddr_%$$ 00403 is to the taddr of the new tape record. 00404 00405 $subhead Variable Indexed Arrays$$ 00406 The procedure call 00407 $syntax% 00408 size_t %Tape%.AddVec(size_t %length%, const %Base% *%data%) 00409 %$$ 00410 adds a variable indexed array with the specified length and values to the tape. 00411 We use $italic i$$ to denote the value returned by $code AddVec$$. 00412 The value $italic length$$ is added to $italic Rec$$ as follows: 00413 $syntax% 00414 %length% == %Rec%.GetVecInd(%i%) 00415 %$$ 00416 Upon return, 00417 the elements of $italic data$$ are stored in $italic Rec$$ 00418 in the following way: 00419 for $latex j = 0 , \ldots , length-1$$, 00420 $syntax% 00421 %data%[%j%] == %Rec%.GetVecInd(%i% + %j% + 1) 00422 %$$ 00423 00424 00425 $end 00426 */ 00427 00428 // BEGIN CppAD namespace 00429 namespace CppAD { 00430 00431 00432 template <class Base> 00433 class ADTape { 00434 00435 // classes 00436 friend class AD<Base>; 00437 friend class ADFun<Base>; 00438 friend class ADDiscrete<Base>; 00439 friend class VecAD<Base>; 00440 friend class VecAD_reference<Base>; 00441 00442 // 00443 // functions 00444 // 00445 00446 // PrintFor 00447 friend void PrintFor <Base> 00448 (const char *text, const AD<Base> &x); 00449 00450 // CondExpOp 00451 friend AD<Base> CondExpOp <Base> ( 00452 enum CompareOp cop , 00453 const AD<Base> &left , 00454 const AD<Base> &right , 00455 const AD<Base> &trueCase , 00456 const AD<Base> &falseCase 00457 ); 00458 00459 // pow 00460 friend AD<Base> pow <Base> 00461 (const AD<Base> &x, const AD<Base> &y); 00462 00463 // Parameter 00464 friend bool Parameter <Base> 00465 (const AD<Base> &u); 00466 // Variable 00467 friend bool Variable <Base> 00468 (const AD<Base> &u); 00469 00470 public: 00471 // constructor 00472 ADTape(size_t id) : id_(id) 00473 { } 00474 00475 // destructor 00476 ~ADTape(void) 00477 { Rec.Erase(); } 00478 00479 // public function only used by CppAD::Independent 00480 template <typename VectorADBase> 00481 void Independent(VectorADBase &u); 00482 00483 private: 00484 // private data 00485 size_t id_; 00486 size_t size_independent; 00487 TapeRec<Base> Rec; 00488 00489 /* 00490 Private functions 00491 */ 00492 00493 // add an empty operator at next tape location 00494 void RecordNonOp(void); 00495 00496 // add a parameter to the tape 00497 size_t RecordParOp(const Base &x); 00498 00499 // add tape entry corresponding to a parameter value 00500 void RecordInvOp(AD<Base> &z); 00501 00502 // see CondExp.h 00503 void RecordCondExp( 00504 enum CompareOp cop , 00505 AD<Base> &returnValue , 00506 const AD<Base> &left , 00507 const AD<Base> &right , 00508 const AD<Base> &trueCase , 00509 const AD<Base> &falseCase 00510 ); 00511 00512 // see Compare.h 00513 void RecordCompare( 00514 enum CompareOp cop , 00515 bool result , 00516 const AD<Base> &left , 00517 const AD<Base> &right 00518 ); 00519 00520 // load ADVec element 00521 void RecordLoadOp( 00522 OpCode op, 00523 AD<Base> &z, 00524 size_t offset, 00525 size_t x_taddr 00526 ); 00527 00528 // store ADVec element 00529 void RecordStoreOp( 00530 OpCode op, 00531 size_t offset, 00532 size_t x_taddr, 00533 size_t y_taddr 00534 ); 00535 00536 // add a tape entry specified by operator 00537 inline void RecordOp( 00538 OpCode op, 00539 AD<Base> &z, 00540 size_t x_taddr, 00541 size_t y_taddr 00542 ); 00543 inline void RecordOp( 00544 OpCode op, 00545 size_t x_taddr, 00546 size_t y_taddr 00547 ); 00548 inline void RecordOp( 00549 OpCode op, 00550 AD<Base> &z, 00551 size_t x_taddr, 00552 const Base &y 00553 ); 00554 inline void RecordOp( 00555 OpCode op, 00556 size_t x_taddr, 00557 const Base &y 00558 ); 00559 inline void RecordOp( 00560 OpCode op, 00561 AD<Base> &z, 00562 const Base &x, 00563 size_t y_taddr 00564 ); 00565 inline void RecordOp( 00566 OpCode op, 00567 const Base &x, 00568 size_t y_taddr 00569 ); 00570 inline void RecordOp( 00571 OpCode op, 00572 const Base &x, 00573 const Base &y 00574 ); 00575 inline void RecordOp( 00576 OpCode op, 00577 AD<Base> &z, 00578 size_t x_taddr 00579 ); 00580 void RecordDisOp( 00581 AD<Base> &z, 00582 size_t x_taddr, 00583 size_t y_taddr 00584 ); 00585 void RecordPripOp( 00586 const char *text, 00587 const Base &x 00588 ); 00589 void RecordPrivOp( 00590 const char *text, 00591 size_t x_taddr 00592 ); 00593 size_t AddVec( 00594 size_t length, 00595 const Base *data 00596 ); 00597 00598 }; 00599 // --------------------------------------------------------------------------- 00600 // Private functions 00601 // 00602 template <class Base> 00603 void ADTape<Base>::RecordNonOp(void) 00604 { 00605 CPPAD_ASSERT_UNKNOWN( NumInd(NonOp) == 0 ); 00606 00607 // Op value for this instruction 00608 Rec.PutOp(NonOp); 00609 00610 // no Ind values for this instruction 00611 CPPAD_ASSERT_UNKNOWN( NumInd(NonOp) == 0 ); 00612 } 00613 00614 template <class Base> 00615 size_t ADTape<Base>::RecordParOp(const Base &z) 00616 { size_t z_taddr; 00617 size_t ind; 00618 00619 CPPAD_ASSERT_UNKNOWN( NumInd(ParOp) == 1 ); 00620 z_taddr = Rec.PutOp(ParOp); 00621 ind = Rec.PutPar(z); 00622 Rec.PutInd(ind); 00623 00624 return z_taddr; 00625 } 00626 00627 template <class Base> 00628 void ADTape<Base>::RecordInvOp(AD<Base> &z) 00629 { 00630 // in the independent variable case, should not already be in tape 00631 CPPAD_ASSERT_UNKNOWN( Parameter(z) ); 00632 00633 // Make z correspond to a next variable in tape 00634 z.id_ = id_; 00635 z.taddr_ = Rec.PutOp(InvOp); 00636 00637 // no Ind values for this instruction 00638 CPPAD_ASSERT_UNKNOWN( NumInd(InvOp) == 0 ); 00639 00640 // check that z is an independent variable 00641 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00642 } 00643 00644 00645 template <class Base> 00646 void ADTape<Base>::RecordLoadOp( 00647 OpCode op, 00648 AD<Base> &z, 00649 size_t offset, 00650 size_t x_taddr 00651 ) 00652 { 00653 CPPAD_ASSERT_UNKNOWN( (op == LdvOp) | (op == LdpOp) ); 00654 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 3 ); 00655 00656 // Make z correspond to a next variable in tape 00657 z.id_ = id_; 00658 z.taddr_ = Rec.PutOp(op); 00659 00660 // Ind values for this instruction 00661 // (space reserved by third taddr is set by f.Forward(0, *) ) 00662 Rec.PutInd(offset, x_taddr, 0); 00663 00664 // check that z is a dependent variable 00665 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00666 } 00667 00668 template <class Base> 00669 void ADTape<Base>::RecordStoreOp( 00670 OpCode op, 00671 size_t offset, 00672 size_t x_taddr, 00673 size_t y_taddr 00674 ) 00675 { 00676 CPPAD_ASSERT_UNKNOWN( 00677 (op == StppOp) | 00678 (op == StvpOp) | 00679 (op == StpvOp) | 00680 (op == StvvOp) 00681 ); 00682 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 3 ); 00683 CPPAD_ASSERT_UNKNOWN( NumVar(op) == 0 ); 00684 CPPAD_ASSERT_UNKNOWN( (op==StppOp) | (op==StpvOp) | (x_taddr!=0) ); 00685 CPPAD_ASSERT_UNKNOWN( (op==StppOp) | (op==StvpOp) | (y_taddr!=0) ); 00686 00687 // Put operator in the tape 00688 Rec.PutOp(op); 00689 00690 // Ind values for this instruction 00691 Rec.PutInd(offset, x_taddr, y_taddr); 00692 } 00693 00694 00695 template <class Base> 00696 inline void ADTape<Base>::RecordOp( 00697 OpCode op, 00698 AD<Base> &z, 00699 size_t x_taddr, 00700 size_t y_taddr 00701 ) 00702 { 00703 CPPAD_ASSERT_UNKNOWN( (x_taddr != 0) & (y_taddr != 0) ); 00704 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00705 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00706 00707 // Make z correspond to a next variable in tape 00708 z.id_ = id_; 00709 z.taddr_ = Rec.PutOp(op); 00710 00711 // Ind values for this instruction 00712 Rec.PutInd(x_taddr, y_taddr); 00713 00714 // check that z is a dependent variable 00715 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00716 } 00717 00718 template <class Base> 00719 inline void ADTape<Base>::RecordOp( 00720 OpCode op, 00721 size_t x_taddr, 00722 size_t y_taddr 00723 ) 00724 { 00725 00726 CPPAD_ASSERT_UNKNOWN( (x_taddr != 0) & (y_taddr != 0) ); 00727 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00728 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00729 CPPAD_ASSERT_UNKNOWN( NumVar(op) == 0 ); 00730 00731 // record operator 00732 Rec.PutOp(op); 00733 00734 // Ind values for this instruction 00735 Rec.PutInd(x_taddr, y_taddr); 00736 } 00737 00738 template <class Base> 00739 inline void ADTape<Base>::RecordOp( 00740 OpCode op, 00741 AD<Base> &z, 00742 size_t x_taddr, 00743 const Base &y 00744 ) 00745 { 00746 CPPAD_ASSERT_UNKNOWN( x_taddr != 0 ); 00747 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00748 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00749 00750 // Make z correspond to a next variable in tape 00751 z.id_ = id_; 00752 z.taddr_ = Rec.PutOp(op); 00753 00754 // Ind values for this instruction 00755 Rec.PutInd(x_taddr, Rec.PutPar(y)); 00756 00757 // check that z is a dependent variable 00758 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00759 } 00760 00761 template <class Base> 00762 inline void ADTape<Base>::RecordOp( 00763 OpCode op, 00764 size_t x_taddr, 00765 const Base &y 00766 ) 00767 { 00768 00769 CPPAD_ASSERT_UNKNOWN( x_taddr != 0 ); 00770 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00771 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00772 CPPAD_ASSERT_UNKNOWN( NumVar(op) == 0 ); 00773 00774 // record this operation 00775 Rec.PutOp(op); 00776 00777 // Ind values for this instruction 00778 Rec.PutInd(x_taddr, Rec.PutPar(y)); 00779 } 00780 00781 template <class Base> 00782 inline void ADTape<Base>::RecordOp( 00783 OpCode op, 00784 AD<Base> &z, 00785 const Base &x, 00786 size_t y_taddr 00787 ) 00788 { 00789 CPPAD_ASSERT_UNKNOWN( y_taddr != 0 ); 00790 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00791 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00792 00793 // Make z correspond to a next variable in tape 00794 z.id_ = id_; 00795 z.taddr_ = Rec.PutOp(op); 00796 00797 // Ind values for this instruction 00798 Rec.PutInd(Rec.PutPar(x), y_taddr); 00799 00800 // check that z is a dependent variable 00801 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00802 } 00803 00804 template <class Base> 00805 inline void ADTape<Base>::RecordOp( 00806 OpCode op, 00807 const Base &x, 00808 size_t y_taddr 00809 ) 00810 { 00811 00812 CPPAD_ASSERT_UNKNOWN( y_taddr != 0 ); 00813 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00814 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00815 CPPAD_ASSERT_UNKNOWN( NumVar(op) == 0 ); 00816 00817 // record this operation 00818 Rec.PutOp(op); 00819 00820 // Ind values for this instruction 00821 Rec.PutInd(Rec.PutPar(x), y_taddr); 00822 } 00823 00824 template <class Base> 00825 inline void ADTape<Base>::RecordOp( 00826 OpCode op, 00827 const Base &x, 00828 const Base &y 00829 ) 00830 { 00831 00832 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00833 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 2 ); 00834 CPPAD_ASSERT_UNKNOWN( NumVar(op) == 0 ); 00835 00836 // record this operation 00837 Rec.PutOp(op); 00838 00839 // Ind values for this instruction 00840 Rec.PutInd(Rec.PutPar(x), Rec.PutPar(y)); 00841 } 00842 00843 template <class Base> 00844 inline void ADTape<Base>::RecordOp( 00845 OpCode op, 00846 AD<Base> &z, 00847 size_t x_taddr 00848 ) 00849 { 00850 CPPAD_ASSERT_UNKNOWN( x_taddr != 0 ); 00851 CPPAD_ASSERT_UNKNOWN( (op != InvOp) & (op != DisOp) ); 00852 CPPAD_ASSERT_UNKNOWN( NumInd(op) == 1 ); 00853 00854 // Make z correspond to a next variable in tape 00855 z.id_ = id_; 00856 z.taddr_ = Rec.PutOp(op); 00857 00858 // Ind value for this instruction 00859 Rec.PutInd(x_taddr); 00860 00861 // check that z is a dependent variable 00862 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00863 } 00864 00865 template <class Base> 00866 void ADTape<Base>::RecordDisOp( 00867 AD<Base> &z, 00868 size_t x_taddr, 00869 size_t y_taddr 00870 ) 00871 { 00872 CPPAD_ASSERT_UNKNOWN( x_taddr != 0 ); 00873 CPPAD_ASSERT_UNKNOWN( NumInd(DisOp) == 2 ); 00874 00875 // Make z correspond to a next variable in tape 00876 z.id_ = id_; 00877 z.taddr_ = Rec.PutOp(DisOp); 00878 00879 // Ind values for this instruction 00880 Rec.PutInd(x_taddr, y_taddr); 00881 00882 // check that z is a dependent variable 00883 CPPAD_ASSERT_UNKNOWN( Variable(z) ); 00884 } 00885 00886 template <class Base> 00887 void ADTape<Base>::RecordPripOp(const char *text, const Base &x) 00888 { 00889 00890 CPPAD_ASSERT_UNKNOWN( NumInd(PripOp) == 2 ); 00891 00892 // put this operator in the tape 00893 Rec.PutOp(PripOp); 00894 00895 // Ind values for this instruction 00896 Rec.PutInd(Rec.PutTxt(text), Rec.PutPar(x)); 00897 } 00898 00899 template <class Base> 00900 void ADTape<Base>::RecordPrivOp(const char *text, size_t x_taddr) 00901 { 00902 00903 CPPAD_ASSERT_UNKNOWN( NumInd(PripOp) == 2 ); 00904 00905 // put this operator in the tape 00906 Rec.PutOp(PrivOp); 00907 00908 // Ind values for this instruction 00909 Rec.PutInd(Rec.PutTxt(text), x_taddr); 00910 } 00911 00912 00913 template <class Base> 00914 size_t ADTape<Base>::AddVec(size_t length, const Base *data) 00915 { CPPAD_ASSERT_UNKNOWN( length > 0 ); 00916 size_t i; 00917 size_t vecInd; 00918 00919 // store the length in VecInd 00920 size_t start = Rec.PutVecInd(length); 00921 00922 // store indices of the values in VecInd 00923 for(i = 0; i < length; i++) 00924 { 00925 vecInd = Rec.PutPar( data[i] ); 00926 Rec.PutVecInd( vecInd ); 00927 } 00928 00929 // return the taddr of the length (where the vector starts) 00930 return start; 00931 } 00932 00933 00934 } // END CppAD namespace 00935 00936 # endif