Prev Next Index-> contents reference index search external Up-> CppAD AD ADValued atomic atomic_base atomic_reverse ADValued-> Arithmetic unary_standard_math binary_math CondExp Discrete numeric_limits atomic atomic-> checkpoint atomic_base atomic_base-> atomic_ctor atomic_option atomic_afun atomic_forward atomic_reverse atomic_for_sparse_jac atomic_rev_sparse_jac atomic_for_sparse_hes atomic_rev_sparse_hes atomic_base_clear atomic_get_started.cpp atomic_norm_sq.cpp atomic_reciprocal.cpp atomic_set_sparsity.cpp atomic_tangent.cpp atomic_eigen_mat_mul.cpp atomic_eigen_mat_inv.cpp atomic_eigen_cholesky.cpp atomic_mat_mul.cpp atomic_reverse-> atomic_reverse.cpp Headings-> Syntax Purpose Implementation q tx ty F G, H py ---..px ok Examples

$\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 Reverse Mode

Syntax
ok = afun.reverse(q, tx, ty, px, py)

Purpose
This function is used by reverse to compute derivatives.

Implementation
If you are using reverse mode, 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 that are greater than those used by your reverse mode calculations.

q
The argument q has prototype       size_t q  It specifies the highest order Taylor coefficient that computing the derivative of.

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       const CppAD::vector<Base>& ty  and tx.size() == (q+1)*m . For $i = 0 , \ldots , m-1$ and $k = 0 , \ldots , q$, we use the Taylor coefficient notation $$\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 ) \\ y_i^k & = & ty [ i * ( q + 1 ) + 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)$$

F
We use the notation $\{ x_j^k \} \in B^{n \times (q+1)}$ for $$\{ x_j^k \W{:} j = 0 , \ldots , n-1, k = 0 , \ldots , q \}$$ We use the notation $\{ y_i^k \} \in B^{m \times (q+1)}$ for $$\{ y_i^k \W{:} i = 0 , \ldots , m-1, k = 0 , \ldots , q \}$$ We define the function $F : B^{n \times (q+1)} \rightarrow B^{m \times (q+1)}$ by $$y_i^k = F_i^k [ \{ x_j^k \} ]$$ Note that $$F_i^0 ( \{ x_j^k \} ) = f_i ( X(0) ) = f_i ( x^0 )$$ We also note that $F_i^\ell ( \{ x_j^k \} )$ is a function of $x^0 , \ldots , x^\ell$ and is determined by the derivatives of $f_i (x)$ up to order $\ell$.

G, H
We use $G : B^{m \times (q+1)} \rightarrow B$ to denote an arbitrary scalar valued function of $\{ y_i^k \}$. We use $H : B^{n \times (q+1)} \rightarrow B$ defined by $$H ( \{ x_j^k \} ) = G[ F( \{ x_j^k \} ) ]$$

py
The argument py has prototype       const CppAD::vector<Base>& py  and py.size() == m * (q+1) . For $i = 0 , \ldots , m-1$, $k = 0 , \ldots , q$, $$py[ i * (q + 1 ) + k ] = \partial G / \partial y_i^k$$

px
The px has prototype       CppAD::vector<Base>& px  and px.size() == n * (q+1) . The input values of the elements of px are not specified (must not matter). Upon return, for $j = 0 , \ldots , n-1$ and $\ell = 0 , \ldots , q$, $$\begin{array}{rcl} px [ j * (q + 1) + \ell ] & = & \partial H / \partial x_j^\ell \\ & = & ( \partial G / \partial \{ y_i^k \} ) \cdot ( \partial \{ y_i^k \} / \partial x_j^\ell ) \\ & = & \sum_{k=0}^q \sum_{i=0}^{m-1} ( \partial G / \partial y_i^k ) ( \partial y_i^k / \partial x_j^\ell ) \\ & = & \sum_{k=\ell}^q \sum_{i=0}^{m-1} py[ i * (q + 1 ) + k ] ( \partial F_i^k / \partial x_j^\ell ) \end{array}$$ Note that we have used the fact that for $k < \ell$, $\partial F_i^k / \partial x_j^\ell = 0$.

ok
The return value ok has prototype       bool ok  If it is true, the corresponding evaluation succeeded, otherwise it failed.

Examples
The file atomic_reverse.cpp contains an example and test that uses this routine. It returns true if the test passes and false if it fails.