Parameter Sensitivity
This notebook uses the direct sensitivity solver in AutoReduce for a one-state decay model. Local sensitivity analysis is performed by solving the sensitivity equations alongside the original system, then comparing the result against an analytical expression.
Model
The model is
with solution \(x(t)=x_0e^{-kt}\). The sensitivity of the state with respect to \(k\) is
[ ]:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sympy import Symbol
from autoreduce import System, solve_sensitivity
x = Symbol("x")
k = Symbol("k")
system = System(
[x],
[-k * x],
params=[k],
params_values=[0.4],
x_init=[5.0],
C=np.array([[1.0]]),
)
Compute local sensitivities
solve_sensitivity returns an array indexed by time point, parameter, and state.
[ ]:
timepoints = np.linspace(0.0, 5.0, 1024)
sensitivities = solve_sensitivity(system, timepoints, normalize=False)
sensitivities.shape
Compare against analytical coefficients
For this model, the analytical expression is available, so it provides a compact check on the numerical sensitivity calculation.
[ ]:
x0 = system.x_init[0]
k_value = system.params_values[0]
analytical = -timepoints * x0 * np.exp(-k_value * timepoints)
numerical = sensitivities[:, 0, 0]
comparison = np.column_stack([timepoints, numerical, analytical])
comparison[:8]
Verify the sensitivity calculation
The maximum absolute error gives a direct numerical check of the computed sensitivity against the analytical expression.
[ ]:
absolute_error = np.abs(numerical - analytical)
max_absolute_error = float(np.max(absolute_error))
tolerance = 1e-6
assert max_absolute_error < tolerance
{
"max_absolute_error": max_absolute_error,
"tolerance": tolerance,
"passes": max_absolute_error < tolerance,
}
Plot a sensitivity heatmap
The heatmap shows how the local sensitivity of \(x\) to \(k\) changes over time.
[ ]:
fig, ax = plt.subplots(figsize=(10, 2.2))
sns.heatmap(
numerical.reshape(1, -1),
cmap="vlag",
center=0,
xticklabels=128,
yticklabels=[r"$\partial x / \partial k$"],
cbar_kws={"label": "Sensitivity"},
ax=ax,
)
ax.set_xlabel("Time index")
ax.set_ylabel("State/parameter pair")
ax.set_title("Sensitivity of x to k over time")
plt.tight_layout()