/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-22 Bradley M. Bell

CppAD is distributed under the terms of the
             Eclipse Public License Version 2.0.

This Source Code may also be made available under the following
Secondary License when the conditions for such availability set forth
in the Eclipse Public License, Version 2.0 are satisfied:
      GNU General Public License, Version 2.0 or later.
---------------------------------------------------------------------------- */
$begin atomic_four_vector$$
$spell
    op
    enum
    mul
    div
    vec_op
$$

$section Atomic Vector Element-wise Operators: Example and Test$$

$head Syntax$$
$codei%atomic_vector_op %vec_op%(%name%)
%$$
$icode%vec_op%(%op%, %x%, %y%)
%$$

$head op$$
The value $icode op$$ has the following possible values:
$srcfile%
    include/cppad/example/atomic_four/vector/vector.hpp%
    0%// BEGIN op_enum_t%// END op_enum_t%0
%$$

$head Purpose$$
This atomic function class can be used as a general purpose utility.
It is unclear how much benefit there is do doing so.
This is because the number of operations internal to an element-wise
atomic function is not much more than the work required to pass the
arguments to the atomic function.

$subhead Vector Operations$$
This atomic function unary operations
$codei%
    %y% = %op%(u)
%$$
and binary operations
$codei%
    %y% = %u% %op% %v%
%$$
where $icode op$$, $icode u$$ and $icode v$$ are defined below.

$subhead atomic_four$$
This example demonstrates all the callbacks for an
$cref atomic_four$$ function.

$subhead base2ad$$
It include examples for how one can
define $codei%AD<%Base%>%$$ atomic operations using atomic operators.
This avoids expanding the atomic operator to an operator for each element
when recording derivative calculations.
For example, notice the difference between $code forward_add$$
for the $code double$$ and the $code AD<double>$$ cases
(note that copying an AD variable does not create a new variable):
$srcfile%
    include/cppad/example/atomic_four/vector/add_op.hpp%
    0%// BEGIN forward_add%// END forward_add%0
%$$

$head x$$
We use $icode x$$ to denote the argument to the atomic function.
The length of $icode x$$ is denoted by $icode n$$.

$head m$$
This is the length of the vectors in the operations.
In the case of unary (binary) operators
$code%m% = %n%$$  ( $icode%m% = %n% / 2%$$ ).

$head u$$
We use $icode u$$ to denote the following sub-vector of $icode x$$:
$codei%
    %u% = ( %x%[1] , %...% , %x%[%m%] )
%$$

$head v$$
For binary operators,
we use $icode v$$ to denote the following sub-vector of $icode x$$:
$codei%
    %v% = ( %x%[%m% + 1] , %...% , %x%[2 * %m%] )
%$$

$head y$$
We use $icode y$$ to denote the atomic function return value.
The length of $icode y$$ is equal to $icode m$$.

$head AD<double>$$
During $code AD<double>$$ operations, copying variables
from one vector to another does not add any operations to the
resulting tape.


$comment BEGIN_SORT_THIS_LINE_PLUS_3$$
$childtable%
    include/cppad/example/atomic_four/vector/implement.omh
    %example/atomic_four/vector/add.cpp
    %example/atomic_four/vector/div.cpp
    %example/atomic_four/vector/hes_sparsity.cpp
    %example/atomic_four/vector/jac_sparsity.cpp
    %example/atomic_four/vector/mul.cpp
    %example/atomic_four/vector/neg.cpp
    %example/atomic_four/vector/rev_depend.cpp
    %example/atomic_four/vector/sub.cpp
%$$
$comment END_SORT_THIS_LINE_MINUS_2$$

$end
