From b1bcfa821eecaac9677cf34a07ae5f4756ba247f Mon Sep 17 00:00:00 2001 From: Moritz Sallermann Date: Sat, 16 Mar 2024 13:17:53 +0000 Subject: [PATCH] ActivityDrivenModel: Include reluctance The ActivityDrivenModel driven model has been extended with a concept, that we call reluctance. This quantifies how receptive to others' opinions an agent is. Reluctance is an per agent quantity and therefore the IO had to be changed slightly. The bots can be thought of as agents with infinite reluctance. TODO: generation of distributions for reluctance, possibly correlated with activities. --- include/models/ActivityDrivenModel.hpp | 36 ++++++++++++++++++-------- test/test_io.cpp | 6 +++-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/models/ActivityDrivenModel.hpp b/include/models/ActivityDrivenModel.hpp index 6710f98..3d2bb9f 100644 --- a/include/models/ActivityDrivenModel.hpp +++ b/include/models/ActivityDrivenModel.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -15,22 +15,38 @@ namespace Seldon struct ActivityAgentData { - double opinion = 0; // x_i - double activity = 0; // a_i + double opinion = 0; // x_i + double activity = 0; // a_i + double reluctance = 1.0; // m_i }; template<> inline std::string Agent::to_string() const { - return fmt::format( "{}, {}", data.opinion, data.activity ); + return fmt::format( "{}, {}, {}", data.opinion, data.activity, data.reluctance ); }; template<> inline void Agent::from_string( const std::string & str ) { - auto pos_comma = str.find_first_of( ',' ); - data.opinion = std::stod( str.substr( 0, pos_comma ) ); - data.activity = std::stod( str.substr( pos_comma + 1, str.size() ) ); + auto pos_comma = str.find_first_of( ',' ); + auto pos_next_comma = str.find( ',', pos_comma + 1 ); + + data.opinion = std::stod( str.substr( 0, pos_comma ) ); + + if( pos_next_comma == std::string::npos ) + { + data.activity = std::stod( str.substr( pos_comma + 1, str.size() ) ); + } + else + { + data.activity = std::stod( str.substr( pos_comma + 1, pos_next_comma ) ); + } + + if( pos_next_comma != std::string::npos ) + { + data.reluctance = std::stod( str.substr( pos_next_comma + 1, str.size() ) ); + } }; class ActivityDrivenModel : public Model> @@ -69,7 +85,8 @@ class ActivityDrivenModel : public Model> for( size_t j = 0; j < neighbour_buffer.size(); j++ ) { j_index = neighbour_buffer[j]; - k_buffer[idx_agent] += K * weight_buffer[j] * std::tanh( alpha * opinion( j_index ) ); + k_buffer[idx_agent] += 1.0 / network.agents[idx_agent].data.reluctance * K * weight_buffer[j] + * std::tanh( alpha * opinion( j_index ) ); } // Multiply by the timestep k_buffer[idx_agent] *= dt; @@ -119,9 +136,6 @@ class ActivityDrivenModel : public Model> void get_agents_from_power_law(); // This needs to be called after eps and gamma have been set void iteration() override; - - // bool finished() overteration() override; - // bool finished() override; }; } // namespace Seldon \ No newline at end of file diff --git a/test/test_io.cpp b/test/test_io.cpp index 1642182..e79fd21 100644 --- a/test/test_io.cpp +++ b/test/test_io.cpp @@ -48,8 +48,9 @@ TEST_CASE( "Test reading in the agents from a file", "[io_agents]" ) auto agents = Seldon::AgentGeneration::generate_from_file( network_file ); - std::vector opinions_expected = { 2.1127107987061544, 0.8088982488089491, -0.8802809369462433 }; - std::vector activities_expected = { 0.044554683389757696, 0.015813166022685163, 0.015863953902810535 }; + std::vector opinions_expected = { 2.1127107987061544, 0.8088982488089491, -0.8802809369462433 }; + std::vector activities_expected = { 0.044554683389757696, 0.015813166022685163, 0.015863953902810535 }; + std::vector reluctances_expected = { 1.0, 1.0, 2.3 }; REQUIRE( agents.size() == 3 ); @@ -58,5 +59,6 @@ TEST_CASE( "Test reading in the agents from a file", "[io_agents]" ) fmt::print( "{}", i ); REQUIRE_THAT( agents[i].data.opinion, Catch::Matchers::WithinAbs( opinions_expected[i], 1e-16 ) ); REQUIRE_THAT( agents[i].data.activity, Catch::Matchers::WithinAbs( activities_expected[i], 1e-16 ) ); + REQUIRE_THAT( agents[i].data.reluctance, Catch::Matchers::WithinAbs( reluctances_expected[i], 1e-16 ) ); } } \ No newline at end of file