Parameters guide
Here we will describe the AIBECS interface. This guide will take you through some examples of setting up model parameters.
The parameters features in AIBECS essentially come from other packages. These include Parameters.jl, FieldMetadata.jl, Flatten.jl, Unitful.jl.
As usual, make sure you are using AIBECS
using AIBECS
Abstract parameters type
The AIBECS provides a set of features to create and use parameters. This features are implemented as functions that must be provided with a parameters type. But each set of parameters is different, and AIBECS cannot know beforehand what parameters you want to use. The AIBECS thus provides an abstract parameters type, called AbstractParameters
, upon which all the AIBECS functionality is built. This is why when you create a set of parameters in AIBECS, you must declare it as a subtype of AbstractParameters
. Here is an example.
struct SimpleParams{T} <: AbstractParameters{T}
α::T
β::T
end
Once the type, which here simply defines the symbols (α
and β
), is constructed, we can instantiate a parameter variable.
p = SimpleParams(1.0, 2.0)
Row │ Symbol Value
│ Symbol Float64
─────┼─────────────────
1 │ α 1.0
2 │ β 2.0
As you can see, the AIBECS will display p
as a table. This is because the show
method converts p
to a table (a DataFrame
to be specific) under the hood:
AIBECS.table(p)
Row | Symbol | Value |
---|---|---|
Symbol | Float64 | |
1 | α | 1.0 |
2 | β | 2.0 |
If you do not remember the order in which you created the parameters (α
is first, β
is second), AIBECS has got your back: keyword arguments are supported.
p = SimpleParams(β = 2.0, α = 1.0)
Row │ Symbol Value
│ Symbol Float64
─────┼─────────────────
1 │ α 1.0
2 │ β 2.0
Unpacking
Probably the most useful feature in AIBECS is the ability to elegantly unpack parameters, thanks to Parameters.jl.
@unpack α, β = p
α, β
(1.0, 2.0)
unpacks the parameters on the left (α
and β
) from the parameter type p
.
Units
One of the main features of parameters in AIBECS is that you can use units and let AIBECS do the conversions for you. Before you use units, though, you must import the @units
and units
functions from AIBECS. Here is an example.
import AIBECS: @units, units
@units struct UnitfulParams{T} <: AbstractParameters{T}
α::T | u"m/s"
β::T | u"d"
end
units (generic function with 11 methods)
Cretaing an instance is just as easy
p = UnitfulParams(1.0, 2.0)
Row │ Symbol Value Unit
│ Symbol Float64 FreeUnit…
─────┼────────────────────────────
1 │ α 1.0 m s⁻¹
2 │ β 2.0 d
And in this case the parameters are shown with units. You can rely on AIBECS to convert units on the fly.
p = UnitfulParams(3.0u"km/hr", 24.0u"hr")
Row │ Symbol Value Unit
│ Symbol Float64 FreeUnit…
─────┼─────────────────────────────
1 │ α 0.833333 m s⁻¹
2 │ β 1.0 d
And use keyword arguments
p = UnitfulParams(β = 24.0u"hr", α = 3.0u"km/hr")
Row │ Symbol Value Unit
│ Symbol Float64 FreeUnit…
─────┼─────────────────────────────
1 │ α 0.833333 m s⁻¹
2 │ β 1.0 d
Unpacking parameters that have units first converts them to SI units.
@unpack β = p
β
86400.0
and β
(which is equal to 1 day) here is expressed in seconds after being unpacked.
Initial values
Another useful feature is to set initial (or default) values. Again, you must import the functions for them to work properly
import AIBECS: @initial_value, initial_value
@initial_value struct ParamsWithInitialValue{T} <: AbstractParameters{T}
α::T | 1.0
β::T | 2.0
end
initial_value (generic function with 11 methods)
This is handy in many applications.
You can instantiate p
with the initial values as, well, its values.
p = ParamsWithInitialValue()
Row │ Symbol Value Initial value
│ Symbol Float64 Float64
─────┼────────────────────────────────
1 │ α 1.0 1.0
2 │ β 2.0 2.0
You could also just set one parameter to a different value
p = ParamsWithInitialValue(β = 10.0)
Row │ Symbol Value Initial value
│ Symbol Float64 Float64
─────┼────────────────────────────────
1 │ α 1.0 1.0
2 │ β 10.0 2.0
Combining initial values and units
You can combine both features in parameters.
@initial_value @units struct UnitfulParamsWithInitialValue{T} <: AbstractParameters{T}
α::T | 1.0 | u"m/s"
β::T | 2.0 | u"d"
end
initial_value (generic function with 13 methods)
And instantiate p
from just one parameter with its unit
p = UnitfulParamsWithInitialValue(β = 1.0u"yr")
Row │ Symbol Value Initial value Unit
│ Symbol Float64 Float64 FreeUnit…
─────┼───────────────────────────────────────────
1 │ α 1.0 1.0 m s⁻¹
2 │ β 365.25 2.0 d
Optimizable parameters
import AIBECS: @flattenable, flattenable
@flattenable struct OptimizableParams{T} <: AbstractParameters{T}
α::T | true
β::T | false
γ::T | true
end
flattenable (generic function with 12 methods)
Then the "flattenable" parameters will be the only ones to remain when converting OptimizableParams
to a vector
p = OptimizableParams(1.0, 2.0, 3.0)
v = vec(p)
2-element Vector{Float64}:
1.0
3.0
The vec
function uses the @unpack
function in AIBECS, so that units are converted when vectorizing. Here is an example of that by first combining units
and flattenable
.
@initial_value @units @flattenable struct OptimizableParamsWithUnits{T} <: AbstractParameters{T}
α::T | 1.0 | u"m/s" | true
β::T | 2.0 | u"d" | false
γ::T | 3.0 | u"km" | true
end
p = OptimizableParamsWithUnits()
Row │ Symbol Value Initial value Unit Optimizable
│ Symbol Float64 Float64 FreeUnit… Bool
─────┼────────────────────────────────────────────────────────
1 │ α 1.0 1.0 m s⁻¹ true
2 │ β 2.0 2.0 d false
3 │ γ 3.0 3.0 km true
And then vectorizing the parameters
vec(p)
2-element Vector{Float64}:
1.0
3000.0
Note how γ
(the third parameter, but the second flattenable one), is converted to meters.
Other features
Coming soon!
This page was generated using Literate.jl.