finmath-lib stochastic automatic differentiation

Enabling finmath lib to utilize automatic differentiation algorithms (e.g. AAD).

This project implements a stochastic automatic differentiation.

The implementation is fast, memory efficient and thread safe. It handles automatic differentiation of the conditional expectation (American Monte-Carlo), see

The project extends finmath lib by providing an interface RandomVariableDifferentiableInterface for random variables which provide automatic differentiation. The interface extends RandomVariableInterface and hence allows to use auto-diff in all Monte-Carlo contexts (via a replacement of the corresponding parameters / factories).

The project also provides implementations of this interface, e.g. utilizing the backward (a.k.a. adjoint) method via RandomVariableDifferentiableAADFactory. This factory creates a random variable RandomVariableDifferentiableAAD which implements RandomVariableDifferentiableInterface.

All the backward automatic differentiation code is contained in RandomVariableDifferentiableAAD.

The interface RandomVariableInterface is provided by finmath-lib and specifies the arithmetic operations which may be performed on random variables, e.g.,

RandomVariableDifferentiableInterface add(RandomVariableDifferentiableInterface randomVariable);    
RandomVariableDifferentiableInterface mult(RandomVariableDifferentiableInterface randomVariable);
RandomVariableDifferentiableInterface exp();

// ...  

The interface RandomVariableDifferentiableInterface will introduce two additional methods:

Long getID();   
Map<Long, RandomVariableInterface> getGradient();

The method getGradient will return a map providing the first order differentiation of the given random variable (this) with respect to all its input RandomVariableDifferentiableInterfaces (leaf nodes). To get the differentiation with respect to a specific object use

/* Get the gradient of X with respect to all its leaf nodes: /*
Map gradientOfX = X.getGradient();

/* Get the derivative of X with respect to Y: */
RandomVariableInterface derivative = gradientOfX.get(Y.getID());

AAD on Cuda GPUs

It is possible to combine the automatic-differentiation-extensions with the cuda-extensions. See


AbstractRandomVariableFactory randomVariableFactory = new RandomVariableDifferentiableAADFactory();

will create a standard (CPU) random variable with automatic differentiation. Instead, using

AbstractRandomVariableFactory randomVariableFactory = new RandomVariableDifferentiableAADFactory(new RandomVariableCudaFactory());

will create a Cuda GPU random variable with automatic differentiation.


The following sample code calculates valuation, delta, vega and rho for an almost arbitrary product (here an EuropeanOption) using AAD on the Monte-Carlo valuation

RandomVariableDifferentiableAADFactory randomVariableFactory = new RandomVariableDifferentiableAADFactory();

// Generate independent variables (quantities w.r.t. to which we like to differentiate)
RandomVariableDifferentiableInterface initialValue  = randomVariableFactory.createRandomVariable(modelInitialValue);
RandomVariableDifferentiableInterface riskFreeRate  = randomVariableFactory.createRandomVariable(modelRiskFreeRate);
RandomVariableDifferentiableInterface volatility    = randomVariableFactory.createRandomVariable(modelVolatility);

// Create a model
AbstractModel model = new BlackScholesModel(initialValue, riskFreeRate, volatility);

// Create a time discretization
TimeDiscretizationInterface timeDiscretization = new TimeDiscretization(0.0 /* initial */, numberOfTimeSteps, deltaT);

// Create a corresponding MC process
AbstractProcess process = new ProcessEulerScheme(new BrownianMotion(timeDiscretization, 1 /* numberOfFactors */, numberOfPaths, seed));

// Using the process (Euler scheme), create an MC simulation of a Black-Scholes model
AssetModelMonteCarloSimulationInterface monteCarloBlackScholesModel = new MonteCarloAssetModel(model, process);

 * Value a call option (using the product implementation)
EuropeanOption europeanOption = new EuropeanOption(optionMaturity, optionStrike);
RandomVariableInterface value = (RandomVariableDifferentiableInterface) europeanOption.getValue(0.0, monteCarloBlackScholesModel);

 * Calculate sensitivities using AAD
Map<Long, RandomVariableInterface> derivative = ((RandomVariableDifferentiableInterface)value).getGradient();

double valueMonteCarlo = value.getAverage();
double deltaAAD = derivative.get(initialValue.getID()).getAverage();
double rhoAAD = derivative.get(riskFreeRate.getID()).getAverage();
double vegaAAD = derivative.get(volatility.getID()).getAverage();