Skip to content

Commit 75ce311

Browse files
julianlitzreneSchmannawendlerjubickerHenrZu
authored
1018 use floating point types consistently (#1307)
- Extended automatic differentiation (AD) support to the Secirvvs model. - Templated floating-point types (FP) across key classes and functions for AD compatibility. - Added math operations for UncertainValue to work correctly with AD types. - Replaced most occurrences of double with FP or ScalarType in the core library. - Added a function eval_intermediate to consolidate usage of Eigen and AD intermediates. Co-authored-by: reneSchm <49305466+reneSchm@users.noreply.github.com> Co-authored-by: annawendler <106674756+annawendler@users.noreply.github.com> Co-authored-by: jubicker <113909589+jubicker@users.noreply.github.com> Co-authored-by: Henrik Zunker <69154294+HenrZu@users.noreply.github.com> Co-authored-by: MaxBetz <104758467+MaxBetzDLR@users.noreply.github.com>
1 parent 10447f3 commit 75ce311

File tree

306 files changed

+6601
-5570
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

306 files changed

+6601
-5570
lines changed

cpp/benchmarks/abm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ mio::abm::Simulation<> make_simulation(size_t num_persons, std::initializer_list
7171
auto prng = mio::abm::PersonalRandomNumberGenerator(person);
7272
//some % of people are infected, large enough to have some infection activity without everyone dying
7373
auto pct_infected = 0.05;
74-
if (mio::UniformDistribution<double>::get_instance()(prng, 0.0, 1.0) < pct_infected) {
74+
if (mio::UniformDistribution<ScalarType>::get_instance()(prng, 0.0, 1.0) < pct_infected) {
7575
auto state = mio::abm::InfectionState(
7676
mio::UniformIntDistribution<int>::get_instance()(prng, 1, int(mio::abm::InfectionState::Count) - 1));
7777
auto infection = mio::abm::Infection(prng, mio::abm::VirusVariant::Wildtype, person.get_age(),
@@ -91,7 +91,7 @@ mio::abm::Simulation<> make_simulation(size_t num_persons, std::initializer_list
9191
//skip homes so persons always have a place to go, simulation might break otherwise
9292
auto pct_require_mask = 0.2;
9393
if (loc.get_type() != mio::abm::LocationType::Home &&
94-
mio::UniformDistribution<double>::get_instance()(model.get_rng()) < pct_require_mask) {
94+
mio::UniformDistribution<ScalarType>::get_instance()(model.get_rng()) < pct_require_mask) {
9595
loc.set_required_mask(mio::abm::MaskType::Community);
9696
}
9797
}

cpp/benchmarks/flow_simulation_ode_secirvvs.h

Lines changed: 80 additions & 70 deletions
Large diffs are not rendered by default.

cpp/benchmarks/flow_simulation_ode_seir.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (C) 2020-2025 MEmilio
33
*
44
* Authors: Rene Schmieding, Daniel Abele, Martin J. Kuehn
@@ -52,8 +52,9 @@ class FlowlessModel
5252
{
5353
}
5454

55-
void get_derivatives(Eigen::Ref<const Eigen::VectorXd> pop, Eigen::Ref<const Eigen::VectorXd> y, double t,
56-
Eigen::Ref<Eigen::VectorXd> dydt) const override
55+
void get_derivatives(Eigen::Ref<const Eigen::VectorX<ScalarType>> pop,
56+
Eigen::Ref<const Eigen::VectorX<ScalarType>> y, ScalarType t,
57+
Eigen::Ref<Eigen::VectorX<ScalarType>> dydt) const override
5758
{
5859
auto& params = this->parameters;
5960
const Index<AgeGroup> age_groups = reduce_index<Index<AgeGroup>>(this->populations.size());
@@ -71,10 +72,10 @@ class FlowlessModel
7172
size_t Ij = this->populations.get_flat_index({j, InfectionState::Infected});
7273
size_t Rj = this->populations.get_flat_index({j, InfectionState::Recovered});
7374

74-
const double Nj_inv = 1.0 / (pop[Sj] + pop[Ej] + pop[Ij] + pop[Rj]);
75-
const double coeffStoE =
76-
params.template get<ContactPatterns<ScalarType>>().get_cont_freq_mat().get_matrix_at(t)(i.get(),
77-
j.get()) *
75+
const ScalarType Nj_inv = 1.0 / (pop[Sj] + pop[Ej] + pop[Ij] + pop[Rj]);
76+
const ScalarType coeffStoE =
77+
params.template get<ContactPatterns<ScalarType>>().get_cont_freq_mat().get_matrix_at(
78+
SimulationTime<ScalarType>(t))(i.get(), j.get()) *
7879
params.template get<TransmissionProbabilityOnContact<ScalarType>>()[i] * Nj_inv;
7980

8081
dydt[Si] -= y[Si] * pop[Ij] * coeffStoE;
@@ -91,8 +92,8 @@ class FlowlessModel
9192
template <class Model>
9293
void setup_model(Model& model)
9394
{
94-
const double total_population = 10000.0;
95-
const auto num_groups = model.parameters.get_num_groups();
95+
const ScalarType total_population = 10000.0;
96+
const auto num_groups = model.parameters.get_num_groups();
9697
for (AgeGroup i = 0; i < num_groups; i++) {
9798
model.populations[{i, oseir::InfectionState::Exposed}] = 100.0 / static_cast<size_t>(num_groups);
9899
model.populations[{i, oseir::InfectionState::Infected}] = 100.0 / static_cast<size_t>(num_groups);
@@ -106,8 +107,9 @@ void setup_model(Model& model)
106107
model.parameters.template set<mio::oseir::TimeExposed<ScalarType>>(5.2);
107108
model.parameters.template set<mio::oseir::TimeInfected<ScalarType>>(6);
108109
model.parameters.template set<mio::oseir::TransmissionProbabilityOnContact<ScalarType>>(0.04);
109-
mio::ContactMatrixGroup& contact_matrix = model.parameters.template get<mio::oseir::ContactPatterns<ScalarType>>();
110-
contact_matrix[0].get_baseline().setConstant(10.);
110+
mio::ContactMatrixGroup<ScalarType>& contact_matrix =
111+
model.parameters.template get<mio::oseir::ContactPatterns<ScalarType>>();
112+
contact_matrix[0].get_baseline().setConstant(10.0);
111113
}
112114

113115
} // namespace benchmark

cpp/benchmarks/graph_simulation.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (C) 2020-2025 MEmilio
33
*
44
* Authors: Henrik Zunker
@@ -78,7 +78,7 @@ mio::osecirvvs::Model<ScalarType> create_model(size_t num_agegroups, const Scala
7878
auto& contact_matrix = contacts.get_cont_freq_mat();
7979
contact_matrix[0].get_baseline().setConstant(0.5);
8080
contact_matrix[0].get_baseline().diagonal().setConstant(5.0);
81-
contact_matrix[0].add_damping(0.3, mio::SimulationTime(5.0));
81+
contact_matrix[0].add_damping(0.3, mio::SimulationTime<ScalarType>(5.0));
8282

8383
for (mio::AgeGroup i = 0; i < (mio::AgeGroup)num_agegroups; i++) {
8484
//times
@@ -115,9 +115,9 @@ auto create_simulation()
115115
{
116116
auto cfg = mio::benchmark::GraphConfig::initialize(config_path);
117117

118-
mio::osecirvvs::Model model = create_model(cfg.num_agegroups, cfg.t_max);
118+
mio::osecirvvs::Model<ScalarType> model = create_model(cfg.num_agegroups, cfg.t_max);
119119

120-
mio::Graph<mio::SimulationNode<mio::Simulation<ScalarType, mio::osecirvvs::Model<ScalarType>>>,
120+
mio::Graph<mio::SimulationNode<ScalarType, mio::Simulation<ScalarType, mio::osecirvvs::Model<ScalarType>>>,
121121
mio::MobilityEdge<ScalarType>>
122122
g;
123123
for (size_t county_id = 0; county_id < cfg.num_regions; county_id++) {
@@ -130,9 +130,9 @@ auto create_simulation()
130130
for (size_t county_idx_j = 0; county_idx_j < g.nodes().size(); ++county_idx_j) {
131131
if (county_idx_i == county_idx_j)
132132
continue;
133-
g.add_edge(
134-
county_idx_i, county_idx_j,
135-
Eigen::VectorXd::Constant((size_t)mio::osecirvvs::InfectionState::Count * cfg.num_agegroups, 0.01));
133+
g.add_edge(county_idx_i, county_idx_j,
134+
Eigen::VectorX<ScalarType>::Constant(
135+
(size_t)mio::osecirvvs::InfectionState::Count * cfg.num_agegroups, 0.01));
136136
}
137137
}
138138

cpp/benchmarks/graph_simulation.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (C) 2020-2025 MEmilio
33
*
44
* Authors: Henrik Zunker
@@ -32,7 +32,7 @@ namespace benchmark
3232
/// @brief parameters for simulation benchmark
3333
struct GraphConfig {
3434
int num_agegroups, num_regions;
35-
double t0, t_max, dt;
35+
ScalarType t0, t_max, dt;
3636
/**
3737
* @brief creates configuration with default parameters for a secir model
3838
* @param num_agegroups number of agegroups
@@ -65,9 +65,9 @@ struct GraphConfig {
6565
auto obj = io.expect_object("bench_graph_simulation");
6666
auto num_agegroups_io = obj.expect_element("num_agegroups", mio::Tag<int>{});
6767
auto num_regions_io = obj.expect_element("num_regions", mio::Tag<int>{});
68-
auto t_io = obj.expect_element("t0", mio::Tag<double>{});
69-
auto t_max_io = obj.expect_element("t_max", mio::Tag<double>{});
70-
auto dt_io = obj.expect_element("dt", mio::Tag<double>{});
68+
auto t_io = obj.expect_element("t0", mio::Tag<ScalarType>{});
69+
auto t_max_io = obj.expect_element("t_max", mio::Tag<ScalarType>{});
70+
auto dt_io = obj.expect_element("dt", mio::Tag<ScalarType>{});
7171
return mio::apply(
7272
io,
7373
[](auto&& num_agegroups, auto&& num_regions, auto&& t0, auto&& t_max, auto&& dt) {

cpp/benchmarks/integrator_step.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (C) 2020-2025 MEmilio
33
*
44
* Authors: Rene Schmieding
@@ -36,13 +36,13 @@ void integrator_step(::benchmark::State& state)
3636
//auto cfg = mio::benchmark::IntegratorStepConfig::initialize();
3737
auto model = mio::benchmark::model::SecirAgeres(cfg.num_agegroups);
3838
// set deriv function and integrator
39-
mio::DerivFunction<ScalarType> f = [model](Eigen::Ref<const Eigen::VectorXd> x, double s,
40-
Eigen::Ref<Eigen::VectorXd> dxds) {
39+
mio::DerivFunction<ScalarType> f = [model](Eigen::Ref<const Eigen::VectorX<ScalarType>> x, ScalarType s,
40+
Eigen::Ref<Eigen::VectorX<ScalarType>> dxds) {
4141
model.eval_right_hand_side(x, x, s, dxds);
4242
};
4343
auto I = Integrator(cfg.abs_tol, cfg.rel_tol, cfg.dt_min, cfg.dt_max);
4444

45-
double t, dt;
45+
ScalarType t, dt;
4646
for (auto _ : state) {
4747
// This code gets timed
4848
t = cfg.t_init;

cpp/benchmarks/integrator_step.h

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (C) 2020-2025 MEmilio
33
*
44
* Authors: Rene Schmieding
@@ -32,31 +32,31 @@ namespace benchmark
3232
/// @brief parameters for integrator-step benchmark
3333
struct IntegratorStepConfig {
3434
int num_agegroups;
35-
double t_init, dt_init, abs_tol, rel_tol, dt_min, dt_max;
36-
Eigen::VectorXd yt, ytp1;
35+
ScalarType t_init, dt_init, abs_tol, rel_tol, dt_min, dt_max;
36+
Eigen::VectorX<ScalarType> yt, ytp1;
3737
/**
38-
* @brief creates configuration with default parameters for a secir model
39-
* @return configuration for integrator-step benchmark
40-
*/
38+
* @brief creates configuration with default parameters for a secir model
39+
* @return configuration for integrator-step benchmark
40+
*/
4141
static IntegratorStepConfig initialize()
4242
{
43-
const double vals[8] = {6377.873644, 35.249156, 30.029611, 182.145865,
44-
66.153059, 79.530621, 3069.383604, 159.634440};
43+
const ScalarType vals[8] = {6377.873644, 35.249156, 30.029611, 182.145865,
44+
66.153059, 79.530621, 3069.383604, 159.634440};
4545
return IntegratorStepConfig{1,
4646
50,
4747
1,
4848
1e-10,
4949
1e-5,
50-
std::numeric_limits<double>::min(),
51-
std::numeric_limits<double>::max(),
52-
Eigen::Matrix<double, 8, 1>(vals),
53-
Eigen::VectorXd::Zero(8)};
50+
std::numeric_limits<ScalarType>::min(),
51+
std::numeric_limits<ScalarType>::max(),
52+
Eigen::Matrix<ScalarType, 8, 1>(vals),
53+
Eigen::VectorX<ScalarType>::Zero(8)};
5454
}
5555
/**
56-
* @brief reads configuration from json file
57-
* @param path the path of the configfile
58-
* @return configuration for integrator-step benchmark
59-
*/
56+
* @brief reads configuration from json file
57+
* @param path the path of the configfile
58+
* @return configuration for integrator-step benchmark
59+
*/
6060
static IntegratorStepConfig initialize(std::string path)
6161
{
6262
auto result = mio::read_json(path, mio::Tag<IntegratorStepConfig>{});
@@ -72,13 +72,13 @@ struct IntegratorStepConfig {
7272
{
7373
auto obj = io.expect_object("integrator_step");
7474
auto num_agegroups_io = obj.expect_element("num_agegroups", mio::Tag<int>{});
75-
auto t_init_io = obj.expect_element("t_init", mio::Tag<double>{});
76-
auto dt_init_io = obj.expect_element("dt_init", mio::Tag<double>{});
77-
auto abs_tol_io = obj.expect_element("abs_tol", mio::Tag<double>{});
78-
auto rel_tol_io = obj.expect_element("rel_tol", mio::Tag<double>{});
79-
auto dt_min_io = obj.expect_element("dt_min", mio::Tag<double>{});
80-
auto dt_max_io = obj.expect_element("dt_max", mio::Tag<double>{});
81-
auto yt_io = obj.expect_list("yt", mio::Tag<double>{});
75+
auto t_init_io = obj.expect_element("t_init", mio::Tag<ScalarType>{});
76+
auto dt_init_io = obj.expect_element("dt_init", mio::Tag<ScalarType>{});
77+
auto abs_tol_io = obj.expect_element("abs_tol", mio::Tag<ScalarType>{});
78+
auto rel_tol_io = obj.expect_element("rel_tol", mio::Tag<ScalarType>{});
79+
auto dt_min_io = obj.expect_element("dt_min", mio::Tag<ScalarType>{});
80+
auto dt_max_io = obj.expect_element("dt_max", mio::Tag<ScalarType>{});
81+
auto yt_io = obj.expect_list("yt", mio::Tag<ScalarType>{});
8282
return mio::apply(
8383
io,
8484
[](auto&& num_agegroups, auto&& t_init, auto&& dt_init, auto&& abs_tol, auto&& rel_tol, auto&& dt_min,
@@ -90,8 +90,8 @@ struct IntegratorStepConfig {
9090
rel_tol,
9191
dt_min,
9292
dt_max,
93-
Eigen::VectorXd::Zero(yt.size()),
94-
Eigen::VectorXd::Zero(yt.size())};
93+
Eigen::VectorX<ScalarType>::Zero(yt.size()),
94+
Eigen::VectorX<ScalarType>::Zero(yt.size())};
9595
for (size_t i = 0; i < yt.size(); i++) {
9696
cfg.yt[i] = yt[i];
9797
}

0 commit comments

Comments
 (0)