Closed tBuLi closed 5 years ago
Referencing #39
Don't worry, it's still very much a work in progress ;). The non-trivial comments I left open were things I wanted to think about carefully before implementing them.
For future reference: this mentiones how the hessian relates to the covariance matrix: https://www8.cs.umu.se/kurser/5DA001/HT07/lectures/lsq-handouts.pdf
My suggestion is to remove finite differences entirely, and to always use the Hessian of the objective to calculate covariances. This removes the discussion about using finite differences for optimization and will finally clean-up the mess that is covariance matrix calculation at this point.
My suggestion is to remove finite differences entirely, and to always use the Hessian of the objective to calculate covariances. This removes the discussion about using finite differences for optimization and will finally clean-up the mess that is covariance matrix calculation at this point.
Bad plan, we still need it to get a covariance matrix for e.g. ODEModels and NumericalModels. What we can do, however, is deprecate the finite difference Jacobian, and change it for a finite difference Hessian method. Or keep both next to each other.
This PR makes two big new changes: support for
sympy.MatrixExpr
as variables and as an indirect consequence it also adds component interdependence.Consider e.g.
This could be a great asset when
y
is expensive to compute and used multiple times. In such a model,y
is no longer a dependent variable, but rather an interdependent one.The big challenge here was how to calculate the Jacobian and Hessian for such a model, since also there we would like
D(z, a)
to be a function ofD(y, a)
:This PR so far addresses:
self.jacobian_model
andself.hessian_model
, which are models to represent those quantities.self.eval_[...]
calls the respective model and properly arranges the output. (The models just have a set of component representing the jacobian and hessian, so they need to be ordered properly.)eval_components
,eval_jacobian
, andeval_hessian
. Unless changed by a subclass,eval_components
callsnumerical_components
. The other two simply callself.jacobian_model
orself.hessian_model
.[x] All models now have an important new property:
connectivity_mapping
. This indicates for every component on which variables and parameters it depends. This is used in code generation when lambdifying symbolic expressions, such that every component is no longer assumed to depend on all independent variables and parameters, but is just provided with those it needs.For
BaseNumericalModel
subclasses such aconnectivity_mapping
should be provided, although the old syntax is also still supported.connectivity_mapping
, a topological sort can be performed to find the right evaluation order of the components. This is stored inordered_symbols
. This added a dependency to the very lightweight packagetoposort
.function_dict
, which is equivalent tomodel_dict
except that all variables have been turned intoFunction
objects and the sorting is based onordered_symbols
, not alphabetical.function_dict
instead though.