Recently I revisited some old Julia code of mine and wondered how to implement it properly.
The setting is: I have a model
struct which holds some model definition. Let’s say, each model just describes some system of equations which we want to solve for all variables x[i]
:
struct model
equations::String # just to simplify (no strings in reality)
end
a = model("x[1] = x[2] and x[2] = 0")
b = model("x[1] = x[2] + 1 and x[2] = 0")
Therefore, I want to have a function solve(foo::model)
which returns [0, 0]
for a
and [1, 0]
in the case of b
. For that reason, I have some macro which autogenerates the functions
function f_a!(F, x)
F[1] = x[2] - x[1]
F[2] = -x[2]
end
and
function f_b!(F, x)
F[1] = x[2] + 1 - x[1]
F[2] = -x[2]
end
These allow us to formulate the model problem as F(x) = 0 and we can plug the respective function into NLsolve.jl.
My simple question is now: How do we properly identify the model foo
with the function f_foo!
inside the function solve
? After all, all models have the same type. My first intention is to just add some field id
or name
which can then be used inside solve
. However, assume we have 1000 models loaded, then this is associated with runtime costs.
We could also have a new field f!::Function
in every model which holds the correct function. This seems kinda odd.
Furthermore, if I define a new type for every model instead, it is not a good user experience. Of course I could hide them with some kind of composition:
struct model
equations <: AbstractEquations
end
and then have the structs Equations1
, Equations2
etc. for each new model.
But I guess I am overthinking this way too much. Any suggestions?