---------------------------------------- lines 6-146 of file: xrst/mul_level.xrst ---------------------------------------- {xrst_begin mul_level} Using Multiple Levels of AD ########################### Alternative *********** Often it is easier to use :ref:`base2ad-name` and :ref:`dynamic` parameters to accomplish the objective below. Background ********** If *f* is an ``ADFun`` < *Base* > object, the vectors returned by :ref:`f.Forward` , and :ref:`f.Reverse` , have values of type *Base* and not ``AD`` < *Base* > . This reflects the fact that operations used to calculate these function values are not recorded by the tape corresponding to ``AD`` < *Base* > operations. 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 *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: #. The function defining the differential equation could be calculated using the class ``AD< AD >`` . #. The operations during the calculation of Taylor's method could be done using the ``AD`` class. #. Derivatives of the solution of the differential equation could then be calculated using the ``double`` class. Procedure ********* First Start AD ====================== If some of the :ref:`parameters` in the ``AD< AD >`` recording depend on the :ref:`variables` in the ``AD`` recording, we must first declaring these variables; i.e., ``Independent`` ( *a1x* ) where *a1x* is a :ref:`SimpleVector-name` with elements of type ``AD`` . This will start recording a new tape of operations performed using ``AD`` class objects. Start AD< AD > Recording ================================ The next step is to declare the independent variables using ``Independent`` ( *a2x* ) where *a2x* is a :ref:`SimpleVector-name` with elements of type ``AD< AD >`` . This will start recording a new tape of operations performed using ``AD< AD >`` class objects. Inner Function ============== The next step is to calculate the inner function using ``AD< AD >`` class objects. We then stop the recording using *a1f* . ``Dependent`` ( *a2x* , *a2y* ) where *a2y* is a :ref:`SimpleVector-name` with elements of type ``AD< AD >`` and *a1f* is an ``ADFun< AD >`` object. Second Start AD< AD > ============================= If none of the :ref:`parameters` in the ``AD< AD >`` recording depend on the :ref:`variables` in the ``AD`` recording, it is preferred to delay declaring these variables to this point; i.e., ``Independent`` ( *a1x* ) where *a1x* is a :ref:`SimpleVector-name` with elements of type ``AD`` . This will start recording a new tape of operations performed using ``AD`` class objects. Outer Function ============== The next step is to calculate the outer function using ``AD`` class objects. Note that derivatives of the inner function can be included in the calculation of the outer function using *a1f* . We then stop the recording of ``AD`` operations using *g* . ``Dependent`` ( *a1x* , *a1y* ) where *a1y* is a :ref:`SimpleVector-name` with elements of type ``AD`` and *g* is an ``ADFun`` object. Derivatives of Outer Function ============================= The AD function object *g* can then be used to calculate the derivatives of the outer function. {xrst_toc_hidden example/general/mul_level.cpp example/general/change_param.cpp } Example ******* The files :ref:`mul_level.cpp-name` and :ref:`change_param.cpp-name` contain an examples and tests of this procedure. They return true if they succeed and false otherwise. The file :ref:`mul_level_ode.cpp-name` is a more complex example use of multiple tapes. {xrst_end mul_level}