Child of Child of Version_20260115-2_Simulator v6_EN

No preview image

1 collaborator

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 3D 7.0.3 • Viewed 25 times • Downloaded 0 times • Run 0 times
Download the 'Child of Child of Version_20260115-2_Simulator v6_EN' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)



WHAT IS IT?

This simulator models how opinions spread and evolve in a connected population (multi-agent system). Each agent has an opinion (−1 to +1), a prevalence (0–99), an influence (0–1), and social links. The model tracks the co-evolution of opinions, prevalence (depth of internal representations), influence, and the network structure.

3D Representation

  • X: opinion (−1 left, +1 right)
  • Y: prevalence (0–99)
  • Z: influence (0–1) Colors: blue (right), red (left), yellow (meta-influencer). Links: green (same sign), gray (opposite signs).

HOW TO USE

  1. Choose the population size with pop.
  2. Click Setup (creates agents, black background, initializes tick-event to event-init).
  3. Click Go to run/pause.

GENERAL CONTROLS

  • Setup: initialize agents/network; sets tick-event ← event-init.
  • Go: start/stop the simulation.
  • in_file: load agent states from a file (for data).
  • refresh: resets plots after ~200 ticks.
  • cumulative: if OFF, resets change/total every tick.
  • output: None | Statistics | Values | File.

POPULATION & ITERATIONS

  • pop: number of agents (e.g., 100–5000).
  • nb_try, max_iter, threshold: repetitions, trial length, majority threshold.
  • choice_iter: iteration to replay when loading from file.

SOCIAL NETWORK (link dynamics)

  • link-removal-threshold: opinion distance (in %) above which a link may be cut.
  • link-formation-threshold: maximum distance to allow a new link.
  • prob: probability applied to deletions/formations.
  • linksdown / linksup: caps on links removed/created per tick.
  • bridge-prob: chance to create bridges across opposing camps.
  • show-links?: toggle link visibility; linktick: visual thickness.

META-INFLUENCERS

Agents with fixed high influence (influence = 1).

  • meta-influencers-selection: All / Right side / Left side.
  • meta-influencers: share of agents promoted to “meta”.
  • prev-low / prev-high: prevalence eligibility bounds.
  • meta-min / meta-max / meta-links: min/max and current quota of meta links.
  • meta-ok: enables dynamic meta linking even if vary-influence = OFF.
  • vary-influence: if ON, influence increases after successes and decreases after setbacks.
  • metablock: if ON, metas cannot flip sign (veto on polarity changes).

At initialization (setup) and at the start of each new trial, the model sets meta-links ← meta-min if vary-influence = true or meta-ok = true (as in your code).


OPINION & PREVALENCE DYNAMICS

  • rate-infl: speed of influence updates after adoption.
  • noise: probability of additive opinion noise.
  • polarization-factor: penalizes adoption across large opinion gaps.
  • prevalence-weight: weight of prevalence differences in adoption.
  • adoption-floor: minimum adoption probability (avoids strict zero).

Prevalence modulation (renamed in code)

  • mod-prev (formerly modulation-prevalence): ON to adapt prevalence to current vs previous opinion.
  • Rate-mod (formerly rate-modulation): adjustment intensity.

GROUP EFFECT

  • group-impact-mode: all (all linked neighbors) or k-nearest.
  • group-k: number of neighbors in k-nearest mode.
  • group-impact-weight: weight of neighborhood alignment in adoption.
  • group-impact-alpha: non-linearity

    • <1: small aligned clusters matter more,
    • =1: linear,
    • >1: only large aligned majorities matter.

REWARD MECHANISM

A successful emitter (who convinces a neighbor) receives a temporary bonus (tx-bonus) that boosts future persuasion.

  • reward-step: bonus increment per success.
  • reward-cap: cap on cumulative bonus.
  • reward-scope: both / left-only / right-only.
  • reward-prev-delta: increase in the target’s prevalence after adoption (optional).
  • reward-decay: bonus decay over ticks.

Meme-Based Representation (Weighted Memes + Targeted Injection)

When use-memes? is ON, opinions and prevalence are computed from internal “meme” stocks.
This version distinguishes meme quantity (how many representations an agent holds) from meme weight (how strongly each representation shapes the opinion).


1) Two levels: Quantity vs Weight

Meme quantity → Prevalence

  • meme-plus, meme-minus store how many pro/anti memes the agent holds.
  • Prevalence (0–99) is derived from the total quantity:
    meme-plus + meme-minus rescaled to 0–99.

Interpretation: prevalence approximates how “rich” an agent’s internal representation system is (how many arguments/frames are available).

Meme weight → Opinion

  • meme-plus-w, meme-minus-w store the cumulative weighted strength of pro/anti memes.
  • Opinion is computed from the weighted balance:

[ opinion = \frac{meme\text{-}plus\text{-}w - meme\text{-}minus\text{-}w}{meme\text{-}plus\text{-}w + meme\text{-}minus\text{-}w} ]

  • If pro-weights dominate → opinion moves toward +1
  • If anti-weights dominate → opinion moves toward −1
  • If balanced → opinion stays near 0

A tiny denominator safeguard is used to avoid division by zero.


2) Weighted transmission during interactions

When an agent is influenced, the receiver gets: - a quantity increment (meme-gain) on the side of the emitter (plus or minus), - and a weight increment proportional to that quantity.

Weight distribution parameters

  • meme-weight-mean (typical 0.2–3.0): average strength of newly acquired memes.

    • Low values → many memes are needed to polarize opinions.
    • High values → opinions polarize faster, even with small meme quantities.
  • meme-weight-sd (typical 0.0–1.0): heterogeneity (memes differ in strength).

    • 0.0 → all memes are equally strong.
    • Higher values → mixed populations with “weak” and “strong” memes.
  • meme-weight-min / meme-weight-max: hard bounds preventing unrealistic weights.


