Skip to content

Commit d367215

Browse files
committed
generalize Region and State
1 parent 97e7dc6 commit d367215

File tree

11 files changed

+311
-320
lines changed

11 files changed

+311
-320
lines changed

cpp/examples/smm.cpp

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
* limitations under the License.
1919
*/
2020

21+
#include "memilio/config.h"
2122
#include "memilio/epidemiology/age_group.h"
2223
#include "smm/simulation.h"
2324
#include "smm/model.h"
2425
#include "smm/parameters.h"
2526
#include "memilio/data/analyze_result.h"
26-
#include "memilio/epidemiology/adoption_rate.h"
2727

2828
enum class InfectionState
2929
{
@@ -36,78 +36,71 @@ enum class InfectionState
3636
Count
3737
};
3838

39-
using Age = mio::AgeGroup;
40-
using Species = mio::AgeGroup;
39+
struct Species : public mio::Index<Species> {
40+
Species(size_t val)
41+
: Index<Species>(val)
42+
{
43+
}
44+
};
4145

4246
int main()
4347
{
48+
using Age = mio::AgeGroup;
49+
using Status = mio::Index<InfectionState, Age, Species>;
50+
using mio::regions::Region;
51+
using enum InfectionState;
4452

4553
//Example how to run the stochastic metapopulation models with four regions
4654
const size_t num_regions = 4;
4755
const size_t num_age_groups = 1;
48-
const size_t num_groups = 1;
49-
using Model = mio::smm::Model<ScalarType, num_regions, InfectionState, num_age_groups, num_groups>;
56+
const size_t num_species = 1;
57+
using Model = mio::smm::Model<ScalarType, InfectionState, Status, Region>;
5058

5159
ScalarType numE = 12, numC = 4, numI = 12, numR = 0, numD = 0;
5260

53-
Model model;
61+
Model model(Status{Count, Age(num_age_groups), Species(num_species)}, Region(num_regions));
5462
//Population are distributed uniformly to the four regions
5563
for (size_t r = 0; r < num_regions; ++r) {
56-
model.populations[{mio::regions::Region(r), InfectionState::S, Age(0), Species(0)}] =
57-
(1000 - numE - numC - numI - numR - numD) / num_regions;
58-
model.populations[{mio::regions::Region(r), InfectionState::E, Age(0), Species(0)}] = numE / num_regions;
59-
model.populations[{mio::regions::Region(r), InfectionState::C, Age(0), Species(0)}] = numC / num_regions;
60-
model.populations[{mio::regions::Region(r), InfectionState::I, Age(0), Species(0)}] = numI / num_regions;
61-
model.populations[{mio::regions::Region(r), InfectionState::R, Age(0), Species(0)}] = numR / num_regions;
62-
model.populations[{mio::regions::Region(r), InfectionState::D, Age(0), Species(0)}] = numD / num_regions;
64+
model.populations[{Region(r), S, Age(0), Species(0)}] = (1000 - numE - numC - numI - numR - numD) / num_regions;
65+
model.populations[{Region(r), E, Age(0), Species(0)}] = numE / num_regions;
66+
model.populations[{Region(r), C, Age(0), Species(0)}] = numC / num_regions;
67+
model.populations[{Region(r), I, Age(0), Species(0)}] = numI / num_regions;
68+
model.populations[{Region(r), R, Age(0), Species(0)}] = numR / num_regions;
69+
model.populations[{Region(r), D, Age(0), Species(0)}] = numD / num_regions;
6370
}
6471

72+
using AR = mio::smm::AdoptionRates<ScalarType, Status, Region>;
73+
using TR = mio::smm::TransitionRates<ScalarType, Status, Region>;
74+
6575
//Set infection state adoption and spatial transition rates
66-
std::vector<mio::AdoptionRate<ScalarType, InfectionState, Age, Species>> adoption_rates;
67-
std::vector<mio::smm::TransitionRate<ScalarType, InfectionState, Age, Species>> transition_rates;
76+
AR::Type adoption_rates;
77+
TR::Type transition_rates;
6878
for (size_t r = 0; r < num_regions; ++r) {
69-
adoption_rates.push_back({InfectionState::S,
70-
InfectionState::E,
71-
mio::regions::Region(r),
79+
adoption_rates.push_back({{S, Age(0), Species(0)},
80+
{E, Age(0), Species(0)},
81+
Region(r),
7282
0.1,
73-
{{InfectionState::C, 1, mio::regions::Region(3), {Age(0), Species(0)}},
74-
{InfectionState::I, 0.5, mio::regions::Region(1), {Age(0), Species(0)}}},
75-
{Age(0), Species(0)}});
76-
adoption_rates.push_back(
77-
{InfectionState::C, InfectionState::R, mio::regions::Region(r), 0.2 / 3., {}, {Age(0), Species(0)}});
78-
adoption_rates.push_back(
79-
{InfectionState::E, InfectionState::C, mio::regions::Region(r), 1.0 / 5., {}, {Age(0), Species(0)}});
80-
adoption_rates.push_back(
81-
{InfectionState::C, InfectionState::I, mio::regions::Region(r), 0.8 / 3., {}, {Age(0), Species(0)}});
82-
adoption_rates.push_back(
83-
{InfectionState::I, InfectionState::R, mio::regions::Region(r), 0.99 / 5., {}, {Age(0), Species(0)}});
84-
adoption_rates.push_back(
85-
{InfectionState::I, InfectionState::D, mio::regions::Region(r), 0.01 / 5., {}, {Age(0), Species(0)}});
83+
{{{C, Age(0), Species(0)}, 1}, {{I, Age(0), Species(0)}, 0.5}}});
84+
adoption_rates.push_back({{C, Age(0), Species(0)}, {R, Age(0), Species(0)}, Region(r), 0.2 / 3., {}});
85+
adoption_rates.push_back({{E, Age(0), Species(0)}, {C, Age(0), Species(0)}, Region(r), 1.0 / 5., {}});
86+
adoption_rates.push_back({{C, Age(0), Species(0)}, {I, Age(0), Species(0)}, Region(r), 0.8 / 3., {}});
87+
adoption_rates.push_back({{I, Age(0), Species(0)}, {R, Age(0), Species(0)}, Region(r), 0.99 / 5., {}});
88+
adoption_rates.push_back({{I, Age(0), Species(0)}, {D, Age(0), Species(0)}, Region(r), 0.01 / 5., {}});
8689
}
8790

8891
//Agents in infection state D do not transition
89-
for (size_t s = 0; s < static_cast<size_t>(InfectionState::D); ++s) {
92+
for (size_t s = 0; s < static_cast<size_t>(D); ++s) {
9093
for (size_t i = 0; i < num_regions; ++i) {
9194
for (size_t j = 0; j < num_regions; ++j)
9295
if (i != j) {
93-
transition_rates.push_back({InfectionState(s),
94-
mio::regions::Region(i),
95-
mio::regions::Region(j),
96-
0.01,
97-
{Age(0), Species(0)},
98-
{Age(0), Species(0)}});
99-
transition_rates.push_back({InfectionState(s),
100-
mio::regions::Region(j),
101-
mio::regions::Region(i),
102-
0.01,
103-
{Age(0), Species(0)},
104-
{Age(0), Species(0)}});
96+
transition_rates.push_back({{InfectionState(s), Age(0), Species(0)}, Region(i), Region(j), 0.01});
97+
transition_rates.push_back({{InfectionState(s), Age(0), Species(0)}, Region(j), Region(i), 0.01});
10598
}
10699
}
107100
}
108101

109-
model.parameters.get<mio::smm::AdoptionRates<ScalarType, InfectionState, Age, Species>>() = adoption_rates;
110-
model.parameters.get<mio::smm::TransitionRates<ScalarType, InfectionState, Age, Species>>() = transition_rates;
102+
model.parameters.get<AR>() = adoption_rates;
103+
model.parameters.get<TR>() = transition_rates;
111104

112105
ScalarType dt = 0.1;
113106
ScalarType tmax = 30.0;

cpp/memilio/epidemiology/adoption_rate.h

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,23 @@
2020
#ifndef MIO_EPI_ADOPTIONRATE_H
2121
#define MIO_EPI_ADOPTIONRATE_H
2222

23-
#include "memilio/utils/index.h"
24-
#include "memilio/config.h"
2523
#include "memilio/geography/regions.h"
26-
#include <limits>
27-
#include <tuple>
28-
#include <optional>
24+
#include <vector>
2925

3026
namespace mio
3127
{
3228

29+
/**
30+
* @brief Struct defining an influence for a second-order adoption.
31+
* The population having "status" is multiplied with "factor."
32+
* @tparam Status An infection state enum.
33+
*/
34+
template <typename FP, class Status>
35+
struct Influence {
36+
Status status;
37+
FP factor;
38+
};
39+
3340
/**
3441
* @brief Struct defining a possible status adoption in a Model based on Poisson Processes.
3542
* The AdoptionRate is considered to be of second-order if there are any "influences".
@@ -38,30 +45,13 @@ namespace mio
3845
* @tparam Status An infection state enum.
3946
* @tparam Groups Additional grouping indices.
4047
*/
41-
template <typename FP, class Status, class... Groups>
48+
template <typename FP, class Status, class Region = mio::regions::Region>
4249
struct AdoptionRate {
43-
44-
/**
45-
* @brief Struct defining an influence for a second-order adoption.
46-
* The population having "status" is multiplied with "factor."
47-
* @tparam status An infection state enum.
48-
* @tparam factor Scaling factor for the influence.
49-
* @tparam
50-
* @tparam Groups Additional grouping indices.
51-
*/
52-
struct Influence {
53-
Status status;
54-
FP factor;
55-
std::optional<mio::regions::Region> region = std::nullopt;
56-
std::tuple<Groups...> group_indices{};
57-
};
58-
5950
Status from; // i
6051
Status to; // j
61-
mio::regions::Region region; // k
52+
Region region; // k
6253
FP factor; // gammahat_{ij}^k
63-
std::vector<Influence> influences; // influences[tau] = ( Psi_{i,j,tau} , gamma_{i,j,tau} )
64-
std::tuple<Groups...> group_indices{};
54+
std::vector<Influence<FP, Status>> influences; // influences[tau] = ( Psi_{i,j,tau} , gamma_{i,j,tau} )};
6555
};
6656

6757
} // namespace mio

cpp/memilio/epidemiology/populations.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,12 @@ class Populations : public CustomIndexArray<UncertainValue<FP>, Categories...>
287287
}
288288
};
289289

290+
template <typename FP, class... Categories>
291+
class Populations<FP, Index<Categories...>> : public Populations<FP, Categories...>
292+
{
293+
using Populations<FP, Categories...>::Populations;
294+
};
295+
290296
} // namespace mio
291297

292298
#endif // MIO_EPI_POPULATIONS_H

0 commit comments

Comments
 (0)