SDESystem
Construction of SDESystems
A SDESystem
is represented by the state function
where $t$ is the time, $x \in R^n$ is the value of state, $u \in R^p$ is the value of the input. $W$ is the Wiener process of the system. The output function is defined by
where $y$ is the value of output at time $t$.
As an example consider a system with the following stochastic differential equation
and the following output equation
The state function statefunc
and the output function outputfunc
is defined as follows.
julia> using Jusdl # hide
julia> f(dx, x, u, t) = (dx[1] = -x[1])
f (generic function with 1 method)
julia> h(dx, x, u, t) = (dx[1] = -x[1])
h (generic function with 1 method)
The state function statefunc
is the tuple of drift and diffusion functions
julia> statefunc = (f, h)
(Main.ex-sde_system_ex.f, Main.ex-sde_system_ex.h)
The output function outputfunc
is defined as,
julia> g(x, u, t) = x
g (generic function with 1 method)
Note that the in drift function f
and diffusion function g
, the vector dx
is mutated while in the output function g
no mutation is done, but the output value is generated instead.
From the definition of drift function f
and the diffusion function g
, it is seen that the system does not have any input, that is, the input of the system is nothing
. Since all the state variables are taken as outputs, the system needs an output bus of length 1. Thus,
julia> input = nothing
julia> output = Bus(1)
1-element Bus{Link{Float64}}:
Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:false)
At this point, we are ready to construct the system ds
.
julia> ds = SDESystem(input, output, statefunc, g, [1.], 0.)
SDESystem(state:[1.0], t:0.0, input:nothing, output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))
Basic Operation of SDESystems
The basic operation of a SDESystem
is the same as those of other dynamical systems. When triggered from its trigger
link, a SDESystem
reads its time t
from its trigger
link, reads its input value from its input
, solves its state equation, which is a stochastic differential equation, computes its output and writes its computed output to its output
bus.
In this section, we continue with the system ds
constructed in the previous section. To make ds
drivable, we need to launch
it.
julia> task = launch(ds)
(Task (runnable) @0x00007f70295c1390, Task (runnable) @0x00007f70295c1120)
When launched, ds
can be driven. For this, either of the syntax put!(ds.trigger, t)
or drive(ds, t)
can be used.
julia> drive(ds, 1.)
1.0
After this command, ds
reads its time t
from its trigger
link, solves its state function and computes its output. The calculated output value is written to the buffer of output
. To signal that, the step is takes with success, ds
writes true
to its handshake
link. To further drive ds
, this handshake
link must be read. For this either of the syntax, take!(ds.handshake)
or approve(ds)
can be used
julia> ds.handshake
Link(state:open, eltype:Bool, hasmaster:false, numslaves:0, isreadable:true, iswritable:false)
julia> take!(ds.handshake)
true
At this point, we can further drive ds
.
julia> for t in 2. : 10.
drive(ds, t)
approve(ds)
end
Note that during the evolution, the output of ds
is written into the buffers of output
bus.
julia> ds.output[1].buffer.data
64-element Array{Float64,1}:
0.0981810568634745
0.005592286116705777
0.00016113025057694087
2.4616485952538222e-5
2.1817134931235956e-6
-1.7544578608241476e-7
-5.7738608243331925e-8
-4.870004324983793e-8
-2.7749120674443662e-8
-1.6879255293621672e-8
⋮
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
The values of the output is written into buffers if the output
of the systems is not nothing
.
When we launched ds
, we constructed a task
whose state is running
which implies that the ds
can be drivable. As long as this task
is running, ds
can be drivable.
The state of the task
is different from running
in case an exception is thwown.
To terminate the task
securely, we need to terminate ds
securely. To do that, can use terminate(ds)
.
julia> terminate(ds)
Note that the task
is terminated without a hassle.
julia> task
(Task (done) @0x00007f70295c1390, Task (done) @0x00007f70295c1120)
Full API
Jusdl.Components.Systems.DynamicSystems.SDESystem
— TypeSDESystem(input, output, statefunc, outputfunc, state, t, modelargs=(), solverargs=();
alg=SDEAlg, modelkwargs=NamedTuple(), solverkwargs=NamedTuple())
Constructs a SDESystem
with input
and output
. statefunc
is the state function and outputfunc
is the output function of SDESystem
. state
is the initial state and t
is the time. modelargs
and modelkwargs
are passed into ODEProblem
and solverargs
and solverkwargs
are passed into solve
method of DifferentialEquations
. alg
is the algorithm to solve the differential equation of the system.
The SDESystem
is represented by the state equation
where $f$ is the drift equation and $h$ is the diffusion equation. The statefunc
is the tuple of drift function $f$ and diffusion function $h$ i.e. statefunc = (f, h)
. $g$ is outputfunc
. $t$ is the time t
, $x$ is the state
, $u$ is the value of input
and $y$ is the value of the output
. $W$ is the Wiever process. noise
is the noise of the system and solver
is used to solve the above differential equation.
The syntax of the drift and diffusion function of statefunc
must be of the form
function f(dx, x, u, t)
dx .= ... # Update dx
end
function h(dx, x, u, t)
dx .= ... # Update dx.
end
and the syntax of outputfunc
must be of the form
function outputfunc(x, u, t)
y = ... # Compute y
return y
end
Example
julia> f(dx, x, u, t) = (dx[1] = -x[1]);
julia> h(dx, x, u, t) = (dx[1] = -x[1]);
julia> g(x, u, t) = x;
julia> ds = SDESystem(nothing, Bus(), (f,h), g, [1.], 0.)
SDESystem(state:[1.0], t:0.0, input:nothing, output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))
See DifferentialEquations for more information about modelargs
, modelkwargs
, solverargs
solverkwargs
and alg
.