ODESystem

Basic Operation of ODESystem

When an ODESystem is triggered, it reads its current time from its trigger link, reads its input, solves its differential equation and computes its output. Let us observe the basic operation of ODESystems with a simple example.

We first construct an ODESystem. Since an ODESystem is represented by its state equation and output equation, we need to define those equations.

julia> using Jusdl # hide

julia> sfunc(dx,x,u,t) = (dx .= -0.5x)
sfunc (generic function with 1 method)

julia> ofunc(x, u, t) = x
ofunc (generic function with 1 method)

Let us construct the system

julia> ds = ODESystem(Bus(1), Bus(1), sfunc, ofunc, [1.], 0.)
ODESystem(state:[1.0], t:0.0, input:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false), output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))

Note that ds is a single input single output ODESystem with an initial state of [1.] and initial time 0.. To drive, i.e. trigger ds, we need to launch it.

julia> task = launch(ds)
(Task (runnable) @0x00007f702959d600, Task (runnable) @0x00007f702959ceb0)

When launced, ds is ready to driven. ds is driven from its trigger link. Note that the trigger link of ds is writable.

julia> ds.trigger
Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:true)

Let us drive ds to the time of t of 1 second.

julia> drive(ds, 1.)
1.0

When driven, ds reads current time of t from its trigger link, reads its input value from its input, solves its differential equation and computes its output values and writes its output. So, for the step to be continued, an input values must be written. Note that the input of ds is writable,

julia> ds.input
1-element Bus{Link{Float64}}:
 Link(state:open, eltype:Float64, hasmaster:false, numslaves:0, isreadable:false, iswritable:true)

Let us write some value.

julia> put!(ds.input, [5.])
1-element Array{Float64,1}:
 5.0

At this point, ds completed its step and put true to its handshake link to signal that its step is succeeded.

julia> ds.handshake
Link(state:open, eltype:Bool, hasmaster:false, numslaves:0, isreadable:true, iswritable:false)

To complete the step and be ready for another step, we need to approve the step by reading its handshake.

julia> take!(ds.handshake)
true

At this point, ds can be driven further.

julia> for t in 2. : 10.
           put!(ds.trigger, t)
           put!(ds.input, [t * 10])
           take!(ds.handshake)
       end

Note that all the output value of ds is written to its outputbus,

julia> ds.output[1].buffer.data
64-element Array{Float64,1}:
 0.60653067653308
 0.36787951505627364
 0.22313028059487142
 0.13533539576281062
 0.08208509196489885
 0.04978714003339768
 0.03019743608348212
 0.018315676429473696
 0.01110902273516018
 0.00673796499594269
 ⋮
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

When we launched ds, we constructed a task and the task is still running.

julia> task
(Task (runnable) @0x00007f702959d600, Task (runnable) @0x00007f702959ceb0)

To terminate the task safely, we need to terminate ds safely.

julia> terminate(ds)

Now, the state of the task is done.

julia> task
(Task (done) @0x00007f702959d600, Task (done) @0x00007f702959ceb0)

So, it is not possible to drive ds.

Mutation in State Function in ODESystem

Consider a system with the following ODE

\[\begin{array}{l} \dot{x} = f(x, u, t) \\ y = g(x, u, t) \\ \end{array}\]

where $x \in R^d, y \in R^m, u \in R^p$. To construct and ODESystem, The signature of the state function statefunc must be of the form

function statefunc(dx, x, u, t)
    dx .= ... # Update dx
end

Note that statefunc does not construct dx but updates dx and does not return anything. This is for performance reasons. On the contrary, the signature of the output function outputfunc must be of the form,

function outputfunc(x, u, t)
    y = ... # Compute y
    return y
end

Note the output value y is computed and returned from outputfunc. y is not updated but generated in the outputfunc.

Full API

Jusdl.Components.Systems.DynamicSystems.ODESystemType
ODESystem(input, output, statefunc, outputfunc, state, t, modelargs=(), solverargs=(); 
    alg=ODEAlg, modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs an ODESystem with input and output. statefunc is the state function and outputfunc is the output function. 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.

ODESystem is represented by the equations.

\[ \begin{array}{l} \dot{x} = f(x, u, t) \\[0.25cm] y = g(x, u, t) \end{array}\]

where $t$ is the time t, $x$ is state, $u$ is the value of input, $y$ is the value of output. $f$ is statefunc and $g$ is outputfunc. solver is used to solve the above differential equation.

The signature of statefunc must be of the form,

function statefunc(dx, x, u, t)
    dx .= ... # Update dx 
end

and the signature of outputfunc must be of the form,

function outputfunc(x, u, t)
    y = ... # Compute y
    return y
end

Example

julia> sfunc(dx,x,u,t) = (dx .= 0.5x)
sfunc (generic function with 1 method)

julia> ofunc(x, u, t) = x
ofunc (generic function with 1 method)

julia> ds = ODESystem(Bus(1), Bus(1), sfunc, ofunc, [1.], 0.)
ODESystem(state:[1.0], t:0.0, input:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false), output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))

