Generators

Basic Operation AbstractSource

An AbstractSource is a subtype of AbstractComponent. (See Components for more information.) An AbstractComponent has input port and output port for data flow. The AbstractComponent reads data from the input port and writes data to output port. Since the input-output relation of AbstractSource depends on just the current time t, Sources do not have input ports since they do not read input values. They just need time t to compute its output. During their evolution, an AbstractComponent reads time t from its trigger pins, computes its output according to its output function and writes its computed output to its output ports. An AbstractComponent also writes true to their handshake pin to signal that the evolution is succeeded. To further clarify the operation of AbstractSource, let us do some examples.

julia> using Causal # hide

julia> f(t) = t * exp(t) + sin(t)
f (generic function with 1 method)

julia> gen = FunctionGenerator(readout=f)
FunctionGenerator(readout:f,  output:Outport(numpins:1, eltype:Outpin{Float64}))

We constructed a FunctionGenerator which is an AbstractSource.

julia> gen isa AbstractSource
true

To drive gen, that is to make gen evolve, we need to launch gen. To this end, we construct ports and pins for input-output and signaling.

julia> trg, hnd, iport = Outpin(), Inpin{Bool}(), Inport(length(gen.output))
(Outpin(eltype:Float64, isbound:false), Inpin(eltype:Bool, isbound:false), Inport(numpins:1, eltype:Inpin{Float64}))

julia> connect!(gen.output, iport)
1-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

julia> connect!(trg, gen.trigger)
Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

julia> connect!(gen.handshake, hnd)
Link(state:open, eltype:Bool, isreadable:false, iswritable:false)

julia> t = launch(gen)
Task (runnable) @0x00007f1fca571390

julia> tout = @async while true
           all(take!(iport) .=== NaN) && break
           end
Task (runnable) @0x00007f1fca592230

At this moment, gen is ready to be triggered from its trigger link. Note that the trigger link gen.trigger and the output gen.output of gen are writable.

julia> gen.trigger.link
Link(state:open, eltype:Float64, isreadable:false, iswritable:true)

julia> gen.output[1].links[1]
Link(state:open, eltype:Float64, isreadable:false, iswritable:true)

gen is triggered by writing time t to trg

julia> put!(trg, 1.)

When triggered gen writes true to its handshake link gen.handshake which can be read from hnd.

julia> hnd.link
Link(state:open, eltype:Bool, isreadable:true, iswritable:false)

and to drive gen for another time hnd must be read.

julia> take!(hnd)
true

Now continue driving gen.

julia> for t in 2. : 10.
           put!(trg, t)
           take!(hnd)
       end

When triggered, the output of gen is written to its output gen.output.

julia> gen.output[1].links[1].buffer
64-element Buffer{Cyclic,Float64,1}:
 220264.11392695628
  72928.1674666637
  23848.65325458045
   7677.0890955979285
   2420.2933454582117
    741.1068712382199
    217.635797637269
     60.39773077762287
     15.687409624686982
      3.5597528132669414
      ⋮
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0

Causal provides some other function generators which are documented in the following section.

Full API

Causal.@def_sourceMacro
@def_source ex

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

@def_source struct MySource{T1,T2,T3,...,TN,OP, RO} <: AbstractSource
    param1::T1 = param1_default     # optional field 
    param2::T2 = param2_default     # optional field 
    param3::T3 = param3_default     # optional field
        ⋮
    paramN::TN = paramN_default     # optional field 
    output::OP = output_default     # mandatory field 
    readout::RO = readout_function  # mandatory field
end

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

Warning

output and readout are mandatory fields to define a new source. The rest of the fields are the parameters of the source.

Warning

readout must be a single-argument function, i.e. a function of time t.

Warning

New source must be a subtype of AbstractSource to function properly.

Example

julia> @def_source struct MySource{OP, RO} <: AbstractSource
       a::Int = 1 
       b::Float64 = 2. 
       output::OP = Outport() 
       readout::RO = t -> (a + b) * sin(t)
       end

julia> gen = MySource();

julia> gen.a 
1

julia> gen.output
1-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
source
Causal.FunctionGeneratorType
struct FunctionGenerator{RO, OP<:Outport, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a generic function generator with readout function and output port.

Fields

  • readout::Any

    Readout function

  • output::Outport

    Output port

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

Example

julia> gen = FunctionGenerator(readout = t -> [t, 2t], output = Outport(2));

julia> gen.readout(1.)
2-element Array{Float64,1}:
 1.0
 2.0
source
Causal.SinewaveGeneratorType

Constructs a SinewaveGenerator with output of the form

\[ x(t) = A sin(2 \pi f (t - \tau) + \phi) + B\]

where $A$ is amplitude, $f$ is frequency, $\tau$ is delay and $\phi$ is phase and $B$ is offset.

Fields

  • amplitude::Real

    Amplitude

  • frequency::Real

    Frequency

  • phase::Real

    Phase

  • delay::Real

    Delay in seconds

  • offset::Real

