atomic_three_forward

View page source

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 .

Syntax

ok = afun . forward (
      parameter_x , type_x ,
      need_y , order_low , order_up , type_x , taylor_x , taylor_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_x , type_x ,
      need_y , order_low , order_up , type_x , ataylor_x , ataylor_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 ( 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{eqnarray} 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{eqnarray}

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{eqnarray} 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{eqnarray}

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{eqnarray} 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{eqnarray}

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.