From b822f8ec5deffb6870bb665b31c3af010b336e13 Mon Sep 17 00:00:00 2001 From: Moritz Sallermann Date: Thu, 21 Mar 2024 20:57:35 +0000 Subject: [PATCH] ActivityDrivenModel: Reworked constructor Now takes the `ActivityDrivenSettings` struct to construct. This also enabled making many member variables private. Also gave the `Model` base class a constructor that takes `max_iterations`. Co-authored-by: Amrita Goswami --- include/model.hpp | 3 +++ include/models/ActivityDrivenModel.hpp | 35 +++++++++++++------------- include/simulation.hpp | 35 +------------------------- src/models/ActivityDrivenModel.cpp | 30 ++++++++++++++++++---- 4 files changed, 46 insertions(+), 57 deletions(-) diff --git a/include/model.hpp b/include/model.hpp index e13f663..9402265 100644 --- a/include/model.hpp +++ b/include/model.hpp @@ -15,6 +15,9 @@ class Model std::optional max_iterations = std::nullopt; + Model() = default; + Model( std::optional max_iterations ) : max_iterations( max_iterations ){}; + virtual void initialize_iterations() { _n_iterations = 0; diff --git a/include/models/ActivityDrivenModel.hpp b/include/models/ActivityDrivenModel.hpp index 7459409..5641326 100644 --- a/include/models/ActivityDrivenModel.hpp +++ b/include/models/ActivityDrivenModel.hpp @@ -1,6 +1,8 @@ #pragma once #include "agents/activity_agent.hpp" +#include "config_parser.hpp" + #include "model.hpp" #include "network.hpp" #include @@ -19,12 +21,17 @@ class ActivityDrivenModel : public Model using AgentT = ActivityAgent; using NetworkT = Network; - ActivityDrivenModel( NetworkT & network, std::mt19937 & gen ); - - void get_agents_from_power_law(); // This needs to be called after eps and gamma have been set + ActivityDrivenModel( const Config::ActivityDrivenSettings & settings, NetworkT & network, std::mt19937 & gen ); void iteration() override; +private: + NetworkT & network; + std::vector> contact_prob_list; // Probability of choosing i in 1 to m rounds + // Random number generation + std::mt19937 & gen; // reference to simulation Mersenne-Twister engine + std::set> reciprocal_edge_buffer{}; + // Model-specific parameters double dt = 0.01; // Timestep for the integration of the coupled ODEs // Various free parameters @@ -41,39 +48,31 @@ class ActivityDrivenModel : public Model bool mean_activities = false; bool mean_weights = false; - double convergence_tol = 1e-12; // TODO: ?? - bool use_reluctances = false; double reluctance_mean{}; double reluctance_sigma{}; double reluctance_eps{}; double covariance_factor{}; - // bot @TODO: less hacky size_t n_bots = 0; // The first n_bots agents are bots std::vector bot_m = std::vector( 0 ); std::vector bot_activity = std::vector( 0 ); std::vector bot_opinion = std::vector( 0 ); std::vector bot_homophily = std::vector( 0 ); - [[nodiscard]] bool bot_present() const - { - return n_bots > 0; - } - -private: - NetworkT & network; - std::vector> contact_prob_list; // Probability of choosing i in 1 to m rounds - // Random number generation - std::mt19937 & gen; // reference to simulation Mersenne-Twister engine - std::set> reciprocal_edge_buffer{}; - // Buffers for RK4 integration std::vector k1_buffer{}; std::vector k2_buffer{}; std::vector k3_buffer{}; std::vector k4_buffer{}; + void get_agents_from_power_law(); + + [[nodiscard]] bool bot_present() const + { + return n_bots > 0; + } + template void get_euler_slopes( std::vector & k_buffer, Opinion_Callback opinion ) { diff --git a/include/simulation.hpp b/include/simulation.hpp index 8d4b132..0815e23 100644 --- a/include/simulation.hpp +++ b/include/simulation.hpp @@ -107,40 +107,7 @@ class Simulation : public SimulationInterface model = [&]() { - auto model = std::make_unique( network, gen ); - model->dt = activitydriven_settings.dt; - model->m = activitydriven_settings.m; - model->eps = activitydriven_settings.eps; - model->gamma = activitydriven_settings.gamma; - model->homophily = activitydriven_settings.homophily; - model->reciprocity = activitydriven_settings.reciprocity; - model->alpha = activitydriven_settings.alpha; - model->K = activitydriven_settings.K; - model->mean_activities = activitydriven_settings.mean_activities; - model->mean_weights = activitydriven_settings.mean_weights; - model->max_iterations = activitydriven_settings.max_iterations; - // Reluctance - model->use_reluctances = activitydriven_settings.use_reluctances; - model->reluctance_mean = activitydriven_settings.reluctance_mean; - model->reluctance_sigma = activitydriven_settings.reluctance_sigma; - model->reluctance_eps = activitydriven_settings.reluctance_eps; - // Bot - model->n_bots = activitydriven_settings.n_bots; - model->bot_opinion = activitydriven_settings.bot_opinion; - model->bot_m = activitydriven_settings.bot_m; - model->bot_homophily = activitydriven_settings.bot_homophily; - model->bot_activity = activitydriven_settings.bot_activity; - model->get_agents_from_power_law(); - - // TODO: this is stupid and should be done in the constructor, but right now it cant since we set mean - // weights only later - if( model->mean_weights ) - { - auto agents_copy = network.agents; - network = NetworkGeneration::generate_fully_connected( network.n_agents() ); - network.agents = agents_copy; - } - + auto model = std::make_unique( activitydriven_settings, network, gen ); return model; }(); diff --git a/src/models/ActivityDrivenModel.cpp b/src/models/ActivityDrivenModel.cpp index 891fda5..62417e2 100644 --- a/src/models/ActivityDrivenModel.cpp +++ b/src/models/ActivityDrivenModel.cpp @@ -9,12 +9,33 @@ namespace Seldon { -ActivityDrivenModel::ActivityDrivenModel( NetworkT & network, std::mt19937 & gen ) - : Model(), +ActivityDrivenModel::ActivityDrivenModel( + const Config::ActivityDrivenSettings & settings, NetworkT & network, std::mt19937 & gen ) + : Model( settings.max_iterations ), network( network ), contact_prob_list( std::vector>( network.n_agents() ) ), - gen( gen ) + gen( gen ), + dt( settings.dt ), + m( settings.m ), + eps( settings.eps ), + gamma( settings.gamma ), + alpha( settings.alpha ), + homophily( settings.homophily ), + reciprocity( settings.reciprocity ), + K( settings.K ), + mean_activities( settings.mean_activities ), + mean_weights( settings.mean_weights ), + use_reluctances( settings.use_reluctances ), + reluctance_mean( settings.reluctance_mean ), + reluctance_sigma( settings.reluctance_sigma ), + reluctance_eps( settings.reluctance_eps ), + n_bots( settings.n_bots ), + bot_m( settings.bot_m ), + bot_activity( settings.bot_activity ), + bot_opinion( settings.bot_opinion ), + bot_homophily( settings.bot_homophily ) { + get_agents_from_power_law(); if( mean_weights ) { @@ -160,8 +181,7 @@ void ActivityDrivenModel::update_network_mean() contact_prob_list[idx_agent] = weights; // set to zero } - auto probability_helper = []( double omega, size_t m ) - { + auto probability_helper = []( double omega, size_t m ) { double p = 0; for( size_t i = 1; i <= m; i++ ) p += ( std::pow( -omega, i + 1 ) + omega ) / ( omega + 1 );