Skip to content

Commit

Permalink
ActivityDrivenModel: refactored homophily weight calculation for less…
Browse files Browse the repository at this point in the history
… code duplication
  • Loading branch information
MSallermann committed Mar 14, 2024
1 parent 13096bd commit 6d9fbaf
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 41 deletions.
2 changes: 2 additions & 0 deletions include/models/ActivityDrivenModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class ActivityAgentModel : public Model<Agent<ActivityAgentData>>
}
}

// The weight for contact between two agents
double homophily_weight( size_t idx_contacter, size_t idx_contacted );
void update_network_probabilistic();
void update_network_mean();
void update_network();
Expand Down
76 changes: 35 additions & 41 deletions src/models/ActivityDrivenModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,35 @@
#include <random>
#include <vector>

Seldon::ActivityAgentModel::ActivityAgentModel( int n_agents, Network & network, std::mt19937 & gen )
: Model<Seldon::ActivityAgentModel::AgentT>( n_agents ),
namespace Seldon
{

ActivityAgentModel::ActivityAgentModel( int n_agents, Network & network, std::mt19937 & gen )
: Model<ActivityAgentModel::AgentT>( n_agents ),
network( network ),
contact_prob_list( std::vector<std::vector<Network::WeightT>>( n_agents ) ),
gen( gen )
{
}

void Seldon::ActivityAgentModel::get_agents_from_power_law()
double ActivityAgentModel::homophily_weight( size_t idx_contacter, size_t idx_contacted )
{
double homophily = this->homophily;

if( idx_contacted == idx_contacter )
return 0.0;

if( bot_present() && idx_contacter < n_bots )
homophily = this->bot_homophily[idx_contacter];

constexpr double tolerance = 1e-10;
auto opinion_diff = std::abs( this->agents[idx_contacter].data.opinion - this->agents[idx_contacted].data.opinion );
opinion_diff = std::max( tolerance, opinion_diff );

return std::pow( opinion_diff, -homophily );
}

void ActivityAgentModel::get_agents_from_power_law()
{
std::uniform_real_distribution<> dis_opinion( -1, 1 ); // Opinion initial values
power_law_distribution<> dist_activity( eps, gamma );
Expand Down Expand Up @@ -45,7 +65,7 @@ void Seldon::ActivityAgentModel::get_agents_from_power_law()
}
}

void Seldon::ActivityAgentModel::update_network_probabilistic()
void ActivityAgentModel::update_network_probabilistic()
{
network.switch_direction_flag();

Expand All @@ -62,19 +82,6 @@ void Seldon::ActivityAgentModel::update_network_probabilistic()
{
// Implement the weight for the probability of agent `idx_agent` contacting agent `j`
// Not normalised since this is taken care of by the reservoir sampling
auto weight_callback = [idx_agent, this]( size_t j )
{
double homophily = this->homophily;

if( bot_present() && idx_agent < n_bots )
{
homophily = this->bot_homophily[idx_agent];
}
if( idx_agent == j ) // The agent does not contact itself
return 0.0;
return std::pow(
std::abs( this->agents[idx_agent].data.opinion - this->agents[j].data.opinion ), -homophily );
};

int m_temp = this->m;

Expand All @@ -83,7 +90,9 @@ void Seldon::ActivityAgentModel::update_network_probabilistic()
m_temp = bot_m[idx_agent];
}

Seldon::reservoir_sampling_A_ExpJ( m_temp, network.n_agents(), weight_callback, contacted_agents, gen );
reservoir_sampling_A_ExpJ(
m_temp, network.n_agents(), [&]( int j ) { return homophily_weight( idx_agent, j ); }, contacted_agents,
gen );

// Fill the outgoing edges into the reciprocal edge buffer
for( const auto & idx_outgoing : contacted_agents )
Expand Down Expand Up @@ -123,7 +132,7 @@ void Seldon::ActivityAgentModel::update_network_probabilistic()
network.toggle_incoming_outgoing(); // switch direction, so that we have incoming edges
}

void Seldon::ActivityAgentModel::update_network_mean()
void ActivityAgentModel::update_network_mean()
{
using WeightT = Network::WeightT;
std::vector<WeightT> weights( network.n_agents(), 0.0 );
Expand All @@ -135,8 +144,7 @@ void Seldon::ActivityAgentModel::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 );
Expand All @@ -147,26 +155,11 @@ void Seldon::ActivityAgentModel::update_network_mean()
{
// Implement the weight for the probability of agent `idx_agent` contacting agent `j`
// Not normalised since this is taken care of by the reservoir sampling
auto weight_callback = [idx_agent, this]( size_t j )
{
double homophily = this->homophily;

if( bot_present() && idx_agent < n_bots )
{
homophily = this->bot_homophily[idx_agent];
}

constexpr double tolerance = 1e-16;
auto opinion_diff = std::abs( this->agents[idx_agent].data.opinion - this->agents[j].data.opinion );
if( opinion_diff < tolerance )
return 0.0;
return std::pow( opinion_diff, -homophily );
};

double normalization = 0;
for( size_t k = 0; k < network.n_agents(); k++ )
{
normalization += weight_callback( k );
normalization += homophily_weight( idx_agent, k );
}

// Go through all the neighbours of idx_agent
Expand All @@ -180,7 +173,7 @@ void Seldon::ActivityAgentModel::update_network_mean()

for( size_t j = 0; j < network.n_agents(); j++ )
{
double omega = weight_callback( j ) / normalization;
double omega = homophily_weight( idx_agent, j ) / normalization;
// We can calculate the probability of i contacting j ( i->j )
// Update contact prob_list (outgoing)
contact_prob_list[idx_agent][j] = agents[idx_agent].data.activity * probability_helper( omega, m_temp );
Expand Down Expand Up @@ -209,7 +202,7 @@ void Seldon::ActivityAgentModel::update_network_mean()
}
}

void Seldon::ActivityAgentModel::update_network()
void ActivityAgentModel::update_network()
{

if( !mean_weights )
Expand All @@ -222,7 +215,7 @@ void Seldon::ActivityAgentModel::update_network()
}
}

void Seldon::ActivityAgentModel::iteration()
void ActivityAgentModel::iteration()
{
Model<AgentT>::iteration();

Expand Down Expand Up @@ -256,4 +249,5 @@ void Seldon::ActivityAgentModel::iteration()
agents[bot_idx].data.opinion = bot_opinion[bot_idx];
}
}
}
}
} // namespace Seldon

0 comments on commit 6d9fbaf

Please sign in to comment.