model.h Source File
|
CPP API
|
lct_secir_2_diseases/model.h
Go to the documentation of this file.
50 class Model : public CompartmentalModel<FP, InfectionState, LctPopulations<FP, LctStates...>, Parameters<FP>>
54 using Base = CompartmentalModel<FP, InfectionState, LctPopulations<FP, LctStates...>, Parameters<FP>>;
86 void get_derivatives(Eigen::Ref<const Eigen::VectorX<FP>> pop, Eigen::Ref<const Eigen::VectorX<FP>> y, FP t,
112 if (!(this->populations.get_num_compartments() == (size_t)subcompartments_ts.get_num_elements())) {
119 for (Eigen::Index timepoint = 0; timepoint < subcompartments_ts.get_num_time_points(); ++timepoint) {
149 void compress_vector(const Eigen::VectorX<FP>& subcompartments, Eigen::VectorX<FP>& compartments) const
151 static_assert((Group < num_groups) && (Group >= 0), "The template parameter Group should be valid.");
154 // Define first index of the group Group in a vector including all compartments without a resolution
183 void get_derivatives_impl(Eigen::Ref<const Eigen::VectorX<FP>> pop, Eigen::Ref<const Eigen::VectorX<FP>> y, FP t,
186 static_assert((Group < num_groups) && (Group >= 0), "The template parameter Group should be valid.");
203 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedNoSymptoms_1a>();
205 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedNoSymptoms_2a>();
207 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedNoSymptoms_1b>();
209 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedNoSymptoms_2b>();
211 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSymptoms_1a>();
213 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSymptoms_2a>();
215 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSymptoms_1b>();
217 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSymptoms_2b>();
219 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSevere_1a>();
221 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSevere_2a>();
223 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSevere_1b>();
225 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedSevere_2b>();
227 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedCritical_1a>();
229 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedCritical_2a>();
231 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedCritical_1b>();
233 first_index_group + LctStateGroup::template get_first_index<InfectionState::InfectedCritical_2b>();
234 size_t Ri_a = first_index_group + LctStateGroup::template get_first_index<InfectionState::Recovered_1a>();
235 size_t Ri_b = first_index_group + LctStateGroup::template get_first_index<InfectionState::Recovered_1b>();
236 size_t Ri_ab = first_index_group + LctStateGroup::template get_first_index<InfectionState::Recovered_2ab>();
237 size_t Di_a = first_index_group + LctStateGroup::template get_first_index<InfectionState::Dead_a>();
238 size_t Di_b = first_index_group + LctStateGroup::template get_first_index<InfectionState::Dead_b>();
242 // To split the outflow correctly, we need the proportion of people infected with each disease which only depends
243 // on the disease-specific parameters (not on e.g. the contact patterns or the seasonality), calculated in the interact function
248 FP div_part_both = ((part_a + part_b) < Limits<FP>::zero_tolerance()) ? 0.0 : 1.0 / (part_a + part_b);
255 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::Exposed_1a>(); subcomp++) {
257 // Ei_1a_first_index + subcomp is always the index of a (sub-)compartment of Exposed_1a and Ei_1a_first_index
268 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::Exposed_1b>(); subcomp++) {
270 // Ei_1a_first_index + subcomp is always the index of a (sub-)compartment of Exposed_1a and Ei_1b_first_index
282 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_1a>();
284 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_1a>() *
285 (1 / params.template get<TimeInfectedNoSymptoms_a<FP>>()[Group]) * y[INSi_1a_first_index + subcomp];
292 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_1b>();
294 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_1b>() *
295 (1 / params.template get<TimeInfectedNoSymptoms_b<FP>>()[Group]) * y[INSi_1b_first_index + subcomp];
303 dydt[Ri_a] = dydt[ISyi_1a_first_index] * params.template get<RecoveredPerInfectedNoSymptoms_a<FP>>()[Group];
305 dydt[ISyi_1a_first_index] * (1 - params.template get<RecoveredPerInfectedNoSymptoms_a<FP>>()[Group]);
307 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_1a>();
309 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_1a>() *
310 (1 / params.template get<TimeInfectedSymptoms_a<FP>>()[Group]) * y[ISyi_1a_first_index + subcomp];
317 dydt[Ri_b] = dydt[ISyi_1b_first_index] * params.template get<RecoveredPerInfectedNoSymptoms_b<FP>>()[Group];
319 dydt[ISyi_1b_first_index] * (1 - params.template get<RecoveredPerInfectedNoSymptoms_b<FP>>()[Group]);
321 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_1b>();
323 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_1b>() *
324 (1 / params.template get<TimeInfectedSymptoms_b<FP>>()[Group]) * y[ISyi_1b_first_index + subcomp];
331 dydt[Ri_a] += dydt[ISevi_1a_first_index] * (1 - params.template get<SeverePerInfectedSymptoms_a<FP>>()[Group]);
337 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSevere_1a>() *
338 (1 / params.template get<TimeInfectedSevere_a<FP>>()[Group]) * y[ISevi_1a_first_index + subcomp];
344 dydt[Ri_b] += dydt[ISevi_1b_first_index] * (1 - params.template get<SeverePerInfectedSymptoms_b<FP>>()[Group]);
350 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSevere_1b>() *
351 (1 / params.template get<TimeInfectedSevere_b<FP>>()[Group]) * y[ISevi_1b_first_index + subcomp];
357 // Split flow from last subcompartment of InfectedSevere_1a between Recovered_1a, Dead1a and InfectedCritical_1a.
358 dydt[Ri_a] += dydt[ICri_1a_first_index] * (1 - params.template get<CriticalPerSevere_a<FP>>()[Group] -
361 dydt[ICri_1a_first_index] = dydt[ICri_1a_first_index] * params.template get<CriticalPerSevere_a<FP>>()[Group];
363 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1a>() - 1;
365 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1a>() *
366 (1 / params.template get<TimeInfectedCritical_a<FP>>()[Group]) * y[ICri_1a_first_index + subcomp];
371 // Split flow from last subcompartment of InfectedSevere_1b between Recovered_1b, Dead_1b and InfectedCritical_1b.
372 dydt[Ri_b] += dydt[ICri_1b_first_index] * (1 - params.template get<CriticalPerSevere_b<FP>>()[Group] -
375 dydt[ICri_1b_first_index] = dydt[ICri_1b_first_index] * params.template get<CriticalPerSevere_b<FP>>()[Group];
377 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1b>() - 1;
379 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1b>() *
380 (1 / params.template get<TimeInfectedCritical_b<FP>>()[Group]) * y[ICri_1b_first_index + subcomp];
385 // Flow from InfectedCritical compartments has to be divided between Recovered and Dead compartments.
386 // Must be calculated separately in order not to overwrite the already calculated values for Recovered.
388 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1a>() *
393 LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1a>() - 1] -= flow;
397 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1b>() *
402 LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_1b>() - 1] -= flow;
419 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::Exposed_2a>(); subcomp++) {
421 // Ei_2a_first_index + subcomp is always the index of a (sub-)compartment of Exposed and Ei_2a_first_index
432 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::Exposed_2b>(); subcomp++) {
434 // Ei_2b_first_index + subcomp is always the index of a (sub-)compartment of Exposed and Ei_2b_first_index
445 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_2a>();
447 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_2a>() *
448 (1 / params.template get<TimeInfectedNoSymptoms_a<FP>>()[Group]) * y[INSi_2a_first_index + subcomp];
454 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_2b>();
456 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedNoSymptoms_2b>() *
457 (1 / params.template get<TimeInfectedNoSymptoms_b<FP>>()[Group]) * y[INSi_2b_first_index + subcomp];
465 dydt[Ri_ab] += dydt[ISyi_2a_first_index] * params.template get<RecoveredPerInfectedNoSymptoms_a<FP>>()[Group];
467 dydt[ISyi_2a_first_index] * (1 - params.template get<RecoveredPerInfectedNoSymptoms_a<FP>>()[Group]);
469 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_2a>();
471 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_2a>() *
472 (1 / params.template get<TimeInfectedSymptoms_a<FP>>()[Group]) * y[ISyi_2a_first_index + subcomp];
479 dydt[Ri_ab] += dydt[ISyi_2b_first_index] * params.template get<RecoveredPerInfectedNoSymptoms_b<FP>>()[Group];
481 dydt[ISyi_2b_first_index] * (1 - params.template get<RecoveredPerInfectedNoSymptoms_b<FP>>()[Group]);
483 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_2b>();
485 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSymptoms_2b>() *
486 (1 / params.template get<TimeInfectedSymptoms_b<FP>>()[Group]) * y[ISyi_2b_first_index + subcomp];
493 dydt[Ri_ab] += dydt[ISevi_2a_first_index] * (1 - params.template get<SeverePerInfectedSymptoms_a<FP>>()[Group]);
499 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSevere_2a>() *
500 (1 / params.template get<TimeInfectedSevere_a<FP>>()[Group]) * y[ISevi_2a_first_index + subcomp];
506 dydt[Ri_ab] += dydt[ISevi_2b_first_index] * (1 - params.template get<SeverePerInfectedSymptoms_b<FP>>()[Group]);
512 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedSevere_2b>() *
513 (1 / params.template get<TimeInfectedSevere_b<FP>>()[Group]) * y[ISevi_2b_first_index + subcomp];
519 // Split flow from last subcompartment of InfectedSevere_2a between Recovered_2ab, Dead_2ab and InfectedCritical_2a.
520 dydt[Ri_ab] += dydt[ICri_2a_first_index] * (1 - params.template get<CriticalPerSevere_a<FP>>()[Group] -
523 dydt[ICri_2a_first_index] = dydt[ICri_2a_first_index] * params.template get<CriticalPerSevere_a<FP>>()[Group];
525 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2a>() - 1;
527 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2a>() *
528 (1 / params.template get<TimeInfectedCritical_a<FP>>()[Group]) * y[ICri_2a_first_index + subcomp];
533 // Split flow from last subcompartment of InfectedSevere_2b between Recovered_2ab and InfectedCritical_2b.
534 dydt[Ri_ab] += dydt[ICri_2b_first_index] * (1 - params.template get<CriticalPerSevere_b<FP>>()[Group] -
537 dydt[ICri_2b_first_index] = dydt[ICri_2b_first_index] * params.template get<CriticalPerSevere_b<FP>>()[Group];
539 subcomp < LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2b>() - 1;
541 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2b>() *
542 (1 / params.template get<TimeInfectedCritical_b<FP>>()[Group]) * y[ICri_2b_first_index + subcomp];
548 // Must be calculated separately in order not to overwrite the already calculated values for Recovered.
550 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2a>() *
555 LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2a>() - 1] -= flow;
559 flow = (FP)LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2b>() *
564 LctStateGroup::template get_num_subcompartments<InfectionState::InfectedCritical_2b>() - 1] -= flow;
590 void interact(Eigen::Ref<const Eigen::VectorX<FP>> pop, Eigen::Ref<const Eigen::VectorX<FP>> y, FP t,
591 Eigen::Ref<Eigen::VectorX<FP>> dydt, double* part_a, double* part_b, int relevant_disease) const
647 FP N_group2 = pop.segment(first_index_group2, LctStateGroup2::Count).sum(); // Sum over all compartments.
648 N_group2 = N_group2 - pop.segment(LctStateGroup2::template get_first_index<InfectionState::Dead_a>(), 1).sum() -
655 FP contact_patterns = params.template get<ContactPatterns<FP>>().get_cont_freq_mat().get_matrix_at(
659 (params.template get<RelativeTransmissionNoSymptoms_a<FP>>()[Group2] * infectedNoSymptoms_group2_a +
660 params.template get<RiskOfInfectionFromSymptomatic_a<FP>>()[Group2] * infectedSymptoms_group2_a);
663 (params.template get<RelativeTransmissionNoSymptoms_b<FP>>()[Group2] * infectedNoSymptoms_group2_b +
664 params.template get<RiskOfInfectionFromSymptomatic_b<FP>>()[Group2] * infectedSymptoms_group2_b);
680 else if (relevant_disease == 2) { // Both diseases drive outflow from the Susceptible compartment.
682 dydt[compartment_index] += -y[compartment_index] * div_N_group2 * season_val * contact_patterns *
705 static_assert((Group < num_groups) && (Group >= 0), "The template parameter Group should be valid.");
709 log_warning("Constraint check: The number of subcompartments for Susceptibles of group {} should be one!",
716 log_warning("Constraint check: The number of subcompartments for Recovered of group {} should be one!",
722 log_warning("Constraint check: The number of subcompartments for Dead of group {} should be one!", Group);
A class template for compartment populations of LCT models.
Definition: lct_populations.h:57
size_t get_num_compartments() const
get_num_compartments Returns the number of compartments.
Definition: lct_populations.h:75
Typesafe wrapper for a floating-point simulation time value (in days).
Definition: damping.h:78
stores vectors of values at time points (or some other abstract variable) the value at each time poin...
Definition: time_series.h:58
Eigen::Index get_num_elements() const
number of elements of vector at each time point
Definition: time_series.h:205
Eigen::Index get_num_time_points() const
number of time points in the series
Definition: time_series.h:197
FP & get_time(Eigen::Index i)
time of time point at index i
Definition: time_series.h:272
Eigen::Ref< Vector > add_time_point()
add one uninitialized time point
Definition: time_series.h:221
Class that defines an LCT-SECIR-2-DISEASE model.
Definition: lct_secir_2_diseases/model.h:51
void interact(Eigen::Ref< const Eigen::VectorX< FP >> pop, Eigen::Ref< const Eigen::VectorX< FP >> y, FP t, Eigen::Ref< Eigen::VectorX< FP >> dydt, double *part_a, double *part_b, int relevant_disease) const
Calculates flows that are caused by people becoming infected (outflow from compartment S,...
Definition: lct_secir_2_diseases/model.h:590
void get_derivatives(Eigen::Ref< const Eigen::VectorX< FP >> pop, Eigen::Ref< const Eigen::VectorX< FP >> y, FP t, Eigen::Ref< Eigen::VectorX< FP >> dydt) const override
Evaluates the right-hand-side f of the ODE dydt = f(y, t).
Definition: lct_secir_2_diseases/model.h:86
TimeSeries< FP > calculate_compartments(const TimeSeries< FP > &subcompartments_ts) const
Cumulates a simulation result with subcompartments to produce a result that divides the population on...
Definition: lct_secir_2_diseases/model.h:107
static constexpr size_t num_groups
Definition: lct_secir_2_diseases/model.h:57
void compress_vector(const Eigen::VectorX< FP > &subcompartments, Eigen::VectorX< FP > &compartments) const
Converts a vector with subcompartments in a vector without subcompartments by summing up subcompartme...
Definition: lct_secir_2_diseases/model.h:149
bool check_constraints_impl() const
Checks whether LctState of a group satisfies all constraints.
Definition: lct_secir_2_diseases/model.h:703
Model(const Populations &pop, const ParameterSet ¶ms)
Constructor using Populations and ParameterSet.
Definition: lct_secir_2_diseases/model.h:70
void get_derivatives_impl(Eigen::Ref< const Eigen::VectorX< FP >> pop, Eigen::Ref< const Eigen::VectorX< FP >> y, FP t, Eigen::Ref< Eigen::VectorX< FP >> dydt) const
Evaluates the right-hand-side f of the ODE dydt = f(y, t) recursively for each group.
Definition: lct_secir_2_diseases/model.h:183
bool check_constraints() const
Checks that the model satisfies all constraints (e.g.
Definition: lct_secir_2_diseases/model.h:131
Parameters of an LCT-SECIR-2-DISEASES model.
Definition: lct_secir_2_diseases/parameters.h:538
ad::internal::unary_intermediate< AD_TAPE_REAL, ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 >, ad::operations::ad_sin< AD_TAPE_REAL > > sin(const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &x1)
Definition: ad.hpp:913
InfectionState
The InfectionState enum describes the basic categories for the infection state of persons.
Definition: lct_secir_2_diseases/infection_state.h:34
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
void log_warning(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:126
typename type_at_index< Index, Types... >::type type_at_index_t
The type at the Index-th position in the list Types.
Definition: metaprogramming.h:118
void log_error(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:114
constexpr std::tuple_element< I, std::tuple< Index< CategoryTags >... > >::type & get(Index< CategoryTags... > &i) noexcept
Retrieves the Index (by reference) at the Ith position of a MultiIndex.
Definition: index.h:304
CompartmentalModel is a template for a compartmental model for an array of initial populations and a ...
Definition: compartmental_model.h:59
Populations populations
Definition: compartmental_model.h:156
LctPopulations< FP, LctStates... > Populations
Definition: compartmental_model.h:62
Parameters< FP > ParameterSet
Definition: compartmental_model.h:63
ParameterSet parameters
Definition: compartmental_model.h:157
Collection of types. Each type is mapped to an index of type size_t.
Definition: type_list.h:32
The percentage of dead patients per hospitalized patients for disease a for each group.
Definition: lct_secir_2_diseases/parameters.h:377
The percentage of dead patients per hospitalized patients for disease b for each group.
Definition: lct_secir_2_diseases/parameters.h:457
The relative InfectedNoSymptoms infectability for disease a for each group.
Definition: lct_secir_2_diseases/parameters.h:265
The relative InfectedNoSymptoms infectability for disease b for each group.
Definition: lct_secir_2_diseases/parameters.h:297
The start day in the LCT-SECIR-2-DISEASES model.
Definition: lct_secir_2_diseases/parameters.h:492
Generated by