@(@\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
.
Atomic Function Forward Mode
Base
This syntax and prototype are used by
afun(ax, ay)
; see
Base
.
They are also used by
f.Forward
and
f.new_dynamic
where
f
has prototype
ADFun<Base> f
and
afun
is used during the recording of
f
.
AD<Base>
This syntax and prototype are used by
af.Forward
and
af.new_dynamic
where
af
has prototype
ADFun< AD<Base> , Base > af
and
afun
is used in
af
(see base2ad
).
Implementation
The
taylor_x
,
taylor_y
version of this function
must be defined by the
atomic_user
class.
It can just return
ok == false
(and not compute anything) for values
of
order_up
that are greater than those used by your
forward
mode calculations
(order zero must be implemented).
need_y
One can ignore this argument and compute all the
taylor_y
Taylor coefficient.
Often, this is not necessary and
need_y
is used to specify this.
The value type_y
is used
to determine which coefficients are necessary as follows:
Constant Parameters
If
need_y == size_t(constant_enum)
,
then only the taylor coefficients
for @(@
Y_i (t)
@)@ where
type_y[i] == constant_enum
are necessary.
This is the case during a from_json
operation.
Dynamic Parameters
If
need_y == size_t(dynamic_enum)
,
then only the taylor coefficients
for @(@
Y_i (t)
@)@ where
type_y[i] == dynamic_enum
are necessary.
This is the case during an new_dynamic
operation.
Variables
If
need_y == size_t(variable_enum)
,
If
ad_type_enum(need_y) == variable_enum
,
then only the taylor coefficients
for @(@
Y_i (t)
@)@ where
type_y[i] == variable_enum
are necessary.
This is the case during a f.Forward
operation.
T
All
If
need_y > size_t(variable_enum)
,
then the taylor coefficients for all @(@
Y_i (t)
@)@ are necessary.
This is the case during an
afun(ax, ay)
operation.
order_low
This argument
specifies the lowest order Taylor coefficient that we are computing.
p
We sometimes use the notation
p = order_low
below.
order_up
This argument
specifies the highest order Taylor coefficient that we are computing
(
order_low <= order_up
).
q
We sometimes use the notation
q = order_up
below.
taylor_x
The size of
taylor_x
is
(q+1)*n
.
For @(@
j = 0 , \ldots , n-1
@)@ and @(@
k = 0 , \ldots , q
@)@,
we use the Taylor coefficient notation
@[@
\begin{array}{rcl}
x_j^k & = & \R{taylor\_x} [ j * ( q + 1 ) + k ]
\\
X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q
\end{array}
@]@
Note that superscripts represent an index for @(@
x_j^k
@)@
and an exponent for @(@
t^k
@)@.
Also note that the Taylor coefficients for @(@
X(t)
@)@ correspond
to the derivatives of @(@
X(t)
@)@ at @(@
t = 0
@)@ in the following way:
@[@
x_j^k = \frac{1}{ k ! } X_j^{(k)} (0)
@]@
parameters
If the j-th component of
x
corresponds to a parameter,
type_x[j] < CppAD::variable_enum
In this case,
the j-th component of
parameter_x
is equal to @(@
x_j^0
@)@;
i.e.,
parameter_x[j] == taylor_x[ j * ( q + 1 ) + 0 ]
Furthermore, for
k > 0
,
taylor_x[ j * ( q + 1 ) + k ] == 0
ataylor_x
The specifications for
ataylor_x
is the same as for
taylor_x
(only the type of
ataylor_x
is different).
taylor_y
The size of
taylor_y
is
(q+1)*m
.
Upon return,
For @(@
i = 0 , \ldots , m-1
@)@ and @(@
k = 0 , \ldots , q
@)@,
@[@
\begin{array}{rcl}
Y_i (t) & = & g_i [ X(t) ]
\\
Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q )
\\
\R{taylor\_y} [ i * ( q + 1 ) + k ] & = & y_i^k
\end{array}
@]@
where @(@
o( t^q ) / t^q \rightarrow 0
@)@ as @(@
t \rightarrow 0
@)@.
Note that superscripts represent an index for @(@
y_j^k
@)@
and an exponent for @(@
t^k
@)@.
Also note that the Taylor coefficients for @(@
Y(t)
@)@ correspond
to the derivatives of @(@
Y(t)
@)@ at @(@
t = 0
@)@ in the following way:
@[@
y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0)
@]@
If @(@
p > 0
@)@,
for @(@
i = 0 , \ldots , m-1
@)@ and @(@
k = 0 , \ldots , p-1
@)@,
the input of
taylor_y
satisfies
@[@
\R{taylor\_y} [ i * ( q + 1 ) + k ] = y_i^k
@]@
These values do not need to be recalculated
and can be used during the computation of the higher order coefficients.
ataylor_y
The specifications for
ataylor_y
is the same as for
taylor_y
(only the type of
ataylor_y
is different).
ok
If this calculation succeeded,
ok
is true.
Otherwise, it is false.
Discussion
For example, suppose that
order_up == 2
,
and you know how to compute the function @(@
g(x)
@)@,
its first derivative @(@
g^{(1)} (x)
@)@,
and it component wise Hessian @(@
g_i^{(2)} (x)
@)@.
Then you can compute
taylor_x
using the following formulas:
@[@
\begin{array}{rcl}
y_i^0 & = & Y(0)
= g_i ( x^0 )
\\
y_i^1 & = & Y^{(1)} ( 0 )
= g_i^{(1)} ( x^0 ) X^{(1)} ( 0 )
= g_i^{(1)} ( x^0 ) x^1
\\
y_i^2
& = & \frac{1}{2 !} Y^{(2)} (0)
\\
& = & \frac{1}{2} X^{(1)} (0)^\R{T} g_i^{(2)} ( x^0 ) X^{(1)} ( 0 )
+ \frac{1}{2} g_i^{(1)} ( x^0 ) X^{(2)} ( 0 )
\\
& = & \frac{1}{2} (x^1)^\R{T} g_i^{(2)} ( x^0 ) x^1
+ g_i^{(1)} ( x^0 ) x^2
\end{array}
@]@
For @(@
i = 0 , \ldots , m-1
@)@, and @(@
k = 0 , 1 , 2
@)@,
@[@
\R{taylor\_y} [ i * (q + 1) + k ] = y_i^k
@]@