Child of Version_20260115-2_Simulator v6_EN
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
- Choose the population size with
pop. - Click Setup (creates agents, black background, initializes
tick-eventtoevent-init). - 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/totalevery 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-mode/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 ifvary-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 setsmeta-links ← meta-minifvary-influence= true ormeta-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(formerlymodulation-prevalence): ON to adapt prevalence to current vs previous opinion.Rate-mod(formerlyrate-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-minusstore how many pro/anti memes the agent holds.- Prevalence (0–99) is derived from the total quantity:
meme-plus + meme-minusrescaled 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-wstore 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.
- Low values → many memes are needed to polarize opinions.
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.
- 0.0 → all memes are equally strong.
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_memeinject-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 whenticks = inject-tick.inject-tick: the tick at which injection happens.repeat-inject?: if ON, injection repeats everyinject-paceticks.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-gaincombined with highmeme-anti-leakaccelerates 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 |
Targeting and Selectivity Parameters
| Slider | Typical range | Role in the model | Low values → effects | High values → effects | |------|---------------|-------------------|----------------------|----------------------| | inject-low_meme | −1.0 – 1.0 | Lower bound of opinion eligible for injection | Broad targeting across ideological spectrum | Injection limited to one side or a narrow ideological niche | | inject-high_meme | −1.0 – 1.0 | Upper bound of opinion eligible for injection | Narrow ideological window | Broad or opposing-side reach (depending on bounds) | | inject-low-prev | 0 – 99 | Minimum prevalence required to receive injected memes | Inclusion of low-salience or weakly engaged agents | Targeting already attentive or mobilized agents | | inject-high-prev | 0 – 99 | Maximum prevalence eligible for injection | Focus on low-to-mid engagement agents | Restriction to highly engaged elites |
Interaction Effects (Key Dynamics)
inject-tick × inject-pace
- Early + short pace → persistent campaign dynamics.
- Late + long pace → isolated shock events.
- Early + short pace → persistent campaign dynamics.
inject-prob-max × inject-amount
- Low prob + high amount → elite seeding (few agents, strong impact).
- High prob + low amount → mass diffusion (many agents, weak signal).
- Low prob + high amount → elite seeding (few agents, strong impact).
inject-weight × inject-amount
- High weight + high amount → rapid opinion polarization.
- Low weight + high amount → agenda-setting without strong persuasion.
- High weight + high amount → rapid opinion polarization.
inject-lowmeme / inject-highmeme × inject-low-prev / inject-high-prev
- Narrow opinion + high prevalence → echo-chamber reinforcement.
- Broad opinion + low prevalence → grassroots diffusion potential.
- Narrow opinion + high prevalence → echo-chamber reinforcement.
Conceptual Interpretation
- Low values generally model background noise, rumors, or weak informational exposure.
- High values approximate organized campaigns, disinformation bursts, or polarizing media events.
- Intermediate combinations allow exploration of threshold effects, diffusion delays, and nonlinear amplification.
These sliders are designed to be orthogonal but non-independent: meaningful experiments emerge from their joint configuration, not isolated tuning.
Preset — Campaign / Rumor / Polarizing shock (recommended default profile)
This preset is a ready-to-run parameter profile designed to reproduce a common empirical pattern in opinion dynamics:
1) a stable baseline (moderate homophily, limited cross-camp contact),
2) a rumor/campaign phase (repeated external shocks reaching only part of the population),
3) a polarizing outcome (network segmentation, fewer inversions, stronger within-camp reinforcement).
It is intended as a starting point for university-level experimentation (reproducible and interpretable), not as a calibrated model for a specific case.
A. Core idea
- Use repeat-event + event-pace to create a campaign/rumeur that reappears periodically.
- Use event-prob-max < 1 so the shock reaches only a subset of eligible agents, generating diffusion rather than an immediate global collapse.
- Keep bridge-prob low but non-zero so rare cross-camp bridges exist (possible inversions), while still allowing polarization to emerge.
- Activate group impact and a mild reward system to reproduce realistic “social proof” and reinforcement mechanisms.
B. Default values (Preset)
(Values assume your current sliders/switches; ranges remain adjustable by the operator.)
1) Events: “campaign / rumor” mechanics
- auto_event: ON
- repeat-event: ON
- event-init:
50(first shock after an initial stabilization period) - event-pace:
25(shock repeats every 25 iterations) - event-prob-max:
0.10(≈10% of eligible agents receive the shock each cycle)
Bounds & targeting
- meme_set: OFF (use bounds rather than structural Left/Right set)
- lowmeme / highmeme: -0.30 / +0.30 (targets the “convertible middle”)
- low-prev / high-prev: 10 / 60 (targets moderate-prevalence agents—reachable but not rigid)
Shock magnitude
- event_size: 0.25 (clear movement without saturating ±1 too fast)
- prev_change: +8 (moderate strengthening of prevalence in targeted agents; set 0 if you want “pure opinion shock”)
Interpretation - This reproduces a campaign/rumeur that repeatedly perturbs the middle rather than only extremes, and spreads indirectly through the network.
2) Network: controlled homophily + rare bridges
- network: ON
- link-formation-threshold:
0.20 - link-removal-threshold:
0.40 - prob:
0.30 - linksup / linksdown:
10 / 10(balanced churn) - bridge-prob:
0.05(rare but non-zero cross-camp bridges) - show-links?: optional (OFF for performance; ON for demonstrations)
Expected effect - The network remains mostly homophilous, but with occasional “bridges” allowing limited cross-camp exposure.
3) Opinion adoption: prevalence-driven, polarization-aware
- prevalence-weight:
1.40 - polarization-factor:
0.60 - adoption-floor:
0.03 - noise:
0.01(small background drift)
Expected effect - Adoption is mostly driven by prevalence differences, while strong polarization reduces cross-camp adoption without making it impossible.
4) Group impact: social proof (moderate strength)
- group-impact-mode:
k-nearest - group-k:
8 - group-impact-weight:
0.60 - group-impact-alpha:
1.20
Expected effect - Local neighbourhood alignment matters; majorities have slightly more weight than minorities (alpha > 1).
5) Reward: modest reinforcement (avoid runaway)
- reward-step:
0.03 - reward-cap:
0.30 - reward-decay:
0.005 - reward-scope:
both - reward-prev-delta:
0(keep prevalence effects attributable to memes/events; set 1–3 if you want “success breeds conviction”)
Expected effect - Successful influencers become moderately more effective over time, but decay prevents permanent dominance.
6) Memes: ON (recommended for this preset)
- use-memes?: ON
- meme-max:
120 - meme-gain:
1.0 - meme-anti-leak:
0.20 - meme-decay:
0.01
Expected effect - Agents gradually accumulate representations; anti-leak creates a mild competitive relation between pro/anti stocks, supporting polarization over repeated shocks.
7) Meta-influencers: optional, controlled
- meta-ok: ON (optional; ON reproduces real-world asymmetric reach)
- meta-influencers-selection:
All - meta-influencers:
5% - prev-low / prev-high:
20 / 80 - meta-min / meta-max:
8 / 20 - metablock: ON (prevents sign switching for metas)
- vary-influence: OFF (recommended OFF to avoid meta inflation; turn ON only if studying endogenous influencer emergence)
Expected effect - A small set of highly connected agents accelerates diffusion while the metablock prevents metas from oscillating across camps.
C. What you should observe (typical outcomes)
- Early phase (before event-init): moderate clustering, limited movement.
- During repeated events: a growing asymmetry in meme stocks and prevalence among the targeted “middle”.
- Over time: stronger within-camp reinforcement, more gray links disappearing, fewer inversions.
- If you increase event-prob-max toward 0.30–0.50: faster and more global shifts.
- If you increase bridge-prob toward 0.10–0.20: more cross-camp exposure and more inversions (polarization weakens).
D. Minimal variant (if you want “shock-only”, no campaign)
- Set repeat-event = OFF and keep a single event-init (or press event once).
- Keep all other values unchanged to compare one-shot shock vs campaign repetition.
Meme Dynamics — Integrated Monitoring Indicators
This simulator includes six dedicated monitors designed to track how memes (internal representations) shape opinion formation, prevalence, and polarization over time.
Each monitor is updated at every tick and provides a complementary analytical perspective on the meme–opinion coupling.
1. Mean Meme Stock
What it measures
The average total number of memes held by agents:
Mean Meme Stock = mean(meme-plus + meme-minus)
Why it matters
This indicator captures the global cognitive density of the population.
- Low values indicate weakly structured opinions (few internal representations).
- High values reflect ideologically “loaded” agents with many arguments.
Interpretation
- Rising values → accumulation of representations (learning, persuasion, repeated events).
- Falling values → forgetting or erosion (via meme-decay).
Implementation (monitor expression)
2. Meme Polarity Index
What it measures
The net ideological balance of all memes in the system.
It compares the total stock of positive memes to negative memes.
Interpretation
- Values close to +1 → dominance of pro (+) memes.
- Values close to -1 → dominance of contra (−) memes.
- Values near 0 → balanced or plural meme ecology.
Implementation (monitor expression)
3. Opinion–Meme Gap
What it measures
The average absolute difference between:
- the agent’s expressed opinion, and
- the opinion implied by its internal meme balance.
Why it matters
This indicator captures latent cognitive inconsistency:
agents may express an opinion that is not fully supported by their internal representations.
Interpretation
- Low gap → opinions are well grounded in memes.
- High gap → cognitive tension, instability, or transitional states.
Implementation (monitor expression)
4. Ideologization Index
What it measures
The degree to which strong opinions are backed by high prevalence.
It combines opinion extremity and representational depth.
Interpretation
- High values → polarized and ideologically entrenched population.
- Low values → pragmatic or weakly structured opinion landscape.
Implementation (monitor expression)
5. Right Meme Polarization
What it measures
The internal ideological polarization of meme stocks among agents holding a positive opinion (opinion >= 0).
It compares reinforcing memes (meme-plus) to counter-memes (meme-minus) within the right-leaning subgroup only, independently of the left side.
Interpretation
- Values close to +1 → strong dominance of reinforcing (pro-right) memes.
- Values near 0 → balanced or internally plural meme structure.
- Values below 0 → erosion or counter-meme dominance inside the right camp.
This indicator reveals whether right-side opinions are: - deeply ideologized, - stable but weakly supported, - or vulnerable to counter-narratives.
Implementation (plot and monitor expression)
6. Left Meme Polarization
What it measures
The internal ideological polarization of meme stocks among agents holding a negative opinion (opinion < 0).
It measures the balance between reinforcing and counter-memes inside the left-leaning subgroup, independently from right-side dynamics.
Interpretation
- Values close to -1 → strong dominance of reinforcing (pro-left) memes.
- Values near 0 → plural or contested internal meme structure.
- Values above 0 → counter-meme pressure within the left camp.
This indicator is essential to detect: - asymmetric polarization, - minority radicalization, - or differential resistance to meme diffusion.
Implementation (plot and monitor expression)
7. Mean Meme-derived Opinion
What it measures
The average opinion value reconstructed from meme stocks, independently of the agents’ current explicit opinions.
This measure computes, for each agent, the opinion implied by the balance of its internal memes
(meme-plus vs meme-minus), then averages this value across the whole population.
Interpretation
- Values close to +1 → the meme ecology strongly supports the positive (right/pro) polarity.
- Values close to -1 → dominance of negative (left/contra) meme representations.
- Values near 0 → balanced or internally conflicting meme structures.
Comparing this indicator with the mean explicit opinion reveals latent ideological tensions:
- If meme-derived opinion is stronger than explicit opinion → opinions may soon shift.
- If explicit opinion is stronger than meme-derived opinion → opinions are weakly grounded and fragile.
Why it matters
This indicator captures the deep cognitive orientation of the population, beyond surface-level expressed opinions.
It helps distinguish:
- superficial opinion alignment,
- structurally grounded ideological states,
- and phases where internal representations lag behind observable behavior.
Implementation (monitor expression)
8. Meme Saturation (%)
What it measures
The overall saturation level of meme stocks in the population, expressed as a percentage of the maximum possible meme capacity.
It compares the total number of memes currently held by all agents to the theoretical maximum (meme-max × population).
Interpretation
- Values close to 0% → agents hold very few internal representations; opinions are shallow and weakly grounded.
- Intermediate values (30–60%) → active circulation of arguments with moderate cognitive load.
- Values close to 100% → saturated cognitive environment; agents are highly entrenched and resistant to change.
This indicator captures the cognitive density of the system and helps distinguish: - early diffusion phases, - mature ideological ecosystems, - and saturation-driven stabilization or lock-in effects.
Implementation (monitor expression)
(These indicators are computed only when use-memes? is ON.)
EXOGENOUS EVENTS (bounded & probabilistic)
Targeting
meme_set+to_left: if ON, structural targeting by camp (Left side / Right side).- Otherwise, use bounds:
low_meme/high_meme(opinion window) andlow-prev/high-prev(prevalence window).
Effects on targeted agents
event_size: opinion shift (toward the intended camp).prev_change: prevalence change (clamped to [0,99]).event-prob-max(0–1): maximum share of targeted agents that actually receive the shock (each agent drawsU(0,1)).
Triggering
eventbutton: one-shot shock (manual).auto_event+tick-event: scheduled automatic shock at iterationtick-event.
Repeated events (per your code)
event-init: initial offset of the first event (onsetupand at each new trial,tick-event ← event-init).repeat-event(switch): if ON, re-schedules the next event after each occurrence.event-pace(≥ 1 tick recommended): spacing between repeated events.Scheduling logic:
- If
auto_event= ON anditer = tick-event→ runevent. - If
repeat-event= ON →tick-event ← tick-event + event-pace. - Else (OFF) → no automatic re-scheduling (you may adjust
tick-eventmanually). - If
auto_event= OFF → each tick,tick-event ← iter + event-pace(the next time you switch ON, the event fires ≈event-paceticks later).
- If
Quick examples
- Single calibration shock:
auto_event=ON,repeat-event=OFF,event-init=2,event-prob-max=1.0. - Periodic pulses:
auto_event=ON,repeat-event=ON,event-init=50,event-pace=50,event-prob-max=0.30. - Diffuse perturbations:
repeat-event=ON,event-pace=100,event-prob-max=0.05.
CSV EXPORT (NEW FEATURE)
The simulator supports buffered CSV export, allowing results to be written efficiently to disk at the end of a run or trial.
Two export modes are available:
Statistics mode
Exports aggregate indicators per tick, including:
- mean opinion
- median opinion (left / right)
- median prevalence (left / right)
- median influence (left / right)
- population shares (left / right)
- number of links created and removed
- inversion rate
- interaction counters
- fractal indicators
Values mode
Exports individual agent states at selected iterations. One row is written per agent per exported iteration, including:
- opinion
- prevalence
- influence
- meme-plus
- meme-minus
- meme-plus weight
- meme-minus weight
CSV Controls
csv-export
Enables or disables CSV export.csv-mode
Selects"Statistics"or"Values"export mode.csv-basename
Base name used for generated CSV files.csv-values-start
First tick at which agent values are exported (Values mode).csv-values-step
Interval (in ticks) between value exports.
CSV Buttons
csv open
Initializes the CSV buffer and writes the file header.csv close
Flushes the buffer and writes the CSV file to disk.
CSV filenames are automatically constructed from the base name, trial number, export mode, and locale.
IMPORTING AGENT STATES (NEW FEATURE)
The simulator supports two distinct formats for importing agent states.
in_file (Simple format)
The in_file button loads a file containing a single snapshot of agents, typically corresponding to iteration 0.
Each line in the file must contain exactly:
- tick
- prevalence
- opinion
- influence
This format is intended for:
- handcrafted initial populations
- externally generated datasets
- controlled experimental starting points
When loaded:
- agents are created once
- meme stocks are initialized from opinion and prevalence
- the social network is rebuilt normally
infilevalues (CSV Values re-import)
The infilevalues button loads agents from a CSV file previously exported in Values mode.
Usage:
- select the iteration to load using choice_iter
- click infilevalues
Behavior:
- agents are reconstructed exactly as they were at the selected iteration
- opinion, prevalence, influence, meme stocks, and meme weights are restored
- agents with influence = 1 are automatically recolored as meta-agents
This enables:
- replaying simulations from an intermediate state
- branching alternative scenarios
- counterfactual experiments
- reproducible analysis from archived runs
OUTPUTS AND MONITORS
The interface provides monitors for:
- population shares (left / right)
- opinion, prevalence, and influence statistics
- meme-based indicators
- polarization and saturation measures
- inversion rates
- network dynamics (links created / removed)
Plots display time trajectories of key variables, supporting both exploratory and analytical use of the simulator.
OUTPUTS / MONITORS / CSV
- Monitors: % left/right, medians (opinion/prevalence/influence), inversions, interactions, fractal dimension, links created/removed.
- Graph: time trajectories of key variables.
- CSV: if
csv-export= ON, per-trial export with a standard header (basename-try.csv).
STATISTICS EXPORT — VARIABLES GUIDE (Automatically exported when csv-export + statistics is ON)
| Variable | Meaning | Analytical role | |---------|---------|-----------------| | try | Run index | Multi-run / Monte Carlo analysis | | tick | Simulation time | Temporal dynamics | | pop | Population size | Normalization | | interactionsperiter | Total interactions per tick | Social activity level | | change | Opinion changes | Instantaneous volatility | | inversions | Sign changes (+↔−) | Ideological switching | | interactionsperinversion | Interactions per inversion | Cognitive inertia | | linkscreated | New links | Network plasticity | | linksremoved | Deleted links | Network fragmentation | | bridgelinks | Cross-camp links | Ideological permeability | | meanopinion | Average opinion | Global orientation | | medianopinion | Median opinion | Robust central tendency | | meanabsopinion | Mean |opinion| | Degree of radicalization | | majoritypct | Majority share | Dominance vs pluralism | | meanprevalence | Average prevalence | Depth of conviction | | medianprevalence | Median prevalence | Distribution of conviction | | meanmemestock | Avg. meme quantity | Cognitive density | | meanmemederivedopinion | Opinion from memes | Latent ideological orientation | | meanpolarityindex | Meme balance index | System-level polarity | | memesaturationpct | Meme capacity usage (%) | Cognitive saturation | | rightmemepolarization | Meme asymmetry (Right) | Intra-camp radicalization | | leftmemepolarization | Meme asymmetry (Left) | Intra-camp radicalization | | opinionmemegap | Opinion–meme distance | Cognitive dissonance | | ideologizationindex | Mean |meme+ − meme−| | Ideological intensity | | metaagents | Number of meta-agents | Influence concentration | | metalinks | Links of meta-agents | Structural reach |
Notes: • Meme-based indicators are meaningful only when use-memes? = ON • ideologization_index measures ideological asymmetry, not direction • inversions capture true allegiance shifts (sign changes)
• opinionmemegap signals latent instability
THINGS TO WATCH
- Polarization, convergence, fragmentation.
- Roles of meta-influencers (and
metablock), group effect, and reward. - Impact of memes (memory, cross-leak, decay).
- How repeated events and
event-prob-maxshape the global dynamics.
QUICK CHEAT SHEET — TYPICAL VALUES
| Parameter | Useful range | Tendency |
| ----------------------- | ------------ | ----------------------------------------------------------- |
| prevalence-weight | 0–2 | ↑ makes prevalence gaps dominate adoption |
| adoption-floor | 0–0.1 | ↑ allows more “noisy” cross-camp adoptions |
| bridge-prob | 0–0.3 | ↑ creates more cross-camp bridges & inversions |
| group-impact-weight | 0–1 | ↑ strengthens neighborhood alignment effect |
| group-impact-alpha | 0.2–3 | <1 favors small aligned clusters; >1 needs large majorities |
| reward-step | 0.01–0.1 | ↑ faster reinforcement of persuasive agents |
| reward-decay | 0–0.05 | ↑ bonus fades faster |
| meme-anti-leak | 0–0.5 | ↑ growth erodes the opposite stock more |
| event-prob-max | 0–1 | ↑ more “massive” shocks per occurrence |
| event-pace | ≥1 | ↓ means more frequent events (if repetition ON) |
| mod-prev & Rate-mod | — | adapt prevalence to opinion changes |
CREDITS
- Original concept: Public Opinion Research Group (GROP.CA)
- NetLogo implementation & enhancements: Pierre-Alain Cotnoir (2015–2026)
- AI-assisted design: GPT-4 & GPT-5 (2024–2026)
- Contact: pacotnoir@gmail.com
Comments and Questions
extensions [sound nw] globals [ ;; core min-prevalence max-prevalence memes-per-change meta-influencers-droit meta-influencers-gauche inject-tick 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 ;; LOCALE ;; locale-format ;; "EN" | "FR" ;; CSV (simplifié, sans BOTH) ;;csv-export ;; switch ;;csv-basename ;; string ;;csv-mode ;; "Statistics" | "Values" csv-file-stats csv-file-values csv-buffer ;; liste de lignes (strings) à écrire en fin de run/try csv-open? ;; buffer initialisé ? ;;csv-values-step ;; pas d’export Values (ticks mod step = 0) ;;csv-values-start ;; tick de départ pour exporter Values ;; NEW: import Values CSV list_values_data values_file_in values_sep ;; compat: si vous n’avez pas le switch, le code compile quand même ;;inject-metas-only ] turtles-own [ opinion prevalence agent-type influence opinion-previous influence-previous x3d y3d z3d meme-plus meme-minus meme-plus-w meme-minus-w old-opinion proposed-opinion tx-bonus ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LOCALE / FORMAT HELPERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to-report col-sep ifelse locale-format = "FR" [ report ";" ] [ report "," ] end to-report replace-all [s old new] let out s while [ position old out != false ] [ let i position old out set out (word (substring out 0 i) new (substring out (i + length old) (length out))) ] report out end to-report fmt [x] ;; formatte nombres selon locale-format (décimale "," en FR) if x = nobody [ report "" ] if not is-number? x [ report (word x) ] let s (word "" x) if locale-format = "FR" [ set s replace-all s "." "," ] report s end to-report join-cols [lst] let sep col-sep let out "" foreach lst [ val -> let s (word "" val) set out ifelse-value (out = "") [ s ] [ (word out sep s) ] ] report out end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; VALUES CSV IMPORT HELPERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to-report split-by [s sep] ;; retourne une liste de segments (strings) let parts [] let rest s while [ position sep rest != false ] [ let i position sep rest set parts lput (substring rest 0 i) parts set rest substring rest (i + length sep) (length rest) ] set parts lput rest parts report parts end to-report to-number-locale [s sep] ;; s: string ; sep: ";" (FR) ou "," (EN) if s = "" [ report 0 ] let x s ;; si colonnes séparées par ";" on suppose décimale "," if sep = ";" [ set x replace-all x "," "." ] set x replace-all x " " "" report read-from-string x end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 inject-tick inject-base set major 0 ;; Locale defaults if not is-string? locale-format [ set locale-format "FR" ] if (locale-format != "FR" and locale-format != "EN") [ set locale-format "FR" ] ;; tick-event initialisé par event-init 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 if (vary-influence = true) or (meta-ok = true) [ set meta-links meta-min ] ;; CSV defaults if not is-boolean? csv-export [ set csv-export false ] if (not is-string? csv-basename) or (csv-basename = "") [ set csv-basename "run" ] if not is-string? csv-mode [ set csv-mode "Statistics" ] if (csv-mode != "Statistics" and csv-mode != "Values") [ set csv-mode "Statistics" ] if not is-number? csv-values-step [ set csv-values-step 10 ] if csv-values-step < 1 [ set csv-values-step 1 ] if not is-number? csv-values-start [ set csv-values-start 0 ] if csv-values-start < 0 [ set csv-values-start 0 ] set csv-file-stats "" set csv-file-values "" set csv-buffer [] set csv-open? false ;; import values defaults set list_values_data [] set values_file_in false set values_sep ";" ;; compat if not is-boolean? inject-metas-only [ set inject-metas-only false ] ;; defaults group-impact 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 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 ] 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" ] 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 ] 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; OUTPUT HEADERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to rapport if output = "Statistics" [ output-print join-cols (list "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" [ ;; memed RETIRÉ des Values output-print join-cols (list "Try" "Ticks" "Agents" "Prevalence" "Opinion" "Influence" "meme plus" "meme minus" "meme plus w" "meme minus w" ) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; META-INFLUENCEURS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to influenceurs if meta-mode = "Pourcent" [ 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 ] ] ] ] ] if meta-mode = "Nombre" [ if meta-influencers-selection = "All" [ let k meta-influencers let candidates turtles with [(prevalence > prev-low and prevalence <= prev-high)] if k > 0 [ ask up-to-n-of k turtles [ set influence 1 set color yellow set meta-agents meta-agents + 1 ] ] ] if meta-influencers-selection = "Right side" [ set meta-influencers-droit meta-influencers let candidates turtles with [opinion > 0 and (prevalence > prev-low and prevalence <= prev-high)] let k min list meta-influencers-droit count candidates if k > 0 [ ask up-to-n-of k candidates [ set influence 1 set color yellow set meta-agents meta-agents + 1 ] ] ] if meta-influencers-selection = "Left side" [ set meta-influencers-gauche meta-influencers let candidates turtles with [opinion < 0 and (prevalence > prev-low and prevalence <= prev-high) ] let k min list meta-influencers-gauche count candidates if k > 0 [ ask up-to-n-of k candidates [ 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 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CSV (bufferisé) — sans BOTH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to-report csv-filename [mode-tag] report (word csv-basename "-" try "-" mode-tag "-" locale-format ".csv") end to csv-begin if not csv-export [ stop ] set csv-buffer [] set csv-open? true if csv-mode = "Statistics" [ set csv-file-stats csv-filename "stats" set csv-buffer lput (join-cols (list "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" "bridge_links" "inversion_pct" "change" "total" "fractale" "major" "interactions_per_iter" "majority_pct" "interactions_per_inversion" "meta_links" "meta_agents" "mean_prevalence" "median_prevalence" "median_opinion" "mean_abs_opinion" "mean_meme_stock" "mean_meme_derived_opinion" "mean_polarity_index" "meme_saturation_pct" "right_meme_polarization" "left_meme_polarization" "opinion_meme_gap" "ideologization_index")) csv-buffer ] if csv-mode = "Values" [ set csv-file-values csv-filename "values" ;; memed RETIRÉ des Values CSV set csv-buffer lput (join-cols (list "try" "tick" "agent" "prevalence" "opinion" "influence" "meme_plus" "meme_minus" "meme_plus_w" "meme_minus_w" )) csv-buffer ] end to ensure-csv-ready if not csv-export [ stop ] if not csv-open? [ csv-begin ] end to csv-row-statistics ;; appelé seulement si csv-mode = "Statistics" 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) ;; bridge links = ties connecting opposite opinion signs let bridge_links count links with [ (sign [opinion] of end1) != (sign [opinion] of end2) ] ;; --- UI monitor-aligned extras --- let interactions-per-iter ifelse-value (iter > 0) [ total / iter ] [ 0 ] let majority-pct %Major let interactions-per-inversion ifelse-value (change > 0) [ total / change ] [ 0 ] let mean-prevalence ifelse-value (any? turtles) [ mean [prevalence] of turtles ] [ 0 ] let median-prevalence safe-median turtles "prevalence" let median-opinion safe-median turtles "opinion" let mean-abs-opinion ifelse-value (any? turtles) [ mean [abs opinion] of turtles ] [ 0 ] ;; meme aggregates (only meaningful when use-memes? = true, but exported regardless) let mean-meme-stock ifelse-value (any? turtles) [ mean [meme-plus + meme-minus] of turtles ] [ 0 ] let mean-meme-derived-opinion ifelse-value (any? turtles) [ mean [ ifelse-value ((meme-plus-w + meme-minus-w) > 0) [ (meme-plus-w - meme-minus-w) / (meme-plus-w + meme-minus-w) ] [ 0 ] ] of turtles ] [ 0 ] let mean-pol-index mean-polarity-index let meme-sat meme-saturation-pct ;; Right/Left meme polarization within camps (quantity-based, for comparability with earlier monitors) let right-den sum [meme-plus + meme-minus] of turtles with [opinion >= 0] let right-num (sum [meme-plus] of turtles with [opinion >= 0]) - (sum [meme-minus] of turtles with [opinion >= 0]) let right-meme-pol ifelse-value (right-den > 0) [ right-num / right-den ] [ 0 ] let left-den sum [meme-plus + meme-minus] of turtles with [opinion < 0] let left-num (sum [meme-plus] of turtles with [opinion < 0]) - (sum [meme-minus] of turtles with [opinion < 0]) let left-meme-pol ifelse-value (left-den > 0) [ left-num / left-den ] [ 0 ] ;; Opinion–Meme Gap: absolute mismatch between expressed opinion and meme-derived opinion (weighted) let opinion-meme-gap ifelse-value (any? turtles) [ mean [ abs (opinion - (ifelse-value ((meme-plus-w + meme-minus-w) > 0) [ (meme-plus-w - meme-minus-w) / (meme-plus-w + meme-minus-w) ] [ 0 ])) ] of turtles ] [ 0 ] ;; Ideologization Index: extremity × conviction depth proxy (0..1) let ideologization-index ifelse-value (any? turtles) [ mean [abs (meme-plus - meme-minus)] of turtles ] [ 0 ] set csv-buffer lput (join-cols (list fmt try fmt iter fmt ticks fmt leftpct fmt rightpct fmt avg-opinion fmt opR fmt opL fmt prevR fmt prevL fmt inflR fmt inflL fmt links-dead fmt links-create fmt bridge_links fmt inversion fmt change fmt total fmt fractale fmt major fmt interactions-per-iter fmt majority-pct fmt interactions-per-inversion fmt meta-links fmt meta-agents fmt mean-prevalence fmt median-prevalence fmt median-opinion fmt mean-abs-opinion fmt mean-meme-stock fmt mean-meme-derived-opinion fmt mean-pol-index fmt meme-sat fmt right-meme-pol fmt left-meme-pol fmt opinion-meme-gap fmt ideologization-index )) csv-buffer end to csv-row-values ;; appelé seulement si csv-mode = "Values" if ticks < csv-values-start [ stop ] if (ticks mod csv-values-step) != 0 [ stop ] foreach sort turtles [ t -> set csv-buffer lput (join-cols (list fmt try fmt ticks fmt [who] of t fmt [prevalence] of t fmt [opinion] of t fmt [influence] of t fmt [meme-plus] of t fmt [meme-minus] of t fmt [meme-plus-w] of t fmt [meme-minus-w] of t )) csv-buffer ] end to csv-flush if empty? csv-buffer [ stop ] file-close-all if csv-mode = "Statistics" [ if file-exists? csv-file-stats [ file-delete csv-file-stats ] file-open csv-file-stats ] if csv-mode = "Values" [ if file-exists? csv-file-values [ file-delete csv-file-values ] file-open csv-file-values ] foreach csv-buffer [ line -> file-print line ] file-close end to csv-end ;; écriture finale du buffer if csv-open? [ csv-flush ] file-close-all set csv-buffer [] set csv-open? false end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; GO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go ifelse (iter < max_iter) [ if csv-export [ ensure-csv-ready ] if iter > 0 [ set Interactions (total / iter) ] if iter > 0 [ set %Major (major / iter * 100) ] set iter iter + 1 set meta-create 0 ;; EVENEMENTS (corrigé) if auto_event [ if (iter = tick-event) [ event if repeat_event [ set tick-event (tick-event + event-pace) ] ] ] ;; INJECTION AUTO 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 ;; OUTPUT Statistics 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 join-cols (list fmt try fmt ti fmt avg-opinion fmt positive-opinion fmt negative-opinion fmt positive-prevalence fmt negative-prevalence fmt positive-influence fmt negative-influence fmt Left% fmt Right% fmt links-dead fmt links-create fmt inversion fmt change fmt total fmt fractale ) ] tick ifelse use-memes? [ if (change > 1 and iter > 1) [ set fractale (ln total / ln change) ] ] [ 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 ] ;; CSV buffer write selon mode if csv-export [ if csv-mode = "Statistics" [ csv-row-statistics ] if csv-mode = "Values" [ csv-row-values ] ] ] [ ;; fin d'un try 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 set tick-event event-init 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 set inject-tick inject-base ] ] [ 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 (widget: mode_prev) if mode_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") [ 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; VALUES OUTPUT (memed RETIRÉ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to compute-statistics if output = "Values" [ output-print join-cols (list fmt try fmt ticks fmt who fmt prevalence fmt opinion fmt influence fmt meme-plus fmt meme-minus fmt meme-plus-w fmt meme-minus-w ) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IMPORT SIMPLE (format existant) + WRAPPER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to in_file in_file_simple end to in_file_simple 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 (simple format)!" set in_data true ] ] [ user-message "File read error" ] set choice_iter 0 data end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IMPORT VALUES CSV (nouveau) — charge un CSV Values multi-ticks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to in_file_values carefully [ set values_file_in user-file if values_file_in = false [ stop ] set list_values_data [] file-open values_file_in if file-at-end? [ user-message "Empty file" stop ] let header file-read-line ;; détecter séparateur colonnes ifelse (position ";" header != false) [ set values_sep ";" ] [ set values_sep "," ] while [not file-at-end?] [ let line file-read-line if line != "" [ let cols split-by line values_sep set list_values_data lput cols list_values_data ] ] file-close user-message "File uploaded (values CSV)!" ] [ user-message "Values file read error" stop ] data-values end to data-values clear-turtles clear-links let tick_to_load choice_iter ;; colonnes attendues (Values sans memed): ;; 0 try, 1 tick, 2 agent, 3 prevalence, 4 opinion, 5 influence, ;; 6 meme_plus, 7 meme_minus, 8 meme_plus_w, 9 meme_minus_w let rows filter [cols -> (length cols >= 10) and (to-number-locale (item 1 cols) values_sep = tick_to_load) ] list_values_data if empty? rows [ user-message (word "No rows found for tick " tick_to_load) stop ] let n min list pop length rows let selected sublist rows 0 n set meta-agents 0 create-turtles n [ let cols item who selected set prevalence to-number-locale (item 3 cols) values_sep set opinion to-number-locale (item 4 cols) values_sep set influence to-number-locale (item 5 cols) values_sep set meme-plus to-number-locale (item 6 cols) values_sep set meme-minus to-number-locale (item 7 cols) values_sep set meme-plus-w to-number-locale (item 8 cols) values_sep set meme-minus-w to-number-locale (item 9 cols) values_sep set opinion-previous opinion set influence-previous influence set tx-bonus 0 ;; bornes prudentes if prevalence < 0 [ set prevalence 0 ] if prevalence > 99 [ set prevalence 99 ] if opinion < -1 [ set opinion -1 ] if opinion > 1 [ set opinion 1 ] if influence < 0 [ set influence 0 ] if influence > 1 [ set influence 1 ] ;; type & couleur ifelse opinion < 0 [ set agent-type "Left side" set color red ] [ set agent-type "Right side" set color blue ] if influence = 1 [ set color yellow set meta-agents meta-agents + 1 ] update-3d self ] update-networks apply-link-visibility recolor-links set repet_data true end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; I/O : DATA (simple) — utilisé par in_file_simple ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to data clear-turtles clear-links set meta-agents 0 let tick_to_load choice_iter ifelse (is-list? list_data) [ let filtered_data filter [ row -> first row = tick_to_load ] list_data if empty? filtered_data [ let available remove-duplicates map [row -> first row] 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 ] 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 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; EVENT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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)) ] ] ] ] if use-memes? [ init-memes-from-state ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; UTILITAIRES DIVERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 ;; Meme Saturation (%) 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é + poids ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 ] 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 ] 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)) ] 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 ] let pool base-pool 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Additional reporter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 about 20 hours ago by Pierre-Alain Cotnoir.
Attached files
| File | Type | Description | Last updated | |
|---|---|---|---|---|
| Architecture_Opinion_Dynamics_Simulator_EN_FINAL.pdf | word | Architecture of the Simulator | about 20 hours ago, by Pierre-Alain Cotnoir | Download |
| Sondage 02-2022.csv | data | Survey_model_02-2022 | about 20 hours ago, by Pierre-Alain Cotnoir | Download |
Download this model