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
trueTo 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) @0x00007fe0d87f8280
julia> tout = @async while true
all(take!(iport) .=== NaN) && break
end
Task (runnable) @0x00007fe0d97ef820At 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)
trueNow continue driving gen.
julia> for t in 2. : 10.
put!(trg, t)
take!(hnd)
endWhen 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.0Causal provides some other function generators which are documented in the following section.
Full API
Causal.@def_source — Macro@def_source exwhere 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
endHere, MySource has N parameters, an output port and a readout function.
output and readout are mandatory fields to define a new source. The rest of the fields are the parameters of the source.
readout must be a single-argument function, i.e. a fucntion of time t.
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)Causal.FunctionGenerator — TypeFunctionGenerator(; readout, output=Outport())Constructs a generic function generator with readout function and output port.
Example
julia> gen = FunctionGenerator(readout = t -> [t, 2t], output = Outport(2));
julia> gen.readout(1.)
2-element Array{Float64,1}:
1.0
2.0Causal.SinewaveGenerator — TypeSinewaveGenerator(;amplitude=1., frequency=1., phase=0., delay=0., offset=0.)Constructs a SinewaveGenerator with output of the form
where $A$ is amplitude, $f$ is frequency, $\tau$ is delay and $\phi$ is phase and $B$ is offset.
Causal.DampedSinewaveGenerator — TypeDampedSinewaveGenerator(;amplitude=1., decay=-0.5, frequency=1., phase=0., delay=0., offset=0.)Constructs a DampedSinewaveGenerator which generates outputs of the form
where $A$ is amplitude, $\alpha$ is decay, $f$ is frequency, $\phi$ is phase, $\tau$ is delay and $B$ is offset.
Causal.SquarewaveGenerator — TypeSquarewaveGenerator(;level1=1., level2=0., period=1., duty=0.5, delay=0.)Constructs a SquarewaveGenerator with output of the form
where $A_1$, $A_2$ is level1 and level2, $T$ is period, $\tau$ is delay $\alpha$ is duty.
Causal.TriangularwaveGenerator — TypeTriangularwaveGenerator(;amplitude=1, period=1, duty=0.5, delay=0, offset=0)Constructs a TriangularwaveGenerator with output of the form
where $A$ is amplitude, $T$ is period, $\tau$ is delay $\alpha$ is duty.
Causal.ConstantGenerator — TypeConstantGenerator(;amplitude=1.)Constructs a ConstantGenerator with output of the form
where $A$ is `amplitude.
Causal.RampGenerator — TypeRampGenerator(;scale=1, delay=0.)Constructs a RampGenerator with output of the form
where $\alpha$ is the scale and $\tau$ is delay.
Causal.StepGenerator — TypeStepGenerator(;amplitude=1, delay=0, offset=0)Constructs a StepGenerator with output of the form
where $A$ is amplitude, $B$ is the offset and $\tau$ is the delay.
Causal.ExponentialGenerator — TypeExponentialGenerator(;scale=1, decay=-1, delay=0.)Constructs an ExponentialGenerator with output of the form
where $A$ is scale, $\alpha$ is decay and $\tau$ is delay.
Causal.DampedExponentialGenerator — TypeDampedExponentialGenerator(;scale=1, decay=-1, delay=0.)Constructs an DampedExponentialGenerator with outpsuts of the form
where $A$ is scale, $\alpha$ is decay, $\tau$ is delay.