Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1081 rework ABM state transitions #1107

Open
wants to merge 42 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3fcb877
firstcommit
xsaschako Jul 31, 2023
3113609
add first draft for tree
xsaschako Aug 25, 2023
cb2a563
Merge main to update to newest version
DavidKerkmann Oct 17, 2023
59d10be
Merge branch 'main' into 664-define-and-use-parameters-that-handle-th…
DavidKerkmann Nov 20, 2023
25e7905
Update parameters
DavidKerkmann Nov 20, 2023
7d92aa8
Use new enum iterator
DavidKerkmann Nov 20, 2023
a4f16e8
Fix parameters
DavidKerkmann Nov 20, 2023
64f2edf
Fix infection setup
DavidKerkmann Nov 20, 2023
8b995e2
Fix analyze_result
DavidKerkmann Nov 20, 2023
e74c26c
Fix error in transmission
DavidKerkmann Nov 20, 2023
e5afe7c
Merge branch 'main' into 664-define-and-use-parameters-that-handle-th…
DavidKerkmann Dec 14, 2023
c7d6f12
Some fixes
DavidKerkmann Dec 20, 2023
5100fb8
Add author
DavidKerkmann Jan 25, 2024
85ab275
Fix recovered people not beeing able to reinfect.
DavidKerkmann Jan 29, 2024
10bd31e
Change back to infection course related time parameters and fix build.
DavidKerkmann Jan 31, 2024
4a47c69
Merge branch main into 664-define-and-use-parameters-that-handle-the-…
DavidKerkmann Jan 31, 2024
6f489f6
Fix from merge
DavidKerkmann Jan 31, 2024
054b746
Fix infection tests
DavidKerkmann Feb 1, 2024
e9069a4
Adjust contact rates correctly and fix dividing by 0 in exposure rate.
DavidKerkmann Feb 2, 2024
223e281
Merge branch 'main' into 664-define-and-use-parameters-that-handle-th…
DavidKerkmann Feb 13, 2024
21c3753
merge main
jubicker Aug 9, 2024
1c36293
merge branch 664
jubicker Aug 13, 2024
6f73cf4
Implement state transition dist
jubicker Aug 22, 2024
19a48c7
mock log normal dist in test
jubicker Aug 22, 2024
eec7073
python bindings
jubicker Aug 22, 2024
fb155bf
add exponential dist as state transition dist
jubicker Aug 23, 2024
f95561e
add adjust contact rates
jubicker Dec 9, 2024
b03f75d
merge main
jubicker Dec 10, 2024
af6111c
fix tests
jubicker Dec 10, 2024
92a2034
merge main
jubicker Dec 10, 2024
32f3a00
fix tests
jubicker Dec 10, 2024
dd13ea9
Fix msvc test
jubicker Dec 11, 2024
af643b9
add param dist wrapper and modify param dists
jubicker Dec 20, 2024
e16b36d
add rng as input for get_rand_sample
jubicker Dec 20, 2024
9b4a51b
replace state transition dist by parameter dist
jubicker Dec 20, 2024
76fa145
delete state transition dist
jubicker Dec 20, 2024
87619a1
constant instead of lognormal function for test
jubicker Jan 2, 2025
d072b6b
fix sigma=0 for normal dist on msvc
jubicker Jan 2, 2025
9efad16
fix
jubicker Jan 2, 2025
1a06e61
Merge branch 'main' into 1081-rework-abm-state-transitions
jubicker Jan 7, 2025
a1772b1
Merge branch '1081-rework-abm-state-transitions' of https://github.co…
jubicker Jan 7, 2025
be07ec6
fix python bindings
jubicker Jan 8, 2025
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
8 changes: 5 additions & 3 deletions cpp/examples/abm_history_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
#include "abm/simulation.h"
#include "abm/model.h"
#include "abm/location_type.h"
#include "memilio/utils/parameter_distribution_wrapper.h"
#include "memilio/io/history.h"
#include "memilio/utils/parameter_distributions.h"

#include <fstream>
#include <string>
Expand Down Expand Up @@ -68,9 +70,9 @@ int main()

// Create the model with 4 age groups.
auto model = mio::abm::Model(num_age_groups);

