SDESystem

Construction of SDESystems

A SDESystem is represented by the state function

\[ dx = f(x, u, t) dt + h(x, u, t)dW \]

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

\[ y = g(x, u, t)\]

where $y$ is the value of output at time $t$.

As an example consider a system with the following stochastic differential equation

\[ \begin{array}{l} dx = -x dt - x dW \end{array}\]

and the following output equation

\[y = x\]

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 = Outport(1)
1-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)

At this point, we are ready to construct the system ds.

julia> ds = SDESystem(righthandside=statefunc, readout=g, state=[1.], input=input, output=output)
ERROR: UndefKeywordError: keyword argument drift not assigned

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> iport, trg, hnd = Inport(1), Outpin(), Inpin{Bool}()
(Inport(numpins:1, eltype:Inpin{Float64}), Outpin(eltype:Float64, isbound:false), Inpin(eltype:Bool, isbound:false))

julia> connect!(ds.output, iport)
ERROR: UndefVarError: ds not defined

julia> connect!(trg, ds.trigger)
ERROR: UndefVarError: ds not defined

julia> connect!(ds.handshake, hnd)
ERROR: UndefVarError: ds not defined

julia> task = launch(ds)
ERROR: UndefVarError: ds not defined

julia> task2 = @async while true
           all(take!(iport) .=== NaN) && break
           end
Task (failed) @0x00007fe233d7e710
UndefRefError: access to undefined reference
getproperty at ./Base.jl:33 [inlined]
take! at /home/sari/.julia/dev/Jusdl/src/connections/pin.jl:97 [inlined]
_broadcast_getindex_evalf at ./broadcast.jl:631 [inlined]
_broadcast_getindex at ./broadcast.jl:604 [inlined]
getindex at ./broadcast.jl:564 [inlined]
macro expansion at ./broadcast.jl:910 [inlined]
macro expansion at ./simdloop.jl:77 [inlined]
copyto! at ./broadcast.jl:909 [inlined]
copyto! at ./broadcast.jl:864 [inlined]
copy at ./broadcast.jl:840 [inlined]
materialize at ./broadcast.jl:820 [inlined]
take!(::Inport{Inpin{Float64}}) at /home/sari/.julia/dev/Jusdl/src/connections/port.jl:178
macro expansion at ./none:2 [inlined]
(::Main.ex-sde_system_ex.var"#1#2")() at ./task.jl:358

When launched, ds can be driven. For this, either of the syntax put!(ds.trigger, t) or drive(ds, t) can be used.

julia> put!(trg, 1.)

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> hnd.link
ERROR: UndefRefError: access to undefined reference

julia> take!(hnd)
ERROR: UndefRefError: access to undefined reference

At this point, we can further drive ds.

julia> for t in 2. : 10.
           put!(trg, t)
           take!(hnd)
       end
ERROR: UndefRefError: access to undefined reference

Note that during the evolution, the output of ds is written into the buffers of output bus.

julia> iport[1].link.buffer
ERROR: UndefRefError: access to undefined reference
Warning

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.

Warning

The state of the task is different from running in case an exception is thrown.

To terminate the task securely, we need to terminate ds securely. To do that, can use terminate!(ds).

julia> put!(trg, NaN)

julia> put!(ds.output, [NaN])
ERROR: UndefVarError: ds not defined

Note that the task is terminated without a hassle.

julia> task
ERROR: UndefVarError: task not defined

julia> task2
Task (failed) @0x00007fe233d7e710
UndefRefError: access to undefined reference
getproperty at ./Base.jl:33 [inlined]
take! at /home/sari/.julia/dev/Jusdl/src/connections/pin.jl:97 [inlined]
_broadcast_getindex_evalf at ./broadcast.jl:631 [inlined]
_broadcast_getindex at ./broadcast.jl:604 [inlined]
getindex at ./broadcast.jl:564 [inlined]
macro expansion at ./broadcast.jl:910 [inlined]
macro expansion at ./simdloop.jl:77 [inlined]
copyto! at ./broadcast.jl:909 [inlined]
copyto! at ./broadcast.jl:864 [inlined]
copy at ./broadcast.jl:840 [inlined]
materialize at ./broadcast.jl:820 [inlined]
take!(::Inport{Inpin{Float64}}) at /home/sari/.julia/dev/Jusdl/src/connections/port.jl:178
macro expansion at ./none:2 [inlined]
(::Main.ex-sde_system_ex.var"#1#2")() at ./task.jl:358

Full API

Jusdl.SDESystemType
SDESystem(; drift, diffusion, readout, state, input, output)

Constructs a SDE system.

source