# StaticSystems

## Basic Operation of StaticSystems

A static system is a system whose output y at time t depends on the current time t and the value of its input u. The input-output relation of a static systems is represented by its output function outputfunc which is of the form

$$$y = g(u, t)$$$

where g is the output function outputfunc. Note that outputfunc is expected to have two inputs, the value u of the input and the current time t. The simulation in Causal is a clocked-simulation, that is the data flowing through the input and output connections of components is actually sampled at time t. Therefore, for example, the system modeled by

$$$y(t) = g(u(t),t)$$$

is actually sampled at clock ticks t which is generated by a Clock. Therefore the sampled system corresponds to

$$$y[k] = g(u_k, t_k)$$$

where $k$ is $k_i T_s$ where $k_i$ is an integer number, $T_s$ is the sampling interval. $T_s$ corresponds to sampling time dt of Clock. Thus, the system given above is coded like

function g(u, t)
# Define the relation y = g(u, t)
end

For further clarity, let us continue with a case study. Consider the following static system,

$$$y(t) = g(u(t), t) = \left[ \begin{array}{l} t u_1(t) \\ sin(u_1(t)) \\ cos(u_2(t)) \end{array} \right]$$$

Note that the number of inputs is 2 and the number of outputs of is 3. To define such a system, the output function is written as

julia> g(u, t) = [t * u[1], sin(u[1]), cos(u[2])]
g (generic function with 1 method)

Note that the function g is defined in such a way that the input value u is sampled, which implies u is not a vector of function but is a vector of real. Having defined output function outputfunc, the system can be constructed.

julia> ss = StaticSystem(readout=g, input=Inport(2), output=Outport(3))

Note the construction of input bus Inport(2) and output bus Outport(3) by recalling that the number of input is 2 and the number of output is 3.

A StaticSystem evolves by being triggered through its trigger pin. When triggered from its trigger pin, a StaticSystem reads the current time t from its trigger pin and computes its output y according to its output function outputfunc and writes its output y(t) to its output port (if output port exists since output port may be nothing depending on the relation defined by outputfunc). When constructed, a StaticSystem is not ready to be triggered since its trigger pin is not writeable. To make ss drivable, we need to construct the ports and pins for input-output and signaling.

julia> oport, iport, trg, hnd = Outport(length(ss.input)), Inport(length(ss.output)), Outpin(), Inpin{Bool}()
(Outport(numpins:2, eltype:Outpin{Float64}), Inport(numpins:3, eltype:Inpin{Float64}), Outpin(eltype:Float64, isbound:false), Inpin(eltype:Bool, isbound:false))

julia> connect!(oport, ss.input)

julia> connect!(ss.output, iport)

julia> connect!(trg, ss.trigger)

julia> connect!(ss.handshake, hnd)

julia> taskout = @async while true
all(take!(iport) .=== NaN) && break
end

Now, ss is drivable from its trg pin.

Now let us drive ss.

julia> put!(trg, 1.)

As this point ss wait for its to be written. Let us write some data to oport.

julia> put!(oport, [10., 10.])
2-element Vector{Float64}:
10.0
10.0

ss read the value u of its input(since ss.input is connected to oport), read the current time t, and computed its output value y and wrote it its output port. To signal that it succeeded to be take the step, it put a true to its handshake which needs to be taken.

julia> take!(hnd)
true

We can see the current data in the output of ss through iport (since iport is connected to ss.output)

64-element Buffer{Cyclic, Float64, 1}:
10.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
⋮
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0

Let us further drive ss.

julia> for t in 2. : 10.
put!(trg, t)
put!(oport, [10 * t, 20 * t])
take!(hnd)
end

The data written to the output of ss is also written to the internal buffers of output.

64-element Buffer{Cyclic, Float64, 1}:
1000.0
810.0
640.0
490.0
360.0
250.0
160.0
90.0
40.0
10.0
⋮
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0

In addition to the generic StaticSystem, Causal provides some well-known static systems given in the next section.

## Full API

Causal.@def_static_systemMacro
@def_static_system ex

where ex is the expression to define to define a new AbstractStaticSystem component type. The usage is as follows:

@def_source struct MyStaticSystem{T1,T2,T3,...,TN,OP, RO} <: AbstractStaticSystem
param1::T1 = param1_default     # optional field
param2::T2 = param2_default     # optional field
param3::T3 = param3_default     # optional field
⋮
paramN::TN = paramN_default     # optional field
input::IP = input_default       # mandatory field
output::OP = output_default     # mandatory field
end

Here, MyStaticSystem has N parameters, an output port, an input port and a readout function.

Warning

input, output and readout are mandatory fields to define a new static system. The rest of the fields are the parameters of the system.

Warning

readout must be a two-argument function, i.e. a function of time t and input value u.

Warning

New static system must be a subtype of AbstractStaticSystem to function properly.

Example

