Skip to content

Commit

Permalink
IO: Start to refactor agent to/from_string
Browse files Browse the repository at this point in the history
Created `agent_writer.hpp` to provide a more streamlined interface
to agent parsing and output. Moved the `to_string` function out of agent
Also changed the agent type of the DeGroot model, so that it contains
the opinion as `agent.data.opinion`.

Co-authored-by: Amrita Goswami <[email protected]>
  • Loading branch information
MSallermann and amritagos committed Mar 18, 2024
1 parent ee6e0f4 commit 6daca16
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 24 deletions.
5 changes: 0 additions & 5 deletions include/agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ class Agent
virtual ~Agent() = default;

void from_string( const std::string & str );

virtual std::string to_string() const
{
return fmt::format( "{:.16f}", data );
}
};

template<>
Expand Down
20 changes: 20 additions & 0 deletions include/agent_writer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
#include <fmt/format.h>

namespace Seldon
{

template<typename AgentT>
std::string agent_to_string( const AgentT & agent )
{
static_assert( false, "Base implementation not valid" );
return "";
}

template<typename AgentT>
std::string opinion_to_string( const AgentT & agent )
{
return fmt::format( "{}", agent.data.opinion );
}

} // namespace Seldon
13 changes: 10 additions & 3 deletions include/models/ActivityDrivenModel.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "agent.hpp"
#include "agent_writer.hpp"
#include "model.hpp"
#include "network.hpp"
#include <cstddef>
Expand All @@ -21,10 +22,16 @@ struct ActivityAgentData
};

template<>
inline std::string Agent<ActivityAgentData>::to_string() const
inline std::string agent_to_string<Agent<ActivityAgentData>>( const Agent<ActivityAgentData> & agent )
{
return fmt::format( "{}, {}, {}", data.opinion, data.activity, data.reluctance );
};
return fmt::format( "{}, {}, {}", agent.data.opinion, agent.data.activity, agent.data.reluctance );
}

template<>
inline std::string opinion_to_string<Agent<ActivityAgentData>>( const Agent<ActivityAgentData> & agent )
{
return fmt::format( "{}", agent.data.opinion );
}

template<>
inline void Agent<ActivityAgentData>::from_string( const std::string & str )
Expand Down
28 changes: 26 additions & 2 deletions include/models/DeGroot.hpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
#pragma once
#include "agent.hpp"
#include "agent_writer.hpp"
#include "model.hpp"
#include "network.hpp"
#include <vector>

namespace Seldon
{

class DeGrootModel : public Model<Agent<double>>
struct DeGrootAgentData
{
double opinion = 0; // x_i
};

template<>
inline std::string agent_to_string<Agent<DeGrootAgentData>>( const Agent<DeGrootAgentData> & agent )
{
return fmt::format( "{}", agent.data.opinion );
}

template<>
inline std::string opinion_to_string<Agent<DeGrootAgentData>>( const Agent<DeGrootAgentData> & agent )
{
return agent_to_string( agent );
}

template<>
inline void Agent<DeGrootAgentData>::from_string( const std::string & str )
{
data.opinion = std::stod( str );
};

class DeGrootModel : public Model<Agent<DeGrootAgentData>>
{
public:
using AgentT = Agent<double>;
using AgentT = Agent<DeGrootAgentData>;
using NetworkT = Network<AgentT>;
double convergence_tol = 1e-12;

Expand Down
3 changes: 2 additions & 1 deletion include/util/io.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include "agent_writer.hpp"
#include "fstream"
#include "network.hpp"
#include <fmt/core.h>
Expand Down Expand Up @@ -48,7 +49,7 @@ void opinions_to_file( const Network<AgentT> & network, const std::string & file
fmt::print( fs, "# idx_agent, opinion[...]\n" );
for( size_t idx_agent = 0; idx_agent < n_agents; idx_agent++ )
{
std::string row = fmt::format( "{:>5}, {:>25}\n", idx_agent, network.agents[idx_agent].to_string() );
std::string row = fmt::format( "{:>5}, {:>25}\n", idx_agent, agent_to_string( network.agents[idx_agent] ) );
fs << row;
}
fs.close();
Expand Down
14 changes: 7 additions & 7 deletions src/models/DeGroot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ DeGrootModel::DeGrootModel( NetworkT & network )

for( size_t i = 0; i < network.agents.size(); i++ )
{
network.agents[i].data = double( i ) / double( network.agents.size() );
network.agents[i].data.opinion = double( i ) / double( network.agents.size() );
}
}

Expand All @@ -31,23 +31,23 @@ void DeGrootModel::iteration()

for( size_t i = 0; i < network.agents.size(); i++ )
{
auto neighbour_buffer = network.get_neighbours( i );
auto weight_buffer = network.get_weights( i );
agents_current_copy[i].data = 0.0;
auto neighbour_buffer = network.get_neighbours( i );
auto weight_buffer = network.get_weights( i );
agents_current_copy[i].data.opinion = 0.0;
for( size_t j = 0; j < neighbour_buffer.size(); j++ )
{
j_index = neighbour_buffer[j];
weight = weight_buffer[j];
agents_current_copy[i].data += weight * network.agents[j_index].data;
agents_current_copy[i].data.opinion += weight * network.agents[j_index].data.opinion;
}
}

max_opinion_diff = 0;
// Update the original agent opinions
for( std::size_t i = 0; i < network.agents.size(); i++ )
{
max_opinion_diff
= std::max( max_opinion_diff, std::abs( network.agents[i].data - agents_current_copy[i].data ) );
max_opinion_diff = std::max(
max_opinion_diff, std::abs( network.agents[i].data.opinion - agents_current_copy[i].data.opinion ) );
network.agents[i] = agents_current_copy[i];
}
}
Expand Down
12 changes: 6 additions & 6 deletions test/test_deGroot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ TEST_CASE( "Test the DeGroot Model Symmetric", "[DeGroot]" )
auto network = Network( std::move( neighbour_list ), std::move( weight_list ), Network::EdgeDirection::Incoming );
auto model = DeGrootModel( network );

model.convergence_tol = 1e-6;
model.max_iterations = 100;
network.agents[0].data = 0.0;
network.agents[1].data = 1.0;
model.convergence_tol = 1e-6;
model.max_iterations = 100;
network.agents[0].data.opinion = 0.0;
network.agents[1].data.opinion = 1.0;

do
{
Expand All @@ -39,7 +39,7 @@ TEST_CASE( "Test the DeGroot Model Symmetric", "[DeGroot]" )
INFO( fmt::format( "N_iterations = {} (with convergence_tol {})\n", model.n_iterations(), model.convergence_tol ) );
for( size_t i = 0; i < n_agents; i++ )
{
INFO( fmt::format( "Opinion {} = {}\n", i, network.agents[i].data ) );
REQUIRE_THAT( network.agents[i].data, WithinAbs( 0.5, model.convergence_tol * 10.0 ) );
INFO( fmt::format( "Opinion {} = {}\n", i, network.agents[i].data.opinion ) );
REQUIRE_THAT( network.agents[i].data.opinion, WithinAbs( 0.5, model.convergence_tol * 10.0 ) );
}
}

0 comments on commit 6daca16

Please sign in to comment.