Python
The following example for first-order adjoint mode illustrates how to use it:
import xad.adj_1st as xadj
# set independent variables
x0_ad = xadj.Real(1.0)
x1_ad = xadj.Real(1.5)
x2_ad = xadj.Real(1.3)
x3_ad = xadj.Real(1.2)
with xadj.Tape() as tape:
# and register them
tape.registerInput(x0_ad)
tape.registerInput(x1_ad)
tape.registerInput(x2_ad)
tape.registerInput(x3_ad)
# start recording derivatives
tape.newRecording()
# calculate the output
y = x0_ad + x1_ad - x2_ad * x3_ad
# register and seed adjoint of output
tape.registerOutput(y)
y.derivative = 1.0
# compute all other adjoints
tape.computeAdjoints()
# output results
print(f"y = {y}")
print(f"first order derivatives:\n")
print(f"dy/dx0 = {x0_ad.derivative}")
print(f"dy/dx1 = {x1_ad.derivative}")
print(f"dy/dx2 = {x2_ad.derivative}")
print(f"dy/dx3 = {x3_ad.derivative}")
The Python bindings follow largely the same syntax and workflow as in C++.
Modules and Naming
Module | Description | Contents |
---|---|---|
xad | The main module, which contain global functions and subpackages | value , derivative |
xad.exceptions | Contains all exceptions, with the same names as described in Exceptions | e.g. NoTapeException |
xad.math | Mirrors Python's math module, with functions for XAD's active types. | e.g. sin , exp |
xad.fwd_1st | Active type for first-order forward mode | Real |
xad.adj_1st | Active type for first-order adjoint mode as well as the corresponding tape type | Real , Tape |
Notes
- First order forward mode (module
xad.fwd_1st
) and first order adjoint mode are supported (modulexad.adj_1st
) - The active type is called
Real
in all modes - In adjoint mode, a newly constructed
Tape
object is not automatically activated on construction. It can be activated usingtape.activate()
later, but we recommend using awith
block as illustrated in the example above. - The math functions in
xad.math
have been designed as a drop-in replacement for the standard Pythonmath
module. They not only support calls with XAD's active type, but also with regularfloat
variables. - Checkpointing and external function features are not yet supported in Python.
- The
x.getDerivative()
andx.setDerivative()
methods of active types are also available as the Python propertyx.derivative
with both set and get functionality. - The
x.getValue()
method of active types is also available as the read-only propertyx.value
- Use
y.setDerivative(1.0)
or the property settery.derivative = 1.0
to seed and access derivatives. - Complex numbers are not yet supported in the Python bindings.