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
6 changes: 6 additions & 0 deletions cpp/examples/abm_history_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ int main()
// Set same infection parameter for all age groups. For example, the incubation period is 4 days.
world.parameters.get<mio::abm::IncubationPeriod>() = 4.;

// Set the age group the can go to school is AgeGroup(1) (i.e. 5-14)
world.parameters.get<mio::abm::AgeGroupGotoSchool>()[age_group_5_to_14] = true;
// Set the age group the can go to work is AgeGroup(2) and AgeGroup(3) (i.e. 15-34 and 35-59)
world.parameters.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);


// There are 3 households for each household group.
int n_households = 3;

Expand Down
5 changes: 1 addition & 4 deletions cpp/examples/abm_minimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,9 @@ int main()
world.parameters.get<mio::abm::IncubationPeriod>() = 4.;

// Set the age group the can go to school is AgeGroup(1) (i.e. 5-14)
world.parameters.get<mio::abm::AgeGroupGotoSchool>() = false;
world.parameters.get<mio::abm::AgeGroupGotoSchool>()[age_group_5_to_14] = true;
// Set the age group the can go to work is AgeGroup(2) and AgeGroup(3) (i.e. 15-34 and 35-59)
world.parameters.get<mio::abm::AgeGroupGotoWork>() = false;
world.parameters.get<mio::abm::AgeGroupGotoWork>()[age_group_15_to_34] = true;
world.parameters.get<mio::abm::AgeGroupGotoWork>()[age_group_35_to_59] = true;
world.parameters.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);

// Check if the parameters satisfy their contraints.
world.parameters.check_constraints();
Expand Down
14 changes: 13 additions & 1 deletion cpp/memilio/utils/custom_index_array.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2020-2024 MEmilio
*
* Authors: Daniel Abele
* Authors: Daniel Abele, Khoa Nguyen
*
* Contact: Martin J. Kuehn <[email protected]>
*
Expand Down Expand Up @@ -323,6 +323,18 @@ class CustomIndexArray
return (Eigen::Index)flatten_index(index, m_dimensions);
}

/**
* @brief Set multiple entries to the same value.
* @param indices A list of indices to be set to the same value.
* @param value The value to set.
*/
void set_multiple(const std::vector<typename CustomIndexArray<Typ, Tags...>::Index>& indices, const Typ& value)
Comment thread
dabele marked this conversation as resolved.
{
for (const auto& index : indices) {
m_y[get_flat_index(index)] = value;
}
}

