Custom model types
The abstract supertype for all models is AbstractSem
, which has two subtypes, AbstractSemSingle{O, I, L, D}
and AbstractSemCollection
. Currently, there are 2 subtypes of AbstractSemSingle
: Sem
, SemFiniteDiff
. All subtypes of AbstractSemSingle
should have at least observed, imply, loss and optimizer fields, and share their types ({O, I, L, D}
) with the parametric abstract supertype. For example, the SemFiniteDiff
type is implemented as
struct SemFiniteDiff{
O <: SemObserved,
I <: SemImply,
L <: SemLoss,
D <: SemOptimizer} <: AbstractSemSingle{O, I, L, D}
observed::O
imply::I
loss::L
optimizer::Dend
Additionally, we need to define a method to compute at least the objective value, and if you want to use gradient based optimizers (which you most probably will), we need also to define a method to compute the gradient. For example, the respective fallback methods for all AbstractSemSingle
models are defined as
function objective!(model::AbstractSemSingle, parameters)
objective!(imply(model), parameters, model)
return objective!(loss(model), parameters, model)
end
function gradient!(gradient, model::AbstractSemSingle, parameters)
fill!(gradient, zero(eltype(gradient)))
gradient!(imply(model), parameters, model)
gradient!(gradient, loss(model), parameters, model)
end
Note that the gradient!
method takes a pre-allocated array that should be filled with the gradient values.
Additionally, we can define constructors like the one in "src/frontend/specification/Sem.jl"
.
It is also possible to add new subtypes for AbstractSemCollection
.