Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
Classes | Functions | Variables
Utopia::Models::Opinionet::Revision Namespace Reference

Classes

struct  TestNetworkD
 
struct  TestNetworkU
 

Functions

template<typename NWType , typename VertexDescType >
void update_opinion_HK (const VertexDescType v, NWType &nw, const double susceptibility, const double tolerance, const Opinion_space_type opinion_space)
 Hegselmann-Krause opinion update function.
 
template<typename NWType , typename RNGType , typename VertexDescType >
void update_opinion_Deffuant (const VertexDescType v, NWType &nw, const double susceptibility, const double tolerance, const Opinion_space_type opinion_space, std::uniform_real_distribution< double > &prob_distr, RNGType &rng)
 Deffuant opinion update function.
 
template<typename NWType , typename RNGType >
void rewire_random_edge (NWType &nw, const double tolerance, const double weighting, RNGType &rng)
 
template<typename NWType , typename RNGType >
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).
 
 BOOST_FIXTURE_TEST_CASE (test_opinion_update_HK_u, TestNetworkU)
 
 BOOST_FIXTURE_TEST_CASE (test_opinion_update_HK_d, TestNetworkD, *boost::unit_test::tolerance(0.0001))
 
 BOOST_FIXTURE_TEST_CASE (test_rewiring_u, TestNetworkU)
 
 BOOST_FIXTURE_TEST_CASE (test_rewiring_d, TestNetworkD)
 
 BOOST_FIXTURE_TEST_CASE (test_opinion_update_D_c, TestNetworkD, *boost::unit_test::tolerance(0.05))
 
 BOOST_FIXTURE_TEST_CASE (test_opinion_update_D_d, TestNetworkU, *boost::unit_test::tolerance(0.05))
 

Variables

std::mt19937 rng {}
 – Type definitions ----------------------------------------------------—
 
std::uniform_real_distribution< doubleprob_distr
 

Function Documentation

◆ BOOST_FIXTURE_TEST_CASE() [1/6]

Utopia::Models::Opinionet::Revision::BOOST_FIXTURE_TEST_CASE ( test_opinion_update_D_c  ,
TestNetworkD  ,
boost::unit_test::tolerance0.05 
)
132{
134
135 TestNetworkD();
136 const double tolerance = 2;
137 const double susceptibility = 0.5;
138 const int num_steps = 10000;
139 const double init_opinion = nw[v1].opinion;
140
141 //Check interaction probabilities equal to ratio of opinion differences
142 int v2_selected = 0;
143 int v3_selected = 0;
144 const double ratio_of_interactions
145 = exp(-weighting*(fabs(nw[v2].opinion-nw[v1].opinion)
146 -fabs(nw[v3].opinion-nw[v1].opinion)));
147
148 for (int i = 0; i<num_steps; ++i) {
150 v1, nw, susceptibility, tolerance, Opinion_space_type::continuous,
151 prob_distr, rng
152 );
153 if (nw[v1].opinion
154 == init_opinion+susceptibility*(nw[v2].opinion-init_opinion)
155 ) {
156 ++v2_selected;
157 }
158 else if (nw[v1].opinion
159 == init_opinion +susceptibility*(nw[v3].opinion-init_opinion)
160 ) {
161 ++v3_selected;
162 }
163 nw[v1].opinion = init_opinion;
164 }
165
166 BOOST_TEST((1. * v2_selected)/v3_selected
167 == ratio_of_interactions);
168
169}
Opinion_space_type
Definition modes.hh:13
void update_opinion_Deffuant(const VertexDescType v, NWType &nw, const double susceptibility, const double tolerance, const Opinion_space_type opinion_space, std::uniform_real_distribution< double > &prob_distr, RNGType &rng)
Deffuant opinion update function.
Definition revision.hh:83

◆ BOOST_FIXTURE_TEST_CASE() [2/6]

