AD Vectors that Record Index Operations
Keywords: ad vectors that record index operations Vecad tape reference Vecad<base> syntax purpose alternatives vecad<base>::reference exceptions constructor v n size size_t indexing i b x r example speed memory

| Prev | Next |  |  |  |  |  |

AD Vectors that Record Index Operations
Syntax
`VecAD<Base> v(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 computed 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], z, u, v)
   ` 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 (Sparse ) are less efficient because the dependence of different elements of the vector cannot be separated.

Constructor
v
The syntax `
VecAD<Base> v(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 floor ( x ) in the vector `v` ( 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/local/vec_ad.hpp