Prev Next

@(@\newcommand{\W}[1]{ \; #1 \; } \newcommand{\R}[1]{ {\rm #1} } \newcommand{\B}[1]{ {\bf #1} } \newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} } \newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} } \newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} } \newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }@)@
AD Vectors that Record Index Operations

Syntax
VecAD<Basev(n)
v.size()
b = v[i]
r = v[x]

Purpose
If either v or x is a variable , the indexing operation
     
r = v[x]
is recorded in the corresponding AD of Base operation sequence and transferred to the corresponding ADFun object f . Such an index can change each time zero order f.Forward is used; i.e., f is evaluated with new value for the independent variables . Note that the value of y depends on the value of x in a discrete fashion and CppAD computes its partial derivative with respect to x as zero.

Alternatives
If only the values in the vector, and not the indices, depend on the independent variables, the class Vector< AD<Base> > is much more efficient for storing AD values where Vector is any SimpleVector template class, If only the indices, and not the values in the vector, depend on the independent variables, The Discrete functions are a much more efficient way to represent these vectors.

VecAD<Base>::reference
The result r has type
     VecAD<
Base>::reference
which is very much like the AD<Base> type with some notable exceptions:

Exceptions
  1. The object r cannot be used with the Value function to compute the corresponding Base value. If v and i are not variables
         
    b = v[i]
    can be used to compute the corresponding Base value.
  2. The object r cannot be used with the compound assignments operators +=, -=, *=, or /=. For example, the following syntax is not valid:
         
    v[x] += z;
    no matter what the types of z .
  3. Assignment to r returns a void. For example, the following syntax is not valid:
         
    z = v[x] = u;
    no matter what the types of z , and u .
  4. The CondExp functions do not accept VecAD<Base>::reference arguments. For example, the following syntax is not valid:
         CondExpGt(
    v[x], zuv)
    no matter what the types of z , u , and v .
  5. The Parameter and Variable functions cannot be used with VecAD<Base>::reference arguments like r , use the entire VecAD<Base> vector instead; i.e. v .
  6. The vectors passed to Independent must have elements of type AD<Base> ; i.e., VecAD vectors cannot be passed to Independent.
  7. If one uses this type in a AD of Base operation sequence , sparsity pattern calculations (sparsity_pattern ) are less efficient because the dependence of different elements of the vector cannot be separated.


Constructor

v
The syntax
     VecAD<
Basev(n)
creates an VecAD object v with n elements. The initial value of the elements of v is unspecified.

n
The argument n has prototype
     size_t 
n

size
The syntax
     
v.size()
returns the number of elements in the vector v ; i.e., the value of n when it was constructed.

size_t Indexing
We refer to the syntax
     
b = v[i]
as size_t indexing of a VecAD object. This indexing is only valid if the vector v is a parameter ; i.e., it does not depend on the independent variables.

i
The operand i has prototype
     size_t 
i
It must be greater than or equal zero and less than n ; i.e., less than the number of elements in v .

b
The result b has prototype
     
Base b
and is a reference to the i-th element in the vector v . It can be used to change the element value; for example,
     
v[i] = c
is valid where c is a Base object. The reference b is no longer valid once the destructor for v is called; for example, when v falls out of scope.

AD Indexing
We refer to the syntax
     
r = v[x]
as AD indexing of a VecAD object.

x
The argument x has prototype
     const AD<
Base> &x
The value of x must be greater than or equal zero and less than n ; i.e., less than the number of elements in v .

r
The result r has prototype
     VecAD<
Base>::reference r
The object r has an AD type and its operations are recorded as part of the same AD of Base operation sequence as for AD<Base> objects. It acts as a reference to the element with index @(@ {\rm floor} (x) @)@ in the vector v (@(@ {\rm floor} (x) @)@ is the greatest integer less than or equal x ). Because it is a reference, it can be used to change the element value; for example,
     
v[x] = z
is valid where z is an VecAD<Base>::reference object. As a reference, r is no longer valid once the destructor for v is called; for example, when v falls out of scope.

Example
The file vec_ad.cpp contains an example and test using VecAD vectors. It returns true if it succeeds and false otherwise.

Speed and Memory
The VecAD vector type is inefficient because every time an element of a vector is accessed, a new CppAD variable is created on the tape using either the Ldp or Ldv operation (unless all of the elements of the vector are parameters ). The effect of this can be seen by executing the following steps:
  1. In the file cppad/local/forward1sweep.h, change the definition of CPPAD_FORWARD1SWEEP_TRACE to
     
         # define CPPAD_FORWARD1SWEEP_TRACE 1
    
  2. In the Example directory, execute the command
     
         ./test_one.sh lu_vec_ad_ok.cpp lu_vec_ad.cpp -DNDEBUG > lu_vec_ad_ok.log
    
    This will write a trace of all the forward tape operations, for the test case lu_vec_ad_ok.cpp , to the file lu_vec_ad_ok.log.
  3. In the Example directory execute the commands
     
         grep "op="           lu_vec_ad_ok.log | wc -l
         grep "op=Ld[vp]"     lu_vec_ad_ok.log | wc -l
         grep "op=St[vp][vp]" lu_vec_ad_ok.log | wc -l
    
    The first command counts the number of operators in the tracing, the second counts the number of VecAD load operations, and the third counts the number of VecAD store operations. (For CppAD version 05-11-20 these counts were 956, 348, and 118 respectively.)

Input File: cppad/core/vec_ad.hpp