Health-GPS 3.0.0.0
Global Health Policy Simulation model (Health-GPS)
Loading...
Searching...
No Matches
static_linear_model.h
Go to the documentation of this file.
1#pragma once
2
4#include "interfaces.h"
6#include "mapping.h"
8
9#include <Eigen/Dense>
10#include <string>
11#include <unordered_map>
12#include <utility>
13#include <vector>
14
15namespace hgps {
16
19 double intercept{};
20 std::unordered_map<core::Identifier, double> coefficients{};
21 std::unordered_map<core::Identifier, double> log_coefficients{};
22};
23
28 std::string model_type{"simple"};
29
31 double intercept{};
32
34 std::unordered_map<core::Identifier, double> coefficients;
35
37 double min_value = 0.0;
38
40 double max_value = std::numeric_limits<double>::max();
41
43 double stddev = 0.06;
44};
45
48 std::pair<std::string, std::shared_ptr<RiskFactorSexAgeTable>>;
49
53 public:
90 std::shared_ptr<RiskFactorSexAgeTable> expected,
91 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_trend,
92 std::shared_ptr<std::unordered_map<core::Identifier, int>> trend_steps,
93 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_trend_boxcox,
94 const std::vector<core::Identifier> &names, const std::vector<LinearModelParams> &models,
95 const std::vector<core::DoubleInterval> &ranges, const std::vector<double> &lambda,
96 const std::vector<double> &stddev, const Eigen::MatrixXd &cholesky,
97 const std::vector<LinearModelParams> &policy_models,
98 const std::vector<core::DoubleInterval> &policy_ranges,
99 const Eigen::MatrixXd &policy_cholesky,
100 std::shared_ptr<std::vector<LinearModelParams>> trend_models,
101 std::shared_ptr<std::vector<core::DoubleInterval>> trend_ranges,
102 std::shared_ptr<std::vector<double>> trend_lambda, double info_speed,
103 const std::unordered_map<core::Identifier, std::unordered_map<core::Gender, double>>
104 &rural_prevalence,
105 const std::unordered_map<core::Income, LinearModelParams> &income_models,
106 double physical_activity_stddev, TrendType trend_type,
107 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend =
108 nullptr,
109 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend_boxcox =
110 nullptr,
111 std::shared_ptr<std::unordered_map<core::Identifier, int>> income_trend_steps = nullptr,
112 std::shared_ptr<std::vector<LinearModelParams>> income_trend_models = nullptr,
113 std::shared_ptr<std::vector<core::DoubleInterval>> income_trend_ranges = nullptr,
114 std::shared_ptr<std::vector<double>> income_trend_lambda = nullptr,
115 std::shared_ptr<std::unordered_map<core::Identifier, double>> income_trend_decay_factors =
116 nullptr,
117 bool is_continuous_income_model = false,
118 const LinearModelParams &continuous_income_model = LinearModelParams{},
119 core::IncomeCategoryLayout income_category_layout = {},
122 const std::unordered_map<core::Identifier, PhysicalActivityModel>
123 &physical_activity_models = {},
126 const std::vector<IncomeStratumExpectedTableEntry> &income_stratum_expected_tables = {},
129 bool income_stratum_adjustment_enabled = false,
131 std::size_t adjustment_income_stratum_count = 0u, bool has_active_policies = true,
134 const std::vector<LinearModelParams> &logistic_models = {},
135 core::Gender gender2_indicator = core::Gender::male);
136
137 RiskFactorModelType type() const noexcept override;
138
139 std::string name() const noexcept override;
140
143 bool is_continuous_income_model() const noexcept;
144
145 void generate_risk_factors(RuntimeContext &context) override;
146
147 void update_risk_factors(RuntimeContext &context) override;
148
149 private:
150 static double inverse_box_cox(double factor, double lambda);
151
152 void initialise_factors(RuntimeContext &context, Person &person, Random &random) const;
153
154 void update_factors(RuntimeContext &context, Person &person, Random &random) const;
155
156 void initialise_UPF_trends(RuntimeContext &context, Person &person) const;
157
158 void update_UPF_trends(RuntimeContext &context, Person &person) const;
159
169 void initialise_income(RuntimeContext &context, Person &person, Random &random);
170
178 void update_income(RuntimeContext &context, Person &person, Random &random);
179
183 void update_income_trends(RuntimeContext &context, Person &person) const;
184
188 void initialise_income_trends(RuntimeContext &context, Person &person) const;
189
190 void initialise_policies(RuntimeContext &context, Person &person, Random &random,
191 bool intervene) const;
192
193 void update_policies(RuntimeContext &context, Person &person, bool intervene) const;
194
195 void apply_policies(Person &person, bool intervene) const;
196
197 std::vector<double> compute_linear_models(RuntimeContext &context, Person &person,
198 const std::vector<LinearModelParams> &models) const;
199
200 std::vector<double> compute_residuals(Random &random, const Eigen::MatrixXd &cholesky) const;
201
206 double calculate_zero_probability(Person &person, size_t risk_factor_index) const;
207
211 void initialise_sector(Person &person, Random &random) const;
212
216 void update_sector(Person &person, Random &random) const;
217
218 // Continuous income model support (FINCH approach)
219 bool is_continuous_income_model_;
220 LinearModelParams continuous_income_model_;
221 core::IncomeCategoryLayout income_category_layout_;
222
227 double calculate_continuous_income(Person &person, Random &random);
228
234 core::Income convert_income_continuous_to_category(double continuous_income,
235 const Population &population,
236 Random &random) const;
237
243 core::Income convert_income_to_category(double continuous_income,
244 const std::vector<double> &quartile_thresholds) const;
245
249 static std::vector<double> calculate_income_quartiles(const Population &population);
250
254 static std::vector<double> calculate_income_tertiles(const Population &population);
255
257 static std::vector<double> calculate_income_percentile_thresholds(const Population &population,
258 std::size_t bucket_count);
259
263 void initialise_categorical_income(Person &person, Random &random);
264
269 void initialise_continuous_income(RuntimeContext &context, Person &person, Random &random);
270
274 void initialise_physical_activity(RuntimeContext &context, Person &person,
275 Random &random) const;
276
284 std::pair<std::vector<core::Identifier>, std::vector<core::DoubleInterval>>
285 build_extended_factors_list(RuntimeContext &context,
286 const std::vector<core::Identifier> &base_factors,
287 const std::vector<core::DoubleInterval> &base_ranges,
288 bool for_trended_adjustment = false) const;
289
291 LinearModelEvalOptions base_linear_eval_options() const noexcept;
292
298 void initialise_continuous_physical_activity(RuntimeContext &context, Person &person,
299 Random &random,
300 const PhysicalActivityModel &model) const;
301
307 void initialise_simple_physical_activity(RuntimeContext &context, Person &person,
308 Random &random,
309 const PhysicalActivityModel &model) const;
310
311 // Regular trend member variables
312 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_trend_;
313 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_trend_boxcox_;
314 std::shared_ptr<std::vector<LinearModelParams>> trend_models_;
315 std::shared_ptr<std::vector<core::DoubleInterval>> trend_ranges_;
316 std::shared_ptr<std::vector<double>> trend_lambda_;
317
318 // Income trend member variables
319 TrendType trend_type_;
320 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend_;
321 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend_boxcox_;
322 std::shared_ptr<std::unordered_map<core::Identifier, int>> income_trend_steps_;
323 std::shared_ptr<std::vector<LinearModelParams>> income_trend_models_;
324 std::shared_ptr<std::vector<core::DoubleInterval>> income_trend_ranges_;
325 std::shared_ptr<std::vector<double>> income_trend_lambda_;
326 std::shared_ptr<std::unordered_map<core::Identifier, double>> income_trend_decay_factors_;
327
328 // Common member variables
329 const std::vector<core::Identifier> &names_;
330 const std::vector<LinearModelParams> &models_;
331 const std::vector<core::DoubleInterval> &ranges_;
332 const std::vector<double> &lambda_;
333 const std::vector<double> &stddev_;
334 const Eigen::MatrixXd &cholesky_;
335 const std::vector<LinearModelParams> &policy_models_;
336 const std::vector<core::DoubleInterval> &policy_ranges_;
337 const Eigen::MatrixXd &policy_cholesky_;
338 const double info_speed_;
339 const std::unordered_map<core::Identifier, std::unordered_map<core::Gender, double>>
340 &rural_prevalence_;
341 const std::unordered_map<core::Income, LinearModelParams> &income_models_;
342 const double physical_activity_stddev_;
343
344 // Physical activity model support (both India and FINCH approaches)
345 std::unordered_map<core::Identifier, PhysicalActivityModel> physical_activity_models_;
346 bool has_physical_activity_models_ = false;
347 // MAHIMA: Phase 2 step 1 wiring only - parsed/loaded per-stratum tables cached on model.
348 std::vector<IncomeStratumExpectedTableEntry> income_stratum_expected_tables_;
349 bool income_stratum_adjustment_enabled_{false};
350 std::size_t adjustment_income_stratum_count_{0};
351 // Policy optimization flag - Mahima's enhancement
352 bool has_active_policies_;
353
354 // Two-stage modeling: Logistic regression for zero probability (optional)
355 // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) reference to model data
356 const std::vector<LinearModelParams> &logistic_models_;
357
359 core::Gender gender2_indicator_{core::Gender::male};
360};
361
364 public:
401 std::unique_ptr<RiskFactorSexAgeTable> expected,
402 std::unique_ptr<std::unordered_map<core::Identifier, double>> expected_trend,
403 std::unique_ptr<std::unordered_map<core::Identifier, int>> trend_steps,
404 std::unique_ptr<std::unordered_map<core::Identifier, double>> expected_trend_boxcox,
405 std::vector<core::Identifier> names, std::vector<LinearModelParams> models,
406 std::vector<core::DoubleInterval> ranges, std::vector<double> lambda,
407 std::vector<double> stddev, Eigen::MatrixXd cholesky,
408 std::vector<LinearModelParams> policy_models,
409 std::vector<core::DoubleInterval> policy_ranges, Eigen::MatrixXd policy_cholesky,
410 std::unique_ptr<std::vector<LinearModelParams>> trend_models,
411 std::unique_ptr<std::vector<core::DoubleInterval>> trend_ranges,
412 std::unique_ptr<std::vector<double>> trend_lambda, double info_speed,
413 std::unordered_map<core::Identifier, std::unordered_map<core::Gender, double>>
414 rural_prevalence,
415 std::unordered_map<core::Income, LinearModelParams> income_models,
416 double physical_activity_stddev, TrendType trend_type = TrendType::Null,
417 std::unique_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend =
418 nullptr,
419 std::unique_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend_boxcox =
420 nullptr,
421 std::unique_ptr<std::unordered_map<core::Identifier, int>> income_trend_steps = nullptr,
422 std::unique_ptr<std::vector<LinearModelParams>> income_trend_models = nullptr,
423 std::unique_ptr<std::vector<core::DoubleInterval>> income_trend_ranges = nullptr,
424 std::unique_ptr<std::vector<double>> income_trend_lambda = nullptr,
425 std::unique_ptr<std::unordered_map<core::Identifier, double>> income_trend_decay_factors =
426 nullptr,
427 bool is_continuous_income_model = false,
428 const LinearModelParams &continuous_income_model = LinearModelParams{},
429 core::IncomeCategoryLayout income_category_layout = {},
430 const std::unordered_map<core::Identifier, PhysicalActivityModel>
431 &physical_activity_models = {},
432 const std::vector<IncomeStratumExpectedTableEntry> &income_stratum_expected_tables = {},
433 bool income_stratum_adjustment_enabled = false,
434 std::size_t adjustment_income_stratum_count = 0u, bool has_active_policies = true,
436 std::vector<LinearModelParams> logistic_models = {},
437 core::Gender gender2_indicator = core::Gender::male);
438
441 std::unique_ptr<RiskFactorModel> create_model() const override;
442
443 private:
444 // Regular trend member variables
445 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_trend_;
446 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_trend_boxcox_;
447 std::shared_ptr<std::vector<LinearModelParams>> trend_models_;
448 std::shared_ptr<std::vector<core::DoubleInterval>> trend_ranges_;
449 std::shared_ptr<std::vector<double>> trend_lambda_;
450
451 // Income trend member variables
452 TrendType trend_type_;
453 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend_;
454 std::shared_ptr<std::unordered_map<core::Identifier, double>> expected_income_trend_boxcox_;
455 std::shared_ptr<std::unordered_map<core::Identifier, int>> income_trend_steps_;
456 std::shared_ptr<std::vector<LinearModelParams>> income_trend_models_;
457 std::shared_ptr<std::vector<core::DoubleInterval>> income_trend_ranges_;
458 std::shared_ptr<std::vector<double>> income_trend_lambda_;
459 std::shared_ptr<std::unordered_map<core::Identifier, double>> income_trend_decay_factors_;
460
461 // Common member variables
462 std::vector<core::Identifier> names_;
463 std::vector<LinearModelParams> models_;
464 std::vector<core::DoubleInterval> ranges_;
465 std::vector<double> lambda_;
466 std::vector<double> stddev_;
467 Eigen::MatrixXd cholesky_;
468 std::vector<LinearModelParams> policy_models_;
469 std::vector<core::DoubleInterval> policy_ranges_;
470 Eigen::MatrixXd policy_cholesky_;
471 double info_speed_;
472 std::unordered_map<core::Identifier, std::unordered_map<core::Gender, double>>
473 rural_prevalence_;
474 std::unordered_map<core::Income, LinearModelParams> income_models_;
475 double physical_activity_stddev_;
476
477 // Physical activity model support (FINCH approach)
478 std::unordered_map<core::Identifier, PhysicalActivityModel> physical_activity_models_;
479 bool has_physical_activity_models_ = false;
480 // MAHIMA: Phase 2 step 1 wiring only - carry per-stratum expected tables into runtime model.
481 std::vector<IncomeStratumExpectedTableEntry> income_stratum_expected_tables_;
482 bool income_stratum_adjustment_enabled_{false};
483 std::size_t adjustment_income_stratum_count_{0};
484
485 // Two-stage modeling: Logistic regression for zero probability (optional)
486 std::vector<LinearModelParams> logistic_models_;
487
488 // Continuous income model support (FINCH approach)
489 bool is_continuous_income_model_;
490 LinearModelParams continuous_income_model_;
491 core::IncomeCategoryLayout income_category_layout_;
492 // Policy optimization flag - Mahima
493 bool has_active_policies_;
494 core::Gender gender2_indicator_{core::Gender::male};
495};
496
497} // namespace hgps
Defines the virtual population data type.
Definition population.h:19
General purpose Random number generator algorithms.
Definition random_algorithm.h:8
Risk factor adjustable model definition interface.
Definition risk_factor_adjustable_model.h:158
Risk factor model interface with mean adjustment by sex and age.
Definition risk_factor_adjustable_model.h:63
Defines the Simulation runtime context data type.
Definition runtime_context.h:22
Defines the static linear model data type.
Definition static_linear_model.h:363
std::unique_ptr< RiskFactorModel > create_model() const override
Construct a new StaticLinearModel from this definition.
Definition static_linear_model.cpp:2601
Implements the static linear model type.
Definition static_linear_model.h:52
std::string name() const noexcept override
Gets the model name.
Definition static_linear_model.cpp:603
bool is_continuous_income_model() const noexcept
Check if using continuous income model (FINCH approach)
Definition static_linear_model.cpp:605
void generate_risk_factors(RuntimeContext &context) override
Generates the initial risk factors for a population and newborns.
Definition static_linear_model.cpp:610
RiskFactorModelType type() const noexcept override
Gets the model type identifier.
Definition static_linear_model.cpp:601
void update_risk_factors(RuntimeContext &context) override
Update risk factors for population.
Definition static_linear_model.cpp:988
Gender
Enumerates gender types.
Definition forward_type.h:18
Income
Enumerates income categories.
Definition forward_type.h:51
Top-level namespace for Health-GPS Console host application.
Definition command_options.cpp:8
std::pair< std::string, std::shared_ptr< RiskFactorSexAgeTable > > IncomeStratumExpectedTableEntry
One expected factors-mean table mapped to a configured income stratum id.
Definition static_linear_model.h:48
RiskFactorModelType
Health GPS risk factor module types enumeration.
Definition risk_factor_model.h:12
TrendType
Defines the trend type enumeration for factors mean adjustment.
Definition risk_factor_adjustable_model.h:29
@ Null
No trends applied to factors mean adjustment.
Definition linear_model_eval_options.h:11
Defines the linear model parameters used to initialise risk factors.
Definition static_linear_model.h:18
std::unordered_map< core::Identifier, double > coefficients
Definition static_linear_model.h:20
std::unordered_map< core::Identifier, double > log_coefficients
Definition static_linear_model.h:21
double intercept
Definition static_linear_model.h:19
Defines a virtual population person data type.
Definition person.h:39
Defines the physical activity model parameters.
Definition static_linear_model.h:26
double min_value
Minimum allowed value for physical activity.
Definition static_linear_model.h:37
std::string model_type
Model type: "simple" for India approach, "continuous" for FINCH approach.
Definition static_linear_model.h:28
std::unordered_map< core::Identifier, double > coefficients
Coefficients for each factor (age, gender, region, ethnicity, etc.)
Definition static_linear_model.h:34
double max_value
Maximum allowed value for physical activity.
Definition static_linear_model.h:40
double intercept
Intercept value for the linear model.
Definition static_linear_model.h:31
double stddev
Standard deviation for simple models (India approach)
Definition static_linear_model.h:43
Entity unique identifier data type.
Definition identifier.h:20
Ordered final income buckets for project_requirements.income.categories (3, 4, or 5).
Definition income_category_layout.h:13