Closed liunelson closed 4 months ago
Thanks for the detailed explanation! This currently happens any time a parameter is used in multiple rate laws. So e.g., if a parameter gamma
is used in two templates and is stratified into two parameters, it will result in 4 new parameters being generated. I agree it would be good to assign parameters in a more sophisticated way to have numbering only depend on the stratified concepts - I will come up with a way to achieve this.
I appreciate the consideration: the logic is probably tricky to implement!
I think the behaviour that the user wants us to support is more or less:
r
is decomposed into n
parameters, r = a * b * c * ...
n
times by N
strata eachn
parameter matrices of size N x N
, a -> a_0, a_1, ..., a_{N^2 - 1}
r
matrix of size N^(n-1) x N^(n-1)
(relevant in cases where the dynamics is not separable 🤷🏻 )@liunelson finally figured this one out. Parameter renaming now depends on the specific strata that were applied to the template that it is involved in. In addition, I added an additional argument to stratify
called param_renaming_uses_strata_names
which, when set to True, uses strata names in parameters.
Example:
In [1]: from mira.metamodel import *
In [2]: from mira.examples.sir import *
In [3]: for t in sir_parameterized.templates:
...: print(t.get_concept_names(), t.rate_law)
...:
{'susceptible_population', 'infected_population'} beta*infected_population*susceptible_population
{'immune_population', 'infected_population'} gamma*infected_population
In [4]: tm = stratify(sir_parameterized, key='age', strata=['young', 'old'], cartesian_control=True,
param_renaming_uses_strata_names=True)
In [5]: for t in tm.templates:
...: print(t.get_concept_names(), t.rate_law)
...:
{'susceptible_population_young', 'infected_population_young'} beta_young_young*infected_population_young*susceptible_population_young
{'susceptible_population_young', 'infected_population_old', 'infected_population_young'} beta_young_old*infected_population_old*susceptible_population_young
{'susceptible_population_old', 'infected_population_old', 'infected_population_young'} beta_old_young*infected_population_young*susceptible_population_old
{'susceptible_population_old', 'infected_population_old'} beta_old_old*infected_population_old*susceptible_population_old
{'infected_population_young', 'immune_population_young'} gamma_young*infected_population_young
{'infected_population_old', 'immune_population_old'} gamma_old*infected_population_old
{'susceptible_population_young', 'susceptible_population_old'} p_young_old*susceptible_population_young
{'susceptible_population_old', 'susceptible_population_young'} p_old_young*susceptible_population_old
{'infected_population_old', 'infected_population_young'} infected_population_young*p_young_old
{'infected_population_old', 'infected_population_young'} infected_population_old*p_old_young
{'immune_population_old', 'immune_population_young'} immune_population_young*p_young_old
{'immune_population_young', 'immune_population_old'} immune_population_old*p_old_young
This scenario came up during the Epi Eval Scenario 2 and the user found
Stratify
's handling of parameters undesirable and inconsistent with their expectation.I start with a simple compartmental SCRHD model (
I
renamed toC
to avoid imaginaryi
issue with sympy).I change the rate law between
C
andH
to be the productb * vaxCtoH * ageCtoH * C
based on the assumption that the vax status and age are independent demographic features.S, C
states anda, vaxCtoH
parametersI optionally add a vaccination process
I stratified the model again, this time by age on all states and parameters, except parameters
b, vaxCtoH_*
vaxCtoH
correctly depends only on vax status only and (b) the parameterageCtoH
incorrectly depends on both age and vax status. The user expected thatageCtoH
to be stratified by age only.actual but incorrect
ageCtoH -> ageCtoH -> ageCtoH_0, ageCtoH_1, ageCtoH_2, ageCtoH_3
expectation
ageCtoH -> ageCtoH -> ageCtoH_0, ageCtoH_1