# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
# SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
# SPDX-FileContributor: 2003-24 Bradley M. Bell
# ----------------------------------------------------------------------------
{xrst_begin compare_change}

Comparison Changes Between Taping and Zero Order Forward
########################################################

Syntax
******
| *f* . ``compare_change_count`` ( *count* )
| *number* = *f* . ``compare_change_number`` ()
| *op_index* = *f* . ``compare_change_op_index`` ()

See Also
********
:ref:`FunCheck-name`

Purpose
*******
We use :math:`F : \B{R}^n \rightarrow \B{R}^m` to denote the
:ref:`glossary@AD Function` corresponding to *f* ; i.e,
given :math:`x \in \B{R}^n`, :math:`F(x)` is defined by

   *F* ( *x* ) = *f* . ``Forward`` (0, *x* )

see :ref:`forward_zero-name` .
If :math:`x` is such that
all the algorithm :ref:`comparison<Compare-name>` operations
have the same result as when the algorithm was taped,
The function :math:`F(x)` and the algorithm will have the same values.
(This is a sufficient, but not necessary condition).

f
*
In the ``compare_change_number`` and ``compare_change_op_index``
syntax, the object *f* has prototype

   ``const ADFun`` < *Base* > *f*

In the ``compare_change_count``
syntax, the object *f* has prototype

   ``ADFun`` < *Base* > *f*

count
*****
The argument *count* has prototype

   *size_t* ``count``

It specifies which comparison change should correspond to the
information stored in *f* during subsequent calls to
:ref:`forward_zero-name` ; i.e.,

   *f* . ``Forward`` (0, *x* )

For example, if *count*  == 1 ,
the operator index corresponding to the first comparison change
will be stored.
This is the default value used if *count* is not specified.

Speed
=====
The special case where *count* == 0 , should be faster because
the comparisons are not checked during

   *f* . ``Forward`` (0, *x* )

number
******
The return value *number* has prototype

   ``size_t`` *number*

If *count* is non-zero,
*number* is the number of
``AD`` < *Base* > :ref:`comparison<Compare-name>` operations,
corresponding to the previous call to

   *f* . ``Forward`` (0, *x* )

that have a different result for this value of *x*
than the value used when *f* was created by taping an algorithm.
If *count* is zero,
or if no calls to *f* . ``Forward`` (0, *x* ) follow the previous
setting of *count* ,
*number* is zero.

Discussion
==========
If *count* and *number* are non-zero,
you may want to re-tape the algorithm with the
:ref:`independent variables<glossary@Tape@Independent Variable>`
equal to the values in *x* ,
so the AD operation sequence properly represents the algorithm
for this value of independent variables.
On the other hand, re-taping the AD operation sequence usually takes
significantly more time than evaluation using :ref:`forward_zero-name` .
If the functions values have not changed (see :ref:`FunCheck-name` )
it may not be worth re-taping a new AD operation sequence.

op_index
********
The return value *op_index* has prototype

   ``size_t`` *op_index*

If *count* is non-zero,
*op_index* is the operator index corresponding the
*count* -th comparison change during the previous call to

   *f* . ``Forward`` (0, *x* )

If *count* is greater than the corresponding
*number* , there is no such comparison change and *op_index*
will also be zero.
If *count* is zero,
if the function *f* has been :ref:`optimized<optimize-name>` ,
or if no calls to *f* . ``Forward`` (0, *x* ) follow the previous
setting of *count* ,
*op_index* is zero.

Purpose
=======
The operator index can be used to generate an error during the taping
process so that the corresponding algorithm can be inspected.
In some cases, it is possible to re-design this part of the
algorithm to avoid the particular comparison operation.
For example, using an :ref:`conditional expression<CondExp-name>`
may be appropriate in some cases.
See :ref:`Independent@abort_op_index` in the syntax

   ``Independent`` ( *x* , *abort_op_index* )

{xrst_toc_hidden
   example/compare_change/compare_change.cpp
}
Example
*******
:ref:`compare_change.cpp-name`
contains an example and test of this operation.

{xrst_end compare_change}
