Module: svIntegratorWeakStochasticRungeKutta
-
template<size_t numberStages>
struct SRKCoefficients - #include <svIntegratorWeakStochasticRungeKutta.h>
Stores the coefficients necessary to use the Stochastic Runge-Kutta method.
The Butcher table looks like:
c0 | A0 | B0 | c1 | A1 | B1 | B2 -—|——————— | alpha | beta0 | beta1
See more in the description of svIntegratorWeakStochasticRungeKutta.
Public Types
-
using StageSizedArray = std::array<double, numberStages>
Array with size = numberStages
-
using StageSizedMatrix = std::array<StageSizedArray, numberStages>
Square matrix with size = numberStages
Public Members
-
StageSizedArray alpha = {}
“alpha” coefficient array of the SRK method
-
StageSizedArray beta0 = {}
“beta0” coefficient array of the SRK method
-
StageSizedArray beta1 = {}
“beta1” coefficient array of the SRK method
-
StageSizedMatrix A0 = {}
“A0” coefficient matrix of the SRK method
-
StageSizedMatrix B0 = {}
“B0” coefficient matrix of the SRK method
-
StageSizedMatrix A1 = {}
“A1” coefficient matrix of the SRK method
-
StageSizedMatrix B1 = {}
“B1” coefficient matrix of the SRK method
-
StageSizedMatrix B2 = {}
“B2” coefficient matrix of the SRK method
-
StageSizedArray c0 = {}
“c0” coefficient array of the SRK method
c0 is the row sum of the A(0) matrix:
\[ c_0 = \sum_j a^{(0)}_{ij} \]
-
StageSizedArray c1 = {}
“c1” coefficient array of the SRK method
c1 is the row sum of the A(1) matrix:
\[ c_1 = \sum_j a^{(1)}_{ij} \]
-
using StageSizedArray = std::array<double, numberStages>
-
struct SRKRandomVariables
- #include <svIntegratorWeakStochasticRungeKutta.h>
Random variables used in the Weak Stochastic Integrator
-
class SRKRandomVariableGenerator
- #include <svIntegratorWeakStochasticRungeKutta.h>
Random Generator for the integrator described in:
Tang, X., Xiao, A. Efficient weak second-order stochastic Runge–Kutta methods for Itô stochastic differential equations. Bit Numer Math 57, 241–260 (2017). https://doi.org/10.1007/s10543-016-0618-9
Public Functions
-
inline void setSeed(size_t seed)
Sets the seed to the RNG
-
inline SRKRandomVariables generate(size_t m, double h)
Generates the random values necessary for one step of the integrator.
- Parameters:
m – number of noise sources
h – time step, in seconds
-
inline void setSeed(size_t seed)
-
template<size_t numberStages>
class svIntegratorWeakStochasticRungeKutta : public StateVecStochasticIntegrator - #include <svIntegratorWeakStochasticRungeKutta.h>
The svIntegratorWeakStochasticRungeKutta class implements a state integrator that provides weak solutions to problems with stochastic dynamics (SDEs).
The method is described in:
Tang, X., Xiao, A. Efficient weak second-order stochastic Runge–Kutta methods for Itô stochastic differential equations. Bit Numer Math 57, 241–260 (2017). https://doi.org/10.1007/s10543-016-0618-9
The method described in said paper is designed for autonomous systems (where f and g do not depend on time), so we need to modify it for non-autonomous systems. This is simple: we just need to treat the time as a state (with f=1 and g=0).
The resulting pseudocode for the (explicit) method is (note that the order of the sums and some elements has moved around to reflect the code):
--- (3.1*) stage definitions --- for i = 1..s: // drift‐stage H0[i] = y_n + h * sum_{j=1..i-1}( a0[i][j] * f( t_n + c0[j]*h, H0[j] ) ) + sum_{k=1..m}( Ihat[k] * sum_{j=1..i-1}( b0[i][j] * g[k]( t_n + c1[j]*h, Hk[j] ) ) ) // diffusion‐stages, one per noise source k for k = 1..m: Hk[i] = y_n + h * sum_{j=1..i-1}( a1[i][j] * f( t_n + c0[j]*h, H0[j] ) ) + xi * sum_{j=1..i-1}( b1[i][j] * g[k]( t_n + c1[j]*h, Hk[j] ) ) + sum_{l=1..m, l!=k}( Ihat_kl[k][l] * sum_{j=1..i-1}( b2[i][j] * g[l]( t_n + c1[i]*h, Hl[i] ) ) ); where c0[j] = sum_{p=1..s}( a0[j][p] ) c1[j] = sum_{p=1..s}( a1[j][p] ) --- (3.2) driving‐variable distributions --- For each k: P( Ihat[k] = +sqrt(3*h) ) = 1/6 P( Ihat[k] = -sqrt(3*h) ) = 1/6 P( Ihat[k] = 0 ) = 2/3 xi = eta1 * sqrt(h) // eta1 is {+1,−1} with equal prob. --- (3.3) mixed‐integral approximations --- for each pair (k,l): if k < l: Ihat_kl[k][l] = 0.5 * ( Ihat[l] - eta2 * Ihat[l] ) else if k > l: Ihat_kl[k][l] = 0.5 * ( Ihat[l] + eta2 * Ihat[l] ) else // k == l: Ihat_kl[k][k] = 0.5 * ( Ihat[k]*Ihat[k] * xi - xi ) --- (3.1*) state evolution --- y_n+1 = y_n + h * sum_{i=1..s}( alpha[i] * f( t_n + c0[i]*h, H0[i] ) ) + sum_{k=1..m}( Ihat[k] * sum_{i=1..s}( beta0[i] * g[k]( t_n + c1[i]*h, Hk[i] ) ) ) + sum_{k=1..m}( Ihat_kl[k][k] * sum_{i=1..s}( beta1[i] * g[k]( t_n + c1[i]*h, Hk[i] ) ) )Public Functions
-
svIntegratorWeakStochasticRungeKutta(DynamicObject *dynIn, const SRKCoefficients<numberStages> &coefficients)
Creates an explicit RK integrator for the given DynamicObject using the passed coefficients.
-
inline void setRNGSeed(size_t seed)
Sets the seed for the Random Number Generator used by this integrator.
As a stochastic integrator, random numbers are drawn during each time step. By default, a randomly generated seed is used each time.
If the seed is set, the integrator will always draw the same numbers during time-stepping.
-
virtual void integrate(double currentTime, double timeStep) override
Performs the integration of the associated dynamic objects up to time currentTime+timeStep
Public Members
-
SRKRandomVariableGenerator rvGenerator
Random Number Generator for the integrator
Protected Functions
-
svIntegratorWeakStochasticRungeKutta(DynamicObject *dynIn, std::unique_ptr<SRKCoefficients<numberStages>> &&coefficients)
Can be used by subclasses to support passing coefficients that are subclasses of SRKCoefficients
-
ExtendedStateVector computeDerivatives(double time, double timeStep)
Computes the derivatives of every state given a time and current states.
Internally, this sets the states on the dynamic objects and calls the equationsOfMotion methods.
-
std::vector<ExtendedStateVector> computeDiffusions(double time, double timeStep, const std::vector<StateIdToIndexMap> &stateIdToNoiseIndexMaps)
Computes the diffusions of every state given a time and current states.
Internally, this sets the states on the dynamic objects and calls the equationsOfMotionDiffusion methods.
-
ExtendedStateVector computeDiffusions(double time, double timeStep, const StateIdToIndexMap &stateIdToNoiseIndexMap)
Computes the diffusions for the states and noise index in
stateIdToNoiseIndexMapgiven a time and current states.Internally, this sets the states on the dynamic objects and calls the equationsOfMotionDiffusion methods.
-
inline ExtendedStateVector scaledSum(const std::array<double, numberStages> &factors, const std::array<ExtendedStateVector, numberStages> &vectors, size_t length)
Utility function, computes:
\[\text{result} = \sum_{i=0}^{\text{length}-1} \text{factors}[i] \cdot \text{vectors}[i] \]
Protected Attributes
-
const std::unique_ptr<SRKCoefficients<numberStages>> coefficients
Coefficients to be used in the method
-
svIntegratorWeakStochasticRungeKutta(DynamicObject *dynIn, const SRKCoefficients<numberStages> &coefficients)