Using Multiple Levels of AD
Keywords: using multiple levels ad background motivation procedure first start ad<double> ad< > recording inner function second outer derivatives example

| Prev | Next |  |  |  |  |  |  |

Using Multiple Levels of AD
Background
If `f` is an `ADFun<Base>` object, the vectors returned by f.Forward , and 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:

1. The function defining the differential equation could be calculated using the class `AD< AD<double> >` .
2. The operations during the calculation of Taylor's method could be done using the `AD<double>` class.
3. Derivatives of the solution of the differential equation could then be calculated using the `double` class.

Procedure
First Start AD<double>
If some of the parameters in the `AD< AD<double> >` recording depend on the variables in the `AD<double>` recording, we must first declaring these variables; i.e., `
Independent(a1x)
` where `a1x` is a SimpleVector with elements of type `AD<double>` . This will start recording a new tape of operations performed using `AD<double>` class objects.
Start AD< AD<double> > Recording
The next step is to declare the independent variables using `
Independent(a2x)
` where `a2x` is a SimpleVector with elements of type `AD< AD<double> >` . This will start recording a new tape of operations performed using `AD< AD<double> >` class objects.
Inner Function
The next step is to calculation the inner function using `AD< AD<double> >` class objects. We then stop the recording using `
a1f.Dependent(a2x, a2y)
` where `a2y` is a SimpleVector with elements of type `AD< AD<double> >` and `a1f` is an `ADFun< AD<double> >` object.
Second Start AD< AD<double> >
If none of the parameters in the `AD< AD<double> >` recording depend on the variables in the `AD<double>` recording, it is preferred to delay declaring these variables to this point; i.e., `
Independent(a1x)
` where `a1x` is a SimpleVector with elements of type `AD<double>` . This will start recording a new tape of operations performed using `AD<double>` class objects.
Outer Function
The next step is to calculation the outer function using `AD<double>` 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<double>` operations using `
g.Dependent(a1x, a1y)
` where `a1y` is a SimpleVector with elements of type `AD<double>` and `g` is an `ADFun<double>` object.
Derivatives of Outer Function
The AD function object `g` can then be used to calculate the derivatives of the outer function.
Example
The files mul_level.cpp and change_param.cpp contain an examples and tests of this procedure. They return true if they succeed and false otherwise. The file mul_level_ode.cpp is a more complex example use of multiple tapes.

Input File: omh/mul_level.omh