private:
// Random Access Iterator for CustomIndexArray
// To Do: As of Eigen 3.4, this is not needed anymore,
Expand Down
9 changes: 2 additions & 7 deletions cpp/models/abm/parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,9 +515,7 @@ struct AgeGroupGotoSchool {
using Type = CustomIndexArray<bool, AgeGroup>;
static Type get_default(AgeGroup num_agegroups)
{
auto a = Type(num_agegroups, false);
a[AgeGroup(1)] = true;
return a;
return Type(num_agegroups, false);
}
static std::string name()
{
Expand All @@ -532,10 +530,7 @@ struct AgeGroupGotoWork {
using Type = CustomIndexArray<bool, AgeGroup>;
static Type get_default(AgeGroup num_agegroups)
{
auto a = Type(num_agegroups, false);
a[AgeGroup(2)] = true;
a[AgeGroup(3)] = true;
return a;
return Type(num_agegroups, false);
}
static std::string name()
{
Expand Down
5 changes: 5 additions & 0 deletions cpp/simulations/abm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,11 @@ void assign_infection_state(mio::abm::World& world, mio::abm::TimePoint t, doubl

void set_parameters(mio::abm::Parameters params)
{
// Set the age group the can go to school is AgeGroup(1) (i.e. 5-14)
params.get<mio::abm::AgeGroupGotoSchool>()[age_group_5_to_14] = true;
// Set the age group the can go to work is AgeGroup(2) and AgeGroup(3) (i.e. 15-34 and 35-59)
params.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);

params.set<mio::abm::IncubationPeriod>({{mio::abm::VirusVariant::Count, mio::AgeGroup(num_age_groups)}, 4.});

// Set protection level from high viral load. Information based on: https://doi.org/10.1093/cid/ciaa886
Expand Down
5 changes: 5 additions & 0 deletions cpp/simulations/abm_braunschweig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ void create_world_from_data(mio::abm::World& world, const std::string& filename,

void set_parameters(mio::abm::Parameters params)
{
// Set the age group the can go to school is AgeGroup(1) (i.e. 5-14)
params.get<mio::abm::AgeGroupGotoSchool>()[age_group_5_to_14] = true;
// Set the age group the can go to work is AgeGroup(2) and AgeGroup(3) (i.e. 15-34 and 35-59)
params.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);

params.set<mio::abm::IncubationPeriod>({{mio::abm::VirusVariant::Count, mio::AgeGroup(num_age_groups)}, 4.});

// Set protection level from high viral load. Information based on: https://doi.org/10.1093/cid/ciaa886
Expand Down
2 changes: 2 additions & 0 deletions cpp/tests/test_abm_location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ TEST(TestLocation, reachCapacity)
world.parameters
.get<mio::abm::InfectedNoSymptomsToRecovered>()[{mio::abm::VirusVariant::Wildtype, age_group_15_to_34}] =
2 * dt.days();
world.parameters.get<mio::abm::AgeGroupGotoSchool>().set_multiple({age_group_5_to_14}, true);
world.parameters.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);

auto home_id = world.add_location(mio::abm::LocationType::Home);
auto school_id = world.add_location(mio::abm::LocationType::School);
Expand Down
12 changes: 7 additions & 5 deletions cpp/tests/test_abm_person.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ TEST(TestPerson, setGetAssignedLocation)
TEST(TestPerson, quarantine)
{
using testing::Return;
auto rng = mio::RandomNumberGenerator();
auto test_params = mio::abm::TestParameters{1.01,1.01}; //100% safe test
auto rng = mio::RandomNumberGenerator();
auto test_params = mio::abm::TestParameters{1.01, 1.01}; //100% safe test

auto infection_parameters = mio::abm::Parameters(num_age_groups);
mio::abm::Location home(mio::abm::LocationType::Home, 0, num_age_groups);
Expand All @@ -124,19 +124,21 @@ TEST(TestPerson, quarantine)
infection_parameters
.get<mio::abm::InfectedSymptomsToRecovered>()[{mio::abm::VirusVariant::Wildtype, age_group_35_to_59}] =
0.5 * dt.days();
infection_parameters.get<mio::abm::AgeGroupGotoSchool>().set_multiple({age_group_5_to_14}, true);
infection_parameters.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);

auto person = make_test_person(home, age_group_35_to_59, mio::abm::InfectionState::InfectedSymptoms, t_morning,
infection_parameters);
auto rng_person = mio::abm::Person::RandomNumberGenerator(rng, person);

person.get_tested(rng_person, t_morning, test_params);

ASSERT_EQ(person.get_infection_state(t_morning), mio::abm::InfectionState::InfectedSymptoms);
ASSERT_EQ(mio::abm::go_to_work(rng_person, person, t_morning, dt, mio::abm::Parameters(num_age_groups)),
ASSERT_EQ(mio::abm::go_to_work(rng_person, person, t_morning, dt, infection_parameters),
mio::abm::LocationType::Home);
ASSERT_EQ(person.get_infection_state(t_morning + dt), mio::abm::InfectionState::Recovered);
person.remove_quarantine();
ASSERT_EQ(mio::abm::go_to_work(rng_person, person, t_morning, dt, mio::abm::Parameters(num_age_groups)),
ASSERT_EQ(mio::abm::go_to_work(rng_person, person, t_morning, dt, infection_parameters),
mio::abm::LocationType::Work);
}

Expand Down
2 changes: 2 additions & 0 deletions cpp/tests/test_abm_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ TEST(TestWorld, evolveMigration)
world.parameters
.get<mio::abm::InfectedNoSymptomsToRecovered>()[{mio::abm::VirusVariant::Wildtype, age_group_15_to_34}] =
2 * dt.days();
world.parameters.get<mio::abm::AgeGroupGotoSchool>().set_multiple({age_group_5_to_14}, true);
world.parameters.get<mio::abm::AgeGroupGotoWork>().set_multiple({age_group_15_to_34, age_group_35_to_59}, true);

auto home_id = world.add_location(mio::abm::LocationType::Home);
auto school_id = world.add_location(mio::abm::LocationType::School);
Expand Down
47 changes: 46 additions & 1 deletion cpp/tests/test_custom_index_array.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2020-2024 MEmilio
*
* Authors: Daniel Abele
* Authors: Daniel Abele, Khoa Nguyen
*
* Contact: Martin J. Kuehn <[email protected]>
*
Expand Down Expand Up @@ -380,3 +380,48 @@ TEST(CustomIndexArray, resize_one_dimension)
ASSERT_EQ(array.size().indices, std::make_tuple(Tag0{3}, Tag1{2}));
ASSERT_EQ(array.numel(), 6);
}

// Additional test for checking the set_multiple functionality
TEST(CustomIndexArray, setMultiple_validIndices) {
using ArrayType = mio::CustomIndexArray<int, Dim1, Dim2>;
// Initialize with zeros
ArrayType array({mio::Index<Dim1>(3), Dim2::Count}, 0);

// Define indices to set
std::vector<ArrayType::Index> indices = {
{mio::Index<Dim1>(0), Dim2::Male},
{mio::Index<Dim1>(2), Dim2::Female}
};

// Set these indices to 42
array.set_multiple(indices, 42);

// Verify that the correct indices have been updated
EXPECT_EQ((array[{mio::Index<Dim1>(0), Dim2::Male}]), 42);
EXPECT_EQ((array[{mio::Index<Dim1>(2), Dim2::Female}]), 42);

// Verify that other indices are unchanged
EXPECT_EQ((array[{mio::Index<Dim1>(0), Dim2::Female}]), 0);
EXPECT_EQ((array[{mio::Index<Dim1>(1), Dim2::Male}]), 0);
EXPECT_EQ((array[{mio::Index<Dim1>(1), Dim2::Female}]), 0);
EXPECT_EQ((array[{mio::Index<Dim1>(2), Dim2::Male}]), 0);
}

TEST(CustomIndexArray, setMultiple_emptyIndices) {
using ArrayType = mio::CustomIndexArray<int, Dim1, Dim2>;
// Initialize with fives
ArrayType array({mio::Index<Dim1>(2), Dim2::Count}, 5);

// Empty vector of indices
std::vector<ArrayType::Index> indices;

// Attempt to set multiple indices to 42
array.set_multiple(indices, 42);

// Verify that all entries remain unchanged
for (int age = 0; age < 2; ++age) {
for (int gender = 0; gender < static_cast<int>(Dim2::Count); ++gender) {
EXPECT_EQ((array[{mio::Index<Dim1>(age), static_cast<Dim2>(gender)}]), 5);
}
}
}