Utopia::Models::Opinionet::Revision::BOOST_FIXTURE_TEST_CASE ( test_opinion_update_D_d  ,
TestNetworkU  ,
boost::unit_test::tolerance0.05 
)
174{
176
177 TestNetworkU();
178 const double tolerance = 5;
179 const double susceptibility = 0.5;
180 const int num_steps = 100000;
181 const double init_opinion = nw[v1].opinion;
182
183 // Check ratio of opinion flips is equal to susceptibility
184 // Check ratio of flips to opinion of v2 is proportional to 1/out_degree
185 int total_opinion_flips = 0;
186 int opinion_flipped_to_v2 = 0;
187 for (int i = 0; i<num_steps; ++i) {
189 v1, nw, susceptibility, tolerance, Opinion_space_type::discrete,
190 prob_distr, rng
191 );
192 if (nw[v1].opinion == nw[v2].opinion) {
193 ++opinion_flipped_to_v2;
194 }
195 if (nw[v1].opinion != init_opinion) {
196 ++total_opinion_flips;
197 }
198 nw[v1].opinion = init_opinion;
199 }
200
201 BOOST_TEST(1.*total_opinion_flips == num_steps * susceptibility);
202 BOOST_TEST(1.*opinion_flipped_to_v2
203 == num_steps * susceptibility/boost::degree(v1, nw)
204 );
205}

◆ BOOST_FIXTURE_TEST_CASE() [3/6]

Utopia::Models::Opinionet::Revision::BOOST_FIXTURE_TEST_CASE ( test_opinion_update_HK_d  ,
TestNetworkD  ,
boost::unit_test::tolerance0.0001 
)
91{
93
94 const double tolerance = 4;
95 const double susceptibility = 1;
97 v1, nw, susceptibility, tolerance, Opinion_space_type::continuous
98 );
99 BOOST_TEST (nw[v1].opinion==4.3296);
100}
void update_opinion_HK(const VertexDescType v, NWType &nw, const double susceptibility, const double tolerance, const Opinion_space_type opinion_space)
Hegselmann-Krause opinion update function.
Definition revision.hh:20

◆ BOOST_FIXTURE_TEST_CASE() [4/6]

Utopia::Models::Opinionet::Revision::BOOST_FIXTURE_TEST_CASE ( test_opinion_update_HK_u  ,
TestNetworkU   
)
76 {
78
79 const double tolerance = 4;
80 const double susceptibility = 1;
82 v1, nw, susceptibility, tolerance, Opinion_space_type::continuous
83 );
84 BOOST_TEST (nw[v1].opinion==2);
85}

◆ BOOST_FIXTURE_TEST_CASE() [5/6]

Utopia::Models::Opinionet::Revision::BOOST_FIXTURE_TEST_CASE ( test_rewiring_d  ,
TestNetworkD   
)
117 {
118 const double tolerance = 3;
119 for (size_t i = 0; i<20; ++i) {
120 rewire_random_edge(nw, tolerance, weighting, rng);
121 }
122
123 // Test rewiring
124 BOOST_TEST(edge(v1, v5, nw).second);
125 BOOST_TEST(!edge(v1, v6, nw).second);
126}
void rewire_random_edge(NWType &nw, const double tolerance, const double weighting, RNGType &rng)
Definition revision.hh:118

◆ BOOST_FIXTURE_TEST_CASE() [6/6]

Utopia::Models::Opinionet::Revision::BOOST_FIXTURE_TEST_CASE ( test_rewiring_u  ,
TestNetworkU   
)
104 {
105 const double tolerance = 3;
106 const double weighting = 1;
107 for (size_t i = 0; i<20; ++i) {
108 rewire_random_edge(nw, tolerance, weighting, rng);
109 }
110
111 BOOST_TEST(edge(v1, v5, nw).second);
112 BOOST_TEST(!edge(v1, v6, nw).second);
113}

◆ revision()

void Utopia::Models::Opinionet::Revision::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).

159{
160 // Choose random vertex for revision
161 const auto v = boost::random_vertex(nw, rng);
162
163 if (boost::out_degree(v, nw) != 0) {
164
165 if (interaction == Interaction_type::HegselmannKrause) {
167 v, nw, susceptibility, tolerance, opinion_space
168 );
169 }
170
171 else if (interaction == Interaction_type::Deffuant) {
172 update_opinion_Deffuant(
173 v, nw, susceptibility, tolerance, opinion_space,
174 prob_distr, rng
175 );
176 }
177
178 if constexpr (Utils::is_directed<NWType>()) {
179 Utils::set_and_normalize_weights(v, nw, weighting);
180 }
181 }
182
183 if (rewire == Rewiring::RewiringOn) {
184 rewire_random_edge(nw, tolerance, weighting, rng);
185 }
186}

◆ rewire_random_edge()

void Utopia::Models::Opinionet::Revision::rewire_random_edge ( NWType nw,
const double  tolerance,
const double  weighting,
RNGType rng 
)

Selects a random edge. If the opinion distance of the source and target exceeds the tolerance, the edge is rewired to a random target.