// Set same infection parameter for all age groups. For example, the incubation period is 4 days.
model.parameters.get<mio::abm::IncubationPeriod>() = 4.;
mio::ParameterDistributionLogNormal log_norm(4., 1.);
// Set same infection parameter for all age groups. For example, the incubation period is log normally distributed with parameters 4 and 1.
model.parameters.get<mio::abm::IncubationPeriod>() = mio::ParameterDistributionWrapper(log_norm);

// Set the age group the can go to school is AgeGroup(1) (i.e. 5-14)
model.parameters.get<mio::abm::AgeGroupGotoSchool>()[age_group_5_to_14] = true;
Expand Down
7 changes: 4 additions & 3 deletions cpp/examples/abm_minimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "abm/lockdown_rules.h"
#include "abm/model.h"
#include "abm/common_abm_loggers.h"
#include "memilio/utils/parameter_distribution_wrapper.h"

#include <fstream>

Expand All @@ -36,9 +37,9 @@ int main()

// Create the model with 4 age groups.
auto model = mio::abm::Model(num_age_groups);

// Set same infection parameter for all age groups. For example, the incubation period is 4 days.
model.parameters.get<mio::abm::IncubationPeriod>() = 4.;
mio::ParameterDistributionLogNormal log_norm(4., 1.);
// Set same infection parameter for all age groups. For example, the incubation period is log normally distributed with parameters 4 and 1.
model.parameters.get<mio::abm::IncubationPeriod>() = mio::ParameterDistributionWrapper(log_norm);

// Set the age group the can go to school is AgeGroup(1) (i.e. 5-14)
model.parameters.get<mio::abm::AgeGroupGotoSchool>() = false;
Expand Down
5 changes: 3 additions & 2 deletions cpp/examples/ode_secir_parameter_sampling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* limitations under the License.
*/
#include "memilio/utils/parameter_distributions.h"
#include "memilio/utils/random_number_generator.h"
#include "ode_secir/parameter_space.h"
#include "ode_secir/model.h"

