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}} }@)@This is cppad-20221105 documentation. Here is a link to its current documentation .
AD Vectors that Record Index Operations

Syntax
VecAD<Basevec(n)
vec.size()
base       = vec[i]
abase      = vec[ind]
vec[ind]   = right
left       = vec[ind]

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

Alternatives
If only the values in vec , and not the indices ind , depend on the independent variables, a SimpleVector with elements of type AD<Base> would be more efficient than using VecAD<Base> . If only the indices, and not the values in the vector, depend on the independent variables, a Discrete functions would be a much more efficient.

Efficiency
If one uses VecAD vector where one could use a simple vector, the sparsity_pattern will be less efficient because the dependence on different elements cannot be separated. In addition, VecAD objects that only depend on dynamic parameters are treated as if they were variables making sparsity patterns even less efficient (have more possibly non-zero values than necessary); see VecAD vectors under dynamic parameters in the wish list.

VecAD<Base>::reference
The expression vec[ind] has prototype
    VecAD<
Base>::reference vec[ind]
which is like the AD<Base> type with some notable exceptions:

Exceptions
  1. This object cannot be used with the Value function to compute the corresponding Base value. In some cases, the syntax
        
    vec[i]
    can be used to obtain the corresponding Base value; see below.
  2. This object cannot be used as the left hand side in a with a compound assignment ; i.e., +=, -=, *=, or /=. For example, the following syntax is not valid:
        
    vec[ind] += z;
    no matter what the types of z .
  3. Assignment to vec[ind] returns a void. For example, the following syntax is not valid:
        
    z = vec[ind] = u;
    no matter what the types of z , and u .
  4. A vec[ind] object cannot appear in a CondExp ; For example, the following syntax is not valid:
        CondExpGt(
    vec[ind], uvw)
    no matter what the types of u , v , and w .
  5. A vec[ind] object should not be used with the Constant, Dynamic, Parameter, and Variable functions (see con_dyn_var ). The entire vector vec should be used instead.
  6. A VecAD vector cannot be passed to Independent function.


Constructor

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

n
The argument n has prototype
    size_t 
n

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

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

i
The operand i has prototype
    size_t 
i
and must be less than n ; i.e., less than the number of elements in vec .

base
The result base has prototype
    
Basebase
i.e., it is a reference to the i-th element in the vector vec . It can be used to change the element value; for example,
    
vec[i] = b
is valid where b is a Base object. The reference base is no longer valid once the vec changes in any way; i.e., has another assignment.

AD Indexing
We refer to the syntax
    
vec[ind]
as AD indexing of a VecAD object.

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

result
The resulting expression has prototype
    VecAD<
Base>::reference vec[ind]
This objects operations are recorded as part of the AD<Base> operation sequence . It acts like a reference to the element with index floor(ind) in the vector vec ; ( floor(ind) is the greatest integer less than or equal ind ).

right
Is the right hand side of the assignment statement and specifies the new value for the corresponding element of vec . It has one of the following prototypes:
    int   
                       right
    const 
Base&                  right
    const AD<
Base>&              right
    const VecAD_reverence<
Base>& right

left
Is the left hand side of the assignment statement is the current value for the corresponding element of vec . It has the following prototype:
    const AD<
Base>& left

Example
The file vec_ad.cpp contains an example and test using VecAD vectors.

base2ad
Forward mode on a base2ad function does not preserve VecAD operations (which might be expected); see the base2vec_ad.cpp example.

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: include/cppad/core/vec_ad/user.omh