forked from daimpi/SocNetABM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprotocol.nls
531 lines (399 loc) · 13.5 KB
/
protocol.nls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
; the reporters for the BehaviorSpace run
; reports true if the run has been run for the minimum number of rounds, all
; scientists have converged and have become sufficiently confident in their
; beliefs
to-report exit-condition
check-convergence-light
ifelse converged [
calc-confidence
if converged-ticks = 0 [
set-converge-reporters-values
]
set converged-ticks converged-ticks + 1
ifelse g-confidence > confidence-cutoff [
set-convlight-dur round-converged g-last-convlight-th
report true
][
if ticks >= max-ticks [
set-convlight-dur round-converged g-last-convlight-th
report true
]
report false
]
][
set converged-ticks 0
set g-confidence 0
if ticks >= max-ticks [
set-converge-reporters-values
if g-last-convlight-th != -1 [
; the round-converged reporter (which larger than steps) is
; intentionally chosen here in order to cohere with the round-converged
; value in the data and b/c the earliest round they could be properly
; converged would be max-ticks + 1 in this case
set-convlight-dur round-converged g-last-convlight-th
]
report true
]
report false
]
end
; manages the recording of convergence trackers during the run via the
; respective globals
to check-convergence-light
ifelse converged-light [
let cur-convlight-th 0
if not any? turtles with [mytheory = 0] [
set cur-convlight-th 1
]
let other-theory ((cur-convlight-th + 1) mod 2)
if g-last-convlight-th != cur-convlight-th [
if g-last-convlight-th = other-theory [
set-convlight-dur ticks other-theory
]
set-conv-start cur-convlight-th
set g-last-convlight-th cur-convlight-th
]
][
if g-last-convlight-th != -1 [
set-convlight-dur ticks g-last-convlight-th
]
set g-last-convlight-th -1
]
end
; records the duration of a convergence during the run
; arguments:
; - time = the time at which the current convergence ended, type: integer
; - theory = the theory from which scientist de-converged type: integer
to set-convlight-dur [time theory]
ifelse theory = 0 [
set g-conv-dur-th1 lput (time - last g-conv-start-th1) g-conv-dur-th1
][
set g-conv-dur-th2 lput (time - last g-conv-start-th2) g-conv-dur-th2
]
end
; records the time-point at which scientists convergence on `theory`
; arguments:
; - theory = the theory on which scientist just converged type: integer
to set-conv-start [theory]
ifelse theory = 0 [
set g-conv-start-th1 lput ticks g-conv-start-th1
][
set g-conv-start-th2 lput ticks g-conv-start-th2
]
end
; reports true if all scientists converged to one theory and consider this
; theory to be among their best theories
to-report converged
let count-th1-scientists count turtles with [
mytheory = 0 and member? 0 cur-best-th]
let count-th2-scientists count turtles with [
mytheory = 1 and member? 1 cur-best-th]
ifelse count-th1-scientists = scientists
or (count-th2-scientists = scientists and (nature-evidence-frequency = 0
or ([item 0 current-theory-info] of max-one-of turtles
[item 0 current-theory-info] < th2-aps + strategy-threshold)))[
ifelse count-th1-scientists > 0 [
if last-converged-th = 1 [
set converged-ticks 0
]
set last-converged-th 0
][
if last-converged-th = 0 [
set converged-ticks 0
]
set last-converged-th 1
]
report true
][
report false
]
end
; reports whether all scientists are on the same theory
to-report converged-light
if any? turtles with [mytheory = 0] and any? turtles with [mytheory = 1] [
report false
]
report true
end
; Calculates how confident the researcher is in the fact that her current best
; theory is actually the best theory (i.e. how unlikely it is that she will
; change her mind). This calculation only makes sense in case researchers have
; converged.
to calc-confidence
;force-update is a boolean. It is true if scientists just converged this round
let force-update? (converged-ticks = 0)
if force-update? [
set g-depressed-confidence false
]
if g-depressed-confidence [stop]
let force-nature-update? 0
if not force-update? [
; the -1 correction in ticks compensates for the fact that this procedure
; will be called after the go procedure and therefore the tick-counter has
; already advanced one step further
set force-nature-update? (nature-evidence-frequency > 0
and ticks > 1
and (ticks - 1) mod nature-evidence-frequency = 0)
]
let cur-theory [mytheory] of one-of turtles
let other-theory ((cur-theory + 1) mod 2)
let avg-neighbor-signal-complete 0
if g-fast-sharing-enabled and (force-update? or force-nature-update?) [
set avg-neighbor-signal-complete mean [item cur-theory subj-th-i-signal] of
turtles
]
ask turtles [
let belief-to-beat item other-theory current-theory-info
- strategy-threshold
; not entirerly sure whether this cutoff at 0 is needed, but I've added it
; for cautionarly reasons
set belief-to-beat max (list 0 belief-to-beat)
if force-update? or force-nature-update? [
ifelse g-fast-sharing-enabled [
set avg-neighbor-signal avg-neighbor-signal-complete
][
set avg-neighbor-signal mean [item cur-theory subj-th-i-signal] of
share-group
]
]
; if the scientist would be given sufficient time for her belief to
; converge to the average signal of her and her link-neighbors, would
; this be enough for her to abandon her current theory? If so, she's not
; confident enough.
if avg-neighbor-signal <= belief-to-beat [
set confidence 0
set g-depressed-confidence true
stop
]
; the following calculations are based on probability maximization of the
; normal-distribution. This is separately documented at [placeholder].
let alpha item mytheory a
let varepsilon avg-neighbor-signal - belief-to-beat
let delta item mytheory current-theory-info - belief-to-beat
if (2 * alpha - 1) * delta <= belief-to-beat [
set confidence 0
stop
]
let exit-probability 0.5 + 0.5 * erf (
((0 - 2 * alpha + 1) * delta + belief-to-beat)
/ (sqrt((0 - 2 * alpha * delta + delta + belief-to-beat)
* (belief-to-beat + varepsilon) * (0 - 1 + belief-to-beat + varepsilon)
/ (varepsilon * (belief-to-beat + delta)))
* (belief-to-beat + delta)))
ifelse exit-probability > 0 [
set confidence 1 - exit-probability
][
set confidence 1
]
]
set g-confidence reduce * [confidence] of turtles
end
; reports a numerical approximation for the error-function function on its
; negative domain, therefore the argument (x) must be smaller than 0. For
; sources see infotab.
to-report erf [x]
let t (1 - .5 * x)
report exp ( 0 - x ^ 2 - 1.26551223 + 1.00002368 / t
+ .37409196 / t ^ 2 + 0.09678418 / t ^ 3
- .18628806 / t ^ 4 + .27886807 / t ^ 5
- 1.13520398 / t ^ 6 + 1.48851587 / t ^ 7
- .82215223 / t ^ 8 + .17087277 / t ^ 9)
/ t - 1
end
; reports 1 if scientists (stably) converged on the best theory (th1) by the end
; of the run, 0 otherwise
to-report successful-run
ifelse not g-depressed-confidence and count turtles with [
mytheory = 0 and member? 0 cur-best-th] = scientists [
report 1
][
report 0
]
end
; translates string values into the form needed by the procedures (in general
; integer-values).
to-report translate-from-string [string]
let value-to-report 0
if string = "th2" [
set value-to-report 1
]
report value-to-report
end
; reports the number of researchers on th# at the end of the run
to-report run-end-scientists [th#]
set th# translate-from-string th#
report count turtles with [mytheory = th#]
end
; reports how often an average researcher switched theories
to-report average-jumps
let jumps 0
let avgjumps 0
ask turtles [
set jumps times-jumped + jumps
]
set avgjumps (jumps / scientists)
report avgjumps
end
; reports the average proportion of time the researchers considered both
; theories equally good. The +1 accounts for the extra calculation already
; taking place during the setup
to-report avg-indiff-time
let avg-indiff-time-cache 0
ifelse converged-ticks = 0 [
set avg-indiff-time-cache (indiff-count / (scientists * (ticks + 1)))
][
set avg-indiff-time-cache
(indiff-count / (scientists * (round-converged + 1)))
]
report avg-indiff-time-cache
end
; reports the last time-point scientists converged. The + 1 correction is due
; to the assumption that this reporter is called after `exit-condition` had a
; chance to update `converged-ticks`
to-report round-converged
report ticks - converged-ticks + 1
end
; reports the average signal for th# at the time of final convergence
; arguments:
; - th# = theory, type: string
; - rec = recording?, type: boolean
to-report average-signal [th# rec?]
let identifier "avgsignal"
ifelse rec? [
let avg-signal-th1 mean [item 0 subj-th-i-signal] of turtles
let avg-signal-th2 mean [item 1 subj-th-i-signal] of turtles
report (list identifier avg-signal-th1 avg-signal-th2)
][
set th# translate-from-string th#
let avg-signal but-first first filter [curitem ->
first curitem = identifier] converge-reporters-values
report item th# avg-signal
]
end
; The values of the reporters which have to be collected in the round when
; researchers converge are recorded
to set-converge-reporters-values
set converge-reporters-values map [curreporter -> runresult curreporter]
converge-reporters
end
; reports the average beliefs among the researchers
; arguments:
; - th# = theory, type: string
; - rec = recording?, type: boolean
to-report average-belief [th# rec?]
let identifier "avgbelief"
ifelse rec? [
let avg-belief [0 0]
ask turtles [
set avg-belief (map + avg-belief current-theory-info)
]
set avg-belief map [cur-avg-belief -> cur-avg-belief / scientists]
avg-belief
report fput identifier avg-belief
][
set th# translate-from-string th#
let avg-belief but-first first filter [curitem ->
first curitem = identifier] converge-reporters-values
report item th# avg-belief
]
end
; reports the average cumulative successes (= turtle-owned variable `a`) for th#
to-report average-cum-successes [th# rec?]
let identifier "avgsuc"
ifelse rec? [
let avg-suc [0 0]
ask turtles [
set avg-suc (map + avg-suc a)
]
set avg-suc map [cur-avg-suc -> cur-avg-suc / scientists]
avg-suc
report fput identifier avg-suc
][
set th# translate-from-string th#
let avg-suc but-first first filter [curitem ->
first curitem = identifier] converge-reporters-values
report item th# avg-suc
]
end
; reports the global confidence of scientists at the point of convergence
to-report average-confidence [rec?]
let identifier "avgconfidence"
ifelse rec? [
let avg-confidence g-confidence
report (list identifier avg-confidence)
][
let avg-confidence item 1 first filter [curitem ->
first curitem = identifier] converge-reporters-values
report avg-confidence
]
end
; reports how many scientists were on each theory at the start of the run
to-report run-start-scientists [th#]
set th# translate-from-string th#
report item th# run-start-scientists-save
end
; reports the round which marks the beginning of the longest lasting connected
; convergence on th#
to-report longest-covergence-start [th#]
let max-time-converged longest-covergence-dur th#
if max-time-converged = -1 [
report -1
]
let convergence-starts convergence-starts-report th#
let conv-durations converge-durations-report th#
let position-longest-conv position max-time-converged conv-durations
report item position-longest-conv convergence-starts
end
; reports for how long the longest connected convergence on th# lasted
to-report longest-covergence-dur [th#]
let conv-durations converge-durations-report th#
if empty? conv-durations [
report -1
]
report max conv-durations
end
; reports the list with rounds which mark all the beginnings of convergence on
; th#
to-report convergence-starts-report [th#]
if th# = "th1" [
report g-conv-start-th1
]
report g-conv-start-th2
end
; reports the list with durations of all the convergences on th#
to-report converge-durations-report [th#]
if th# = "th1" [
report g-conv-dur-th1
]
report g-conv-dur-th2
end
; reports the cumulative time which scientists were converged on th# over the
; course of the run
to-report cum-conv-dur [th#]
let conv-durations converge-durations-report th#
if empty? conv-durations [
report -1
]
report sum conv-durations
end
; reports how often scientists converged on th# over the course of the run
to-report frequency-converged [th#]
let conv-durations converge-durations-report th#
if empty? conv-durations [
report -1
]
report length conv-durations
end
; reports the (weighted-)average round where scientists were converged on th#,
; weighted by the length of the convergence
to-report center-of-convergence [th#]
let cur-cum-conv-dur cum-conv-dur th#
if cur-cum-conv-dur <= 0 [
report -1
]
let convergence-starts convergence-starts-report th#
let conv-durations converge-durations-report th#
let weighted-convergences sum (map [ [curstart curlength] ->
2 * curstart * curlength + curlength ^ 2] convergence-starts conv-durations)
report weighted-convergences / (2 * cur-cum-conv-dur)
end