Expand All @@ -41,7 +42,7 @@ int main()
printf("\n N(%.0f,%.0f)-distribution with sampling only in [%.0f,%.0f]", mean, stddev, min, max);
int counter[10] = {0};
for (int i = 0; i < 1000; i++) {
int rounded = (int)(some_parameter.get_sample() - 1);
int rounded = (int)(some_parameter.get_sample(mio::thread_local_rng()) - 1);
if (rounded >= 0 && rounded < 10) {
counter[rounded]++;
}
Expand All @@ -59,7 +60,7 @@ int main()

double counter_unif[10] = {0};
for (int i = 0; i < 1000; i++) {
int rounded = (int)(some_other_parameter.get_sample() - 1);
int rounded = (int)(some_other_parameter.get_sample(mio::thread_local_rng()) - 1);
if (rounded >= 0 && rounded < 10) {
counter_unif[rounded]++;
}
Expand Down
1 change: 1 addition & 0 deletions cpp/memilio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ add_library(memilio
utils/custom_index_array.h
utils/memory.h
utils/parameter_distributions.h
utils/parameter_distribution_wrapper.h
utils/time_series.h
utils/time_series.cpp
utils/span.h
Expand Down
1 change: 1 addition & 0 deletions cpp/memilio/epidemiology/damping_sampling.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define EPI_SECIR_DAMPING_SAMPLING_H

#include "memilio/epidemiology/damping.h"
#include "memilio/utils/random_number_generator.h"
#include "memilio/utils/uncertain_value.h"
#include <memory>

Expand Down
139 changes: 139 additions & 0 deletions cpp/memilio/utils/parameter_distribution_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (C) 2020-2024 MEmilio
*
* Authors: Julia Bicker
*
* Contact: Martin J. Kuehn <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PARAMETER_DISTRIBUTION_WRAPPER_H
#define PARAMETER_DISTRIBUTION_WRAPPER_H

#include "memilio/io/io.h"
#include "memilio/utils/compiler_diagnostics.h"
#include "parameter_distributions.h"

namespace mio
{

class ParameterDistributionWrapper
{
public:
ParameterDistributionWrapper()
: m_dist(nullptr)
{
}

ParameterDistributionWrapper(ParameterDistribution& dist)
: m_dist(std::unique_ptr<ParameterDistribution>(dist.clone()))
{
}

ParameterDistributionWrapper(const ParameterDistributionWrapper& other)
{
m_dist = (other.m_dist == nullptr) ? nullptr : std::unique_ptr<ParameterDistribution>(other.m_dist->clone());
}

ParameterDistributionWrapper(ParameterDistributionWrapper&& other)
{
m_dist = (other.m_dist == nullptr) ? nullptr : std::unique_ptr<ParameterDistribution>(other.m_dist->clone());
}
Comment on lines +48 to +51
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but shouldn't the move constructors move the distribution instead of copying it?


ParameterDistributionWrapper& operator=(ParameterDistributionWrapper const& other)
{
m_dist = (other.m_dist == nullptr) ? nullptr : std::unique_ptr<ParameterDistribution>(other.m_dist->clone());
return *this;
}

ParameterDistributionWrapper& operator=(ParameterDistributionWrapper&& other)
{
m_dist = (other.m_dist == nullptr) ? nullptr : std::unique_ptr<ParameterDistribution>(other.m_dist->clone());
return *this;
};

~ParameterDistributionWrapper() = default;

std::vector<double> params() const
{
if (m_dist == nullptr) {
log_error("Distribution is not defined. Parameters cannot be deduced.");

Check warning on line 70 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L70

Added line #L70 was not covered by tests
}
return m_dist->params();
Comment on lines +69 to +72
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging is not enough here, as a nullptr dereference is undefined behaviour. If we are lucky, this return will immediately cause a segfault and crash.

}

template <class RNG>
double get(RNG& rng)
{
if (m_dist == nullptr) {
log_error("Distribution is not defined. Value cannot be sampled.");

Check warning on line 79 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L79

Added line #L79 was not covered by tests
}
return m_dist->get_sample(rng);
}

/**
* serialize this.
* @see mio::serialize
*/
template <class IOContext>
void serialize(IOContext& io) const
{
m_dist->serialize(io);
}

private:
std::unique_ptr<ParameterDistribution> m_dist;
};

/**
* deserialize a ParameterDistributionWrapper.
* @see mio::deserialize
*/
template <class IOContext>
IOResult<ParameterDistributionWrapper> deserialize_internal(IOContext& io, Tag<ParameterDistributionWrapper>)
{

auto obj = io.expect_object("ParameterDistribution");
auto type = obj.expect_element("Type", Tag<std::string>{});
if (type) {
if (type.value() == "Uniform") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to avoid having to touch this each time a distribution is added?

BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionUniform::deserialize_elements(io, obj));
return ParameterDistributionWrapper(r);
}

Check warning on line 112 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L110-L112

Added lines #L110 - L112 were not covered by tests
else if (type.value() == "Normal") {
BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionNormal::deserialize_elements(io, obj));
return ParameterDistributionWrapper(r);
}

Check warning on line 116 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L114-L116

Added lines #L114 - L116 were not covered by tests
else if (type.value() == "LogNormal") {
BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionLogNormal::deserialize_elements(io, obj));
return ParameterDistributionWrapper(r);
}
else if (type.value() == "Exponential") {
BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionExponential::deserialize_elements(io, obj));
return ParameterDistributionWrapper(r);
}
else if (type.value() == "Constant") {
BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionConstant::deserialize_elements(io, obj));
return ParameterDistributionWrapper(r);
}

Check warning on line 128 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L121-L128

Added lines #L121 - L128 were not covered by tests
else {
return failure(StatusCode::InvalidValue, "Type of ParameterDistribution in ParameterDistributionWrapper" +
type.value() + " not valid.");

Check warning on line 131 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L131

Added line #L131 was not covered by tests
}
}
return failure(type.error());

Check warning on line 134 in cpp/memilio/utils/parameter_distribution_wrapper.h

View check run for this annotation

Codecov / codecov/patch

cpp/memilio/utils/parameter_distribution_wrapper.h#L134

Added line #L134 was not covered by tests
}

} // namespace mio

#endif //PARAMETER_DISTRIBUTION_WRAPPER_H
Loading