    Offset

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.DampedSinewaveGeneratorType
struct DampedSinewaveGenerator{T1<:Real, T2<:Real, T3<:Real, T4<:Real, T5<:Real, T6<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a DampedSinewaveGenerator which generates outputs of the form

\[ x(t) = A e^{\alpha t} sin(2 \pi f (t - \tau) + \phi) + B\]

where $A$ is amplitude, $\alpha$ is decay, $f$ is frequency, $\phi$ is phase, $\tau$ is delay and $B$ is offset.

Fields

  • amplitude::Real

    Amplitude

  • decay::Real

    Attenuation rate

  • frequency::Real

    Frequency

  • phase::Real

    Phase

  • delay::Real

    Delay in seconds

  • offset::Real

    Offset

  • output::Outport

    Output port

  • readout::Any

    Readout funtion

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.SquarewaveGeneratorType
struct SquarewaveGenerator{T1<:Real, T2<:Real, T3<:Real, T4<:Real, T5<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a SquarewaveGenerator with output of the form

\[ x(t) = \left\{\begin{array}{lr} A_1 + B, & kT + \tau \leq t \leq (k + \alpha) T + \tau \\ A_2 + B, & (k + \alpha) T + \tau \leq t \leq (k + 1) T + \tau \end{array} \right. \quad k \in Z\]

where $A_1$, $A_2$ is level1 and level2, $T$ is period, $\tau$ is delay $\alpha$ is duty.

Fields

  • high::Real

    High level

  • low::Real

    Low level

  • period::Real

    Period

  • duty::Real

    Duty cycle given in range (0, 1)

  • delay::Real

    Delay in seconds

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.TriangularwaveGeneratorType
struct TriangularwaveGenerator{T1<:Real, T2<:Real, T3<:Real, T4<:Real, T5<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a TriangularwaveGenerator with output of the form

\[ x(t) = \left\{\begin{array}{lr} \dfrac{A t}{\alpha T} + B, & kT + \tau \leq t \leq (k + \alpha) T + \tau \\[0.25cm] \dfrac{A (T - t)}{T (1 - \alpha)} + B, & (k + \alpha) T + \tau \leq t \leq (k + 1) T + \tau \end{array} \right. \quad k \in Z\]

where $A$ is amplitude, $T$ is period, $\tau$ is delay $\alpha$ is duty.

Fields

  • amplitude::Real

    Amplitude

  • period::Real

    Period

  • duty::Real

    Duty cycle

  • delay::Real

    Delay in seconds

  • offset::Real

    Offset

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.ConstantGeneratorType
struct ConstantGenerator{T1<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a ConstantGenerator with output of the form

\[ x(t) = A\]

where $A$ is `amplitude.

Fields

  • amplitude::Real

    Amplitude

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.RampGeneratorType
struct RampGenerator{T1<:Real, T2<:Real, T3<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a RampGenerator with output of the form

\[ x(t) = \alpha (t - \tau)\]

where $\alpha$ is the scale and $\tau$ is delay.

Fields

  • scale::Real

    Scale

  • delay::Real

    Delay in seconds

  • offset::Real

    Offset

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.StepGeneratorType
struct StepGenerator{T1<:Real, T2<:Real, T3<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs a StepGenerator with output of the form

\[ x(t) = \left\{\begin{array}{lr} B, & t \leq \tau \\ A + B, & t > \tau \end{array} \right.\]

where $A$ is amplitude, $B$ is the offset and $\tau$ is the delay.

Fields

  • amplitude::Real

    Amplitude

  • delay::Real

    Delay in seconds

  • offset::Real

    Offset

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.ExponentialGeneratorType
struct ExponentialGenerator{T1<:Real, T2<:Real, T3<:Real, T4<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs an ExponentialGenerator with output of the form

\[ x(t) = A e^{\alpha (t - \tau)}\]

where $A$ is scale, $\alpha$ is decay and $\tau$ is delay.

Fields

  • scale::Real

    Scale

  • decay::Real

    Attenuation decay

  • delay::Real

    Delay in seconds

  • offset::Real

    Offset

  • output::Outport

    Output port

  • readout::Any

    Readout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source
Causal.DampedExponentialGeneratorType
struct DampedExponentialGenerator{T1<:Real, T2<:Real, T3<:Real, T4<:Real, OP<:Outport, RO, var"253", var"254", var"255", Symbol, var"256"} <: AbstractSource

Constructs an DampedExponentialGenerator with outpsuts of the form

\[ x(t) = A (t - \tau) e^{\alpha (t - \tau)}\]

where $A$ is scale, $\alpha$ is decay, $\tau$ is delay.

Fields

  • scale::Real

    Scale

  • decay::Real

    Attenuation rate

  • delay::Real

    Delay in seconds

  • offset::Real

    Offet

  • output::Outport

    Output port

  • readout::Any

    Reaodout function

  • trigger::Any

  • handshake::Any

  • callbacks::Any

  • name::Any

  • id::Any

source