Description
To make the package even better I want to make the suggestion to standardize the way you retrieve parameters and supply them to constructors. This standardization should be independent of the scale of the parameters, be it problem or inference space.
To illustrate why this is useful, I am currently trying to achieve the following.
I have an optimisation result and the original problem:
result::PEtabOptimisationResult
problem::PEtabODEProblem
Now I want to achieve the following:
- get xmin from the result
- save xmin somewhere in its problem scale, so linear
- take xmin and compute
problem.nllh
,problem.FIM
etc. - make a slight change in xmin and test the effect on the outputs
How to achieve this?
I go to the API and see what's available. I can get result.xmin
and pass it directly to problem.nllh
and it works, great. But xmin
is the in the inference scale, I want to save the parameters in linear scale. Well there is no method to do that, but I can do: xmin_lin = PEtab.get_ps(result, problem)
. But this method is missing the noise parameters? I want to save those too.
I can get the noise parameters from xmin however, and combine them with the linear parameters:
param_out = Dict(PEtab.get_ps(result, problem))
xmin = Dict(pairs(NamedTuple(result.xmin)))
param_out[:sigma_T_i] = xmin[:sigma_T_i]
param_out[:sigma_T_h] = xmin[:sigma_T_h]
return DataFrame(param_out)
But this is really ugly. If I want to remake
the problem, I have to supply:
remake(prob::PEtabODEProblem, xchange::Dict)
But where to get this dict? Also why is it a dict, why can't I pass my ComponentArray? Yeah okay, you can hardcode it, but for larger models this is not doable.
Lastly, I can use the very convenient get_x
to get my parameters on linear scale and in the right order. But to get my inference result in this format, I need to remake
it first with xmin
. But if I do that, the result from remake
is missing all of the parameters.
new_prob = remake(problem, xmin)
FIM = problem.FIM(get_x(new_prob))
So this fails with KeyError: key :log10_C_e not found
I think instead of passing results, dicts, componentarrays and parameter vectors around I think it would improve usability a lot if we had one single definition of a parameter object. So that each method takes the exact same object, knows at what scale (or is specified by the user) it is so that if it needs to put it in inference scale it can do that internally. It should not have to rely on the order of the parameter, or whether it's called log10_C_e
instead of C_e
.