/* $Id: atomic_base.omh 3505 2014-12-26 15:06:54Z bradbell $ */ /* -------------------------------------------------------------------------- CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell CppAD is distributed under multiple licenses. This distribution is under the terms of the Eclipse Public License Version 1.0. 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 cppad hpp afun arg vx vy tx ty px py jac hes CppAD checkpointing algo $$ $section User Defined Atomic AD Functions$$ $index atomic, user function$$ $index user, atomic function$$ $index operation, user atomic$$ $index function, user atomic$$ $head Syntax$$ $codei% %atomic_user% %afun%(%n%, %m%, %use_set%, %user_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/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