Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 22 additions & 23 deletions cpp/examples/lct_secir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,59 +47,58 @@ int main()
{50}, {10, 10, 5, 3, 2}, {20}, {10}};

// Assert that initial_populations has the right shape.
if (initial_populations.size() != (int)LctState::InfectionState::Count) {
if (initial_populations.size() != (size_t)LctState::InfectionState::Count) {
mio::log_error("The number of vectors in initial_populations does not match the number of InfectionStates.");
return 1;
}
if ((initial_populations[(int)LctState::InfectionState::Susceptible].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::Susceptible>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::Susceptible>()) ||
(initial_populations[(int)LctState::InfectionState::Exposed].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::Exposed>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::Exposed>()) ||
(initial_populations[(int)LctState::InfectionState::InfectedNoSymptoms].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::InfectedNoSymptoms>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::InfectedNoSymptoms>()) ||
(initial_populations[(int)LctState::InfectionState::InfectedSymptoms].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::InfectedSymptoms>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::InfectedSymptoms>()) ||
(initial_populations[(int)LctState::InfectionState::InfectedSevere].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::InfectedSevere>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::InfectedSevere>()) ||
(initial_populations[(int)LctState::InfectionState::InfectedCritical].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::InfectedCritical>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::InfectedCritical>()) ||
(initial_populations[(int)LctState::InfectionState::Recovered].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::Recovered>()) ||
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::Recovered>()) ||
(initial_populations[(int)LctState::InfectionState::Dead].size() !=
LctState::get_num_subcompartments<LctState::InfectionState::Dead>())) {
(size_t)LctState::get_num_subcompartments<LctState::InfectionState::Dead>())) {
mio::log_error("The length of at least one vector in initial_populations does not match the related number of "
"subcompartments.");
return 1;
}

