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 .
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<
Basef
and afun is used during the recording of f .

Syntax
ok = afun.forward(
    
parameter_xtype_x,
    
need_yorder_loworder_uptype_xtaylor_xtaylor_y
)


Prototype

template <class Base>
bool atomic_three<Base>::forward(
    const vector<Base>&          parameter_x ,
    const vector<ad_type_enum>&  type_x      ,
    size_t                       need_y      ,
    size_t                       order_low   ,
    size_t                       order_up    ,
    const vector<Base>&          taylor_x    ,
    vector<Base>&                taylor_y    )

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 ).

Syntax
ok = afun.forward(
    
parameter_xtype_x,
    
need_yorder_loworder_uptype_xataylor_xataylor_y
)


Prototype

template <class Base>
bool atomic_three<Base>::forward(
    const vector< AD<Base> >&    aparameter_x ,
    const vector<ad_type_enum>&  type_x       ,
    size_t                       need_y       ,
    size_t                       order_low    ,
    size_t                       order_up     ,
    const vector< AD<Base> >&    ataylor_x    ,
    vector< AD<Base> >&          ataylor_y    )

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).

parameter_x
See parameter_x .

aparameter_x
The specifications for aparameter_x is the same as for parameter_x (only the type of ataylor_x is different).

type_x
See type_x .

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(axay) 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_xj * ( q + 1 ) + 0 ]
Furthermore, for k > 0 ,
    
taylor_xj * ( 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 @]@

Examples
The files atomic_three_forward.cpp and atomic_three_dynamic.cpp contain examples and tests that uses this routine.
Input File: include/cppad/core/atomic/three/forward.hpp