lines 8-199 of file: include/cppad/core/atomic/three/atomic.hpp

{xrst_begin atomic_three_define}

Defining Atomic Functions: Third Generation
###########################################

Syntax
******

Define Class
============

| ``class`` *atomic_user* : ``public CppAD::atomic_three<`` *Base* > {
| |tab| ...
| };

Construct Atomic Function
=========================
*atomic_user* *afun* ( *ctor_arg_list* )

Use Atomic Function
===================
*afun* ( *ax* , *ay* )

Class Member Callbacks
======================

| *ok* = *afun* . ``for_type`` (
| |tab| *parameter_x* , *type_x* , *type_y*
| )
| *ok* = *afun* . ``forward`` (
| |tab| *parameter_x* , *type_x* ,
| |tab| *need_y* , *order_low* , *order_up* , *taylor_x* , *taylor_y*
| )
| *ok* = *afun* . ``reverse`` (
| |tab| *parameter_x* , *type_x* ,
| |tab| *order_up* , *taylor_x* , *taylor_y* , *partial_x* , *partial_y*
| )
| *ok* = *afun* . ``jac_sparsity`` (
| |tab| *parameter_x* , *type_x* , *dependency* , *select_x* *select_y* , *pattern_out*
| )
| *ok* = *afun* . ``hes_sparsity`` (
| |tab| *parameter_x* , *type_x* , *select_x* *select_y* , *pattern_out*
| )
| *ok* = *afun* . ``rev_depend`` (
| |tab| *parameter_x* , *type_x* , *depend_x* , *depend_y*
| )

See Also
********
:ref:`chkpoint_two-name` , :ref:`atomic_two-name`

Purpose
*******

Speed
=====
In some cases, it is possible to compute derivatives of a function

.. math::

   y = g(x) \; {\rm where} \; g : \B{R}^n \rightarrow \B{R}^m

more efficiently than by coding it using ``AD`` < *Base* >
:ref:`glossary@Operation@Atomic` operations
and letting CppAD do the rest.
The class ``atomic_three`` < ``Base`` > is used to
create a new atomic operation corresponding to a function :math:`g(x)`
where the user specifies how to compute the derivatives
and sparsity patterns for :math:`g(x)`.

Reduce Memory
=============
If the function :math:`g(x)` is used many times during the recording
of an :ref:`ADFun-name` object,
using an atomic version of :math:`g(x)` removes the need for repeated
copies of the corresponding ``AD`` < *Base* > operations and variables
in the recording.

ad_type
*******
The type ``CppAD::ad_type_enum``
is used to specify if an AD object is a
:ref:`constant parameter<glossary@Parameter@Constant>`
:ref:`dynamic parameter<glossary@Parameter@Dynamic>`
or :ref:`glossary@Variable` .
It has the following possible values:

.. csv-table::
   :widths: auto

   *ad_type_enum*,Meaning
   ``constant_enum``,constant parameter
   ``dynamic_enum``,dynamic parameter
   ``variable_enum``,variable

In addition,
``constant_enum < dynamic_enum < variable_enum`` .

Virtual Functions
*****************
The
:ref:`callback functions<atomic_three_define@Syntax@Class Member Callbacks>`
are implemented by defining the virtual functions in the
*atomic_user* class.
These functions compute derivatives,
sparsity patterns, and dependency relations.
Each virtual function has a default implementation
that returns *ok* == ``false`` .
The :ref:`for_type<atomic_three_for_type-name>`
and :ref:`forward<atomic_three_forward-name>` function
(for the case *order_up*  == 0 ) must be implemented.
Otherwise, only those functions and orders
required by the your calculations need to be implemented.
For example,
*forward* for the case *order_up*  == 2 can just return
*ok* == ``false`` unless you require
forward mode calculation of second derivatives.

Base
****
This is the base type of the elements of
:ref:`atomic_three_afun@ax` and :ref:`atomic_three_afun@ay`
in the corresponding *afun* ( *ax* , *ay* ) call; i.e.,
the elements of *ax* and *ay* have type
``AD`` < *Base* > .

parameter_x
***********
All the virtual functions include this argument which has prototype

   ``const CppAD::vector<`` *Base* > *parameter_x*

Its size is equal to *n* = *ax* . ``size`` ()
in corresponding *afun* ( *ax* , *ay* ) call.

Constant
========
For *j* =0,..., *n* ``-1`` ,
if *ax* [ *j* ] is a :ref:`con_dyn_var@Constant` parameter,

   *parameter_x* [ *j* ] == *ax* [ *j* ]

Dynamic
=======
If *ax* [ *j* ] is a :ref:`con_dyn_var@Dynamic` parameter,
*parameter_x* [ *j* ] value of *ax* [ *j* ] corresponding to the
previous call to :ref:`new_dynamic-name` for the corresponding function object.

Variable
========
If *ax* [ *j* ] is a variable,
the value of *parameter_x* [ *j* ] is not specified.
See the
:ref:`atomic_three_mat_mul.hpp<atomic_three_mat_mul.hpp@Purpose@parameter_x>`
for an example using *parameter_x* .

type_x
******
All the virtual functions include this argument.
Its size is equal to *n* = *ax* . ``size`` ()
in corresponding *afun* ( *ax* , *ay* ) call.
For *j* =0,..., *n* ``-1`` ,
if *ax* [ *j* ] is a constant parameter,

   *type_x* [ *j* ] == ``CppAD::constant_enum``

if *ax* [ *j* ] is a dynamic parameter,

   *type_x* [ *j* ] == ``CppAD::dynamic_enum``

if *ax* [ *j* ] is a variable,

   *type_x* [ *j* ] == ``CppAD::variable_enum``

See the
:ref:`atomic_three_mat_mul.hpp<atomic_three_mat_mul.hpp@Purpose@type_x>`
for an example using *type_x* .

Contents
********
{xrst_toc_table
   include/cppad/core/atomic/three/ctor.hpp
   include/cppad/core/atomic/three/afun.hpp
   include/cppad/core/atomic/three/for_type.hpp
   include/cppad/core/atomic/three/forward.hpp
   include/cppad/core/atomic/three/reverse.hpp
   include/cppad/core/atomic/three/jac_sparsity.hpp
   include/cppad/core/atomic/three/hes_sparsity.hpp
   include/cppad/core/atomic/three/rev_depend.hpp
}

{xrst_end atomic_three_define}
