$Id: mul_level.omh 2780 2013-04-20 03:07:14Z bradbell $
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 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
$$
$index multiple, AD level$$
$index AD, multiple level$$
$index level, multiple AD$$
$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 in the base 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 uses 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 operations during the calculations of the function defining the
differential equation could be preformed using the a class of the form
$codei% AD< AD<double> >%$$.
$lnext
The operations during the calculation of Taylor's method
could be preformed using the $codei% AD<double>%$$ class.
$lnext
The results of the solution of the differential equation
could then be preformed using the $code double$$ class.
$lend
$head General Solution$$
Provided that we are currently recording
$codei% AD<double>%$$ operations,
and $icode fin$$ is an $codei%ADFun< AD<double> >%$$ object,
the operations used to compute the vectors
returned by
$icode%fin%.Forward%$$,
$icode%fin%.Rev%$$,
and
$icode%fin%.RevTwo%$$,
will be recorded on the tape corresponding to
$codei%AD<double>%$$ operations.
$head General Procedure$$
$subhead Start ADBaseTape$$
The first step is to declare the independent variables using
$codei%
Independent(%x%)
%$$
where $icode x$$ 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 ADDBaseTape$$
The next step is to declare the independent variables using
$codei%
Independent(%X%)
%$$
where $icode X$$ 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 Calculations$$
The next step is to calculation
the inner functions
using $codei%AD< AD<double> >%$$ class objects.
$subhead Derivative of Inner Function$$
The next step is to create the
$codei%ADFun< AD<double> >%$$ function object $icode fin$$.
This will also stop recording of
operations performed using $codei%AD< AD<double> >%$$ class objects.
The $icode fin$$ object can then be used to calculate
the derivatives needed to compute the outer function.
$subhead Outer Function$$
The next step is to compute the
outer function
using $codei%AD<double>%$$ class objects.
$subhead Derivative of Outer Function$$
The next step is to create the
$codei%ADFun<double>%$$ function object $icode fout$$.
This will also stop the recording of
operations performed using $codei%AD<double>%$$ class objects.
The $icode fout$$ object can then be used to calculate
the derivatives of the outer function.
$children%
example/mul_level.cpp%
example/change_const.cpp
%$$
$head Example$$
The files
$cref mul_level.cpp$$ and $cref change_const.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