Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix sensitivities for models with events / extend and cleanup event tests #2084

Merged
merged 13 commits into from
May 16, 2023
2 changes: 1 addition & 1 deletion python/sdist/amici/de_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -2024,7 +2024,7 @@ def _compute_equation(self, name: str) -> None:
# This part only works if we use self.eq('xdot')
# instead of self.sym('xdot'). Not immediately clear
# why that is.
tmp_dxdp += smart_multiply(self.eq("xdot"), self.sym("stau").T)
tmp_dxdp += smart_multiply(self.eq("xdot_old"), self.sym("stau").T)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does seem plausible. Would argue though that self.sym("xdot_old") is more intuitive (should be the same, no?).

But the fact that this makes a difference does point to a more conceptual problem. If xdot needs to be evaluated before the event (which kinda makes sense), the same should also apply to ddeltaxdt, ddeltaxdx and ddeltaxdp. Probably best to add to derived state, add respective methods to model and compute these quantities pre-event. Probably worthwhile to come up with a testcase where this applies beforehand. Should be straightforward to do, use current testcase and change deltax such that ddeltaxdt, ddeltaxdx and ddeltaxdp have a dependency on x, i.e., are different pre- and post-event.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would argue though that self.sym("xdot_old") is more intuitive (should be the same, no?).

Yes, I already changed that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into that. I will merge this PR, as it clearly improves things already, and keep your suggestions for another one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS: Some of these cases are already covered:

python/tests/test_events.py::test_models[events_plus_heavisides]
ddeltaxdp [Matrix([
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0, 0,   0],
[0, 0, 0, 0, 0, 0, 0, 0,   0],
[0, 0, 0, 0, 0, 0, 0, 0, 1/3]]), Matrix([
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]])]
ddeltaxdx [Matrix([
[0, 0, -1/2],
[0, 0,    0],
[0, 0,    0]]), Matrix([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]), Matrix([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]), Matrix([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]), Matrix([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])]


python/tests/test_events.py::test_models[piecewise_plus_event_simple_case]
ddeltaxdp [Matrix([[0, 0, 1, 0]]), Matrix([[0, 0, 0, 0]]), Matrix([[0, 0, 0, 0]]), Matrix([[0, 0, 0, 0]])]
ddeltaxdx [Matrix([[-1]]), Matrix([[0]]), Matrix([[0]]), Matrix([[0]])]

python/tests/test_events.py::test_models[piecewise_plus_event_semi_complicated]
ddeltaxdp [Matrix([
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]), Matrix([
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]])]
ddeltaxdx [Matrix([
[-1, 0],
[ 0, 0]]), Matrix([
[0, 1],
[0, 0]]), Matrix([
[0, 0],
[0, 0]]), Matrix([
[0, 0],
[0, 0]]), Matrix([
[0, 0],
[0, 0]])]

Only non-zero ddeltaxdt seems to be missing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, they are non-zero, but not dependent on x. Noted.


# finish chain rule for the state variables
tmp_eq += smart_multiply(self.eq("ddeltaxdx")[ie], tmp_dxdp)
Expand Down