Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
utils.hh
Go to the documentation of this file.
1#ifndef UTOPIA_MODELS_OPINIONET_UTILS
2#define UTOPIA_MODELS_OPINIONET_UTILS
3
4#include <cmath>
5
6#include <boost/graph/adjacency_list.hpp>
7#include <boost/graph/graph_traits.hpp>
8
10
11// .. Random distribution utility functions ...................................
13template<typename RT, typename T, typename RNGType>
14RT get_rand(std::pair<T, T> range, RNGType& rng) {
15 if (range.first > range.second) {
16 throw std::invalid_argument(
17 "Error, invalid parameter range! Upper limit has to be higher "
18 "than the lower limit."
19 );
20 }
21 if constexpr (std::is_floating_point<RT>()) {
22 return
23 std::uniform_real_distribution<RT>(range.first, range.second)(rng);
24 }
25 else {
26 return
27 std::uniform_int_distribution<RT>(range.first, range.second)(rng);
28 }
29}
30
31// .. Network utility functions ...............................................
32
34template<typename NWType>
35constexpr bool is_directed() {
36 return std::is_convertible<
37 typename boost::graph_traits<NWType>::directed_category,
38 boost::directed_tag>::value;
39}
40
43template<typename NWType, typename VertexDescType, typename RNGType>
45
46 const int nb_shift = get_rand<int>(
47 std::make_pair<int, int>(0, boost::out_degree(v, nw)-1), rng
48 );
49 auto nb = boost::adjacent_vertices(v, nw).first;
50 nb += nb_shift;
51 return *nb;
52}
53
56template<typename NWType, typename RNGType, typename VertexDescType>
58 const VertexDescType v,
59 NWType& nw,
60 std::uniform_real_distribution<double>& prob_distr,
61 RNGType& rng)
62{
63 auto nb = v;
64
65 if constexpr (Utils::is_directed<NWType>()) {
66 // The probability for choosing neighbor w is given by the weight on
67 // the edge (v, w).
68 const double nb_prob_frac = prob_distr(rng);
69 double cumulative_weights = 0.;
70 for (const auto w : range<IterateOver::neighbors>(v, nw)) {
71 cumulative_weights += nw[boost::edge(v, w, nw).first].weight;
73 nb = w;
74 break;
75 }
76 }
77 }
78 else {
79 nb = Utils::get_rand_neighbor(v, nw, rng);
80 }
81
82 return nb;
83}
84
86template<typename NWType, typename VertexDescType>
88 return fabs(nw[v].opinion - nw[w].opinion);
89}
90
92
101template<typename NWType, typename VertexDescType>
103 const VertexDescType v,
104 NWType& nw,
105 const double weighting)
106{
107 double weight_norm = 0.;
108 for (const auto e : range<IterateOver::out_edges>(v, nw)) {
109 double op_diff = opinion_difference(boost::target(e, nw), v, nw);
110 nw[e].weight = exp(-(weighting*op_diff));
111 weight_norm += nw[e].weight;
112 }
113 for (const auto e : range<IterateOver::out_edges>(v, nw)) {
114 nw[e].weight /= weight_norm;
115 }
116}
117
118} // namespace Utopia::Models::Opinionet::Utils
119
120#endif // UTOPIA_MODELS_OPINIONET_UTILS
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
decltype(auto) range(const Graph &g)
Get the iterator range over selected graph entities.
Definition iterator.hh:149
Definition test_utils.cc:13
double opinion_difference(VertexDescType v, VertexDescType w, NWType &nw)
Calculate the absolute opinion difference of two vertices.
Definition utils.hh:87
constexpr bool is_directed()
Check whether the network type allows for directed edges.
Definition utils.hh:35
auto get_rand_neighbor(const VertexDescType v, NWType &nw, RNGType &rng)
Definition utils.hh:44
RT get_rand(std::pair< T, T > range, RNGType &rng)
Generate a random number within the given range.
Definition utils.hh:14
VertexDescType select_neighbor(const VertexDescType v, NWType &nw, std::uniform_real_distribution< double > &prob_distr, RNGType &rng)
Definition utils.hh:57
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