$Id: mul_level.omh 3735 2015-10-01 13:43:46Z 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 mul_level$$
$spell
	Taylor
	fout
	const
	var
	Cpp
	Arg
$$


$section Using Multiple Levels of AD$$


$head Background$$
If $icode f$$ is an $codei%ADFun<%Base%>%$$ object,
the vectors returned by
$cref/f.Forward/Forward/$$,
and
$cref/f.Reverse/Reverse/$$,
have values of type $icode Base$$ and not
$codei%AD<%Base%>%$$.
This reflects the fact that operations used to calculate
these function values are not recorded by the tape corresponding to
$codei%AD<%Base%>%$$ operations.

$head Motivation$$
Suppose that you use derivatives of one or more inner functions
as part of the operations
needed to compute an outer function.
For example,
the derivatives returned by $icode%f%.Forward%$$
might be used as part of
Taylor's method for solving ordinary
differential equations.
In addition, we might want to differentiate the
solution of a differential equation with respect to parameters
in the equation.
This can be accomplished in the following way:

$list number$$
The function defining the
differential equation could be calculated using the class
$codei AD< AD<double> >$$.

$lnext
The operations during the calculation of Taylor's method
could be done using the $codei AD<double>$$ class.

$lnext
Derivatives of the solution of the differential equation
could then be calculated using the $code double$$ class.

$lend

$head Procedure$$

$subhead First Start AD<double>$$
If some of the $cref/parameters/glossary/Parameter/$$
in the $codei AD< AD<double> >$$ recording depend on the
$cref/variables/glossary/Variable/$$
in the $codei AD<double>$$ recording,
we must first declaring these variables; i.e.,
$codei%
	Independent(%a1x%)
%$$
where $icode a1x$$ is
a $cref SimpleVector$$ with elements of type $codei AD<double>$$.
This will start recording a new tape of
operations performed using $codei AD<double>$$ class objects.

$subhead Start AD< AD<double> > Recording$$
The next step is to declare the independent variables using
$codei%
	Independent(%a2x%)
%$$
where $icode a2x$$ is
a $cref SimpleVector$$ with elements of type
$codei AD< AD<double> >$$.
This will start recording a new tape of
operations performed using $codei AD< AD<double> >$$ class objects.

$subhead Inner Function$$
The next step is to calculation the inner function
using $codei AD< AD<double> >$$ class objects.
We then stop the recording using
$codei%
	%a1f%.Dependent(%a2x%, %a2y%)
%$$
where $icode a2y$$ is
a $cref SimpleVector$$ with elements of type
$codei AD< AD<double> >$$
and $icode a1f$$ is an $codei%ADFun< AD<double> >%$$ object.

$subhead Second Start AD< AD<double> >$$
If none of the $cref/parameters/glossary/Parameter/$$
in the $codei AD< AD<double> >$$ recording depend on the
$cref/variables/glossary/Variable/$$
in the $codei AD<double>$$ recording,
it is preferred to delay declaring these variables to this point; i.e.,
$codei%
	Independent(%a1x%)
%$$
where $icode a1x$$ is
a $cref SimpleVector$$ with elements of type $codei AD<double>$$.
This will start recording a new tape of
operations performed using $codei AD<double>$$ class objects.

$subhead Outer Function$$
The next step is to calculation the outer function
using $codei AD<double>$$ class objects.
Note that derivatives of the inner function can be included
in the calculation of the outer function using $icode a1f$$.
We then stop the recording of $codei AD<double>$$ operations using
$codei%
	%g%.Dependent(%a1x%, %a1y%)
%$$
where $icode a1y$$ is
a $cref SimpleVector$$ with elements of type
$codei AD<double>$$
and $icode g$$ is an $codei%ADFun<double>%$$ object.

$subhead Derivatives of Outer Function$$
The AD function object $icode g$$ can then be used to calculate
the derivatives of the outer function.

$children%
	example/mul_level.cpp%
	example/change_param.cpp
%$$

$head Example$$
The files
$cref mul_level.cpp$$ and $cref change_param.cpp$$
contain an examples and tests of this procedure.
They return true if they succeed and false otherwise.
The file $cref mul_level_ode.cpp$$ is a more complex example
use of multiple tapes.

$end
