sim14 โ Heterogeneous Agents
Open the interactive visualization โ renders the grid heatmap (play/pause, step slider) and all metric charts from
results.json.
One-line: Agents carry a structure ID; deposits are tagged with the depositor's ID; co-presence checks for material from TWO DISTINCT IDs โ so a 1-seed control is structurally zero, regardless of agent wander.
The question
sim13 showed that agent wander (not the torus leak) causes false boundaries: agents on a torus deposit material in both halves, creating real co-presence from a single structure. Every spatial filter โ diffusion (sim12), direct-material max filter (sim13) โ picks up wander material because it detects WHERE material is, not WHOSE it is.
sim14 tests agent-level fidelity: each termite carries a structure ID (0=left, 1=right). Deposits go into material_by_id[agent.id]. Co-presence = min(dilate(material_by_id[0]), dilate(material_by_id[1])). For a single seed, all agents have id=0, so material_by_id[1] is zero everywhere โ co-presence = 0 โ B = 0. This is a structural guarantee โ no spatial filter can achieve it.
Design
- HeteroTermites: first n//2 agents get id=0 (left), rest get id=1 (right). For 1-seed control, all get id=0.
- Material tracking:
material_by_id[0]andmaterial_by_id[1]track deposits by ID. Totalfield.material = sum(for compatibility with sim09 curvature/on_surface/metrics). - Deposits:
material_by_id[agent.id] += pelletANDfield.material += pellet. - Excavation: proportional removal from both ID arrays.
- Co-presence:
min(dilate_no_x_wrap(material_by_id[0]), dilate_no_x_wrap(material_by_id[1]))โ sim13's max filter, but on ID-separated arrays. - Boundary B: identical growth/decay to sim12 (
B_new = B*(1-decay) + growth*co_presence). - Suppression: identical to sim12 (
p_dep *= (1 - g*B_norm/(1+B_norm))).
Results
8-Condition experiment (seed 42, g=0.9)
| Condition | L2 | Outcome | Stable | H7 | Cells | L_retain | R_retain |
|---|---|---|---|---|---|---|---|
| hetero 2-seed | YES | coexist | YES | NO | 167 | 0.55 | 0.49 |
| hetero 1-seed | NO | none | NO | YES | 3936 | 0.95 | 1.00 |
| passive 2-seed | YES | coexist | NO | YES | 1779 | 0.99 | 1.00 |
| passive 1-seed | YES | none | YES | YES | 1727 | 0.95 | 1.00 |
| none 2-seed | NO | none | NO | YES | 4832 | 1.00 | 1.00 |
| none 1-seed | NO | none | NO | YES | 4494 | 0.99 | 1.00 |
| shadow 2-seed | YES | coexist | YES | YES | 3714 | 0.99 | 1.00 |
| shadow 1-seed | YES | coexist | YES | YES | 3129 | 0.99 | 1.00 |
4-Seed robustness sweep
| Mode | Seeds | L2 | Coexist | Stable | H7 | Clean |
|---|---|---|---|---|---|---|
| hetero | 2 | 4/4 | 2/4 | 2/4 | 0/4 | 2/4 |
| hetero | 1 | 0/4 | 0/4 | 0/4 | 4/4 | โ |
| shadow | 2 | 4/4 | 4/4 | 4/4 | 4/4 | 2/4 |
| shadow | 1 | 4/4 | 2/4 | 2/4 | 4/4 | โ |
| passive | 2 | 4/4 | 2/4 | 1/4 | 4/4 | 2/4 |
| passive | 1 | 4/4 | 1/4 | 2/4 | 4/4 | โ |
| none | 2 | 0/4 | 0/4 | 0/4 | 4/4 | 0/4 |
| none | 1 | 0/4 | 0/4 | 0/4 | 4/4 | โ |
Key findings
The 1-seed control is 0/4 on ALL metrics. l2_crossed=0/4, coexist=0/4, stable=0/4, B_max=0.0 across all seeds. This is the first time the false-positive rate has been structurally zero. No spatial filter achieves this โ sim12's shadow has 4/4 l2_false positives, sim13's direct-material has 4/4 l2 and 1/4 coexist.
Clean composition: 2/4 โ matching shadow and passive. The heterogeneous approach achieves the same clean rate, but through a different mechanism: eliminating false positives (0/4 in 1-seed) rather than generating enough true positives to overcome them.
H7 crossing suppressed: 0/4. The ID-based boundary is too strong โ it suppresses growth below the H7 crossing threshold (cells: 167 vs 3714 for shadow). The cost of structural specificity is a boundary that is too aggressive.
The memory-specificity trade-off is broken on the specificity axis but not on the strength axis. Agent IDs eliminate false positives (specificity), but the boundary's strength (memory) needs tuning โ the same trade-off in a new form.
Selftest
All 7 parts pass: ID co-presence high for 2 seeds (1.83), EXACTLY zero for 1 seed (max=0.0), B grows/decays, B=0 for 1 seed, full run produces ID metrics, B=0 throughout 1-seed run, determinism verified.
Comparison to previous simulations
| sim | 1-seed l2_false | 1-seed coexist | 2-seed coexist | clean | mechanism |
|---|---|---|---|---|---|
| sim11 (passive) | 4/4 | 1/4 | 2/4 | 2/4 | passive lateral inhibition |
| sim12 (shadow) | 4/4 | 2/4 | 4/4 | 2/4 | diffused-shadow autopoietic |
| sim13 (direct) | 4/4 | 1/4 | 1/4 | 1/4 | direct-material max filter |
| sim14 (hetero) | 0/4 | 0/4 | 2/4 | 2/4 | ID-tagged agents |
sim14 is the first approach where the 1-seed control fires 0/4 on l2_crossed. The structural guarantee (id1 material = 0 for a single seed) is absolute โ it cannot be broken by agent wander, torus topology, or boundary radius.
Limitations
- H7 crossing suppressed (0/4). The boundary is too strong at g=0.9. A lower inh_gain might allow both crossing and composition โ but that is a parameter-tuning question, not a mechanism question.
- 2/4 coexist, not higher. The same rate as passive and shadow. The heterogeneous approach improves specificity without improving the raw coexistence rate.
- Agents still wander freely. The IDs tag deposits, not movement. Agents from the left can still wander to the right and deposit there โ their deposits carry id=0, which doesn't create false co-presence, but it does mean the boundary's spatial location is still determined by where agents deposit, which is influenced by wander.
Files
sim14.pyโ the simulation (imports sim13/sim12/sim11/sim10/sim09)results.jsonโ 8-condition experimentoutput/robustness_sweep.jsonโ 4-seed robustness sweepvisualize.htmlโ interactive visualization
Run
python3 sim14.py selftest # 7-part selftest
python3 sim14.py run # 8-condition experiment
python3 sim14.py robustness # 4-seed robustness sweep
Density Scaling (Session 41)
Queued-topic #119: does scaling n_termites with grid area rescue the 160ร160 grid's degradation?
| grid | nT | density | jit | l2(2s) | coexist | stable | h7(2s) | l2(1s) | cells |
|---|---|---|---|---|---|---|---|---|---|
| 80 | 150 | 23.44 | 0.0 | 4/4 | 4/4 | 4/4 | 4/4 | 0/4 | 1770 |
| 80 | 150 | 23.44 | 10.0 | 4/4 | 4/4 | 4/4 | 4/4 | 0/4 | 1970 |
| 80 | 150 | 23.44 | 20.0 | 2/4 | 1/4 | 0/4 | 4/4 | 0/4 | 2022 |
| 160 | 150 | 5.86 | 0.0 | 4/4 | 4/4 | 3/4 | 4/4 | 0/4 | 1674 |
| 160 | 150 | 5.86 | 10.0 | 4/4 | 4/4 | 1/4 | 2/4 | 0/4 | 1685 |
| 160 | 150 | 5.86 | 20.0 | 4/4 | 0/4 | 0/4 | 0/4 | 2/4 | 1216 |
| 160 | 300 | 11.72 | 0.0 | 4/4 | 4/4 | 4/4 | 4/4 | 0/4 | 2744 |
| 160 | 300 | 11.72 | 10.0 | 4/4 | 2/4 | 2/4 | 4/4 | 0/4 | 3393 |
| 160 | 300 | 11.72 | 20.0 | 4/4 | 0/4 | 0/4 | 4/4 | 3/4 | 3324 |
| 160 | 600 | 23.44 | 0.0 | 4/4 | 4/4 | 4/4 | 4/4 | 0/4 | 4515 |
| 160 | 600 | 23.44 | 10.0 | 4/4 | 4/4 | 3/4 | 4/4 | 2/4 | 5780 |
| 160 | 600 | 23.44 | 20.0 | 4/4 | 2/4 | 0/4 | 4/4 | 4/4 | 6748 |
H7 fully rescued by density (4/4 at all jitter). Composition partially rescued (4/4 at jit=0, 3/4 stable at jit=10, 2/4 at jit=20). 1-seed structural guarantee leaks at 160ร600 (absolute-size effect โ bigger structure overwhelms midline). See density_sweep.py.
N550 Plateau (Session 66)
Queued-topic #157/#161: does g* ever hit zero at n=550โ600 (~31% grid fill)?
| Label | n | density | g | l2(2s) | coexist | stable | h7(2s) | clean | full | cf | l2(1s) | h7(1s) | cells | fill% |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| n550_g003 | 550 | 21.48 | 0.003 | 4/4 | 4/4 | 3/4 | 4/4 | 4/4 | 3/4 | 0.600 | 2/4 | 4/4 | 7848 | 30.7% |
| n550_g005 | 550 | 21.48 | 0.005 | 4/4 | 4/4 | 3/4 | 4/4 | 4/4 | 3/4 | 0.637 | 2/4 | 4/4 | 7795 | 30.4% |
| n550_g010 | 550 | 21.48 | 0.010 | 4/4 | 4/4 | 4/4 | 4/4 | 4/4 | 4/4 | 0.712 | 2/4 | 4/4 | 7775 | 30.4% |
| n600_g003 | 600 | 23.44 | 0.003 | 4/4 | 3/4 | 2/4 | 4/4 | 3/4 | 2/4 | 0.537 | 2/4 | 4/4 | 8047 | 31.4% |
| n600_g005 | 600 | 23.44 | 0.005 | 4/4 | 4/4 | 1/4 | 4/4 | 4/4 | 1/4 | 0.450 | 2/4 | 4/4 | 7977 | 31.2% |
| n600_g010 | 600 | 23.44 | 0.010 | 4/4 | 4/4 | 3/4 | 4/4 | 4/4 | 3/4 | 0.538 | 2/4 | 4/4 | 7960 | 31.1% |
g does NOT hit zero.* The 1/โn scaling holds at ~31% fill. H7=4/4 at all combos. n=550 g=0.01 achieves 4/4 full (cf=0.712). The LSW "droplet dissolves" prediction is not realized โ ~31% fill is far below the 2D percolation threshold (~59%). The 43rd mechanism: the 1/โn scaling is conservative (actual optimal > predicted). The 30th mechanism (stability-density trade-off) continues at n=600. See n550_plateau_sweep.py.
No-inhibition control: n=550 g=0 โ 3/4 coexist, 1/4 stable, cells=15691 (61% fill). n=600 g=0 โ 0/4 coexist, cells=17020 (66% fill). The boundary remains necessary at every density.
N700 Plateau (Session 67)
Queued-topic #157 (continuation): does g* hit zero at n=700โ800 (~33โ35% grid fill)? The 1/โn formula predicts NEGATIVE g* at n=700โ800 โ the 43rd mechanism says actual > predicted.
| Label | n | density | g | l2(2s) | coexist | stable | h7(2s) | clean | full | cf | l2(1s) | h7(1s) | cells | fill% |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| n700_g003 | 700 | 27.34 | 0.003 | 4/4 | 4/4 | 1/4 | 4/4 | 4/4 | 1/4 | 0.325 | 1/4 | 4/4 | 8538 | 33.4% |
| n700_g005 | 700 | 27.34 | 0.005 | 4/4 | 4/4 | 2/4 | 4/4 | 4/4 | 2/4 | 0.500 | 1/4 | 4/4 | 8479 | 33.1% |
| n700_g010 | 700 | 27.34 | 0.010 | 4/4 | 4/4 | 2/4 | 4/4 | 4/4 | 2/4 | 0.500 | 1/4 | 4/4 | 8474 | 33.1% |
| n800_g003 | 800 | 31.25 | 0.003 | 4/4 | 4/4 | 3/4 | 4/4 | 4/4 | 3/4 | 0.575 | 3/4 | 4/4 | 8832 | 34.5% |
| n800_g005 | 800 | 31.25 | 0.005 | 4/4 | 4/4 | 2/4 | 4/4 | 4/4 | 2/4 | 0.500 | 3/4 | 4/4 | 8852 | 34.6% |
| n800_g010 | 800 | 31.25 | 0.010 | 4/4 | 1/4 | 2/4 | 4/4 | 1/4 | 0/4 | 0.450 | 3/4 | 4/4 | 8813 | 34.4% |
g does NOT hit zero.* The 43rd mechanism (conservative scaling) confirmed: the 1/โn formula predicts NEGATIVE g* but actual g* is positive. H7=4/4 at all 8 combos. n=800 g=0.003 achieves 3/4 full (cf=0.575). The 30th mechanism (stability-density trade-off) worsens at n=800 g=0.01 (coexist 1/4, 3/4 fragmented). The 1-seed structural guarantee degrades: 1/4 at n=700, 3/4 at n=800. See n700_plateau_sweep.py.
No-inhibition control: n=700 g=0 โ 0/4 coexist, cells=18954 (74% fill). n=800 g=0 โ 2/4 coexist (measurement artifact at 82% fill), cells=20960. The boundary remains necessary at every density tested.
N900 Plateau (Session 68)
Queued-topic #157 (continuation): does g* hit zero at n=900โ1000 (~36% grid fill)? The 1/โn formula predicts deeply NEGATIVE g* (g*โ-0.44 to -0.47) โ the 43rd mechanism says actual > predicted.
| Label | n | density | g | l2(2s) | coexist | stable | h7(2s) | clean | full | cf | l2(1s) | h7(1s) | cells | fill% |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| n900_g003 | 900 | 35.16 | 0.003 | 4/4 | 4/4 | 0/4 | 4/4 | 4/4 | 0/4 | 0.300 | 1/4 | 4/4 | 9164 | 35.8% |
| n900_g005 | 900 | 35.16 | 0.005 | 4/4 | 3/4 | 2/4 | 4/4 | 3/4 | 2/4 | 0.450 | 1/4 | 4/4 | 9017 | 35.2% |
| n900_g010 | 900 | 35.16 | 0.010 | 4/4 | 4/4 | 2/4 | 4/4 | 4/4 | 2/4 | 0.525 | 1/4 | 4/4 | 9077 | 35.5% |
| n1000_g003 | 1000 | 39.06 | 0.003 | 4/4 | 4/4 | 2/4 | 4/4 | 3/4 | 1/4 | 0.475 | 4/4 | 4/4 | 9357 | 36.6% |
| n1000_g005 | 1000 | 39.06 | 0.005 | 4/4 | 4/4 | 2/4 | 4/4 | 3/4 | 1/4 | 0.450 | 4/4 | 4/4 | 9337 | 36.5% |
| n1000_g010 | 1000 | 39.06 | 0.010 | 4/4 | 4/4 | 2/4 | 4/4 | 3/4 | 2/4 | 0.400 | 4/4 | 4/4 | 9356 | 36.5% |
g does NOT hit zero.* The 43rd mechanism (conservative scaling) confirmed at a third density range: the 1/โn formula predicts deeply NEGATIVE g* but actual g* is positive. H7=4/4 at all 8 combos. n=900 g=0.01 achieves 2/4 full (cf=0.525). The 30th mechanism (stability-density trade-off) persists: stable 0โ2/4. The 1-seed structural guarantee is stochastic, not monotonic: 1/4 at n=900, 4/4 at n=1000 โ the 12th member does not degrade monotonically. See n900_plateau_sweep.py.
No-inhibition control: n=900 g=0 โ 0/4 coexist, cells=22240 (87% fill). n=1000 g=0 โ 0/4 coexist (1/4 l2_crossed artifact at 92% fill), cells=23519. The boundary remains necessary โ it prevents percolation.