CppAD: A C++ Algorithmic Differentiation Package  20130102
vec_ad.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_VEC_AD_INCLUDED
00003 # define CPPAD_VEC_AD_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 $begin VecAD$$
00017 $spell
00018      cppad.hpp
00019      CondExpGt
00020      grep
00021      Ld
00022      vp
00023      Lu
00024      wc
00025      op
00026      Ldp
00027      Ldv
00028      Taylor
00029      VecAD
00030      const
00031      Cpp
00032 $$
00033 
00034 $index VecAD$$
00035 $index vector, AD index$$
00036 $index record, AD index$$
00037 $index tape, AD index$$
00038 $index index, AD record$$
00039 
00040 $section AD Vectors that Record Index Operations$$
00041 
00042 
00043 $head Syntax$$
00044 $codei%VecAD<%Base%> %v%(%n%)%$$
00045 $pre
00046 $$
00047 $icode%v%.size()%$$
00048 $pre
00049 $$
00050 $icode%b% = %v%[%i%]%$$
00051 $pre
00052 $$
00053 $icode%r% = %v%[%x%]%$$
00054 
00055 
00056 $head Purpose$$
00057 If either $icode v$$ or $icode x$$ is a 
00058 $cref/variable/glossary/Variable/$$,
00059 the indexing operation
00060 $codei%
00061      %y% = %v%[%x%]
00062 %$$
00063 is recorded in the corresponding
00064 AD of $icode Base$$
00065 $cref/operation sequence/glossary/Operation/Sequence/$$ and 
00066 transferred to the corresponding $cref ADFun$$ object $icode f$$.
00067 Such an index can change each time
00068 zero order $cref/f.Forward/Forward/$$ is used; i.e.,
00069 $icode f$$ is evaluated with new value for the 
00070 $cref/independent variables/glossary/Tape/Independent Variable/$$. 
00071 Note that the value of $icode y$$ depends on the value of $icode x$$
00072 in a discrete fashion and CppAD computes its partial derivative with 
00073 respect to $icode x$$ as zero.
00074 
00075 $head Alternatives$$
00076 If only the values in the vector, 
00077 and not the indices, 
00078 depend on the independent variables,
00079 the class $icode%Vector%< AD<%Base%> >%$$ is much more efficient for
00080 storing AD values where $icode Vector$$ is any
00081 $cref SimpleVector$$ template class, 
00082 If only the indices, 
00083 and not the values in the vector,
00084 depend on the independent variables,
00085 The $cref Discrete$$ functions are a much more efficient
00086 way to represent these vectors.
00087 
00088 $head VecAD<Base>::reference$$
00089 $index VecAD<Base>::reference$$
00090 $index reference, VecAD<Base>$$
00091 The result $icode y$$ has type
00092 $codei%
00093      VecAD<%Base%>::reference
00094 %$$ 
00095 which is very much like the $codei%AD<%Base%>%$$ type 
00096 with some notable exceptions:
00097 
00098 $subhead Exceptions$$
00099 $list number$$
00100 The object $icode y$$ cannot be used with the
00101 $cref Value$$ function to compute the corresponding $icode Base$$ value.
00102 If $icode v$$ is not a $cref/variable/glossary/Variable/$$
00103 $codei%
00104      v[%i%]
00105 %$$
00106 can be used to compute the corresponding $icode Base$$ value.
00107 
00108 $lnext
00109 The object $icode y$$ cannot be used
00110 with the $cref/computed assignments operators/Arithmetic/$$ 
00111 $code +=$$, 
00112 $code -=$$, 
00113 $code *=$$, or
00114 $code /=$$.
00115 For example, the following syntax is not valid:
00116 $codei%
00117      %v%[%x%] += %z%;
00118 %$$
00119 no matter what the types of $icode z$$.
00120 
00121 $lnext
00122 Assignment to $icode y$$ returns a $code void$$.
00123 For example, the following syntax is not valid:
00124 $codei%
00125      %z% = %v%[%x%] = %u%;
00126 %$$
00127 no matter what the types of $icode z$$, and $icode u$$.
00128 
00129 $lnext
00130 The $cref CondExp$$ functions do not accept 
00131 $codei%VecAD<%Base%>::reference%$$ arguments.
00132 For example, the following syntax is not valid:
00133 $codei%
00134      CondExpGt(%y%, %z%, %u%, %v%)
00135 %$$
00136 no matter what the types of $icode z$$, $icode u$$, and $icode v$$.
00137 
00138 $lnext
00139 The $cref/Parameter and Variable/ParVar/$$ functions cannot be used with
00140 $codei%VecAD<%Base%>::reference%$$ arguments
00141 (use the entire $codei%VecAD<%Base%>%$$ vector instead).
00142 
00143 $lnext
00144 The vectors passed to $cref Independent$$ must have elements
00145 of type $codei%AD<%Base%>%$$; i.e., $cref VecAD$$ vectors
00146 cannot be passed to $code Independent$$.
00147 
00148 $lnext
00149 If one uses this type in a 
00150 AD of $icode Base$$
00151 $cref/operation sequence/glossary/Operation/Sequence/$$,
00152 $cref/sparsity pattern/glossary/Sparsity Pattern/$$ calculations
00153 ($cref Sparse$$)
00154 are less efficient because the dependence of different
00155 elements of the vector cannot be separated.
00156 
00157 $lend
00158 
00159 $head Constructor$$
00160 
00161 $subhead v$$
00162 The syntax 
00163 $codei%
00164      VecAD<%Base%> %v%(%n%)
00165 %$$
00166 creates an $code VecAD$$ object $icode v$$ with 
00167 $icode n$$ elements.
00168 The initial value of the elements of $icode v$$ is unspecified.
00169 
00170 $head n$$
00171 The argument $icode n$$ has prototype
00172 $codei%
00173      size_t %n%
00174 %$$
00175 
00176 $head size$$
00177 The syntax
00178 $codei%
00179      %v%.size()
00180 %$$
00181 returns the number of elements in the vector $icode v$$;
00182 i.e., the value of $icode n$$ when it was constructed.
00183 
00184 $head size_t Indexing$$
00185 We refer to the syntax
00186 $codei%
00187      %b% = %v%[%i%]
00188 %$$
00189 as $code size_t$$ indexing of a $code VecAD$$ object.
00190 This indexing is only valid if the vector $icode v$$ is a 
00191 $cref/parameter/ParVar/$$; i.e.,
00192 it does not depend on the independent variables.
00193 
00194 $subhead i$$
00195 The operand $icode i$$ has prototype
00196 $codei%
00197      size_t %i%
00198 %$$
00199 It must be greater than or equal zero
00200 and less than $icode n$$; i.e., less than
00201 the number of elements in $icode v$$. 
00202 
00203 $subhead b$$
00204 The result $icode b$$ has prototype
00205 $codei%
00206      %Base% %b%
00207 %$$
00208 and is a reference to the $th i$$ element in the vector $icode v$$.
00209 It can be used to change the element value;
00210 for example,
00211 $codei%
00212      %v%[%i%] = %c%
00213 %$$
00214 is valid where $icode c$$ is a $icode Base$$ object.
00215 The reference $icode b$$ is no longer valid once the
00216 destructor for $icode v$$ is called; for example,
00217 when $icode v$$ falls out of scope.
00218 
00219 $head AD Indexing$$
00220 We refer to the syntax
00221 $codei%
00222      %r% = %v%[%x%]
00223 %$$
00224 as AD indexing of a $code VecAD$$ object.
00225 
00226 $subhead x$$
00227 The argument $icode x$$ has prototype
00228 $codei%
00229      const AD<%Base%> &%x%
00230 %$$
00231 The value of $icode x$$ must be greater than or equal zero
00232 and less than $icode n$$; i.e., less than
00233 the number of elements in $icode v$$. 
00234 
00235 $subhead r$$
00236 The result $icode y$$ has prototype
00237 $codei%
00238      VecAD<%Base%>::reference %r%
00239 %$$
00240 The object $icode r$$ has an AD type and its 
00241 operations are recorded as part of the same
00242 AD of $icode Base$$
00243 $cref/operation sequence/glossary/Operation/Sequence/$$ as
00244 for $codei%AD<%Base%>%$$ objects.
00245 It acts as a reference to the 
00246 element with index $latex {\rm floor} (x)$$ in the vector $icode v$$
00247 ($latex {\rm floor} (x)$$ is 
00248 the greatest integer less than or equal $icode x$$).
00249 Because it is a reference, it can be used to change the element value;
00250 for example,
00251 $codei%
00252      %v%[%x%] = %z%
00253 %$$
00254 is valid where $icode z$$ is an
00255 $codei%VecAD<%Base%>::reference%$$ object.
00256 As a reference, $icode r$$ is no longer valid once the
00257 destructor for $icode v$$ is called; for example,
00258 when $icode v$$ falls out of scope.
00259 
00260 $head Example$$
00261 $children%
00262      example/vec_ad.cpp
00263 %$$
00264 The file
00265 $cref vec_ad.cpp$$
00266 contains an example and test using $code VecAD$$ vectors.
00267 It returns true if it succeeds and false otherwise.
00268 
00269 
00270 $head Speed and Memory$$
00271 The $cref VecAD$$ vector type is inefficient because every
00272 time an element of a vector is accessed, a new CppAD 
00273 $cref/variable/glossary/Variable/$$ is created on the tape
00274 using either the $code Ldp$$ or $code Ldv$$ operation
00275 (unless all of the elements of the vector are
00276 $cref/parameters/glossary/Parameter/$$).
00277 The effect of this can be seen by executing the following steps:
00278 
00279 $list number$$
00280 In the file $code cppad/local/forward_sweep.h$$,
00281 change the definition of $code CPPAD_FORWARD_SWEEP_TRACE$$ to
00282 $codep
00283      # define CPPAD_FORWARD_SWEEP_TRACE 1
00284 $$
00285 $lnext
00286 In the $code Example$$ directory, execute the command
00287 $codep
00288      ./test_one.sh lu_vec_ad_ok.cpp lu_vec_ad.cpp -DNDEBUG > lu_vec_ad_ok.log
00289 $$
00290 This will write a trace of all the forward tape operations,
00291 for the test case $cref lu_vec_ad_ok.cpp$$,
00292 to the file $code lu_vec_ad_ok.log$$.
00293 $lnext
00294 In the $code Example$$ directory execute the commands
00295 $codep
00296      grep "op="           lu_vec_ad_ok.log | wc -l
00297      grep "op=Ld[vp]"     lu_vec_ad_ok.log | wc -l
00298      grep "op=St[vp][vp]" lu_vec_ad_ok.log | wc -l
00299 $$
00300 The first command counts the number of operators in the tracing,
00301 the second counts the number of VecAD load operations,
00302 and the third counts the number of VecAD store operations.
00303 (For CppAD version 05-11-20 these counts were 956, 348, and 118
00304 respectively.)
00305 $lend
00306 
00307 $end
00308 ------------------------------------------------------------------------ 
00309 */
00310 # include <cppad/local/pod_vector.hpp>
00311 
00312 // Use this define to get around a bug in doxygen 1.7.5.
00313 // To be explicit, the documentiion for the routines in tape_link.hpp
00314 // you use this typedef in place of the macro below.
00315 # define CPPAD_VEC_AD_TYPEDEF_ADBASE  typedef AD<Base> AD_Base
00316 
00317 # define CPPAD_VEC_AD_COMPUTED_ASSIGNMENT(op, name)                     \
00318 VecAD_reference& operator op (const VecAD_reference<Base> &right)       \
00319 {    CPPAD_ASSERT_KNOWN(                                                \
00320           0,                                                            \
00321           "Cannot use a ADVec element on left side of" name             \
00322      );                                                                 \
00323      return *this;                                                      \
00324 }                                                                       \
00325 VecAD_reference& operator op (const AD<Base> &right)                    \
00326 {    CPPAD_ASSERT_KNOWN(                                                \
00327           0,                                                            \
00328           "Cannot use a ADVec element on left side of" name             \
00329      );                                                                 \
00330      return *this;                                                      \
00331 }                                                                       \
00332 VecAD_reference& operator op (const Base &right)                        \
00333 {    CPPAD_ASSERT_KNOWN(                                                \
00334           0,                                                            \
00335           "Cannot use a ADVec element on left side of" name             \
00336      );                                                                 \
00337      return *this;                                                      \
00338 }
00339 
00340 
00341 //  BEGIN CppAD namespace
00342 namespace CppAD {
00343 
00344 // Element of VecAD
00345 template <class Base>
00346 class VecAD_reference {
00347      friend bool  Parameter<Base> (const VecAD<Base> &vec);
00348      friend bool  Variable<Base>  (const VecAD<Base> &vec);
00349      friend class VecAD<Base>;
00350      friend class ADTape<Base>;
00351 
00352 private:
00353      CPPAD_VEC_AD_TYPEDEF_ADBASE;    // define ADBase as AD<Base>
00354      VecAD<Base>      *vec_;         // pointer to entire vector
00355      mutable AD_Base     x_;         // index for this element
00356 public:
00357      VecAD_reference(VecAD<Base> *v, const AD<Base> &x) 
00358           : vec_( v ) , x_(x)
00359      { }
00360 
00361      // assignment operators
00362      inline void operator = (const VecAD_reference<Base> &right);
00363      void operator = (const AD<Base> &right);
00364      void operator = (const Base     &right);
00365      void operator = (int             right);
00366 
00367      // computed assignments
00368      CPPAD_VEC_AD_COMPUTED_ASSIGNMENT( += , " += " )
00369      CPPAD_VEC_AD_COMPUTED_ASSIGNMENT( -= , " -= " )
00370      CPPAD_VEC_AD_COMPUTED_ASSIGNMENT( *= , " *= " )
00371      CPPAD_VEC_AD_COMPUTED_ASSIGNMENT( /= , " /= " )
00372 
00373 
00374      // AD<Base> constructor
00375      AD<Base> ADBase(void) const
00376      {    AD<Base> result;
00377 
00378           size_t i = static_cast<size_t>( Integer(x_) );
00379           CPPAD_ASSERT_UNKNOWN( i < vec_->length_ );
00380 
00381           // AD<Base> value corresponding to this element
00382           result.value_ = vec_->data_[i];
00383 
00384           // this address will be recorded in tape and must be
00385           // zero for parameters
00386           CPPAD_ASSERT_UNKNOWN( Parameter(result) );
00387           result.taddr_ = 0;
00388 
00389           // index corresponding to this element
00390           if( Variable(*vec_) )
00391           {
00392                ADTape<Base>* tape = AD<Base>::tape_ptr(vec_->tape_id_);
00393                CPPAD_ASSERT_UNKNOWN( tape != CPPAD_NULL );
00394                CPPAD_ASSERT_UNKNOWN( vec_->offset_ > 0  );
00395      
00396                if( IdenticalPar(x_) )
00397                {    CPPAD_ASSERT_UNKNOWN( NumRes(LdpOp) == 1 );
00398                     CPPAD_ASSERT_UNKNOWN( NumArg(LdpOp) == 3 );
00399 
00400                     // put operand addresses in tape
00401                     // (value of third arugment does not matter)
00402                     tape->Rec_.PutArg(
00403                          vec_->offset_, i, 0
00404                     );
00405                     // put operator in the tape, x_ is a parameter
00406                     result.taddr_ = tape->Rec_.PutOp(LdpOp);
00407                     // change result to variable for this load
00408                     result.tape_id_ = tape->id_;
00409                } 
00410                else
00411                {    CPPAD_ASSERT_UNKNOWN( NumRes(LdvOp) == 1 );
00412                     CPPAD_ASSERT_UNKNOWN( NumArg(LdvOp) == 3 );
00413 
00414                     if( Parameter(x_) )
00415                     {    // kludge that should not be needed
00416                          // if x_ instead of i is used for index
00417                          // in the tape
00418                          x_.tape_id_    = vec_->tape_id_;
00419                          x_.taddr_ = tape->RecordParOp(
00420                               x_.value_
00421                          );
00422                     }
00423                     CPPAD_ASSERT_UNKNOWN( Variable(x_) );
00424                     CPPAD_ASSERT_UNKNOWN( x_.taddr_ > 0 );
00425 
00426                     // put operand addresses in tape
00427                     // (value of third arugment does not matter)
00428                     tape->Rec_.PutArg(
00429                          vec_->offset_, x_.taddr_, 0
00430                     );
00431                     // put operator in the tape, x_ is a variable
00432                     result.taddr_ = tape->Rec_.PutOp(LdvOp);
00433                     // change result to variable for this load
00434                     result.tape_id_ = tape->id_;
00435                }
00436           }
00437           return result;
00438      }
00439 };
00440 
00441 // VecAD
00442 template <class Base>
00443 class VecAD {
00444      friend bool  Parameter<Base> (const VecAD<Base> &vec);
00445      friend bool  Variable<Base>  (const VecAD<Base> &vec);
00446      friend class ADTape<Base>;
00447      friend class VecAD_reference<Base>;
00448 
00449      friend std::ostream& operator << <Base>
00450           (std::ostream &os, const VecAD<Base> &vec_);
00451 private:
00452      // size of this VecAD vector
00453      const  size_t   length_; 
00454 
00455      // elements of this vector 
00456      pod_vector<Base> data_; 
00457 
00458      // offset in cummulate vector corresponding to this object
00459      size_t offset_; 
00460 
00461      // tape id corresponding to the offset
00462      tape_id_t tape_id_;
00463 public:
00464      // declare the user's view of this type here
00465      typedef VecAD_reference<Base> reference;
00466 
00467      // default constructor
00468      // initialize tape_id_ same as for default constructor; see default.hpp
00469      VecAD(void) 
00470      : length_(0) 
00471      , offset_(0)
00472      , tape_id_(0)
00473      {    CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); }
00474 
00475      // constructor 
00476      // initialize tape_id_ same as for parameters; see ad_copy.hpp
00477      VecAD(size_t n) 
00478      : length_(n)
00479      , offset_(0)
00480      , tape_id_(0)
00481      {    if( length_ > 0 )
00482           {    size_t i;
00483                Base zero(0);
00484                data_.extend(length_);
00485 
00486                // Initialize data to zero so all have same value.
00487                // This uses less memory and avoids a valgrind error
00488                // during TapeRec<Base>::PutPar 
00489                for(i = 0; i < length_; i++)
00490                     data_[i] = zero;
00491           }
00492           CPPAD_ASSERT_UNKNOWN( Parameter(*this) );
00493      }
00494 
00495      // destructor
00496      ~VecAD(void)
00497      { }
00498 
00499      // size
00500      size_t size(void)
00501      {    return length_; }
00502 
00503      // not taped element access
00504      Base &operator[](size_t i)
00505      {
00506           CPPAD_ASSERT_KNOWN( 
00507                Parameter(*this),
00508                "VecAD: cannot use size_t indexing because this"
00509                " VecAD vector is a variable."
00510           );
00511           CPPAD_ASSERT_KNOWN(
00512                i < length_,
00513                "VecAD: element index is >= vector length"
00514           );
00515 
00516           return data_[i];
00517      }
00518 
00519      // taped elemement access
00520      VecAD_reference<Base> operator[](const AD<Base> &x) 
00521      {
00522           CPPAD_ASSERT_KNOWN(
00523                0 <= Integer(x),
00524                "VecAD: element index is less than zero"
00525           );
00526           CPPAD_ASSERT_KNOWN(
00527                static_cast<size_t>( Integer(x) ) < length_,
00528                "VecAD: element index is >= vector length"
00529           );
00530 
00531           // if no need to track indexing operation, return now
00532           if( Parameter(*this) & Parameter(x) )
00533                return VecAD_reference<Base>(this, x);
00534 
00535           CPPAD_ASSERT_KNOWN( 
00536                Parameter(*this) | Parameter(x) | (tape_id_ == x.tape_id_),
00537                "VecAD: vector and index are variables for"
00538                " different tapes."
00539           );
00540 
00541           if( Parameter(*this) )
00542           {    // must place a copy of vector in tape
00543                offset_ = 
00544                AD<Base>::tape_ptr(x.tape_id_)->AddVec(length_, data_);
00545 
00546                // advance pointer by one so is always > 0
00547                offset_++; 
00548 
00549                // tape id corresponding to this offest
00550                tape_id_ = x.tape_id_;
00551           }
00552 
00553           return VecAD_reference<Base>(this, x); 
00554      }
00555 
00556 };
00557 
00558 
00559 template <class Base>
00560 void VecAD_reference<Base>::operator=(const AD<Base> &y)
00561 {
00562      if( Parameter(y) )
00563      {    // fold into the Base type assignment
00564           *this = y.value_;
00565           return;
00566      }
00567      CPPAD_ASSERT_UNKNOWN( y.taddr_ > 0 );
00568 
00569      CPPAD_ASSERT_KNOWN( 
00570           Parameter(*vec_) | (vec_->tape_id_ == y.tape_id_),
00571           "VecAD assignment: vector and new element value are variables"
00572           "\nfor different tapes."
00573      );
00574 
00575      ADTape<Base>* tape = AD<Base>::tape_ptr(y.tape_id_);
00576      CPPAD_ASSERT_UNKNOWN( tape != CPPAD_NULL );
00577      if( Parameter(*vec_) )
00578      {    // must place a copy of vector in tape
00579           vec_->offset_ = tape->AddVec(vec_->length_, vec_->data_);
00580 
00581           // advance offset to be start of vector plus one
00582           (vec_->offset_)++; 
00583 
00584           // tape id corresponding to this offest
00585           vec_->tape_id_ = y.tape_id_;
00586      }
00587      CPPAD_ASSERT_UNKNOWN( Variable(*vec_) );
00588 
00589 
00590      // index in vector for this element
00591      size_t i = static_cast<size_t>( Integer(x_) );
00592      CPPAD_ASSERT_UNKNOWN( i < vec_->length_ );
00593 
00594      // assign value for this element (as an AD<Base> object) 
00595      vec_->data_[i] = y.value_;
00596 
00597      // record the setting of this array element
00598      CPPAD_ASSERT_UNKNOWN( vec_->offset_ > 0 );
00599      if( Parameter(x_) )
00600      {    CPPAD_ASSERT_UNKNOWN( NumArg(StpvOp) == 3 );
00601           CPPAD_ASSERT_UNKNOWN( NumRes(StpvOp) == 0 );
00602 
00603           // put operand addresses in tape
00604           tape->Rec_.PutArg(vec_->offset_, i, y.taddr_);
00605 
00606           // put operator in the tape, x_ is parameter, y is variable
00607           tape->Rec_.PutOp(StpvOp);
00608      }
00609      else
00610      {    CPPAD_ASSERT_UNKNOWN( NumArg(StvvOp) == 3 );
00611           CPPAD_ASSERT_UNKNOWN( NumRes(StvvOp) == 0 );
00612           CPPAD_ASSERT_UNKNOWN( x_.taddr_ > 0 );
00613 
00614           // put operand addresses in tape
00615           tape->Rec_.PutArg(vec_->offset_, x_.taddr_, y.taddr_);
00616 
00617           // put operator in the tape, x_ is variable, y is variable
00618           tape->Rec_.PutOp(StvvOp);
00619      }
00620 }
00621 
00622 template <class Base>
00623 void VecAD_reference<Base>::operator=(const Base &y)
00624 { 
00625      size_t i = static_cast<size_t>( Integer(x_) );
00626      CPPAD_ASSERT_UNKNOWN( i < vec_->length_ );
00627 
00628      // assign value for this element 
00629      vec_->data_[i] = y;
00630 
00631      // check if this ADVec object is a parameter
00632      if( Parameter(*vec_) )
00633           return;
00634 
00635      ADTape<Base>* tape = AD<Base>::tape_ptr(vec_->tape_id_);
00636      CPPAD_ASSERT_UNKNOWN( tape != CPPAD_NULL );
00637 
00638      // put value of the parameter y in the tape
00639      addr_t p = tape->Rec_.PutPar(y);
00640 
00641      // record the setting of this array element
00642      CPPAD_ASSERT_UNKNOWN( vec_->offset_ > 0 );
00643      if( Parameter(x_) )
00644      {    CPPAD_ASSERT_UNKNOWN( NumArg(StppOp) == 3 );
00645           CPPAD_ASSERT_UNKNOWN( NumRes(StppOp) == 0 );
00646 
00647           // put operand addresses in tape
00648           tape->Rec_.PutArg(vec_->offset_, i, p);
00649 
00650           // put operator in the tape, x_ is parameter, y is parameter
00651           tape->Rec_.PutOp(StppOp);
00652      }
00653      else
00654      {    CPPAD_ASSERT_UNKNOWN( NumArg(StvpOp) == 3 );
00655           CPPAD_ASSERT_UNKNOWN( NumRes(StvpOp) == 0 );
00656           CPPAD_ASSERT_UNKNOWN( x_.taddr_ > 0 );
00657 
00658           // put operand addresses in tape
00659           tape->Rec_.PutArg(vec_->offset_, x_.taddr_, p);
00660 
00661           // put operator in the tape, x_ is variable, y is parameter
00662           tape->Rec_.PutOp(StvpOp);
00663      }
00664 }
00665 
00666 // fold this case into AD<Base> case above
00667 template <class Base>
00668 inline void VecAD_reference<Base>::operator=
00669 (const VecAD_reference<Base> &y)
00670 {    *this = y.ADBase(); }
00671 
00672 // fold this case into Base case above
00673 template <class Base>
00674 inline void VecAD_reference<Base>::operator=(int y)
00675 {    *this = Base(y); }
00676 
00677 template <class Base>
00678 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00679 std::ostream& operator << (std::ostream &os, const VecAD<Base> &v)
00680 {
00681      os << "vecAD( length = " << v.length_ 
00682         << ", offset = "      << v.offset_ << ")";
00683      return os;
00684 }
00685 
00686 
00687 } // END CppAD namespace
00688 
00689 // preprocessor symbols that are local to this file
00690 # undef CPPAD_VEC_AD_COMPUTED_ASSIGNMENT
00691 # undef CPPAD_VEC_AD_TYPEDEF_ADBASE
00692 
00693 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines