Skip to content

Commit

Permalink
ActivityDrivenModel: Include reluctance
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
MSallermann committed Mar 16, 2024
1 parent fb63ccd commit b1bcfa8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 13 deletions.
36 changes: 25 additions & 11 deletions include/models/ActivityDrivenModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <cstddef>
#include <random>
#include <set>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

Expand All @@ -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<ActivityAgentData>::to_string() const
{
return fmt::format( "{}, {}", data.opinion, data.activity );
return fmt::format( "{}, {}, {}", data.opinion, data.activity, data.reluctance );
};

template<>
inline void Agent<ActivityAgentData>::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<Agent<ActivityAgentData>>
Expand Down Expand Up @@ -69,7 +85,8 @@ class ActivityDrivenModel : public Model<Agent<ActivityAgentData>>
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;
Expand Down Expand Up @@ -119,9 +136,6 @@ class ActivityDrivenModel : public Model<Agent<ActivityAgentData>>
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
6 changes: 4 additions & 2 deletions test/test_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ TEST_CASE( "Test reading in the agents from a file", "[io_agents]" )

auto agents = Seldon::AgentGeneration::generate_from_file<ActivityDrivenModel::AgentT>( network_file );

std::vector<double> opinions_expected = { 2.1127107987061544, 0.8088982488089491, -0.8802809369462433 };
std::vector<double> activities_expected = { 0.044554683389757696, 0.015813166022685163, 0.015863953902810535 };
std::vector<double> opinions_expected = { 2.1127107987061544, 0.8088982488089491, -0.8802809369462433 };
std::vector<double> activities_expected = { 0.044554683389757696, 0.015813166022685163, 0.015863953902810535 };
std::vector<double> reluctances_expected = { 1.0, 1.0, 2.3 };

REQUIRE( agents.size() == 3 );

Expand All @@ -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 ) );
}
}

0 comments on commit b1bcfa8

Please sign in to comment.