Variable
In Cropbox, a variable is defined as a unit element of modeling that denotes a value determined by a specific operation relying on other variables. Each variable represents a field within the system struct defined by the @system
macro.
Variable Declaration
Variables are declared when a system is declared with the @system
macro. @system
macro accepts lines of variable declaration specified by its own syntax. They are loosely based on Julia syntax sharing common expressions and operators, but have distinct semantics as explained below.
name[(args..; kwargs..)][: alias] [=> body] ~ [state][::type][(tags..)]
name
: variable name (usually short abbreviation)args
: automatically bound depending variableskwargs
: custom bound depending variables (only for call now)alias
: alternative name (long description)body
: code snippet (state/type specific,begin .. end
block for multiple lines)state
: verb indicating kind of state (empty if notState
-based)type
: internal type (i.e.Float64
by default for mostState
variable)tags
: variable specific options (i.e. unit, min/max, etc.)
Example
Here is an example of a system declaration where all three variables are valid declarations:
@system S begin
a: variable_a ~ advance
b(a) => a^2 ~ track
c => true ~ ::Bool
end
Main.S
Variable States
Within Cropbox, a variable inside a system can be one of many different abstract types based on the variable's purpose. Depending on its type, each variable has its own behavior when a system is instantiated. In Cropbox, we refer to these as the state of the variables, originating from the term state variables often used in mathematical modeling.
Specifying a state is not mandatory when declaring a variable. Cropbox also allows plain variables, which are commonly used for creating variable references to other systems.
Currently, there are 19 different variable states implemented in Cropbox.
Instant derivation
preserve
: keeps an initially assigned value with no further updates; constants, parameterstrack
: evaluates expression and assigns a new value for each time stepflag
: checks a conditional logic; similar to track with boolean type, but composition is allowedremember
: keeps tracking the variable until a certain condition is met; like track switching to preserve
Cumulative update
accumulate
: emulates integration of a rate variable over time; essentially Euler methodcapture
: calculates the difference between time stepsintegrate
: calculates an integral over a non-time variable using Gaussian methodadvance
: updates an internal time-keeping variable
Data source
provide
: provides a table-like multi-column time-series data; i.e. weather datadrive
: fetches the current value from a time-series; often used with provide; i.e. air temperaturetabulate
: makes a two dimensional table with named keys; i.e. partitioning tableinterpolate
: makes a curve function interpolated with discrete values; i.e. soil characteristic curve
Equation solving
solve
: solves a polynomial equation symbolically; i.e. quadratic equation for coupling photosynthesisbisect
: solves a nonlinear equation using bisection method; i.e. energy balance equation
Dynamic structure
produce
: attaches a new instance of dynamically generated system; i.e. root structure growth
Language extension
hold
: marks a placeholder for the variable shared between mixinswrap
: allows passing a reference to the state variable object, not a dereferenced valuecall
: defines a partial function accepting user-defined arguments, while bound to other variablesbring
: duplicates variables declaration from another system into the current system
Instant derivation
preserve
preserve
variables are fixed values with no further modification after instantiation of a system. As a result, they are often used as the state
for parameter
variables, which allow any initial value to be set via a configuration object supplied at the start of a simulation. Non-parameter constants are also used for fixed variables that do not need to be computed at each time step.
Supported tags: unit
, optional
, parameter
, override
, extern
, ref
, min
, max
, round
Example
@system S(Controller) begin
a => 1 ~ preserve
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 1.0 |
2 | 1.0 hr | 1.0 |
3 | 2.0 hr | 1.0 |
track
track
variables are evaluated and assigned a new value at every time step. In a conventional model, these are the variables that would be computed in every update loop. At every time step, the formula in the variable code is evaluated and saved for use. This assignment of value occurs only once per time step, as intended by the Cropbox framework. No manual assignment of computation at an arbitrary time is allowed. This is to ensure that that there are no logical errors resulting from premature or incorrectly ordered variable assignments. For example, a cyclical reference between two track
variables is caught by Cropbox as an error.
Supported tags: unit
, override
, extern
, ref
, skip
, init
, min
, max
, round
, when
Example
@system S(Controller) begin
a ~ advance
b(a) => 2*a ~ track
end
simulate(S; stop=2)
Row | time | a | b |
---|---|---|---|
Quantity… | Float64 | Float64 | |
1 | 0.0 hr | 0.0 | 0.0 |
2 | 1.0 hr | 1.0 | 2.0 |
3 | 2.0 hr | 2.0 | 4.0 |
flag
flag
variables are expressed in a conditional statement or logical operator for which a boolean value is evaluated at every time step. They function like a track
variable but with a boolean value.
Supported tags: parameter
, override
, extern
, once
, when
Example
@system S(Controller) begin
a ~ advance
b => 1 ~ preserve
f(a, b) => (a > b) ~ flag
end
simulate(S; stop=2)
Row | time | a | b | f |
---|---|---|---|---|
Quantity… | Float64 | Float64 | Bool | |
1 | 0.0 hr | 0.0 | 1.0 | false |
2 | 1.0 hr | 1.0 | 1.0 | false |
3 | 2.0 hr | 2.0 | 1.0 | true |
remember
remember
variables keep track of a variable until a specified condition is met. When the condition is met, it is saved as either its latest update or a specified value. They are like track variables that turn into preserve variables. The when
tag is required to specify condition. Unless specified, the initial value for remember
defaults to 0
.
Supported tags: unit
, init
, when
Example
@system S(Controller) begin
t(context.clock.tick) ~ track
f(t) => t > 1 ~ flag
r1(t) ~ remember(when=f)
r2(t) => t^2 ~ remember(when=f)
end
simulate(S; stop=2)
Row | time | t | f | r1 | r2 |
---|---|---|---|---|---|
Quantity… | Float64 | Bool | Float64 | Float64 | |
1 | 0.0 hr | 0.0 | false | 0.0 | 0.0 |
2 | 1.0 hr | 1.0 | false | 0.0 | 0.0 |
3 | 2.0 hr | 2.0 | true | 2.0 | 4.0 |
Cumulative update
accumulate
accumulate
variables emulate the integration of a rate variable over time. It uses the Euler's method of integration. By default, an accumulate
variable accumulates every hour, unless a unit of time is specified.
Supported tags: unit
, init
, time
, timeunit
, reset
, min
, max
, when
Example
@system S(Controller) begin
a => 1 ~ accumulate
b => 1 ~ accumulate(u"d")
end
simulate(S; stop=2)
Row | time | a | b |
---|---|---|---|
Quantity… | Float64 | Quantity… | |
1 | 0.0 hr | 0.0 | 0.0 d |
2 | 1.0 hr | 1.0 | 0.0416667 d |
3 | 2.0 hr | 2.0 | 0.0833333 d |
capture
capture
variables calculate the difference of a variable between time steps. The time
tag allows evaluations for varying rates of time.
Supported tags: unit
, time
, timeunit
, when
Example
@system S(Controller) begin
a => 1 ~ track
b(a) => a + 1 ~ capture
c(a) => a + 1 ~ accumulate
end
simulate(S; stop=2)
Row | time | a | b | c |
---|---|---|---|---|
Quantity… | Float64 | Float64 | Float64 | |
1 | 0.0 hr | 1.0 | 0.0 | 0.0 |
2 | 1.0 hr | 1.0 | 2.0 | 2.0 |
3 | 2.0 hr | 1.0 | 2.0 | 4.0 |
integrate
integrate
variables calculate an integral over a non-time variable using the Gaussian method.
Supported tags: unit
, from
, to
Example
@system S(Controller) begin
w => 1 ~ preserve(parameter)
a => 0 ~ preserve(parameter)
b => π ~ preserve(parameter)
f(w; x) => w*sin(x) ~ integrate(from=a, to=b)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
w | = | 1.0 | |
a | = | 0.0 | |
b | = | 3.14159 | |
f | = | 2.0 |
advance
advance
variables update an internal time-keeping variable. By default, it starts at 0 and increases by 1 every time step. Note that the unit does not have to be time-related.
Supported tags: init
, step
, unit
Example
@system S(Controller) begin
a ~ advance(init=1)
b ~ advance(step=2)
c ~ advance(u"m")
end
simulate(S; stop=2)
Row | time | a | b | c |
---|---|---|---|---|
Quantity… | Float64 | Float64 | Quantity… | |
1 | 0.0 hr | 1.0 | 0.0 | 0.0 m |
2 | 1.0 hr | 2.0 | 2.0 | 1.0 m |
3 | 2.0 hr | 3.0 | 4.0 | 2.0 m |
Data source
provide
provide
variables provide a DataFrame with a given index (index
) starting from an initial value (init
). By default, autounit
is true
, meaning that provide
variables will attempt to get units from column names.
Supported tags: index
, init
, step
, autounit
, parameter
Example
@system S(Controller) begin
a => DataFrame("index (hr)" => 0:2, "value (m)" => 0:10:20) ~ provide
end
instance(S).a
3×2 DataFrame
Row │ index value
│ Quantity… Quantity…
─────┼──────────────────────
1 │ 0 hr 0 m
2 │ 1 hr 10 m
3 │ 2 hr 20 m
drive
drive
variables fetch the current value from a time-series. It is often used in conjunction with provide
.
Supported tags: tick
, unit
, from
, by
, parameter
, override
Example
@system S(Controller) begin
a => [2, 4, 6] ~ drive
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 2.0 |
2 | 1.0 hr | 4.0 |
3 | 2.0 hr | 6.0 |
tabulate
tabulate
variables make a two dimensional table with named keys. The rows
tag must be assigned.
Supported tags: unit
, rows
, columns
, parameter
Example
@system S(Controller) begin
T => [
# a b
0 4 ; # A
1 5 ; # B
2 6 ; # C
3 7 ; # D
] ~ tabulate(rows=(:A, :B, :C, :D), columns=(:a, :b))
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
T | = | [0.0 4.0; 1.0 5.0; 2.0 6.0; 3.0 7.0] |
interpolate
interpolate
variables make a curve function for a provided set of discrete values.
Supported tags: unit
, knotunit
, reverse
, parameter
Example
@system S(Controller) begin
m => [1 => 10, 2 => 20, 3 => 30] ~ interpolate
a(m) => m(2.5) ~ track
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
m | = | 3-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Int64}, Gridded(Linear())), Throw()) with element type Float64:… | |
a | = | 25.0 |
A matrix can also be used instead of a vector of pairs.
@system S(Controller) begin
m => [1 10; 2 20; 3 30] ~ interpolate
a(m) => m(2.5) ~ track
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
m | = | 3-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Int64}, Gridded(Linear())), Throw()) with element type Float64:… | |
a | = | 25.0 |
Equation solving
solve
solve
variables solve a polynomial equation symbolically. By default, it will return the highest solution. Therefore, when using the lower
tag, it is recommended to pair it with another tag.
Supported tags: unit
, lower
, upper
, pick
Example
The solution is x = 1, 2, 3
@system S(Controller) begin
a => 1 ~ preserve(parameter)
b => -6 ~ preserve(parameter)
c => 11 ~ preserve(parameter)
d => -6 ~ preserve(parameter)
x(a, b, c, d) => begin
a*x^3 + b*x^2 + c*x + d
end ~ solve
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | -6.0 | |
c | = | 11.0 | |
d | = | -6.0 | |
x | = | 3.0 |
bisect
bisect
variables solve a nonlinear equation using the bisection method. The tags lower
and upper
must be provided.
Supported tags: unit
, evalunit
, lower
, upper
, maxiter
, tol
, min
, max
Example
The solution is x = 1, 2, 3
@system S(Controller) begin
x(x) => x^3 - 6x^2 + 11x - 6 ~ bisect(lower=0, upper=3)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
x | = | 3.0 |
Dynamic structure
produce
produce
variables attach a new instance of a dynamically generated system.
Example
@system S begin
a => produce(S) ~ produce
end
@system SController(Controller) begin
s(context) ~ ::S
end
instance(SController)
SController | |||
context | = | <Context> | |
config | = | <Config> | |
s | = | <S> |
Language extension
hold
hold
variables are placeholders for variables that are supplied by another system as a mixin.
Supported tags: None
Example
@system S1 begin
a ~ advance
end
@system S2(S1, Controller) begin
a ~ hold
b(a) => 2*a ~ track
end
simulate(S2; stop=2)
Row | time | a | b |
---|---|---|---|
Quantity… | Float64 | Float64 | |
1 | 0.0 hr | 0.0 | 0.0 |
2 | 1.0 hr | 1.0 | 2.0 |
3 | 2.0 hr | 2.0 | 4.0 |
wrap
wrap
allows passing a reference to the state variable object, not a dereferenced value
Supported tags: None
Example
@system S(Controller) begin
a => 1 ~ preserve
b(a) => a == a' ~ flag
c(wrap(a)) => a == a' ~ flag
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | true | |
c | = | false |
call
call
defines a partial function accepting user-defined arguments
Supported tags: unit
Example
@system S(Controller) begin
a => 1 ~ preserve
f(a; x) => a + x ~ call
b(f) => f(1) ~ track
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
f | = | <call> | |
b | = | 2.0 |
bring
bring
duplicates variable declaration from another system into the current system
Supported tags: parameters
, override
Example
@system S1 begin
a => 1 ~ preserve
b(a) => 2a ~ track
end
@system S2(Controller) begin
c(context) ~ bring::S1
end
instance(S2)
S2 | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | 2.0 | |
c | = | <S1> |
Variable Tags
Most variable states have tags in the form of (tag)
for tag-specific behaviors. Available tags vary between variable states. Some tags are shared by multiple variable states while some tags are exclusive to certain variable states.
autounit
Allows provide
variables to automatically assign units to variables depending on column headers of the DataFrame. By default, autounit
is true
and only needs to be specified when false
.
Used by: provide
Example
@system S(Controller) begin
a => DataFrame("index" => (0:2)u"hr", "value (m)" => 0:10:20) ~ provide
b => DataFrame("index" => (0:2)u"hr", "value (m)" => 0:10:20) ~ provide(autounit=false)
end
Main.S
instance(S).a
3×2 DataFrame
Row │ index value
│ Quantity… Quantity…
─────┼──────────────────────
1 │ 0 hr 0 m
2 │ 1 hr 10 m
3 │ 2 hr 20 m
instance(S).b
3×2 DataFrame
Row │ index value (m)
│ Quantity… Int64
─────┼──────────────────────
1 │ 0 hr 0
2 │ 1 hr 10
3 │ 2 hr 20
by
Specifies the column and series from which the drive
variable receives data. Can be omitted if the variable name is identical to column name.
Used by: drive
Example
@system S(Controller) begin
p => DataFrame(index=(0:2)u"hr", a=[2,4,6], x=1:3) ~ provide
a ~ drive(from=p)
b ~ drive(from=p, by=:x)
end
simulate(S; stop=2)
Row | time | a | b |
---|---|---|---|
Quantity… | Float64 | Float64 | |
1 | 0.0 hr | 2.0 | 1.0 |
2 | 1.0 hr | 4.0 | 2.0 |
3 | 2.0 hr | 6.0 | 3.0 |
columns
Specifies the names of columns from the table created by the tabulate
variable.
Used by: tabulate
Example
@system S(Controller) begin
T => [
# a b
0 4 ; # A
1 5 ; # B
2 6 ; # C
3 7 ; # D
] ~ tabulate(rows=(:A, :B, :C, :D), columns=(:a, :b))
end
instance(S).T
│ a b
───┼──────────
A │ 0.0 4.0
B │ 1.0 5.0
C │ 2.0 6.0
D │ 3.0 7.0
evalunit
Specifies the evaluation unit of bisect
, as opposed to the unit of solution.
Used by: bisect
Example
@system S(Controller) begin
f(x) => (x/1u"s" - 1u"m/s") ~ track(u"m/s")
x(f) ~ bisect(lower=0, upper=2, u"m", evalunit=u"m/s")
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
f | = | 0.0 m s^-1 | |
x | = | 1.0 m |
extern
Used by: preserve
, track
, flag
from
drive
: Specifies the DataFrame that the drive
variable will receive data from. If the variable name of the drive
variable differs from column name, from
must be accompanied with by
.
integrate
: Specifies lower bound of integration.
Example: drive
@system S(Controller) begin
p => DataFrame(index=(0:2)u"hr", a=[2,4,6], x=1:3) ~ provide
a ~ drive(from=p)
b ~ drive(from=p, by=:x)
end
simulate(S; stop=2)
Row | time | a | b |
---|---|---|---|
Quantity… | Float64 | Float64 | |
1 | 0.0 hr | 2.0 | 1.0 |
2 | 1.0 hr | 4.0 | 2.0 |
3 | 2.0 hr | 6.0 | 3.0 |
Example: integrate
@system S(Controller) begin
w => 1 ~ preserve(parameter)
a => 0 ~ preserve(parameter)
b => π ~ preserve(parameter)
f(w; x) => w*sin(x) ~ integrate(from=a, to=b)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
w | = | 1.0 | |
a | = | 0.0 | |
b | = | 3.14159 | |
f | = | 2.0 |
index
Used by provide
variables to specify the index column from provided DataFrame. Can be omitted if DataFrame contains column "index".
Used by: provide
Example
@system S(Controller) begin
a => DataFrame(i=(0:3)u"hr", value=0:10:30) ~ provide(index=:i)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 4×2 DataFrame… |
init
Assigns the first value of the variable at system instantiation.
Used by: track
, remember
, accumulate
, advance
, provide
Example
@system S(Controller) begin
a => 1 ~ accumulate(init=100)
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 100.0 |
2 | 1.0 hr | 101.0 |
3 | 2.0 hr | 102.0 |
knotunit
Specifies the unit of discrete x-values of interpolate
.
Used by: interpolate
Example
@system S(Controller) begin
m => ([1 => 10, 2 => 20, 3 => 30]) ~ interpolate(u"s", knotunit=u"m")
n(m) ~ interpolate(u"m", reverse)
a(m) => m(2.5u"m") ~ track(u"s")
b(n) => n(25u"s") ~ track(u"m")
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
m | = | 3-element extrapolate(interpolate((::Vector{Quantity{Int64, 𝐋, FreeUnits{(m,), 𝐋, nothing}}},), ::Vector{Quantity{Int64, 𝐓, FreeUnits{(s,), 𝐓, nothing}}}, Gridded(Linear())), Throw()) with element type Quantity{Float64, 𝐓, FreeUnits{(s,), 𝐓, nothing}}:… | |
n | = | 3-element extrapolate(interpolate((::Vector{Quantity{Int64, 𝐓, FreeUnits{(s,), 𝐓, nothing}}},), ::Vector{Quantity{Int64, 𝐋, FreeUnits{(m,), 𝐋, nothing}}}, Gridded(Linear())), Throw()) with element type Quantity{Float64, 𝐋, FreeUnits{(m,), 𝐋, nothing}}:… | |
a | = | 25.0 s | |
b | = | 2.5 m |
lower
Specifies the lower bound of the solution for solve
and bisect
variables.
Example
The solution is x = 1, 2, 3
@system S(Controller) begin
a => 1 ~ preserve(parameter)
b => -6 ~ preserve(parameter)
c => 11 ~ preserve(parameter)
d => -6 ~ preserve(parameter)
x(a, b, c, d) => begin
a*x^3 + b*x^2 + c*x + d
end ~ solve(lower=1.1, upper=2.9)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | -6.0 | |
c | = | 11.0 | |
d | = | -6.0 | |
x | = | 2.0 |
max
Defines the maximum value of the variable.
Used by: preserve
, track
, accumulate
, bisect
Example
@system S(Controller) begin
a => 1 ~ accumulate(max=1)
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 0.0 |
2 | 1.0 hr | 1.0 |
3 | 2.0 hr | 1.0 |
maxiter
Defines the maximum number of iterations for the bisect
.
Used by: bisect
Example
@system S(Controller) begin
x(x) => x - 0.25 ~ bisect(lower=0, upper=1, maxiter=4)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
x | = | 0.25 |
min
Defines the minimum value of the variable.
Used by: preserve
, track
, accumulate
, bisect
Example
@system S(Controller) begin
a => -1 ~ accumulate(min=-1)
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 0.0 |
2 | 1.0 hr | -1.0 |
3 | 2.0 hr | -1.0 |
once
Makes a flag
variable unable to go from true
to false
.
Used by: flag
Example
@system S(Controller)begin
a ~ advance(init=1)
f(a) => (a % 2 == 0) ~ flag(once)
end
simulate(S; stop=2)
Row | time | a | f |
---|---|---|---|
Quantity… | Float64 | Bool | |
1 | 0.0 hr | 1.0 | false |
2 | 1.0 hr | 2.0 | true |
3 | 2.0 hr | 3.0 | true |
optional
Makes a preserve
variable optional, allowing a system to be instantiated without variable assignment.
Used by: preserve
Example
@system S(Controller) begin
a ~ preserve(optional, parameter)
b => 1 ~ preserve
end
simulate(S; stop=2)
Row | time | b |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 1.0 |
2 | 1.0 hr | 1.0 |
3 | 2.0 hr | 1.0 |
override
Used by: preserve
, track
, flag
, drive
, bring
Example
@system S1 begin
a ~ track(override)
end
@system S2(Controller) begin
c(context, a) ~ ::S1
a => 1 ~ track
end
instance(S2)
S2 | |||
context | = | <Context> | |
config | = | <Config> | |
c | = | <S1> | |
a | = | 1.0 |
parameter
Allows the variable to be altered through a configuration at system instantiation.
Used by: preserve
, flag
, provide
, drive
, tabulate
, interpolate
Example
@system S(Controller) begin
a ~ preserve(parameter)
end
instance(S; config = :S => :a => 1)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 |
parameters
Use by bring
variables to duplicate only variables that can have the parameter
tag (if they did not have the parameter
tag originally, they become parameters regardless). The duplicated variables must have their values reassigned through a configuration.
Used by: bring
Example
@system S1 begin
a => 1 ~ preserve
b(a) => 2a ~ track
c => true ~ flag
d(a) ~ accumulate
end
@system S2(Controller) begin
p(context) ~ bring::S1(parameters)
end
instance(S2; config = :S2 => (:a => 2, :b => 3, :c => false))
S2 | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 2.0 | |
b | = | 3.0 | |
c | = | 0.0 | |
p | = | <S1> |
pick
Picks which solution to return based on tag argument.
Used by: solve
Example
The solution is x = 1, 2, 3
@system S(Controller) begin
a => 1 ~ preserve(parameter)
b => -3 ~ preserve(parameter)
c => 2 ~ preserve(parameter)
x(a, b, c) => begin
a*x^2 + b*x + c
end ~ solve(pick=:minimum)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | -3.0 | |
c | = | 2.0 | |
x | = | 1.0 |
ref
reset
Resets the sum to 0 at every time step.
Used by: accumulate
Example
@system S(Controller) begin
a => 1 ~ accumulate(reset)
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 0.0 |
2 | 1.0 hr | 1.0 |
3 | 2.0 hr | 1.0 |
reverse
Returns the inverse function of an existing interpolate
variable.
Used by: interpolate
Example
@system S(Controller) begin
m => ([1 => 10, 2 => 20, 3 => 30]) ~ interpolate
n(m) ~ interpolate(reverse)
a(m) => m(2.5) ~ preserve
b(n) => n(25) ~ preserve
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
m | = | 3-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Int64}, Gridded(Linear())), Throw()) with element type Float64:… | |
n | = | 3-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Int64}, Gridded(Linear())), Throw()) with element type Float64:… | |
a | = | 25.0 | |
b | = | 2.5 |
round
Rounds to the nearest integer or to a floor or ceiling based on tag argument.
Example
@system S(Controller) begin
a => 1.4 ~ preserve(round)
b => 1.4 ~ preserve(round=:round)
c => 1.4 ~ preserve(round=:ceil)
d => 1.6 ~ preserve(round=:floor)
e => 1.6 ~ preserve(round=:trunc)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | 1.0 | |
c | = | 2.0 | |
d | = | 1.0 | |
e | = | 1.0 |
rows
Specifies the names of rows from the table created by the tabulate
variable. Required tag for tabulate
.
Used by: tabulate
Example
@system S(Controller) begin
T => [
# a b
0 4 ; # A
1 5 ; # B
2 6 ; # C
3 7 ; # D
] ~ tabulate(rows=(:A, :B, :C, :D), columns=(:a, :b))
end
Main.S
single
Used by: produce
skip
Used by: track
Example
@system S(Controller) begin
a ~ advance
b(a) => 2*a ~ track(skip=true)
end
simulate(S; stop=2)
Row | time | a | b |
---|---|---|---|
Quantity… | Float64 | Float64 | |
1 | 0.0 hr | 0.0 | 0.0 |
2 | 1.0 hr | 1.0 | 0.0 |
3 | 2.0 hr | 2.0 | 0.0 |
step
advance
: Specifies the increments of the advance
variable.
provide
: Specifies the intervals of the index column.
Example: advance
@system S(Controller) begin
a ~ advance
b ~ advance(step=2)
c ~ advance(step=-1)
end
simulate(S; stop=2)
Row | time | a | b | c |
---|---|---|---|---|
Quantity… | Float64 | Float64 | Float64 | |
1 | 0.0 hr | 0.0 | 0.0 | 0.0 |
2 | 1.0 hr | 1.0 | 2.0 | -1.0 |
3 | 2.0 hr | 2.0 | 4.0 | -2.0 |
Example: integrate
@system S(Controller) begin
a => DataFrame("index (hr)" => 0:4, "value (m)" => 0:10:40) ~ provide(step=2u"hr")
end
instance(S).a
3×2 DataFrame
Row │ index value
│ Quantity… Quantity…
─────┼──────────────────────
1 │ 0 hr 0 m
2 │ 2 hr 20 m
3 │ 4 hr 40 m
tick
Used by: drive
time
Accumulates variable at a specified rate of time.
Used by: accumulate
, capture
Example
@system S(Controller) begin
t(x=context.clock.time) => 0.5x ~ track(u"hr")
a => 1 ~ accumulate
b => 1 ~ accumulate(time=t)
end
simulate(S; stop=5)
Row | time | t | a | b |
---|---|---|---|---|
Quantity… | Quantity… | Float64 | Float64 | |
1 | 0.0 hr | 0.0 hr | 0.0 | 0.0 |
2 | 1.0 hr | 0.5 hr | 1.0 | 0.5 |
3 | 2.0 hr | 1.0 hr | 2.0 | 1.0 |
4 | 3.0 hr | 1.5 hr | 3.0 | 1.5 |
5 | 4.0 hr | 2.0 hr | 4.0 | 2.0 |
6 | 5.0 hr | 2.5 hr | 5.0 | 2.5 |
timeunit
Specifies the time unit of the variable.
Used by: accumulate
, capture
Example
@system S(Controller) begin
a => 1 ~ accumulate(timeunit=u"d")
end
simulate(S; stop=2)
Row | time | a |
---|---|---|
Quantity… | Float64 | |
1 | 0.0 hr | 0.0 |
2 | 1.0 hr | 0.0416667 |
3 | 2.0 hr | 0.0833333 |
to
Specifies upper bound of integration.
Used by: integrate
Example
@system S(Controller) begin
w => 1 ~ preserve(parameter)
a => 0 ~ preserve(parameter)
b => π ~ preserve(parameter)
f(w; x) => w*sin(x) ~ integrate(from=a, to=b)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
w | = | 1.0 | |
a | = | 0.0 | |
b | = | 3.14159 | |
f | = | 2.0 |
tol
Defines the tolerance for the bisection method used in bisect
.
Used by: bisect
Example
@system S(Controller) begin
x(x) => x - 2.7 ~ bisect(lower=1, upper=3)
y(y) => y - 2.7 ~ bisect(lower=1, upper=3, tol=0.05)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
x | = | 2.7 | |
y | = | 2.71875 |
unit
Specifies the unit of the variable. The tag unit
can be omitted.
Used by: preserve
, track
, remember
, accumulate
, capture
, integrate
, advance
, drive
, tabulate
, interpolate
, solve
, bisect
, call
@system S(Controller) begin
a => 1 ~ preserve(unit=u"hr")
b => 1 ~ preserve(u"hr")
end
instance(S)
upper
Specifies the upper bound of solution.
Example
The solution is x = 1, 2, 3
@system S(Controller) begin
a => 1 ~ preserve(parameter)
b => -6 ~ preserve(parameter)
c => 11 ~ preserve(parameter)
d => -6 ~ preserve(parameter)
x(a, b, c, d) => begin
a*x^3 + b*x^2 + c*x + d
end ~ solve(upper=2.9)
end
instance(S)
S | |||
context | = | <Context> | |
config | = | <Config> | |
a | = | 1.0 | |
b | = | -6.0 | |
c | = | 11.0 | |
d | = | -6.0 | |
x | = | 2.0 |
when
Specifies when a variable should be evaluated. It is supplied with a flag
variable, and the specified variable is evaluated when the flag
variable is true
.
Used by: track
, flag
, remember
, accumulate
, capture
, produce
Example
@system S(Controller) begin
a ~ advance
flag(a) => (a >= 2) ~ flag
b(a) => a ~ track(when=flag)
end
simulate(S; stop=3u"hr")
Row | time | a | flag | b |
---|---|---|---|---|
Quantity… | Float64 | Bool | Float64 | |
1 | 0.0 hr | 0.0 | false | 0.0 |
2 | 1.0 hr | 1.0 | false | 0.0 |
3 | 2.0 hr | 2.0 | true | 2.0 |
4 | 3.0 hr | 3.0 | true | 3.0 |