Skip to content

Commit

Permalink
agent_io: agents_to_file and agents_from_file
Browse files Browse the repository at this point in the history
Removed the corresponding functions in `agent_generation` and `io`.
It makes more sense to localize the agent_io in a single header.

Co-authored-by: Amrita Goswami <[email protected]>
  • Loading branch information
MSallermann and amritagos committed Mar 18, 2024
1 parent eae15a3 commit 4303d50
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 75 deletions.
41 changes: 0 additions & 41 deletions include/agent_generation.hpp
Original file line number Diff line number Diff line change
@@ -1,50 +1,9 @@
#pragma once
#include "agent_io.hpp"
#include "util/misc.hpp"
#include <cstddef>
#include <vector>

namespace Seldon::AgentGeneration
{

template<typename AgentT>
std::vector<AgentT> generate_from_file( const std::string & file )
{
std::vector<AgentT> agents{};

std::string file_contents = get_file_contents( file );
bool finished = false;
size_t start_of_line = 0;

while( !finished )
{
// Find the end of the current line
auto end_of_line = file_contents.find( '\n', start_of_line );
if( end_of_line == std::string::npos )
{
finished = true;
}
// Get the current line as a substring
auto line = file_contents.substr( start_of_line, end_of_line - start_of_line );
start_of_line = end_of_line + 1;

if( line.empty() )
{
break;
}
if( line[0] == '#' )
{
continue;
}

// First column is the index of the agent
auto end_of_first_column = line.find( ',', 0 );
auto opinion_substring = line.substr( end_of_first_column + 1, end_of_line );

agents.push_back( agent_from_string<AgentT>( opinion_substring ) );
}

return agents;
}

} // namespace Seldon::AgentGeneration
72 changes: 72 additions & 0 deletions include/agent_io.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#pragma once
#include "fstream"
#include "network.hpp"
#include "util/misc.hpp"
#include <fmt/core.h>
#include <fmt/format.h>
#include <fmt/ostream.h>
#include <fmt/ranges.h>
#include <vector>

namespace Seldon
Expand Down Expand Up @@ -29,4 +35,70 @@ std::vector<std::string> agent_to_string_column_names()
return { "agent_data[...]" };
}

template<typename AgentT>
void agents_to_file( const Network<AgentT> & network, const std::string & file_path )
{
std::fstream fs;
fs.open( file_path, std::fstream::in | std::fstream::out | std::fstream::trunc );

size_t n_agents = network.n_agents();

auto column_names = agent_to_string_column_names<AgentT>();

std::string header = "# idx_agent";
for( auto col : column_names )
{
header += ", " + col;
}
header += "\n";

fmt::print( fs, "{}", header );
for( size_t idx_agent = 0; idx_agent < n_agents; idx_agent++ )
{
std::string row = fmt::format( "{:>5}, {:>25}\n", idx_agent, agent_to_string( network.agents[idx_agent] ) );
fs << row;
}
fs.close();
}

template<typename AgentT>
std::vector<AgentT> agents_from_file( const std::string & file )
{
std::vector<AgentT> agents{};

std::string file_contents = get_file_contents( file );
bool finished = false;
size_t start_of_line = 0;

while( !finished )
{
// Find the end of the current line
auto end_of_line = file_contents.find( '\n', start_of_line );
if( end_of_line == std::string::npos )
{
finished = true;
}
// Get the current line as a substring
auto line = file_contents.substr( start_of_line, end_of_line - start_of_line );
start_of_line = end_of_line + 1;

if( line.empty() )
{
break;
}
if( line[0] == '#' )
{
continue;
}

// First column is the index of the agent
auto end_of_first_column = line.find( ',', 0 );
auto opinion_substring = line.substr( end_of_first_column + 1, end_of_line );

agents.push_back( agent_from_string<AgentT>( opinion_substring ) );
}

return agents;
}

} // namespace Seldon
10 changes: 4 additions & 6 deletions include/simulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "network.hpp"
#include <fmt/chrono.h>
#include <fmt/format.h>
#include <agent_generation.hpp>
#include <filesystem>
#include <memory>
#include <models/ActivityDrivenModel.hpp>
Expand Down Expand Up @@ -95,7 +94,7 @@ class Simulation : public SimulationInterface

if( cli_agent_file.has_value() )
{
network.agents = AgentGeneration::generate_from_file<DeGrootModel::AgentT>( cli_agent_file.value() );
network.agents = agents_from_file<DeGrootModel::AgentT>( cli_agent_file.value() );
}
}
else if constexpr( std::is_same_v<AgentType, ActivityDrivenModel::AgentT> )
Expand Down Expand Up @@ -133,8 +132,7 @@ class Simulation : public SimulationInterface

if( cli_agent_file.has_value() )
{
network.agents
= AgentGeneration::generate_from_file<ActivityDrivenModel::AgentT>( cli_agent_file.value() );
network.agents = agents_from_file<ActivityDrivenModel::AgentT>( cli_agent_file.value() );
}
}
}
Expand All @@ -154,7 +152,7 @@ class Simulation : public SimulationInterface
{
Seldon::IO::network_to_file( network, ( output_dir_path / fs::path( "network_0.txt" ) ).string() );
auto filename = fmt::format( "opinions_{}.txt", 0 );
Seldon::IO::opinions_to_file( network, ( output_dir_path / fs::path( filename ) ).string() );
Seldon::agents_to_file( network, ( output_dir_path / fs::path( filename ) ).string() );
}
this->model->initialize_iterations();

Expand Down Expand Up @@ -182,7 +180,7 @@ class Simulation : public SimulationInterface
&& ( this->model->n_iterations() % n_output_agents.value() == 0 ) )
{
auto filename = fmt::format( "opinions_{}.txt", this->model->n_iterations() );
Seldon::IO::opinions_to_file( network, ( output_dir_path / fs::path( filename ) ).string() );
Seldon::agents_to_file( network, ( output_dir_path / fs::path( filename ) ).string() );
}

// Write out the network?
Expand Down
27 changes: 0 additions & 27 deletions include/util/io.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "agent_io.hpp"
#include "fstream"
#include "network.hpp"
#include <fmt/core.h>
Expand Down Expand Up @@ -38,32 +37,6 @@ void network_to_dot_file( const Network<AgentT> & network, const std::string & f
fs.close();
}

template<typename AgentT>
void opinions_to_file( const Network<AgentT> & network, const std::string & file_path )
{
std::fstream fs;
fs.open( file_path, std::fstream::in | std::fstream::out | std::fstream::trunc );

size_t n_agents = network.n_agents();

auto column_names = agent_to_string_column_names<AgentT>();

std::string header = "# idx_agent";
for( auto col : column_names )
{
header += ", " + col;
}
header += "\n";

fmt::print( fs, "{}", header );
for( size_t idx_agent = 0; idx_agent < n_agents; idx_agent++ )
{
std::string row = fmt::format( "{:>5}, {:>25}\n", idx_agent, agent_to_string( network.agents[idx_agent] ) );
fs << row;
}
fs.close();
}

template<typename AgentT>
void network_to_file( const Network<AgentT> & network, const std::string & file_path )
{
Expand Down
2 changes: 1 addition & 1 deletion test/test_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ TEST_CASE( "Test reading in the agents from a file", "[io_agents]" )
auto proj_root_path = fs::current_path();
auto network_file = proj_root_path / fs::path( "test/res/opinions.txt" );

auto agents = Seldon::AgentGeneration::generate_from_file<ActivityDrivenModel::AgentT>( network_file );
auto agents = Seldon::agents_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 };
Expand Down

0 comments on commit 4303d50

Please sign in to comment.