$Id: mul_level.omh 3688 2015-05-27 00:09:43Z 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 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 mul_level$$ $spell zdouble 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 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 function defining the differential equation could be calculated using the class $codei AD< AD >$$; see $cref zdouble$$. $lnext The operations during the calculation of Taylor's method could be done using the $codei AD$$ class. $lnext Derivatives of the solution of the differential equation could then be calculated using the $cref zdouble$$ class. $lend $head Procedure$$ $subhead Double Record AD< AD >$$ If some of the $cref/parameters/glossary/Parameter/$$ in the $codei AD< AD >$$ recording depend on the $cref/variables/glossary/Variable/$$ in the $codei AD$$ 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$$. This will start recording a new tape of operations performed using $codei AD$$ class objects. $subhead Start AD< AD > 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 >$$. This will start recording a new tape of operations performed using $codei AD< AD >$$ class objects. $subhead Inner Function$$ The next step is to calculation the inner function using $codei AD< AD >$$ 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 >$$ and $icode a1f$$ is an $codei%ADFun< AD >%$$ object. $subhead Single Record AD< AD >$$ If none of the $cref/parameters/glossary/Parameter/$$ in the $codei AD< AD >$$ recording depend on the $cref/variables/glossary/Variable/$$ in the $codei AD$$ 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$$. This will start recording a new tape of operations performed using $codei AD$$ class objects. $subhead Outer Function$$ The next step is to calculation the outer function using $codei AD$$ 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$$ operations using $codei% %g%.Dependent(%a1x%, %a1y%) %$$ where $icode a1y$$ is a $cref SimpleVector$$ with elements of type $codei AD$$ and $icode g$$ is an $codei%ADFun%$$ 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