\(\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}} }\)
VecAD¶
View page sourceAD Vectors that Record Index Operations¶
Syntax¶
VecAD
< Base > vec ( n )size
()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¶
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.
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 .
Assignment to
vec
[ind
] returns avoid
. For example, the following syntax is not valid:z = vec [ ind ] = u ;
no matter what the types of z , and u .
A vec [ ind ] object cannot appear in a CondExp ; For example, the following syntax is not valid:
CondExpGt
( vec [ ind ], u , v , w )no matter what the types of u , v , and w .
A vec [ ind ] object should not be used with the
Constant
,Dynamic
,Parameter
, andVariable
functions (see con_dyn_var ). The entire vector vec should be used instead.A
VecAD
vector cannot be passed toIndependent
function.
Constructor¶
vec¶
The syntax
VecAD
< Base > vec ( 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
Base & base
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
rightconst
Base & rightconst AD
< Base >& rightconst VecAD_reverence
< Base >& rightleft¶
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:
In the file
cppad/local/forward1sweep.h
, change the definition ofCPPAD_FORWARD1SWEEP_TRACE
to# define CPPAD_FORWARD1SWEEP_TRACE 1
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
.In the
Example
directory execute the commandsgrep "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.)