Skip to content

Commit

Permalink
simplify, stricter tolerances, dbg output
Browse files Browse the repository at this point in the history
  • Loading branch information
dweindl committed Oct 9, 2024
1 parent f66c6a5 commit 8559b8e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 36 deletions.
41 changes: 15 additions & 26 deletions python/sdist/amici/de_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1719,13 +1719,13 @@ def _compute_equation(self, name: str) -> None:
elif name == "deltaxB":
event_eqs = []
for ie, event in enumerate(self._events):
# ==== 1st group of terms: Heaviside functions ===========
tmp_eq = smart_multiply(
self.sym("xdot") - self.sym("xdot_old"),
self.eq("dtaudx")[ie],
)
if event._state_update is not None:
# ==== 1st group of terms : Heaviside functions ===========
tmp_eq = smart_multiply(
self.sym("xdot") - self.sym("xdot_old"),
self.eq("dtaudx")[ie],
)
# ==== 2nd group of terms : Derivatives of Dirac deltas ===
# ==== 2nd group of terms: Derivatives of Dirac deltas ===
# Part 2a: explicit time dependence of bolus function
tmp_eq -= smart_multiply(

Check warning on line 1730 in python/sdist/amici/de_model.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/de_model.py#L1730

Added line #L1730 was not covered by tests
self.eq("ddeltaxdt")[ie], self.eq("dtaudx")[ie]
Expand All @@ -1737,28 +1737,22 @@ def _compute_equation(self, name: str) -> None:
),
self.eq("dtaudx")[ie],
)
# ==== 3rd group of terms : Dirac deltas ==================
# ==== 3rd group of terms: Dirac deltas ==================
tmp_eq += self.eq("ddeltaxdx")[ie]

Check warning on line 1741 in python/sdist/amici/de_model.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/de_model.py#L1741

Added line #L1741 was not covered by tests
tmp_eq = smart_multiply(self.sym("xB").T, tmp_eq)
else:
tmp_eq = smart_multiply(
self.sym("xdot") - self.sym("xdot_old"),
self.eq("dtaudx")[ie],
)
tmp_eq = smart_multiply(self.sym("xB").T, tmp_eq)
tmp_eq = smart_multiply(self.sym("xB").T, tmp_eq)
event_eqs.append(tmp_eq)
self._eqs[name] = event_eqs

elif name == "deltaqB":
event_eqs = []
for ie, event in enumerate(self._events):
# ==== 1st group of terms: Heaviside functions ===========
tmp_eq = smart_multiply(
self.sym("xdot") - self.sym("xdot_old"),
self.eq("dtaudp")[ie],
)
if event._state_update is not None:
# ==== 1st group of terms : Heaviside functions ===========
tmp_eq = smart_multiply(
self.sym("xdot") - self.sym("xdot_old"),
self.eq("dtaudp")[ie],
)
# ==== 2nd group of terms : Derivatives of Dirac deltas ===
# ==== 2nd group of terms: Derivatives of Dirac deltas ===
# Part 2a: explicit time dependence of bolus function
tmp_eq -= smart_multiply(

Check warning on line 1757 in python/sdist/amici/de_model.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/de_model.py#L1757

Added line #L1757 was not covered by tests
self.eq("ddeltaxdt")[ie], self.eq("dtaudp")[ie]
Expand All @@ -1770,13 +1764,8 @@ def _compute_equation(self, name: str) -> None:
),
self.eq("dtaudp")[ie],
)
# ==== 3rd group of terms : Dirac deltas ==================
# ==== 3rd group of terms: Dirac deltas ==================
tmp_eq += self.eq("ddeltaxdp")[ie]

Check warning on line 1768 in python/sdist/amici/de_model.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/de_model.py#L1768

Added line #L1768 was not covered by tests
else:
tmp_eq = smart_multiply(
self.sym("xdot") - self.sym("xdot_old"),
self.eq("dtaudp")[ie],
)
event_eqs.append(smart_multiply(self.sym("xB").T, tmp_eq))
self._eqs[name] = event_eqs

Expand Down
37 changes: 27 additions & 10 deletions python/tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import libsbml
import numpy as np
import pandas as pd

from amici import (
AmiciModel,
ExpData,
Expand Down Expand Up @@ -185,30 +187,44 @@ def check_trajectories_with_adjoint_sensitivities(amici_model: AmiciModel):
solver = amici_model.getSolver()
solver.setSensitivityOrder(SensitivityOrder.first)
solver.setSensitivityMethod(SensitivityMethod.forward)
solver.setAbsoluteTolerance(1e-15)
solver.setRelativeTolerance(1e-10)
solver.setAbsoluteTolerance(1e-16)
solver.setRelativeTolerance(1e-14)
rdata_fsa = runAmiciSimulation(amici_model, solver=solver, edata=edata)

# Show that we can do arbitrary precision here (test 8 digits)
solver = amici_model.getSolver()
solver.setSensitivityOrder(SensitivityOrder.first)
solver.setSensitivityMethod(SensitivityMethod.adjoint)
solver.setAbsoluteTolerance(1e-15)
solver.setRelativeTolerance(1e-10)
solver.setAbsoluteToleranceB(1e-15)
solver.setRelativeToleranceB(1e-10)
solver.setAbsoluteToleranceQuadratures(1e-15)
solver.setRelativeToleranceQuadratures(1e-8)
solver.setAbsoluteTolerance(1e-16)
solver.setRelativeTolerance(1e-14)
solver.setAbsoluteToleranceB(1e-16)
solver.setRelativeToleranceB(1e-15)
solver.setAbsoluteToleranceQuadratures(1e-16)
solver.setRelativeToleranceQuadratures(1e-10)
rdata_asa = runAmiciSimulation(amici_model, solver=solver, edata=edata)

assert_allclose(rdata_fsa.x, rdata_asa.x, atol=1e-14, rtol=1e-10)
assert_allclose(rdata_fsa.llh, rdata_asa.llh, atol=1e-14, rtol=1e-10)
df = pd.DataFrame(
{
"fsa": rdata_fsa["sllh"],
"asa": rdata_asa["sllh"],
"fd": np.nan,
},
index=list(amici_model.getParameterIds()),
)
df["abs_diff"] = df["fsa"] - df["asa"]
df["rel_diff"] = df["abs_diff"] / df["fsa"]
print(df)

# Also test against finite differences
parameters = amici_model.getUnscaledParameters()
sllh_fd = []
eps = 1e-5
for i_par, par in enumerate(parameters):
solver = amici_model.getSolver()
solver.setSensitivityOrder(SensitivityOrder.none)
solver.setSensitivityMethod(SensitivityMethod.none)
solver.setSensitivityOrder(SensitivityOrder.first)
solver.setSensitivityMethod(SensitivityMethod.adjoint)
solver.setAbsoluteTolerance(1e-15)
solver.setRelativeTolerance(1e-13)
tmp_par = np.array(parameters[:])
Expand All @@ -220,6 +236,7 @@ def check_trajectories_with_adjoint_sensitivities(amici_model: AmiciModel):
amici_model.setParameters(tmp_par)
rdata_m = runAmiciSimulation(amici_model, solver=solver, edata=edata)
sllh_fd.append((rdata_p["llh"] - rdata_m["llh"]) / (2 * eps))
df["fd"] = sllh_fd

# test less strict in terms of absolute error, as the gradient are
# typically in the order of 1e3
Expand Down

0 comments on commit 8559b8e

Please sign in to comment.