Utopia  2
Framework for studying models of complex & adaptive systems.
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 ...................................
13 template<typename RT, typename T, typename RNGType>
14 RT 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 
34 template<typename NWType>
35 constexpr bool is_directed() {
36  return std::is_convertible<
37  typename boost::graph_traits<NWType>::directed_category,
38  boost::directed_tag>::value;
39 }
40 
43 template<typename NWType, typename VertexDescType, typename RNGType>
44 auto get_rand_neighbor(const VertexDescType v, NWType& nw, RNGType& rng) {
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 
56 template<typename NWType, typename RNGType, typename VertexDescType>
57 VertexDescType select_neighbor(
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;
72  if (cumulative_weights >= nb_prob_frac) {
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 
86 template<typename NWType, typename VertexDescType>
87 double opinion_difference(VertexDescType v, VertexDescType w, NWType& nw) {
88  return fabs(nw[v].opinion - nw[w].opinion);
89 }
90 
92 
101 template<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
decltype(auto) range(const Graph &g)
Get the iterator range over selected graph entities.
Definition: iterator.hh:149
std::uniform_real_distribution< double > prob_distr
Definition: test_revision.cc:18
std::mt19937 rng
– Type definitions ----------------------------------------------------—
Definition: test_revision.cc:17
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