1 #ifndef UTOPIA_MODELS_OPINIONET_HH
2 #define UTOPIA_MODELS_OPINIONET_HH
5 #include <boost/graph/random.hpp>
52 boost::bidirectionalS,
79 template<
typename NWType=NetworkUndirected>
81 public Model<Opinionet<NWType>, OpinionetTypes>
126 template<
class ParentModel>
142 "weighting", this->
_cfg[
"network"][
"edges"])),
147 {boost::num_vertices(
_nw)})),
150 this->
_log->debug(
"Constructing the Opinionet Model ...");
156 "Initialized network with {} vertices and {} edges. Directed: {}",
157 boost::num_vertices(
_nw),
158 boost::num_edges(
_nw),
166 _dset_opinion->add_attribute(
"coords_mode__vertex_idx",
"trivial");
170 this->
_log->debug(
"Network saved.");
175 auto _dset_vertices =
_dgrp_nw->open_dataset(
176 "_vertices", {boost::num_vertices(
_nw)}
178 auto [v, v_end] = boost::vertices(
_nw);
179 _dset_vertices->write(
182 return boost::get(boost::vertex_index_t(),
_nw, vd);
185 _dset_vertices->add_attribute(
"dim_name__0",
"vertex_idx");
186 _dset_vertices->add_attribute(
187 "coords_mode__vertex_idx",
"trivial"
198 if (get_as<std::string>(
"interaction_function", this->
_cfg)
209 if (get_as<std::string>(
"type", this->
_cfg[
"opinion_space"])
220 if (get_as<bool>(
"rewiring", this->
_cfg[
"network"][
"edges"])) {
229 this->
_log->debug(
"Initializing the properties ...");
233 const std::pair<double, double> opinion_interval =
234 get_as<std::pair<double, double>>(
235 "interval", this->
_cfg[
"opinion_space"]
238 if (opinion_interval.first >= opinion_interval.second) {
239 throw std::invalid_argument(
"Error: The given opinion interval"
240 " is invalid! Specify an interval of the kind [a, b], "
244 for (
const auto v : range<IterateOver::vertices>(
_nw)) {
245 _nw[v].opinion = Utils::get_rand<double>(
246 opinion_interval, *this->
_rng);
251 const int opinion_values =
252 get_as<int>(
"num_opinions", this->
_cfg[
"opinion_space"]);
254 for (
const auto v : range<IterateOver::vertices>(
_nw)) {
256 Utils::get_rand<int>(
257 std::make_pair<int, int>(0, opinion_values-1),
265 if constexpr (Utils::is_directed<NWType>()) {
266 for (
const auto v : range<IterateOver::vertices>(
_nw)) {
267 if (boost::out_degree(v,
_nw) != 0) {
275 this->
_log->debug(
"Creating the network ...");
277 auto g = Graph::create_graph<NWType>(this->
_cfg[
"network"], *this->
_rng);
279 this->
_log->debug(
"Network created.");
286 if constexpr (Utils::is_directed<NWType>()) {
331 double mean_opinion = 0.;
332 double opinion_std = 0.;
333 double min_opinion = std::numeric_limits<double>::infinity();
334 double max_opinion = -std::numeric_limits<double>::infinity();
337 for (
const auto v : range<IterateOver::vertices>(
_nw)) {
338 temp_op =
_nw[v].opinion;
339 mean_opinion += temp_op;
341 if (temp_op < min_opinion) {
342 min_opinion = temp_op;
345 if (temp_op > max_opinion) {
346 max_opinion = temp_op;
350 mean_opinion /= boost::num_vertices(
_nw);
352 for (
const auto v : range<IterateOver::vertices>(
_nw)) {
353 opinion_std += std::pow(
_nw[v].opinion - mean_opinion, 2.);
356 opinion_std = std::sqrt(opinion_std / (boost::num_vertices(
_nw) - 1.));
358 this->
_monitor.set_entry(
"mean_opinion", mean_opinion);
359 this->
_monitor.set_entry(
"opinion_std", opinion_std);
360 this->
_monitor.set_entry(
"min_opinion", min_opinion);
361 this->
_monitor.set_entry(
"max_opinion", max_opinion);
369 auto [v, v_end] = boost::vertices(
_nw);
373 v, v_end, [
this](
auto vd) {
return _nw[vd].opinion; }
379 const auto get_edge_data = std::make_tuple(
380 std::make_tuple(
"_edges",
"type",
381 std::make_tuple(
"source",
382 [](
auto& ed,
auto&
_nw) {
384 boost::vertex_index_t(),
_nw,
385 boost::source(ed,
_nw));
388 std::make_tuple(
"target",
389 [](
auto& ed,
auto&
_nw) {
391 boost::vertex_index_t(),
_nw,
392 boost::target(ed,
_nw));
404 if constexpr (Utils::is_directed<NWType>()) {
406 auto [e, e_end] = boost::edges(
_nw);
409 e, e_end, [
this](
auto ed) {
return _nw[ed].weight; }
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
const std::shared_ptr< DataGroup > _hdfgrp
The HDF group this model instance should write its data to.
Definition: model.hh:176
Monitor _monitor
The monitor.
Definition: model.hh:188
typename ModelTypes::DataSet DataSet
Data type that is used for storing data.
Definition: model.hh:125
const Config _cfg
Config node belonging to this model instance.
Definition: model.hh:158
std::shared_ptr< DataSet > create_dset(const std::string name, const std::shared_ptr< DataGroup > &hdfgrp, std::vector< hsize_t > add_write_shape, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a new dataset within the given group.
Definition: model.hh:752
Time get_time() const
Return the current time of this model.
Definition: model.hh:393
typename ModelTypes::DataGroup DataGroup
Data type that is used for storing datasets.
Definition: model.hh:122
typename ModelTypes::Config Config
Data type that holds the configuration.
Definition: model.hh:116
typename ModelTypes::RNG RNG
Data type of the shared RNG.
Definition: model.hh:128
const std::shared_ptr< spdlog::logger > _log
The (model) logger.
Definition: model.hh:164
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition: model.hh:161
The Opinionet model class.
Definition: Opinionet.hh:82
typename Base::Config Config
Data type that holds the configuration.
Definition: Opinionet.hh:88
Rewiring initialize_rewiring()
Definition: Opinionet.hh:219
const double _tolerance
Definition: Opinionet.hh:109
const double _susceptibility
Definition: Opinionet.hh:110
const std::shared_ptr< DataSet > _dset_edge_weights
Definition: Opinionet.hh:119
typename Base::DataSet DataSet
Data type for a dataset.
Definition: Opinionet.hh:94
NWType _nw
Network and model dynamics parameters.
Definition: Opinionet.hh:108
void write_data()
Write data.
Definition: Opinionet.hh:366
const Opinion_space_type _opinion_space
Definition: Opinionet.hh:104
void monitor()
Monitor model information.
Definition: Opinionet.hh:330
Opinion_space_type initialize_opinion_space()
Definition: Opinionet.hh:208
const std::shared_ptr< DataSet > _dset_opinion
Definition: Opinionet.hh:118
const double _weighting
Definition: Opinionet.hh:111
void initialize_properties()
Definition: Opinionet.hh:228
typename Base::DataGroup DataGroup
Data type of the group to write model data to, holding datasets.
Definition: Opinionet.hh:91
typename Base::RNG RNG
Data type of the shared RNG.
Definition: Opinionet.hh:97
std::shared_ptr< DataSet > create_edge_weight_dset()
Definition: Opinionet.hh:285
void perform_step()
Iterate a single step @detail Each step consists of an opinion update and edge rewiring....
Definition: Opinionet.hh:308
const std::shared_ptr< DataGroup > _dgrp_nw
Definition: Opinionet.hh:117
NWType initialize_nw() const
Definition: Opinionet.hh:274
Opinionet(const std::string name, ParentModel &parent)
Construct the Opinionet model.
Definition: Opinionet.hh:127
Interaction_type initialize_interaction()
Definition: Opinionet.hh:197
const Interaction_type _interaction
Modes.
Definition: Opinionet.hh:103
const Rewiring _rewire
Definition: Opinionet.hh:105
std::uniform_real_distribution< double > _uniform_prob_distr
A uniform probability distribution.
Definition: Opinionet.hh:114
ReturnType get_as(const std::string &key, const DataIO::Config &node)
This function is a wrapper around the yaml-cpp YAML::Node::as function.
Definition: cfg_utils.hh:158
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
void save_edge_properties(Graph &&g, const std::shared_ptr< HDFGroup > &nw_grp, const std::string &label, const std::tuple< Adaptors... > &adaptor_tuple)
Definition: graph_utils.hh:573
std::shared_ptr< HDFGroup > create_graph_group(const Graph &g, const std::shared_ptr< HDFGroup > &parent_grp, const std::string &name)
Definition: graph_utils.hh:291
void save_graph(const Graph &g, const std::shared_ptr< HDFGroup > &grp)
Write function for a boost::Graph.
Definition: graph_utils.hh:332
Opinion_space_type
Definition: modes.hh:13
@ discrete
Definition: modes.hh:15
@ continuous
Definition: modes.hh:14
Interaction_type
Definition: modes.hh:8
@ Deffuant
Definition: modes.hh:9
@ HegselmannKrause
Definition: modes.hh:10
Rewiring
Definition: modes.hh:18
@ RewiringOn
Definition: modes.hh:19
@ RewiringOff
Definition: modes.hh:20
void revision(NWType &nw, const double susceptibility, const double tolerance, const double weighting, const Interaction_type interaction, const Opinion_space_type opinion_space, const Rewiring rewire, std::uniform_real_distribution< double > &prob_distr, RNGType &rng)
Performs an opinion update and edge rewiring (if enabled).
Definition: revision.hh:149
constexpr bool is_directed()
Check whether the network type allows for directed edges.
Definition: utils.hh:35
void set_and_normalize_weights(const VertexDescType v, NWType &nw, const double weighting)
Set and normalize weights according to opinion difference.
Definition: utils.hh:102
boost::adjacency_list< EdgeContainer, VertexContainer, boost::undirectedS, Agent > NetworkUndirected
The undirected network type.
Definition: Opinionet.hh:46
boost::adjacency_list< EdgeContainer, VertexContainer, boost::bidirectionalS, Agent, Edge > NetworkDirected
The directed network type.
Definition: Opinionet.hh:54
boost::vecS VertexContainer
The vertex container type.
Definition: Opinionet.hh:36
boost::vecS EdgeContainer
The edge container type.
Definition: Opinionet.hh:39
InteractionMode
Definition: Opinionet.hh:64
@ hegselmann_krause
Definition: Opinionet.hh:66
@ deffuant
Definition: Opinionet.hh:65
boost::adjacency_list< EdgeContainer, VertexContainer, boost::undirectedS, Agent > NetworkUndir
Definition: Opinionet.hh:62
Wrapper struct for defining model class data types.
Definition: model.hh:92
Each node in the network accomodates a single agent.
Definition: Opinionet.hh:24
double opinion
Definition: Opinionet.hh:25
Each network edge has a weight representing an interaction probability.
Definition: Opinionet.hh:29
double weight
Definition: Opinionet.hh:30