// Transfer the initial values in initial_populations to the vector init.
Eigen::VectorXd init = Eigen::VectorXd::Zero(LctState::Count);
init[(int)LctState::get_first_index<LctState::InfectionState::Susceptible>()] =
init[LctState::get_first_index<LctState::InfectionState::Susceptible>()] =
initial_populations[(int)LctState::InfectionState::Susceptible][0];
for (unsigned int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::Exposed>(); i++) {
init[(int)LctState::get_first_index<LctState::InfectionState::Exposed>() + i] =
for (int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::Exposed>(); i++) {
init[LctState::get_first_index<LctState::InfectionState::Exposed>() + i] =
initial_populations[(int)LctState::InfectionState::Exposed][i];
}
for (unsigned int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedNoSymptoms>();
i++) {
init[(int)LctState::get_first_index<LctState::InfectionState::InfectedNoSymptoms>() + i] =
for (int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedNoSymptoms>(); i++) {
init[LctState::get_first_index<LctState::InfectionState::InfectedNoSymptoms>() + i] =
initial_populations[(int)LctState::InfectionState::InfectedNoSymptoms][i];
}
for (unsigned int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedSymptoms>(); i++) {
init[(int)LctState::get_first_index<LctState::InfectionState::InfectedSymptoms>() + i] =
for (int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedSymptoms>(); i++) {
init[LctState::get_first_index<LctState::InfectionState::InfectedSymptoms>() + i] =
initial_populations[(int)LctState::InfectionState::InfectedSymptoms][i];
}
for (unsigned int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedSevere>(); i++) {
init[(int)LctState::get_first_index<LctState::InfectionState::InfectedSevere>() + i] =
for (int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedSevere>(); i++) {
init[LctState::get_first_index<LctState::InfectionState::InfectedSevere>() + i] =
initial_populations[(int)LctState::InfectionState::InfectedSevere][i];
}
for (unsigned int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedCritical>(); i++) {
init[(int)LctState::get_first_index<LctState::InfectionState::InfectedCritical>() + i] =
for (int i = 0; i < LctState::get_num_subcompartments<LctState::InfectionState::InfectedCritical>(); i++) {
init[LctState::get_first_index<LctState::InfectionState::InfectedCritical>() + i] =
initial_populations[(int)LctState::InfectionState::InfectedCritical][i];
}
init[(int)LctState::get_first_index<LctState::InfectionState::Recovered>()] =
init[LctState::get_first_index<LctState::InfectionState::Recovered>()] =
initial_populations[(int)LctState::InfectionState::Recovered][0];
init[(int)LctState::get_first_index<LctState::InfectionState::Dead>()] =
init[LctState::get_first_index<LctState::InfectionState::Dead>()] =
initial_populations[(int)LctState::InfectionState::Dead][0];

// Initialize model.
Expand Down
19 changes: 10 additions & 9 deletions cpp/memilio/epidemiology/lct_infection_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ namespace mio
* @tparam Ns Number of subcompartments for each infection state defined in InfectionState.
* The number of given template arguments must be equal to the entry Count from InfectionState.
*/
template <class InfectionStates, unsigned int... Ns>
template <class InfectionStates, int... Ns>
class LctInfectionState
{
public:
using InfectionState = InfectionStates;
static_assert((unsigned int)InfectionState::Count == sizeof...(Ns),
static_assert((size_t)InfectionState::Count == sizeof...(Ns),
"The number of integers provided as template parameters must be "
"the same as the entry Count of InfectionState.");

Expand All @@ -46,10 +46,10 @@ class LctInfectionState
* @brief Gets the number of subcompartments in an infection state.
*
* @tparam State: Infection state for which the number of subcompartments should be returned.
* @return Number of subcompartments for State.
* @return Number of subcompartments for State. Returned value is always at least one.
*/
template <InfectionState State>
static constexpr unsigned int get_num_subcompartments()
static constexpr int get_num_subcompartments()
Comment thread
lenaploetzke marked this conversation as resolved.
{
static_assert(State < InfectionState::Count, "State must be a a valid InfectionState.");
return m_subcompartment_numbers[(int)State];
Expand All @@ -61,23 +61,24 @@ class LctInfectionState
* In a simulation, the number of individuals in the subcompartments are stored in vectors.
* Accordingly, the index of the first subcompartment of State in such a vector is returned.
* @tparam State: Infection state for which the index should be returned.
* @return Index of the first subcompartment for a vector with one entry per subcompartment.
* @return Index of the first subcompartment for a vector with one entry per subcompartment.
* Returned value is always non-negative.
*/
template <InfectionState State>
static constexpr unsigned int get_first_index()
static constexpr int get_first_index()
Comment thread
lenaploetzke marked this conversation as resolved.
{
static_assert(State < InfectionState::Count, "State must be a a valid InfectionState.");
unsigned int index = 0;
int index = 0;
for (int i = 0; i < (int)(State); i++) {
index = index + m_subcompartment_numbers[i];
}
return index;
}

static constexpr unsigned int Count{(... + Ns)};
static constexpr int Count{(... + Ns)};

private:
static constexpr const std::array<unsigned int, sizeof...(Ns)> m_subcompartment_numbers{
static constexpr const std::array<int, sizeof...(Ns)> m_subcompartment_numbers{
Ns...}; ///< Vector which defines the number of subcompartments for each infection state of InfectionState.
};

Expand Down
8 changes: 4 additions & 4 deletions cpp/models/lct_secir/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ namespace lsecir
* @tparam NumInfectedSevere The number of subcompartents used for the InfectedSevere compartment.
* @tparam NumInfectedCritical The number of subcompartents used for the InfectedCritical compartment.
*/
template <unsigned int NumExposed, unsigned int NumInfectedNoSymptoms, unsigned int NumInfectedSymptoms,
unsigned int NumInfectedSevere, unsigned int NumInfectedCritical>
template <int NumExposed, int NumInfectedNoSymptoms, int NumInfectedSymptoms, int NumInfectedSevere,
int NumInfectedCritical>
class Model
{

Expand Down Expand Up @@ -75,7 +75,7 @@ class Model
log_error("Size of the initial values does not match subcompartments.");
return true;
}
for (unsigned int i = 0; i < LctState::Count; i++) {
for (int i = 0; i < LctState::Count; i++) {
if (m_initial_values[i] < 0) {
log_warning(
"Initial values for one subcompartment are less than zero. Simulation results are not realistic.");
Expand Down Expand Up @@ -291,7 +291,7 @@ class Model
void set_initial_values(Eigen::VectorXd init)
{
m_initial_values = init;
m_N0 = m_initial_values.sum();
m_N0 = m_initial_values.sum();
}

Parameters parameters{}; ///< Parameters of the model.
Expand Down
13 changes: 6 additions & 7 deletions cpp/models/lct_secir/parameters_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ IOResult<void> set_initial_data_from_confirmed_cases(Model& model, const std::st
int idxInfectedNoSymptoms_last =
LctState::template get_first_index<InfectionState::InfectedNoSymptoms>() +
LctState::template get_num_subcompartments<InfectionState::InfectedNoSymptoms>() - 1;
for (int i = 0;
i < (int)LctState::template get_num_subcompartments<InfectionState::InfectedNoSymptoms>(); i++) {
for (int i = 0; i < LctState::template get_num_subcompartments<InfectionState::InfectedNoSymptoms>();
i++) {
if (offset == std::floor(i * timeInfectedNoSymptoms_i)) {
init[idxInfectedNoSymptoms_last - i] -=
(1 - (i * timeInfectedNoSymptoms_i - std::floor(i * timeInfectedNoSymptoms_i))) *
Expand Down Expand Up @@ -152,7 +152,7 @@ IOResult<void> set_initial_data_from_confirmed_cases(Model& model, const std::st
// Index of the last subcompartment of Exposed.
int idxExposed_last = LctState::template get_first_index<InfectionState::Exposed>() +
LctState::template get_num_subcompartments<InfectionState::Exposed>() - 1;
for (int i = 0; i < (int)LctState::template get_num_subcompartments<InfectionState::Exposed>(); i++) {
for (int i = 0; i < LctState::template get_num_subcompartments<InfectionState::Exposed>(); i++) {
if (offset == std::floor(timeInfectedNoSymptoms + i * timeExposed_i)) {
init[idxExposed_last - i] -= (1 - (timeInfectedNoSymptoms + i * timeExposed_i -
std::floor(timeInfectedNoSymptoms + i * timeExposed_i))) *
Expand Down Expand Up @@ -185,7 +185,7 @@ IOResult<void> set_initial_data_from_confirmed_cases(Model& model, const std::st
(ScalarType)LctState::template get_num_subcompartments<InfectionState::InfectedSymptoms>();
// Index of the first subcompartment of InfectedSymptoms.
int idxInfectedSymptoms_first = LctState::template get_first_index<InfectionState::InfectedSymptoms>();
for (int i = 0; i < (int)LctState::template get_num_subcompartments<InfectionState::InfectedSymptoms>();
for (int i = 0; i < LctState::template get_num_subcompartments<InfectionState::InfectedSymptoms>();
i++) {
if (offset == std::floor(-timeInfectedSymptoms_i * (i + 1))) {
init[idxInfectedSymptoms_first + i] -=
Expand Down Expand Up @@ -221,8 +221,7 @@ IOResult<void> set_initial_data_from_confirmed_cases(Model& model, const std::st
ScalarType prob_SeverePerInfectedSymptoms = model.parameters.template get<SeverePerInfectedSymptoms>();
// Index of the first subcompartment of InfectedSevere.
int idxInfectedSevere_first = LctState::template get_first_index<InfectionState::InfectedSevere>();
for (int i = 0; i < (int)LctState::template get_num_subcompartments<InfectionState::InfectedSevere>();
i++) {
for (int i = 0; i < LctState::template get_num_subcompartments<InfectionState::InfectedSevere>(); i++) {
if (offset == std::floor(-timeInfectedSymptoms - timeInfectedSevere_i * (i + 1))) {
init[idxInfectedSevere_first + i] -=
prob_SeverePerInfectedSymptoms *
Expand Down Expand Up @@ -265,7 +264,7 @@ IOResult<void> set_initial_data_from_confirmed_cases(Model& model, const std::st
ScalarType prob_CriticalPerSevere = model.parameters.template get<CriticalPerSevere>();
// Index of the first subcompartment of InfectedCritical.
int idxInfectedCritical_first = LctState::template get_first_index<InfectionState::InfectedCritical>();
for (int i = 0; i < (int)LctState::template get_num_subcompartments<InfectionState::InfectedCritical>();
for (int i = 0; i < LctState::template get_num_subcompartments<InfectionState::InfectedCritical>();
i++) {
if (offset ==
std::floor(-timeInfectedSymptoms - timeInfectedSevere - timeInfectedCritical_i * (i + 1))) {
Expand Down
2 changes: 1 addition & 1 deletion cpp/tests/test_lct_parameters_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ TEST(TestLCTParametersIo, ReadPopulationDataRKI)
Eigen::VectorXd compare(LctState::Count);
compare << 863.05, 14.30625, 8.53125, 30.1125, 36.1875, 3.8125, 9.88, 3.52, 0.09, 0.25, 0.6888, 27.8712, 1.7;

for (unsigned int i = 0; i < LctState::Count; i++) {
for (int i = 0; i < LctState::Count; i++) {
EXPECT_NEAR(model.get_initial_values()[i], compare[i], 1e-4) << "at subcompartment number " << i;
}
}
Expand Down
10 changes: 5 additions & 5 deletions cpp/tests/test_lct_secir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,15 @@ TEST(TestLCTSecir, testEvalRightHandSide)
model.parameters.get<mio::lsecir::DeathsPerCritical>() = 0.3;

// Compare the result of eval_right_hand_side() with a hand calculated result.
unsigned int num_subcompartments = LctState::Count;
int num_subcompartments = LctState::Count;
Eigen::VectorXd dydt(num_subcompartments);
model.eval_right_hand_side(model.get_initial_values(), 0, dydt);

Eigen::VectorXd compare(num_subcompartments);
compare << -15.3409, -3.4091, 6.25, -17.5, 15, 0, 3.3052, 3.4483, -7.0417, 6.3158, -2.2906, -2.8169, 12.3899,
1.6901;

for (unsigned int i = 0; i < num_subcompartments; i++) {
for (int i = 0; i < num_subcompartments; i++) {
ASSERT_NEAR(compare[i], dydt[i], 1e-3);
}
}
Expand Down Expand Up @@ -460,17 +460,17 @@ TEST(TestLCTSecir, testConstraints)
using LctState = Model::LctState;

// Check wrong size of initial value vector.
Model model1(std::move(Eigen::VectorXd::Ones((int)LctState::Count - 1)), std::move(parameters_lct));
Model model1(std::move(Eigen::VectorXd::Ones(LctState::Count - 1)), std::move(parameters_lct));
constraint_check = model1.check_constraints();
EXPECT_TRUE(constraint_check);

// Check with values smaller than zero.
Model model2(std::move(Eigen::VectorXd::Constant((int)LctState::Count, -1)), std::move(parameters_lct));
Model model2(std::move(Eigen::VectorXd::Constant(LctState::Count, -1)), std::move(parameters_lct));
constraint_check = model2.check_constraints();
EXPECT_TRUE(constraint_check);

// Check with correct conditions.
Model model3(std::move(Eigen::VectorXd::Constant((int)LctState::Count, 1)));
Model model3(std::move(Eigen::VectorXd::Constant(LctState::Count, 1)));
constraint_check = model3.check_constraints();
EXPECT_FALSE(constraint_check);

Expand Down