Definition of a diffusion process
To define a diffusion model suitable for inference with BridgeSDEInference.jl
one must define two processes:
- the
target
diffusion - and the
auxiliary
diffusion
Imports
The diffusion definitions will extend some of the functionality of the existing functions from Bridge.jl
, so the following imports are necessary:
using Bridge
import Bridge: b, σ, B, β, a, constdiff
Definition of the target process
The target process needs to be a struct inheriting from ContinuousTimeProcess{ℝ{d,T}}
(where d
is a dimension of the diffusion) with the first type parameter {T}
defining the data-type of the parameters. The members of the struct must define the diffusion process and are usually limited to a list of parameters. An example of a valid definition of a 10
dimensional diffusion with two parameters $\alpha$ and $\beta$ would be
struct TargetDiffusion{T} <: ContinuousTimeProcess{ℝ{10,T}}
α::T
β::T
TargetDiffusion(α::T, β::T) where T = new{T}(α, β)
end
Then, one must specify the dynamics of the diffusion by specifying the behaviour of the drift and volatility functions b
and σ
(defined in Bridge.jl
) for TargetDiffusion
:
b(t, x, P::TargetDiffusion) = foo(t, x, P.α, P.β)
σ(t, x, P::TargetDiffusion) = bar(t, x, P.α, P.β)
where foo
and bar
are some user-defined functions. Finally, three auxiliary functions must be defined:
constdiff(::TargetDiffusion) = false
indicating whether σ(t, x, P::TargetDiffusion)
is independent from the values of x
and t
,
clone(P::TargetDiffusion, θ) = TargetDiffusion(θ...)
which returns a new copy of the process with new set of parameters, and finally
params(P::TargetDiffusion) = [P.α, P.β]
which returns an array with all parameter values. Optionally, functions nonhypo
, hypo_a_inv
, num_non_hypo
and phi
can be defined to make it possible to perform conjugate updates of the parameters (see ... for more details on conjugate updates [TODO add])
Definition of the auxiliary process
The auxiliary diffusion, similarly, needs to be a struct inheriting from ContinuousTimeProcess{ℝ{d,T}}
with the first type parameter {T}
defining the data-type of the parameters. It is often necessary for the auxiliary diffusion to have to have access to the information regarding the starting and ending time of the interval on which it is defined. Additionally, the starting and end-point of the target process are also sometimes used (if available). An example of a definition of the auxiliary diffusion is:
struct AuxiliaryDiffusion{R,S1,S2}
α::R
β::R
t::Float64 # starting time of the interval
u::S1 # starting position of the target process
T::Float64 # end-time of the interval
v::S2 # final position of the target process
AuxiliaryDiffusion(α::R, β::R, t, u::S1, T, v::S2) = new{R,S1,S2}(α, β, t, u, T, v)
end
It is now necessary to specify the dynamics of the process. Unlike in the case of the Target
, specifying the volatility coefficient is not necessary and it is sufficient to only provide a diffusion coefficient (a:=σσ'
). The package supports only linear diffusions as auxiliary processes and thus function b
should be defined as:
b(t, x, P::AuxiliaryDiffusion) = B(t, P) * x + β(t, P)
where B
and β
need to be overwritten as follows:
B(t, P::AuxiliaryDiffusion) = foo2(t, P)
β(t, P::AuxiliaryDiffusion) = foo3(t, P)
where the user-defined functions foo2
and foo3
should return a d
by d
matrix and a length-d
vector respectively. One needs to define the diffusion coefficient
a(t, P::AuxiliaryDiffusion) = bar2(t, P)
As previously, the clone
constructor, params
and also a convenience function returning the names of the paramters:
clone(P::AuxiliaryDiffusion, θ) = AuxiliaryDiffusion(θ..., P.t, P.u, P.T, P.v)
params(P::AuxiliaryDiffusion) = (P.α, P.β)
param_names(P::AuxiliaryDiffusion) = (:α, :β)