mul_level

View page source

Using Multiple Levels of AD

Alternative

Often it is easier to use base2ad and dynamic parameters to accomplish the objective below.

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 calculate 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 calculate 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.