julia> @def_static_system struct MyStaticSystem{IP, OP, RO} <: AbstractStaticSystem
α::Float64 = 1.
β::Float64 = 2.
input::IP = Inport()
output::OP = Outport()
readout::RO = (t,u) -> α * u[1] + β * u[2]
end

julia> sys = MyStaticSystem();

julia> sys.α
1.0

julia> sys.input
1-element Inport{Inpin{Float64}}:
Inpin(eltype:Float64, isbound:false)
Causal.StaticSystemType
struct StaticSystem{RO, IP, OP, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Consructs a generic static system with readout function, input port and output port.

Fields

• input::Any

Input port

• output::Any

Output. May be an Outport of Nothing

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Example

julia> ss = StaticSystem(readout = (t,u) -> u[1] + u[2], input=Inport(2), output=Outport(1));

2.0
struct Adder{S, IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Construts an Adder with input bus input and signs signs. signs is a tuplle of + and/or -. The output function g of Adder is of the form,

$$$y = g(u, t) = \sum_{j = 1}^n s_k u_k$$$

where n is the length of the input, $s_k$ is the kth element of signs, $u_k$ is the kth value of input and $y$ is the value of output. The default value of signs is all +.

Fields

• signs::Any

• input::Any

Input port

• output::Any

Output port

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Example

true
Causal.MultiplierType
struct Multiplier{S, IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Construts an Multiplier with input bus input and signs signs. signs is a tuplle of * and/or /. The output function g of Multiplier is of the form,

$$$y = g(u, t) = \prod_{j = 1}^n s_k u_k$$$

where n is the length of the input, $s_k$ is the kth element of signs, $u_k$ is the kth value of input and $y$ is the value of the output. The default value of signs is all *.

Fields

• ops::Any

Operators

• input::Any

Input port

• output::Any

Output port

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Example

julia> mlt = Multiplier(ops=(*, *, /));

julia> mlt.readout([3, 4, 5], 0.) == 3 * 4 / 5
true
Causal.GainType
struct Gain{G, IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Constructs a Gain whose output function g is of the form

$$$y = g(u, t) = K u$$$

where $K$ is gain, $u$ is the value of input and y is the value of output.

Fields

• gain::Any

Gain

• input::Any

Input port

• output::Any

Output port

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Example

julia> K = [1. 2.; 3. 4.];

julia> sfunc = Gain(input=Inport(2), gain=K);

julia> sfunc.readout([1., 2.], 0.) == K * [1., 2.]
true
Causal.TerminatorType
struct Terminator{IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Constructs a Terminator with input bus input. The output function g is eqaul to nothing. A Terminator is used just to sink the incomming data flowing from its input.

Fields

• input::Any

Input port

• output::Any

Output. Must be nothing

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Causal.MemoryType
struct Memory{D, IN, TB, DB, IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractMemory

Constructs a 'Memorywith input businput. A 'Memory delays the values of input by an amount of numdelay. initial determines the transient output from the Memory, that is, until the internal buffer of Memory is full, the values from initial is returned.

Fields

• delay::Any

Delay in seconds

• initial::Any

Inital value of memory

• numtaps::Int64

Number of taps memory. The number of taps is length of internal(timebuf, databuf) buffers of memory

• timebuf::Any

Time buffer of memory to record time instants

• databuf::Any

Data buffer of memory to record input data values

• input::Any

Input port

• output::Any

Output port

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Example

julia> Memory(delay=0.1)
Memory(delay:0.1, numtaps:5, input:Inport(numpins:1, eltype:Inpin{Float64}), output:Outport(numpins:1, eltype:Outpin{Float64}))

julia> Memory(delay=0.1, numtaps=5)
Memory(delay:0.1, numtaps:5, input:Inport(numpins:1, eltype:Inpin{Float64}), output:Outport(numpins:1, eltype:Outpin{Float64}))
Causal.CouplerType
struct Coupler{C1, C2, IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Constructs a coupler from connection matrix conmat of size $n \times n$ and coupling matrix cplmat of size $d \times d$. The output function g of Coupler is of the form

$$$y = g(u, t) = (E \otimes P) u$$$

where $\otimes$ is the Kronecker product, $E$ is conmat and $P$ is cplmat, $u$ is the value of input and y is the value of output.

Fields

• conmat::Any

Outer coupling matrix

• cplmat::Any

Inner coupling matrix

• input::Any

Input port

• output::Any

Output port

• trigger::Any

• handshake::Any

• callbacks::Any

• name::Any

• id::Any

Causal.DifferentiatorType
struct Differentiator{T1<:Real, T2<:Real, T3<:Real, IP, OP, RO, var"4004", var"4005", var"4006", Symbol, var"4007"} <: AbstractStaticSystem

Consructs a Differentiator whose input output relation is of the form

$$$y(t) = k_d \dot{u}(t)$$$

where $u(t)$ is the input and $y(t)$ is the output and $kd$ is the differentiation constant.

Fields

• kd::Real

Differentiation gain

• t::Real

Time

• u::Real

Input value

• input::Any

Input port

• output::Any

Output port