julia> ds = ODESystem(Bus(1), Bus(1), sfunc, ofunc, [1.], 0., solverkwargs=(dt=0.1, reltol=1e-6))
ODESystem(state:[1.0], t:0.0, input:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false), output:Bus(nlinks:1, eltype:Link{Float64}, isreadable:false, iswritable:false))
Info

See DifferentialEquations for more information about modelargs, modelkwargs, solverargs, solverkwargs and alg.

source
Jusdl.Components.Systems.DynamicSystems.LinearSystemType
LinearSystem(input, output, modelargs=(), solverargs=(); 
    A=fill(-1, 1, 1), B=fill(0, 1, 1), C=fill(1, 1, 1), D=fill(0, 1, 1), state=rand(size(A,1)), t=0., 
    alg=ODEAlg, modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a LinearSystem with input and output. 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 LinearSystem is represented by the following state and output equations.

\[\begin{array}{l} \dot{x} = A x + B u \\[0.25cm] y = C x + D u \end{array}\]

where $x$ is state. solver is used to solve the above differential equation.

source
Jusdl.Components.Systems.DynamicSystems.LorenzSystemType
LorenzSystem(input, output, modelargs=(), solverargs=(); 
    sigma=10, beta=8/3, rho=28, gamma=1, outputfunc=allstates, state=rand(3), t=0.,
    alg=ODEAlg, cplmat=diagm([1., 1., 1.]), modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a LorenzSystem with input and output. sigma, beta, rho and gamma is the system parameters. 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.

If input is nothing, the state equation of LorenzSystem is

\[\begin{array}{l} \dot{x}_1 = \gamma (\sigma (x_2 - x_1)) \\[0.25cm] \dot{x}_2 = \gamma (x_1 (\rho - x_3) - x_2) \\[0.25cm] \dot{x}_3 = \gamma (x_1 x_2 - \beta x_3) \end{array}\]

where $x$ is state. solver is used to solve the above differential equation. If input is not nothing, then the state eqaution is

\[\begin{array}{l} \dot{x}_1 = \gamma (\sigma (x_2 - x_1)) + \sum_{j = 1}^3 \alpha_{1j} u_j \\[0.25cm] \dot{x}_2 = \gamma (x_1 (\rho - x_3) - x_2) + \sum_{j = 1}^3 \alpha_{2j} u_j \\[0.25cm] \dot{x}_3 = \gamma (x_1 x_2 - \beta x_3) + \sum_{j = 1}^3 \alpha_{3j} u_j \end{array}\]

where $A = [\alpha_{ij}]$ is cplmat and $u = [u_{j}]$ is the value of the input. The output function is

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

where $t$ is time t, $y$ is the value of the output and $g$ is outputfunc.

source
Jusdl.Components.Systems.DynamicSystems.ChenSystemType
ChenSystem(input, output, modelargs=(), solverargs=(); 
    a=35, b=3, c=28, gamma=1, outputfunc=allstates, state=rand(3), t=0.,
    alg=ODEAlg, cplmat=diagm([1., 1., 1.]), modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a ChenSystem with input and output. a, b, c and gamma is the system parameters. 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.

If input is nothing, the state equation of ChenSystem is

\[\begin{array}{l} \dot{x}_1 = \gamma (a (x_2 - x_1)) \\[0.25cm] \dot{x}_2 = \gamma ((c - a) x_1 + c x_2 + x_1 x_3) \\[0.25cm] \dot{x}_3 = \gamma (x_1 x_2 - b x_3) \end{array}\]

where $x$ is state. solver is used to solve the above differential equation. If input is not nothing, then the state eqaution is

\[\begin{array}{l} \dot{x}_1 = \gamma (a (x_2 - x_1)) + \sum_{j = 1}^3 \alpha_{1j} u_j \\[0.25cm] \dot{x}_2 = \gamma ((c - a) x_1 + c x_2 + x_1 x_3) + \sum_{j = 1}^3 \alpha_{2j} u_j \\[0.25cm] \dot{x}_3 = \gamma (x_1 x_2 - b x_3) + \sum_{j = 1}^3 \alpha_{3j} u_j \end{array}\]

where $A = [\alpha_{ij}]$ is cplmat and $u = [u_{j}]$ is the value of the input. The output function is

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

where $t$ is time t, $y$ is the value of the output and $g$ is outputfunc.

source
Jusdl.Components.Systems.DynamicSystems.ChuaSystemType
ChuaSystem(input, output, modelargs=(), solverargs=(); 
    diode=PiecewiseLinearDiode(), alpha=15.6, beta=28., gamma=1., outputfunc=allstates, state=rand(3), t=0., 
    alg=ODEAlg, cplmat=diagm([1., 1., 1.]), modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a ChuaSystem with input and output. diode, alpha, beta and gamma is the system parameters. 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.

If input is nothing, the state equation of ChuaSystem is

\[\begin{array}{l} \dot{x}_1 = \gamma (\alpha (x_2 - x_1 - h(x_1))) \\[0.25cm] \dot{x}_2 = \gamma (x_1 - x_2 + x_3 ) \\[0.25cm] \dot{x}_3 = \gamma (-\beta x_2) \end{array}\]

where $x$ is state. solver is used to solve the above differential equation. If input is not nothing, then the state eqaution is

\[\begin{array}{l} \dot{x}_1 = \gamma (\alpha (x_2 - x_1 - h(x_1))) + \sum_{j = 1}^3 \theta_{1j} u_j \\[0.25cm] \dot{x}_2 = \gamma (x_1 - x_2 + x_3 ) + \sum_{j = 1}^3 \theta_{2j} u_j \\[0.25cm] \dot{x}_3 = \gamma (-\beta x_2) + \sum_{j = 1}^3 \theta_{3j} u_j \end{array}\]

where $\Theta = [\theta_{ij}]$ is cplmat and $u = [u_{j}]$ is the value of the input. The output function is

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

where $t$ is time t, $y$ is the value of the output and $g$ is outputfunc.

source
Jusdl.Components.Systems.DynamicSystems.RosslerSystemType
RosslerSystem(input, output, modelargs=(), solverargs=(); 
    a=0.38, b=0.3, c=4.82, gamma=1., outputfunc=allstates, state=rand(3), t=0., 
    alg=ODEAlg, cplmat=diagm([1., 1., 1.]), modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a RosllerSystem with input and output. a, b, c and gamma is the system parameters. 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.

If input is nothing, the state equation of RosslerSystem is

\[\begin{array}{l} \dot{x}_1 = \gamma (-x_2 - x_3) \\[0.25cm] \dot{x}_2 = \gamma (x_1 + a x_2) \\[0.25cm] \dot{x}_3 = \gamma (b + x_3 (x_1 - c)) \end{array}\]

where $x$ is state. solver is used to solve the above differential equation. If input is not nothing, then the state eqaution is

\[\begin{array}{l} \dot{x}_1 = \gamma (-x_2 - x_3) + \sum_{j = 1}^3 \theta_{1j} u_j \\[0.25cm] \dot{x}_2 = \gamma (x_1 + a x_2 ) + \sum_{j = 1}^3 \theta_{2j} u_j \\[0.25cm] \dot{x}_3 = \gamma (b + x_3 (x_1 - c)) + \sum_{j = 1}^3 \theta_{3j} u_j \end{array}\]

where $\Theta = [\theta_{ij}]$ is cplmat and $u = [u_{j}]$ is the value of the input. The output function is

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

where $t$ is time t, $y$ is the value of the output and $g$ is outputfunc.

source
Jusdl.Components.Systems.DynamicSystems.VanderpolSystemType
VanderpolSystem(input, output, modelargs=(), solverargs=(); 
    mu=5., gamma=1., outputfunc=allstates, state=rand(2), t=0., 
    alg=ODEAlg, cplmat=diagm([1., 1]), modelkwargs=NamedTuple(), solverkwargs=NamedTuple())

Constructs a VanderpolSystem with input and output. mu and gamma is the system parameters. 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.

If input is nothing, the state equation of VanderpolSystem is

\[\begin{array}{l} \dot{x}_1 = \gamma (x_2) \\[0.25cm] \dot{x}_2 = \gamma (\mu (x_1^2 - 1) x_2 - x_1 ) \end{array}\]

where $x$ is state. solver is used to solve the above differential equation. If input is not nothing, then the state eqaution is

\[\begin{array}{l} \dot{x}_1 = \gamma (x_2) + \sum_{j = 1}^3 \theta_{1j} u_j \\[0.25cm] \dot{x}_2 = \gamma (\mu (x_1^2 - 1) x_2 - x_1) + \sum_{j = 1}^3 \theta_{2j} u_j \end{array}\]

where $\Theta = [\theta_{ij}]$ is cplmat and $u = [u_{j}]$ is the value of the input. The output function is

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

where $t$ is time t, $y$ is the value of the output and $g$ is outputfunc.

source