3) Meme anti-leak and decay (optional)

  • meme-anti-leak (0–1): when one side grows, a fraction of the opposite stock is reduced.
    High values create “winner-takes-more” dynamics (polarization reinforcement).

  • meme-decay (0–0.05 typical): forgetting rate applied each tick to quantities and weights.


Meme Injection (Targeted diffusion of new representations)

Beyond “events” that shift opinions directly, the simulator can inject memes into a selected subgroup to simulate the introduction and diffusion of a new narrative, argument, or frame.

1) Targeting bounds (preferred controls)

Agents are eligible for injection if they satisfy:

  • inject-low_meme ≤ opinion ≤ inject-high_meme
  • inject-low-prev ≤ prevalence ≤ inject-high-prev

This allows injection into: - moderates only (e.g., −0.2 to +0.2), - one camp only (e.g., +0.2 to +1), - low-prevalence agents only (e.g., 0 to 30).

2) Injection strength and reach

  • inject-prob-max (0–1): maximum share of eligible agents that actually receive the injected memes.
  • inject-sign: "plus" or "minus" (which direction the injected memes support).
  • inject-amount (typical 1–10): how many memes are injected (quantity → raises prevalence).
  • inject-weight (typical 0.2–5.0): how strong injected memes are (weight → shifts opinion more sharply).

Rule of thumb:
- Increase inject-amount to raise prevalence (more representations).
- Increase inject-weight to raise polarization intensity (stronger conviction shift).

3) Scheduling injection

  • auto_inject?: if ON, injection occurs when ticks = inject-tick.
  • inject-tick: the tick at which injection happens.
  • repeat-inject?: if ON, injection repeats every inject-pace ticks.
  • inject-pace: the interval between repeated injections.

Example scenarios

  • One-shot targeted campaign:
    auto_inject? = ON, repeat-inject? = OFF, inject-tick = 50, inject-prob-max = 0.2,
    inject-low_meme = -0.2, inject-high_meme = 0.2, inject-sign = "plus",
    inject-amount = 3, inject-weight = 2.0.

  • Slow diffusion of a weak but persistent narrative:
    repeat-inject? = ON, inject-pace = 25, inject-prob-max = 0.05,
    inject-amount = 1, inject-weight = 0.5.

  • High-impact shock on a small subgroup:
    inject-prob-max = 0.02, inject-amount = 2, inject-weight = 5.0,
    targeting a narrow opinion band.


Parameter Ranges — Key Sliders (Overview)

The table below summarizes the recommended value ranges for the nine main sliders governing opinion transmission, meme dynamics, and external shocks.
Ranges are indicative and meant to support exploratory, comparative, and pedagogical simulations rather than strict calibration.

| Slider name | Typical range | What it controls | Low values → expected effects | High values → expected effects | |------------|---------------|------------------|-------------------------------|--------------------------------| | prevalence-weight | 0.0 – 2.0 | Weight of prevalence differences in adoption probability | Opinion change weakly tied to representational depth; more random diffusion | Deeply rooted agents dominate transmission; strong inertia | | adoption-floor | 0.0 – 0.10 | Minimum probability of adoption regardless of distance | Near-impossible cross-camp adoption | Persistent low-level noise and occasional inversions | | polarization-factor | 0.0 – 1.0 | Penalty applied to large opinion gaps | Distance barely matters; smooth convergence | Strong ideological barriers; entrenched camps | | group-impact-weight | 0.0 – 1.0 | Strength of group alignment effect | Individual interactions dominate | Local majorities strongly condition adoption | | group-impact-alpha | 0.2 – 3.0 | Non-linearity of group effect | Small minorities exert strong influence | Only large aligned groups matter | | meme-max | 50 – 200 | Maximum stock of memes per agent (prevalence scale) | Shallow belief systems; fast saturation | Deep ideological accumulation; slow dynamics | | meme-gain | 0.5 – 2.0 | Meme increment per successful transmission | Slow learning; weak reinforcement | Rapid ideological buildup | | meme-anti-leak | 0.0 – 0.5 | Cross-erosion of opposite meme stock | Memes accumulate independently | Strong competition; winner-takes-more dynamics | | meme-decay | 0.0 – 0.05 | Forgetting rate of memes per tick | Stable long-term memory | Rapid erosion; volatile belief systems | | event-prob-max | 0.0 – 1.0 | Proportion of agents affected by an event | Micro-perturbations, local shocks | System-wide shocks |


Usage notes

  • Low–mid ranges are recommended for exploratory runs and sensitivity analysis.
  • Extreme values are useful to study boundary cases (lock-in, collapse, polarization).
  • Parameters interact strongly: e.g., high meme-gain combined with high meme-anti-leak accelerates polarization.

This table is intended as a cheat sheet; empirical calibration should rely on systematic parameter sweeps.

Meme Injection — Slider Ranges, Effects, and Interactions

This table documents the nine sliders governing meme injection.
Together, they define when, how often, to whom, and with what strength new memes are introduced into the population, allowing controlled simulations of campaigns, rumors, or polarizing shocks.


Core Injection Parameters

| Slider | Typical range | Role in the model | Low values → effects | High values → effects | |------|---------------|-------------------|----------------------|----------------------| | inject-tick | 1 – max_iter | First tick at which meme injection can occur | Early priming of agents; long-run structural impact | Late shock; short-term perturbation with limited propagation | | inject-pace | 1 – 200 | Interval (ticks) between injections | Continuous or quasi-continuous pressure | Rare, punctuated shocks | | inject-prob-max | 0.0 – 1.0 | Maximum probability that an eligible agent receives a meme at an injection tick | Injection remains marginal or localized | Broad exposure; near-systemic dissemination | | inject-amount | 0 – meme-max | Quantity of meme stock added per injection | Subtle informational nudges | Strong narrative saturation or propaganda burst | | inject-weight | 0.0 – 2.0 (or higher) | Relative impact of injected memes on opinion vs. prevalence | Injected memes mainly increase prevalence (attention/salience) | Injected memes strongly bias opinion formation |


