/* $Id: atomic_base.omh 3717 2015-08-31 22:16:15Z bradbell $ */
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell

CppAD is distributed under multiple licenses. This distribution is under
the terms of the
                    GNU General Public License Version 3.

A copy of this license is included in the COPYING file of this distribution.
Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
-------------------------------------------------------------------------- */
$begin atomic_base$$
$spell
	ctor
	cppad
	hpp
	afun
	arg
	vx
	vy
	tx
	ty
	px
	py
	jac
	hes
	CppAD
	checkpointing
	algo
$$

$section User Defined Atomic AD Functions$$


$head Syntax$$

$codei%
%atomic_user% %afun%(%ctor_arg_list%)
%afun%(%ax%, %ay%)
%ok% = %afun%.forward(%p%, %q%, %vx%, %vy%, %tx%, %ty%)
%ok% = %afun%.reverse(%q%, %tx%, %ty%, %px%, %py%)
%ok% = %afun%.for_sparse_jac(%q%, %r%, %s%)
%ok% = %afun%.rev_sparse_jac(%q%, %r%, %s%)
%ok% = %afun%.rev_sparse_hes(%vx%, %s%, %t%, %q%, %r%, %u%, %v%)
atomic_base<%Base%>::clear()%$$

$head Purpose$$
In some cases, the user knows how to compute derivatives of a function
$latex \[
	y = f(x) \; {\rm where} \; f : B^n \rightarrow B^m
\] $$
more efficiently than by coding it using $codei%AD<%Base%>%$$
$cref/atomic/glossary/Operation/Atomic/$$ operations
and letting CppAD do the rest.
In this case $codei%atomic_base%<%Base%>%$$ can use
the user code for $latex f(x)$$, and its derivatives,
as $codei%AD<%Base%>%$$ atomic operations.

$head Virtual Functions$$
User defined derivatives are implemented by defining the
following virtual functions in the $icode base_atomic$$ class:
$cref/forward/atomic_forward/$$,
$cref/reverse/atomic_reverse/$$,
$cref/for_sparse_jac/atomic_for_sparse_jac/$$,
$cref/rev_sparse_jac/atomic_rev_sparse_jac/$$, and
$cref/rev_sparse_hes/atomic_rev_sparse_hes/$$.
These virtual functions have a default implementation
that returns $icode%ok% == false%$$.
The $code forward$$ function,
for the case $icode%q% == 0%$$, must be implemented.
Otherwise, only those functions
required by the your calculations need to be implemented.
For example,
$icode forward$$ for the case $icode%q% == 2%$$ can just return
$icode%ok% == false%$$ unless you require
forward mode calculation of second derivatives.

$childtable%
	cppad/local/atomic_base.hpp%
	example/atomic/get_started.cpp%
	example/atomic/norm_sq.cpp%
	example/atomic/reciprocal.cpp%
	example/atomic/sparsity.cpp%
	example/atomic/tangent.cpp%
	example/atomic/hes_sparse.cpp%
	example/atomic/mat_mul.cpp
%$$

$head Examples$$

$subhead Getting Started$$
The file $cref atomic_get_started.cpp$$ contains an example and test
that shows the minimal amount of information required to create
a user defined atomic operation.

$subhead Scalar Function$$
The file $cref atomic_reciprocal.cpp$$ contains an example and test
where the user provides the code for computing derivatives.
This example is simple because the domain and range are scalars.

$subhead Vector Range$$
The file $cref atomic_tangent.cpp$$ contains another example
where the user provides the code for computing derivatives.
This example is more complex because the range has two components.

$subhead Hessian Sparsity Patterns$$
The file $cref atomic_hes_sparse.cpp$$ contains an minimal example
where the user provides the code for computing Hessian sparsity patterns.

$head General Case$$
The file $cref atomic_mat_mul.cpp$$ contains a more general example
where the user provides the code for computing derivatives.
This example is more complex because both the domain and range
dimensions are arbitrary.

$end
