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?