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}} }@)@
Atomic Forward Mode

Syntax
ok = afun.forward(pqvxvytxty)

Purpose
This virtual function is used by atomic_afun to evaluate function values. It is also used buy forward to compute function vales and derivatives.

Implementation
This virtual function must be defined by the atomic_user class. It can just return ok == false (and not compute anything) for values of q > 0 that are greater than those used by your forward mode calculations.

p
The argument p has prototype
     size_t 
p
It specifies the lowest order Taylor coefficient that we are evaluating. During calls to atomic_afun , p == 0 .

q
The argument q has prototype
     size_t 
q
It specifies the highest order Taylor coefficient that we are evaluating. During calls to atomic_afun , q == 0 .

vx
The forward argument vx has prototype
     const CppAD::vector<bool>& 
vx
The case vx.size() > 0 only occurs while evaluating a call to atomic_afun . In this case, p == q == 0 , vx.size() == n , and for @(@ j = 0 , \ldots , n-1 @)@, vx[j] is true if and only if ax[j] is a variable in the corresponding call to
     
afun(axay)
If vx.size() == 0 , then vy.size() == 0 and neither of these vectors should be used.

vy
The forward argument vy has prototype
     CppAD::vector<bool>& 
vy
If vy.size() == 0 , it should not be used. Otherwise, q == 0 and vy.size() == m . The input values of the elements of vy are not specified (must not matter). Upon return, for @(@ j = 0 , \ldots , m-1 @)@, vy[i] is true if and only if ay[i] is a variable (CppAD uses vy to reduce the necessary computations).

tx
The argument tx has prototype
     const CppAD::vector<
Base>& tx
and tx.size() == (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 & = & tx [ 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) @]@

ty
The argument ty has prototype
     CppAD::vector<
Base>& ty
and tx.size() == (q+1)*m . Upon return, For @(@ i = 0 , \ldots , m-1 @)@ and @(@ k = 0 , \ldots , q @)@, @[@ \begin{array}{rcl} Y_i (t) & = & f_i [ X(t) ] \\ Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q ) \\ ty [ 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 ty satisfies @[@ ty [ i * ( q + 1 ) + k ] = y_i^k @]@ and hence the corresponding elements need not be recalculated.

ok
If the required results are calculated, ok should be true. Otherwise, it should be false.

Discussion
For example, suppose that q == 2 , and you know how to compute the function @(@ f(x) @)@, its first derivative @(@ f^{(1)} (x) @)@, and it component wise Hessian @(@ f_i^{(2)} (x) @)@. Then you can compute ty using the following formulas: @[@ \begin{array}{rcl} y_i^0 & = & Y(0) = f_i ( x^0 ) \\ y_i^1 & = & Y^{(1)} ( 0 ) = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 ) = f_i^{(1)} ( x^0 ) x^1 \\ y_i^2 & = & \frac{1}{2 !} Y^{(2)} (0) \\ & = & \frac{1}{2} X^{(1)} (0)^\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 ) + \frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 ) \\ & = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1 + f_i^{(1)} ( x^0 ) x^2 \end{array} @]@ For @(@ i = 0 , \ldots , m-1 @)@, and @(@ k = 0 , 1 , 2 @)@, @[@ ty [ i * (q + 1) + k ] = y_i^k @]@

Examples
The file atomic_forward.cpp contains an example and test that uses this routine. It returns true if the test passes and false if it fails.
Input File: cppad/core/atomic_base.hpp