123{
124 using namespace boost;
125
126 // Choose random edge for rewiring
127 const auto e = random_edge(nw, rng);
128 const auto s = source(e, nw);
129
130 if (Utils::opinion_difference(s, target(e, nw), nw) > tolerance) {
131 const auto new_target = random_vertex(nw, rng);
132
133 if (new_target != s and not edge(s, new_target, nw).second)
134 {
135 remove_edge(e, nw);
136 add_edge(s, new_target, nw);
137
138 if constexpr (Utils::is_directed<NWType>()) {
139 Utils::set_and_normalize_weights(s, nw, weighting);
140 }
141 }
142 }
143}

◆ update_opinion_Deffuant()

void Utopia::Models::Opinionet::Revision::update_opinion_Deffuant ( const VertexDescType  v,
NWType nw,
const double  susceptibility,
const double  tolerance,
const Opinion_space_type  opinion_space,
std::uniform_real_distribution< double > &  prob_distr,
RNGType rng 
)

Deffuant opinion update function.

91{
92 // Get neighbor
93 const VertexDescType nb = Utils::select_neighbor(v, nw, prob_distr, rng);
94
95 // Discrete case: adopt nb opinion with probability = susceptibility
96 if (opinion_space == Opinion_space_type::discrete) {
97 if (Utils::opinion_difference(v, nb, nw) <= tolerance) {
98 const double interaction_probability = prob_distr(rng);
99 if (interaction_probability < susceptibility) {
100 nw[v].opinion = nw[nb].opinion;
101 }
102 }
103 }
104
105 // Continuous case: move towards nb opinion proportional to susceptibility
106 else {
107 if (Utils::opinion_difference(v, nb, nw) <= tolerance) {
108 nw[v].opinion += susceptibility * (nw[nb].opinion - nw[v].opinion);
109 }
110 }
111}
std::uniform_real_distribution< double > prob_distr
Definition test_revision.cc:18

◆ update_opinion_HK()

void Utopia::Models::Opinionet::Revision::update_opinion_HK ( const VertexDescType  v,
NWType nw,
const double  susceptibility,
const double  tolerance,
const Opinion_space_type  opinion_space 
)

Hegselmann-Krause opinion update function.

26{
27 double expectation = 0;
28 size_t num_interaction_partners = 0;
29
30 // Directed case: Calculate the expectation based on the probability
31 // distribution given by the weights.
32 if constexpr (Utils::is_directed<NWType>()) {
33 VertexDescType nb;
34 for (const auto e : range<IterateOver::out_edges>(v, nw)) {
35 nb = target(e, nw);
36 if (Utils::opinion_difference(v, nb, nw) <= tolerance) {
37 expectation += nw[nb].opinion * nw[e].weight;
38 ++num_interaction_partners;
39 }
40 }
41
42 // If interaction partners found: normalize weighted opinion average to
43 // number of interaction partners participating in interaction.
44 if (num_interaction_partners != 0) {
45 expectation *= static_cast<double>(boost::out_degree(v, nw)) /
46 num_interaction_partners;
47 }
48 else {
49 expectation = nw[v].opinion;
50 }
51 }
52
53 // Undirected case: Calculate the opinion average
54 else {
55 for (const auto e : range<IterateOver::out_edges>(v, nw)) {
56 auto nb = boost::target(e, nw);
57 if (Utils::opinion_difference(v, nb, nw) <= tolerance) {
58 expectation += nw[nb].opinion;
59 ++num_interaction_partners;
60 }
61 }
62
63 // If interaction partners found: normalize opinion average to
64 // number of interaction partners
65 if (num_interaction_partners != 0) {
66 expectation /= num_interaction_partners;
67 }
68 else {
69 expectation = nw[v].opinion;
70 }
71 }
72
73 // Update opinion
74 nw[v].opinion += susceptibility * (expectation - nw[v].opinion);
75
76 if (opinion_space == Opinion_space_type::discrete) {
77 nw[v].opinion = round(nw[v].opinion);
78 }
79}
IterateOver
Over which graph entity to iterate.
Definition iterator.hh:19
decltype(auto) range(const Graph &g)
Get the iterator range over selected graph entities.
Definition iterator.hh:149
@ out_edges
Iterate over the out edges of a vertex.

Variable Documentation

◆ prob_distr

std::uniform_real_distribution<double> Utopia::Models::Opinionet::Revision::prob_distr

◆ rng

std::mt19937 Utopia::Models::Opinionet::Revision::rng {}

– Type definitions ----------------------------------------------------—

17{};