Opinion Dynamics Simulator – “Inject Metas Only” Extension

Purpose of the Extension

This version of the model introduces an option controlled by a switch (inject-metas-only) that allows restricting meme injection to meta-agents only, as they exist at the moment of injection.

Meta-agents are defined operationally as agents colored yellow, that is, agents explicitly selected by the influenceurs button.

The goal of this extension is to enable targeted meme injection scenarios without altering the endogenous opinion dynamics or the standard meme mechanisms.


General Principle

  • Meme injection continues to rely on the inject-memes procedure.
  • A new switch, inject-metas-only, optionally filters the target agents.
  • When the switch is ON, only yellow agents present at the time of injection can receive memes.
  • When the switch is OFF, the injection behavior is strictly identical to the original version of the model.

No additional distinction is introduced between different types of meta-agents: the visual criterion (yellow color) is used as the sole reference.


Detailed Operation

1. Selection of Target Agents

The inject-memes procedure first builds a base pool of agents, defined by the existing bounds:

  • opinion ∈ [inject-low_meme, inject-high_meme]
  • prevalence ∈ [inject-low-prev, inject-high-prev]

This pool corresponds exactly to the historical behavior of the model.

2. Optional “Meta-only” Filtering

If the inject-metas-only switch is activated:

  • the pool is restricted to agents colored yellow (color = yellow)
  • meme injection applies exclusively to those agents

No additional conditions are imposed.

3. Interaction with vary-influence

  • The inject-metas-only switch remains operational regardless of the state of vary-influence.
  • There is intentionally no software safeguard preventing both options from being enabled simultaneously.
  • The analytical interpretation of such configurations is left to the user.

This design choice ensures maximum experimental flexibility while preserving fully deterministic model behavior.


Relevant Code (Conceptual Excerpt)

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

extensions [sound nw] ;; For using sound and Network package

globals [ 
  ;;meme-net-gain
  min-prevalence
  max-prevalence
  memes-per-change
  meta-influencers-droit
  meta-influencers-gauche
  iter change total inversion try major fractale
  ordonnee abcisse profondeur
  list_data file-in in_data repet_data
  links-dead links-create meta-agents meta-links meta-create Interactions %Major  


  ;; === CSV export ===
  csv-export
  csv-basename
  csv-file
  csv-open?

  ;; === Paramètres d’inversion / ponts (sliders UI) ===
  ;;prevalence-weight
  ;;adoption-floor
  ;;bridge-prob

  ;; === Paramètres de RÉCOMPENSE (sliders/inputs UI) ===
  ;;reward-step
  ;;reward-cap
  ;;reward-scope
  ;;reward-prev-delta
  ;;reward-decay

  ;; === MEMES (existing) ===
  ;;use-memes?
  ;;meme-max
  ;;meme-gain
  ;;meme-anti-leak
  ;;meme-decay

  ;; === MEMES PONDÉRÉS (nouveau) ===
  ;;meme-weight-mean
  ;;meme-weight-sd
  ;;meme-weight-min
  ;;meme-weight-max

  ;; === INJECTION DE MEMES (nouveau) ===
  ;;auto_inject?
  ;;repeat-inject?
  ;;inject-tick
  ;;inject-pace

  ;;inject-sign           ;; "plus" | "minus"
  ;;inject-amount         ;; quantité injectée
  ;;inject-weight         ;; poids associé à l’injection
  ;;inject-prob-max       ;; proportion max touchée (0..1)

  ;;inject-low_meme
  ;;inject-high_meme
  ;;inject-low-prev
  ;;inject-high-prev

  ;; === EVENEMENTS (déjà chez vous, rappel) ===
  ;;auto_event
  ;;repeat-event
  ;;event-pace
  ;;event-init
  ;;tick-event
]

turtles-own [
  opinion
  prevalence
  agent-type
  influence
  opinion-previous
  influence-previous
  x3d y3d z3d

  ;; MEMES quantités
  meme-plus
  meme-minus

  ;; MEMES pondérés (impact sur opinion)
  meme-plus-w
  meme-minus-w

  ;; utilitaires
  old-opinion
  proposed-opinion

  ;; bonus d’émetteur
  tx-bonus
]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SETUP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to setup
  clear-all
  set repet_data false
  set iter 0
  set min-prevalence 0
  set max-prevalence 99
  set-default-shape turtles "person"
  set try 1
  set major 0
  set inject-tick 60
  

  ;; tick-event initialisé par event-init (slider/input)
  if not is-number? event-init [ set event-init 50 ]
  set tick-event event-init

  set links-dead 0
  set links-create 0
  set meta-create 0
  set meta-agents 0
  set change 0
  set total 0
  set inversion 0
  set fractale 0

  ;; meta-ok peut être activé sans vary-influence
  if (vary-influence = true) or (meta-ok = true) [ set meta-links meta-min ]

  ;; === Defaults CSV ===
  if not is-boolean? csv-export [ set csv-export false ]
  if (not is-string? csv-basename) or (csv-basename = "") [ set csv-basename "run" ]
  set csv-open? false

  ;; === Defaults IMPACT DE GROUPE ===
  if (not is-string? group-impact-mode) [ set group-impact-mode "all" ]
  if (not is-number? group-k) [ set group-k 10 ]
  if (not is-number? group-impact-weight) [ set group-impact-weight 0.5 ]
  if (not is-number? group-impact-alpha) [ set group-impact-alpha 1.0 ]

  ;; === Default switches ===
  if not is-boolean? show-links? [ set show-links? false ]
  if not is-boolean? metablock   [ set metablock false ]

  ;; === Defaults inversion/ponts ===
  if (not is-number? prevalence-weight) [ set prevalence-weight 1.5 ]
  if (not is-number? adoption-floor)    [ set adoption-floor 0.02 ]
  if (not is-number? bridge-prob)       [ set bridge-prob 0.10 ]

  ;; === Defaults REWARD ===
  if not is-number? reward-step       [ set reward-step 0.05 ]
  if not is-number? reward-cap        [ set reward-cap  0.50 ]
  if not is-string? reward-scope      [ set reward-scope "both" ]
  if not is-number? reward-prev-delta [ set reward-prev-delta 0 ]
  if not is-number? reward-decay      [ set reward-decay 0 ]

  ;; === Defaults MEMES (quantité) ===
  if not is-boolean? use-memes?    [ set use-memes? false ]
  if not is-number? meme-max       [ set meme-max 100 ]
  if not is-number? meme-gain      [ set meme-gain 1.0 ]
  if not is-number? meme-anti-leak [ set meme-anti-leak 0.0 ]
  if not is-number? meme-decay     [ set meme-decay 0.0 ]

  ;; === Defaults MEMES pondérés ===
  if not is-number? meme-weight-mean [ set meme-weight-mean 1.0 ]
  if not is-number? meme-weight-sd   [ set meme-weight-sd 0.0 ]    ;; hétérogénéité
  if not is-number? meme-weight-min  [ set meme-weight-min 0.05 ]
  if not is-number? meme-weight-max  [ set meme-weight-max 5.0 ]

  ;; === Defaults INJECTION ===
  if not is-boolean? auto_inject?   [ set auto_inject? false ]
  if not is-boolean? repeat-inject? [ set repeat-inject? false ]
  if not is-number? inject-tick     [ set inject-tick 50 ]
  if not is-number? inject-pace     [ set inject-pace 50 ]

  if not is-string? inject-sign     [ set inject-sign "plus" ]     ;; "plus"|"minus"
  if not is-number? inject-amount   [ set inject-amount 1 ]
  if not is-number? inject-weight   [ set inject-weight 1.0 ]
  if not is-number? inject-prob-max [ set inject-prob-max 1.0 ]

  ;; bornes (votre préférence)
  if not is-number? inject-low_meme  [ set inject-low_meme -1.0 ]
  if not is-number? inject-high_meme [ set inject-high_meme  1.0 ]
  if not is-number? inject-low-prev  [ set inject-low-prev  0.0 ]
  if not is-number? inject-high-prev [ set inject-high-prev 99.0 ]

  set-background-black

  create
  rapport
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CREATE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to create
  create-turtles pop / 2 [
    set agent-type "Right side"
    set opinion random-float 1
    set color blue
    set prevalence random-float (opinion * 100)
    set influence random-float 1
    set opinion-previous opinion
    set influence-previous influence
    set tx-bonus 0
    init-memes-from-state
    update-3d self
  ]

  create-turtles pop / 2 [
    set agent-type "Left side"
    set opinion (random-float 1 - 1)
    set color red
    set prevalence random-float (abs opinion * 100)
    set influence random-float 1
    set opinion-previous opinion
    set influence-previous influence
    set tx-bonus 0
    init-memes-from-state
    update-3d self
  ]

  influenceurs

  reset-ticks

  set total 0
  set change 0
  set Interactions 0
  set %Major 0
  update-networks

  recolor-links
  apply-link-visibility
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; RAPPORT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to rapport
  if output = "Statistics" [
    output-print (word
      "Try ; " "Iter ; "
      "Opinion global ; "
      "Opinion right side ; "
      "Opinion left side ; "
      "Prevalence right side ; "
      "Prevalence left side ; "
      "Influence right side ; "
      "Influence left side ; "
      "Left % ; "  "Right % ; "
      "Links-Remove ; " "Links-Create ; "
      "Inversion % ; " "change ; " "total ; " "fractale")
  ]
  if output = "Values" [
    output-print (word "Try ; " "Ticks ; "  "Agents ; "
                      "Prevalence ; " "Opinion ; " "Influence ; "
                      "memed ; " "meme plus ; " "meme minus ; "
                      "meme plus w ; " "meme minus w")
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; META-INFLUENCEURS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to influenceurs
  if meta-influencers-selection = "All" [
    let k round (count turtles * meta-influencers / 100)
    if k > 0 [
      ask n-of k turtles [
        if (prevalence >= prev-low and prevalence <= prev-high) [
          set influence 1
          set color yellow
          set meta-agents meta-agents + 1
        ]
      ]
    ]
  ]

  if meta-influencers-selection = "Right side" [
    set meta-influencers-droit round (count turtles * meta-influencers / 100)
    let candidates turtles with [opinion > 0]
    let k min list meta-influencers-droit count candidates
    if k > 0 [
      ask n-of k candidates [
        if (prevalence > prev-low and prevalence <= prev-high) [
          set influence 1
          set color yellow
          set meta-agents meta-agents + 1
        ]
      ]
    ]
  ]

  if meta-influencers-selection = "Left side" [
    set meta-influencers-gauche round (count turtles * meta-influencers / 100)
    let candidates turtles with [opinion < 0]
    let k min list meta-influencers-gauche count candidates
    if k > 0 [
      ask n-of k candidates [
        if (prevalence > prev-low and prevalence <= prev-high) [
          set influence 1
          set color yellow
          set meta-agents meta-agents + 1
        ]
      ]
    ]
  ]
end 

to-report meta?
  report (color = yellow) or (influence = 1)
end 

to maybe-set-opinion [ new-op ]
  let old-op opinion
  let bounded-op max list -1 min list 1 new-op

  ;; Solution 1 : méta se renforce sans changer de signe
  if metablock and meta? and (sign old-op != sign bounded-op) [
    let mag max list (abs old-op) (abs bounded-op)
    set opinion (sign old-op) * mag
    stop
  ]
  set opinion bounded-op
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to go
  ifelse (iter < max_iter) [
    if iter > 0 [ set Interactions (total / iter) ]
    if iter > 0 [ set %Major (major / iter * 100) ]
    set iter iter + 1
    set meta-create 0
    
;;if vary-influence [ set inject-metas-only false ]
    
    if (iter = 1 and csv-export and not csv-open?) [ csv-begin ]

    ;; EVENEMENTS (votre logique conservée)
    ifelse auto_event = true [
      if (tick-event = iter) [
        event
        if repeat-event [ set tick-event (tick-event + event-pace) ]
      ]
    ] [
      set tick-event (iter + event-pace)
    ]

    ;; INJECTION (nouveau, indépendant de event)
    if auto_inject? [
      if ticks = inject-tick [
        inject-memes
        if repeat-inject? [ set inject-tick (inject-tick + inject-pace) ]
      ]
    ]

    if meta-ok = true [ meta ]

    update-opinions
    if network = true [ update-networks ]
    recolor-links
    apply-link-visibility

    if output = "Statistics" [
      let avg-opinion mean [opinion] of turtles
      let positive-opinion safe-median (turtles with [opinion >= 0]) "opinion"
      let negative-opinion safe-median (turtles with [opinion < 0])  "opinion"
      let positive-prevalence (safe-median (turtles with [opinion >= 0]) "prevalence") / 100
      let negative-prevalence (safe-median (turtles with [opinion < 0])  "prevalence") / 100
      let positive-influence safe-median (turtles with [opinion >= 0]) "influence"
      let negative-influence safe-median (turtles with [opinion < 0])  "influence"
      let Left%  (count turtles with [opinion < 0])  / (pop / 100)
      let Right% (count turtles with [opinion >= 0]) / (pop / 100)
      let ti iter
      output-print (word try " ; " ti " ; " avg-opinion " ; "
                        positive-opinion " ; " negative-opinion " ; "
                        positive-prevalence " ; " negative-prevalence " ; "
                        positive-influence " ; " negative-influence " ; "
                        Left% " ; " Right% " ; "
                        links-dead " ; " links-Create " ; "
                        inversion " ; " change " ; " total " ; " fractale)
    ]

    tick

    ifelse use-memes? [if (change > 1 and iter > 1) [set fractale (ln iter / ln total)]] [if (change > 1 and total > 1) [ set fractale (ln total) / (ln change)]] 

    if (cumulative = false) [
      set change 0
      set total 0
    ]

    colorer

    if (refresh = true) [
      if ticks > 200 [ reset-ticks clear-plot ]
    ]

    if threshold <= (count turtles with [opinion > 0]) / (pop / 100) [
      set major major + 1
    ]

    if csv-export [ csv-row ]

  ] [
    ifelse (try < nb_try) [
      if csv-export [ csv-end ]

      set try try + 1
      set major 0
      clear-turtles
      clear-plot
      set change 0
      set total 0
      set fractale 0
      set meta-links meta-min
      set iter 0

      ;; réinitialisation du calendrier d'événement
      set tick-event event-init

      ;; (optionnel) réinitialiser aussi l'injection automatique :
      ;; set inject-tick inject-tick   ;; laissez tel quel ou réinitialisez à une valeur initiale si vous le souhaitez

      set links-create 0
      set links-dead 0
      set meta-create 0
      set meta-agents 0
      set min-prevalence 0
      set max-prevalence 99

      ifelse (repet_data = true) [
        data
      ] [
        create
        set meta-links meta-min
      ]
    ] [
      if csv-export [ csv-end ]
      sound:play-note "Tubular Bells" 60 64 1
      stop
    ]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UPDATE OPINIONS (mèmes pondérés)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-opinions
  ask turtles [
    set opinion-previous opinion
    let target one-of link-neighbors

    if target != nobody [
      let raw-dprev ([prevalence] of target) - prevalence
      if raw-dprev < 1 [ set raw-dprev 0 ]
      let dprev raw-dprev / max-prevalence

      if dprev > 0 [
        let dmem abs(abs(opinion) - abs([opinion] of target))

        let base-prob dprev * prevalence-weight
        let pol-penalty max list adoption-floor (1 - polarization-factor * dmem)

        let p-adopt base-prob * pol-penalty * [influence] of target * (1 + [tx-bonus] of target)

        let sgn-emetteur sign ([opinion] of target)
        let gprob group-alignment-effective self sgn-emetteur
        let w group-impact-weight
        let alpha group-impact-alpha
        set p-adopt p-adopt * ((1 - w) + (w * (gprob ^ alpha)))

        if p-adopt < 0 [ set p-adopt 0 ]
        if p-adopt > 1 [ set p-adopt 1 ]

        if random-float 1 < p-adopt [
          set old-opinion opinion
          set proposed-opinion [opinion] of target

          ifelse use-memes? [
            transmit-memes target
            recompute-from-memes
          ] [
            maybe-set-opinion proposed-opinion
          ]

          if opinion = old-opinion [ stop ]

          set total total + 1

          let emitter-sign sign ([opinion] of target)
          let eligible? (reward-scope = "both") or
                         (reward-scope = "left-only"  and emitter-sign < 0) or
                         (reward-scope = "right-only" and emitter-sign >= 0)
          if eligible? [
            ask target [
              set tx-bonus min (list reward-cap (tx-bonus + reward-step))
            ]
          ]

          if reward-prev-delta > 0 [
            set prevalence min (list max-prevalence (prevalence + reward-prev-delta))
          ]

          set influence-previous influence
          if vary-influence = true [
            if abs(old-opinion) > abs(opinion) [
              set influence min (list 1 (influence + rate-infl))
              if (influence-previous < 1 and influence = 1) [
                if meta-ok = true [
                  if meta-links < meta-max [ set meta-links meta-links + 1 ]
                  set meta-agents meta-agents + 1
                ]
                set color yellow
              ]
            ]
            if abs(old-opinion) < abs(opinion) [
              set influence max (list 0 (influence - rate-infl))
              if (influence < influence-previous and influence-previous = 1) [
                if meta-ok = true [
                  set meta-agents meta-agents - 1
                  ifelse opinion >= 0 [ set color blue ] [ set color red ]
                ]
              ]
            ]
          ]

          if (sign old-opinion) != (sign opinion) [
            set change change + 1]
         if change > 0 [
  set memes-per-change
    (((sum [meme-plus + meme-minus] of turtles) / change) / pop)
]
 
        ]
      ]
    ]

    ;; modulation prevalence (vos noms)
    if mod-prev = true [
      if prevalence > abs opinion * 100 [
        set prevalence prevalence - abs(opinion - opinion-previous) * influence * Rate-mod
      ]
      if prevalence < abs opinion * 100 [
        set prevalence prevalence + abs(opinion - opinion-previous) * influence * Rate-mod
      ]
      if prevalence < min-prevalence [ set prevalence min-prevalence ]
      if prevalence > max-prevalence [ set prevalence max-prevalence ]
    ]

    if random-float 1 < noise [
      let delta (random-float 0.4 - 0.2)
      maybe-set-opinion (opinion + delta)
    ]

    if use-memes? [ decay-memes ]

    update-3d self

    if (output = "Values" or output = "File") [
      compute-statistics
    ]
  ]

  if reward-decay > 0 [
    ask turtles [
      set tx-bonus max (list 0 (tx-bonus - reward-decay))
    ]
  ]

  ifelse (total > 0)
    [ set inversion (100 * change / total) ]
    [ set inversion 0 ]
end 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; I/O : LECTURE FICHIER D’AGENTS (requis car GO appelle `data`)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to in_file
  carefully [
    set file-in user-file
    if (file-in != false) [
      set list_data []
      file-open file-in
      while [not file-at-end?] [
        ;; format attendu : tick prevalence opinion influence
        set list_data sentence list_data (list (list file-read file-read file-read file-read))
      ]
      file-close
      user-message "File uploaded!"
      set in_data true
    ]
  ] [
    user-message "File read error"
  ]
  data
end 

to data
  clear-turtles
  clear-links
  let tick_to_load choice_iter

  ifelse (is-list? list_data) [
    let filtered_data filter [ row -> first row = tick_to_load ] list_data

    create-turtles length filtered_data [
      let my_index who
      let agent_data item my_index filtered_data

      set prevalence item 1 agent_data
      set opinion    item 2 agent_data
      set influence  item 3 agent_data

      if influence = 1 [ set meta-agents meta-agents + influence ]

      set opinion-previous opinion
      set influence-previous influence
      set tx-bonus 0

      if opinion < 0 [ set color red  set agent-type "Left side"  ]
      if opinion > 0 [ set color blue set agent-type "Right side" ]
      if influence = 1 [ set color yellow ]

      ;; (re)initialiser mèmes (quantité + poids) en cohérence avec prevalence/opinion
      init-memes-from-state

      update-3d self
    ]
  ] [
    set in_data false
    user-message "Read error"
  ]

  update-networks
  apply-link-visibility
  recolor-links

  influenceurs
  update-opinions
  set repet_data true
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; COLORATION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to colorer
  ask turtles [
    ifelse meta? [ set color yellow ] [
      ifelse opinion >= 0 [ set color blue ] [ set color red ]
    ]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; NETWORK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-networks
  let doomed links with [
    abs([opinion] of end1 - [opinion] of end2) > (link-removal-threshold / 100)
  ]
  let doomedProb doomed with [ random-float 1 < prob ]
  let n-remove min (list linksdown count doomedProb)
  if n-remove > 0 [
    ask n-of n-remove doomedProb [ die ]
    set links-dead links-dead + n-remove
  ]

  let j linksup
  while [j > 0] [
    let t one-of turtles
    if t = nobody [ stop ]
    ask t [
      let myop opinion
      let candidates other turtles with [ not link-neighbor? myself ]
      let pool-homo candidates with [ abs(opinion - myop) < (link-formation-threshold / 100) ]
      let pool-bridge candidates with [ (sign opinion) != (sign myop) ]

      let friend nobody
      if any? pool-bridge and (random-float 1 < bridge-prob) [
        set friend max-one-of pool-bridge [ abs(opinion - myop) ]
      ]
      if (friend = nobody) and any? pool-homo [
        set friend min-one-of pool-homo [ abs(opinion - myop) ]
      ]

      if friend != nobody and (random-float 1 < prob) [
        create-link-with friend
        set links-create links-create + 1
        let same-sign? (sign opinion) = (sign [opinion] of friend)
        ask link-with friend [
          set color (ifelse-value same-sign? [ green ] [ gray ])
          set thickness linktick
          if show-links? [ show-link ]
        ]
      ]
    ]
    set j j - 1
  ]
end 

to meta
  if not network [ stop ]
  ask turtles [
    let pool other turtles with [
      color = yellow and
      not link-neighbor? myself and
      (count link-neighbors) < meta-links
    ]
    if any? pool [
      let friend one-of pool
      create-link-with friend
      let same-sign? (sign opinion) = (sign [opinion] of friend)
      ask link-with friend [
        set color (ifelse-value same-sign? [ green ] [ gray ])
        set thickness linktick
        if show-links? [ show-link ]
      ]
    ]
  ]
end 

to apply-link-visibility
  ifelse show-links? [ ask links [ show-link ] ] [ ask links [ hide-link ] ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; STATS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to compute-statistics
  if output = "Values" [
    let pre prevalence
    let mem opinion
    let infl influence
    let ag who
    let ti ticks
    let ess try
    let memed (count turtles with [opinion > 0]) / (pop / 100)

    output-print (word ess " ; " ti " ; " ag " ; "
                      pre " ; " mem " ; " infl " ; " memed " ; "
                      meme-plus " ; " meme-minus " ; "
                      meme-plus-w " ; " meme-minus-w)
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; EVENT (votre version, avec réalignement des mèmes si use-memes?)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to event
  ask turtles [
    let event-prob random-float 1
    if event-prob <= event-prob-max [
      ifelse meme_set = true [
        if (to_left = false) [
          if agent-type = "Right side" [
            if opinion < 0 [ maybe-set-opinion (opinion + event_size) ]
          ]
        ]
        if (to_left = true) [
          if agent-type = "Left side" [
            if opinion > 0 [ maybe-set-opinion (opinion - event_size) ]
          ]
        ]
      ] [
        if (to_left = false) [
          if (opinion < high_meme and opinion > low_meme and prevalence < high-prev and prevalence > low-prev) [
            maybe-set-opinion (opinion + event_size)
            if (prev_change != 0) [ set prevalence min (list max-prevalence (prevalence + prev_change)) ]
          ]
        ]
        if (to_left = true) [
          if (opinion > low_meme and opinion < high_meme and prevalence > low-prev and prevalence < high-prev) [
            maybe-set-opinion (opinion - event_size)
            if (prev_change != 0) [ set prevalence min (list max-prevalence (prevalence + prev_change)) ]
          ]
        ]
      ]

      ;; si use-memes? : réaligner l’état mèmes après choc d'opinion/prévalence
      if use-memes? [ init-memes-from-state ]
    ]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UTILITAIRES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to set-background-black
  ask patches [ set pcolor black ]
end 

to update-3d [agt]
  ask agt [
    set x3d opinion * 16
    set y3d prevalence / 6
    set z3d influence * 16
    setxyz x3d y3d z3d
  ]
end 

to-report safe-median [agentset varname]
  if not any? agentset [ report 0 ]
  report median [ runresult varname ] of agentset
end 

to-report sign [x]
  ifelse x > 0 [ report 1 ] [ ifelse x < 0 [ report -1 ] [ report 0 ] ]
end 

to recolor-links
  ask links [
    let s1 sign [opinion] of end1
    let s2 sign [opinion] of end2
    ifelse s1 = s2 [ set color green ] [ set color gray ]
    set thickness linktick
  ]
end 
;; ---------------------------------------------------------------------------
;; Meme Saturation (%)  — system-level cognitive density
;; Returns the percentage (0..100) of the total meme capacity currently filled.
;; ---------------------------------------------------------------------------
;; Share of agents above a high saturation threshold (0..100)

to-report meme-saturation-pct
  if not use-memes? [ report 0 ]
  if not any? turtles [ report 0 ]

  let total-memes sum [meme-plus + meme-minus] of turtles
  let capacity meme-max * count turtles
  if capacity <= 0 [ report 0 ]

  report 100 * total-memes / capacity
end 



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IMPACT DE GROUPE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to-report group-alignment-all [agt sign-ref]
  let nbrs [link-neighbors] of agt
  if not any? nbrs [ report 0.5 ]
  let same count nbrs with [ (sign opinion) = sign-ref ]
  report same / count nbrs
end 

to-report group-alignment-k [agt sign-ref k]
  let nbrs [link-neighbors] of agt
  let deg count nbrs
  if deg = 0 [ report 0.5 ]
  let kk max list 1 min list deg floor k
  let agop [opinion] of agt
  let pool min-n-of kk nbrs [ abs(opinion - agop) ]
  if not any? pool [ report 0.5 ]
  let same count pool with [ (sign opinion) = sign-ref ]
  report same / count pool
end 

to-report group-alignment-effective [agt sign-ref]
  ifelse (group-impact-mode = "k-nearest")
  [ report group-alignment-k agt sign-ref group-k ]
  [ report group-alignment-all agt sign-ref ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MEMES : quantité (prévalence) + poids (opinion)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to-report initial-prevalence-to-memes [prev]
  report (prev / 99) * meme-max
end 

to init-memes-from-state
  let totq initial-prevalence-to-memes prevalence

  ifelse opinion >= 0 [
    set meme-plus  totq * (0.5 + 0.5 * abs opinion)
    set meme-minus totq - meme-plus
  ] [
    set meme-minus totq * (0.5 + 0.5 * abs opinion)
    set meme-plus  totq - meme-minus
  ]

  ;; poids init = quantité * moyenne
  set meme-plus-w  meme-plus  * meme-weight-mean
  set meme-minus-w meme-minus * meme-weight-mean

  if meme-plus < 0 [ set meme-plus 0 ]
  if meme-minus < 0 [ set meme-minus 0 ]
  if meme-plus-w < 0 [ set meme-plus-w 0 ]
  if meme-minus-w < 0 [ set meme-minus-w 0 ]
end 

to-report draw-meme-weight
  let w meme-weight-mean
  if meme-weight-sd > 0 [
    set w (meme-weight-mean + (random-float (2 * meme-weight-sd) - meme-weight-sd))
  ]
  if w < meme-weight-min [ set w meme-weight-min ]
  if w > meme-weight-max [ set w meme-weight-max ]
  report w
end 

to recompute-from-memes
  let totw meme-plus-w + meme-minus-w
  if totw < 1e-6 [ set totw 1e-6 ]   ;; garde-fou numérique
  set proposed-opinion ((meme-plus-w - meme-minus-w) / totw)
  maybe-set-opinion proposed-opinion

  let totq meme-plus + meme-minus
  let scaled (totq / meme-max) * 99
  if scaled < 0 [ set scaled 0 ]
  if scaled > 99 [ set scaled 99 ]
  set prevalence scaled
end 

to decay-memes
  if meme-decay <= 0 [ stop ]
  let f (1 - meme-decay)
  set meme-plus    max list 0 (meme-plus    * f)
  set meme-minus   max list 0 (meme-minus   * f)
  set meme-plus-w  max list 0 (meme-plus-w  * f)
  set meme-minus-w max list 0 (meme-minus-w * f)
end 

to transmit-memes [emitter]
  let sgn sign [opinion] of emitter
  let w draw-meme-weight
  let leak (meme-anti-leak * meme-gain)

  ifelse sgn >= 0 [
    set meme-plus   meme-plus + meme-gain
    set meme-plus-w meme-plus-w + (w * meme-gain)

    set meme-minus   max list 0 (meme-minus - leak)
    set meme-minus-w max list 0 (meme-minus-w - (w * leak))
  ] [
    set meme-minus   meme-minus + meme-gain
    set meme-minus-w meme-minus-w + (w * meme-gain)

    set meme-plus   max list 0 (meme-plus - leak)
    set meme-plus-w max list 0 (meme-plus-w - (w * leak))
  ]

  ;; plafonnement cohérent quantité + poids
  let totq meme-plus + meme-minus
  if totq > meme-max [
    let factor meme-max / totq
    set meme-plus    meme-plus    * factor
    set meme-minus   meme-minus   * factor
    set meme-plus-w  meme-plus-w  * factor
    set meme-minus-w meme-minus-w * factor
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INJECTION (préférence inject-low_meme)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to inject-memes
  let base-pool turtles with [
    opinion >= inject-low_meme and opinion <= inject-high_meme and
    prevalence >= inject-low-prev and prevalence <= inject-high-prev
  ]

  ;; Comportement par défaut : identique à l'original
  let pool base-pool

  ;; Meta-only autorisé UNIQUEMENT lorsque vary-influence est désactivé ajout au besoin dans la commande IF 'and (vary-influence = false)'
 if (inject-metas-only)  [
   set pool base-pool with [ color = yellow ]
  ]
  
  ask pool [
    if random-float 1 <= inject-prob-max [
      let w inject-weight
      if w < meme-weight-min [ set w meme-weight-min ]
      if w > meme-weight-max [ set w meme-weight-max ]

      if inject-amount < 0 [ stop ]

      if inject-sign = "plus" [
        set meme-plus   meme-plus + inject-amount
        set meme-plus-w meme-plus-w + (w * inject-amount)
      ]
      if inject-sign = "minus" [
        set meme-minus   meme-minus + inject-amount
        set meme-minus-w meme-minus-w + (w * inject-amount)
      ]

      let totq meme-plus + meme-minus
      if totq > meme-max [
        let factor meme-max / totq
        set meme-plus    meme-plus    * factor
        set meme-minus   meme-minus   * factor
        set meme-plus-w  meme-plus-w  * factor
        set meme-minus-w meme-minus-w * factor
      ]

      if use-memes? [ recompute-from-memes ]
    ]
  ]
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CSV
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to csv-begin
  if not csv-export [ stop ]
  set csv-file (word csv-basename "-" try ".csv")
  file-close-all
  if file-exists? csv-file [ file-delete csv-file ]
  file-open csv-file
  set csv-open? true
  file-print "try,iter,tick,left_pct,right_pct,avg_opinion,med_op_right,med_op_left,med_prev_right,med_prev_left,med_infl_right,med_infl_left,links_remove,links_create,inversion_pct,change,total,fractale,major"
end 

to csv-row
  if not csv-open? [ stop ]
  let avg-opinion     mean [opinion] of turtles
  let opR             safe-median (turtles with [opinion >= 0]) "opinion"
  let opL             safe-median (turtles with [opinion < 0])  "opinion"
  let prevR           (safe-median (turtles with [opinion >= 0]) "prevalence") / 100
  let prevL           (safe-median (turtles with [opinion < 0])  "prevalence") / 100
  let inflR           safe-median (turtles with [opinion >= 0]) "influence"
  let inflL           safe-median (turtles with [opinion < 0])  "influence"
  let leftpct         (count turtles with [opinion < 0])  / (pop / 100)
  let rightpct        (count turtles with [opinion >= 0]) / (pop / 100)
  file-print (word try "," iter "," ticks ","
              leftpct "," rightpct "," avg-opinion ","
              opR "," opL "," prevR "," prevL ","
              inflR "," inflL ","
              links-dead "," links-create ","
              inversion "," change "," total "," fractale "," major)
end 

to csv-end
  if csv-open? [
    file-close
    set csv-open? false
  ]
end 

to-report mean-polarity-index
  let total-plus  sum [meme-plus] of turtles
 let total-minus sum [meme-minus] of turtles
 ifelse (total-plus + total-minus > 0)
   [ report (total-plus - total-minus) / (total-plus + total-minus) ]
   [ report 0 ]
end 




There is only one version of this model, created 5 days ago by Pierre-Alain Cotnoir.

Attached files

No files