FAILURE MAP
← Case archive

FA-65376 / Ecological population dynamics / Open access

Ricker map trajectory and dynamic regime: neutral growth · case 01

A population with zero intrinsic growth is reported as monotone convergence.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The r==0 neutral case is missing and falls into the monotone band.

THE FAILURE

The r==0 neutral case is missing and falls into the monotone band.

Unsuccessful approach: Requiring an occupied patch makes an empty neutral patch monotone.

Case contract

Regime by r: r<0 decline, r==0 neutral, 0<r<=1 monotone, 1<r<2 damped, 2<=r<2.526 cycle2, else complex; trajectory N[t+1]=N*exp(r*(1-N/K)) rounded 4; None for K<=0 or N0<0.

Why this case matters

Population projections set harvest quotas, conservation status and pest-control timing; a wrong update order, boundary or rate conversion silently changes management advice.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(r, k, n0, years):
    if k <= 0 or n0 < 0:
        return None
    if r < 0:
        regime = 'decline'
    elif r <= 1:
        regime = 'monotone'
    elif r < 2:
        regime = 'damped'
    elif r < 2.526:
        regime = 'cycle2'
    else:
        regime = 'complex'
    n = float(n0)
    traj = []
    for _ in range(years):
        n = n * math.exp(r * (1 - n / k))
        traj.append(round(n, 4))
    return [regime, traj]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('control: superstable r one',
   (1.0, 500, 100, 5),
   ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
  ('control: two cycle',
   (2.2, 100, 30, 6),
   ['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
  ('control: period doubling onset exactly 2',
   (2.0, 100, 40, 5),
   ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
  ('control: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]])],
 [('control: period doubling onset exactly 2',
   (2.0, 100, 40, 5),
   ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
  ('control: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
  ('control: chaotic', (3.0, 100, 10, 5), ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
  ('control: declining', (-0.3, 100, 80, 4), ['decline', [75.3412, 69.9688, 63.9407, 57.3848]]),
  ('control: invalid capacity', (1.0, 0, 10, 3), None)],
 [('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
  ('control: declining', (-0.3, 100, 80, 4), ['decline', [75.3412, 69.9688, 63.9407, 57.3848]]),
  ('control: invalid capacity', (1.0, 0, 10, 3), None),
  ('control: weak growth above K',
   (0.5, 200, 350, 5),
   ['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
  ('control: weak growth below K',
   (0.7, 200, 20, 5),
   ['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
 [('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('control: superstable r one',
   (1.0, 500, 100, 5),
   ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
  ('control: invalid capacity', (1.0, 0, 10, 3), None),
  ('control: weak growth above K',
   (0.5, 200, 350, 5),
   ['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
  ('control: weak growth below K',
   (0.7, 200, 20, 5),
   ['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
 [('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('control: superstable r one',
   (1.0, 500, 100, 5),
   ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
  ('control: two cycle',
   (2.2, 100, 30, 6),
   ['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
  ('control: period doubling onset exactly 2',
   (2.0, 100, 40, 5),
   ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
  ('control: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
control: salmon stock damped['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]Passed
control: superstable r one['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]Passed
control: two cycle['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]Passed
control: period doubling onset exactly 2['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]Passed
control: near two['damped', [129.6553, 72.5035, 124.2836, 77.2161]]['damped', [129.6553, 72.5035, 124.2836, 77.2161]]Passed
regression: neutral['monotone', [60.0, 60.0, 60.0]]['neutral', [60.0, 60.0, 60.0]]Failed
regression: neutral empty patch['monotone', [0.0, 0.0, 0.0]]['neutral', [0.0, 0.0, 0.0]]Failed

SHA-256 / 5d50b002019b58b5c881edb19ce63bf66d654328f171c8b6bf8cf35176fbc420

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(r, k, n0, years):
    if k <= 0 or n0 < 0:
        return None
    if r < 0:
        regime = 'decline'
    elif r == 0 and n0 > 0:
        regime = 'neutral'
    elif r <= 1:
        regime = 'monotone'
    elif r < 2:
        regime = 'damped'
    elif r < 2.526:
        regime = 'cycle2'
    else:
        regime = 'complex'
    n = float(n0)
    traj = []
    for _ in range(years):
        n = n * math.exp(r * (1 - n / k))
        traj.append(round(n, 4))
    return [regime, traj]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('control: superstable r one',
   (1.0, 500, 100, 5),
   ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
  ('control: two cycle',
   (2.2, 100, 30, 6),
   ['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
  ('control: period doubling onset exactly 2',
   (2.0, 100, 40, 5),
   ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
  ('control: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]])],
 [('control: period doubling onset exactly 2',
   (2.0, 100, 40, 5),
   ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
  ('control: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
  ('control: chaotic', (3.0, 100, 10, 5), ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
  ('control: declining', (-0.3, 100, 80, 4), ['decline', [75.3412, 69.9688, 63.9407, 57.3848]]),
  ('control: invalid capacity', (1.0, 0, 10, 3), None)],
 [('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
  ('control: declining', (-0.3, 100, 80, 4), ['decline', [75.3412, 69.9688, 63.9407, 57.3848]]),
  ('control: invalid capacity', (1.0, 0, 10, 3), None),
  ('control: weak growth above K',
   (0.5, 200, 350, 5),
   ['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
  ('control: weak growth below K',
   (0.7, 200, 20, 5),
   ['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
 [('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('control: superstable r one',
   (1.0, 500, 100, 5),
   ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
  ('control: invalid capacity', (1.0, 0, 10, 3), None),
  ('control: weak growth above K',
   (0.5, 200, 350, 5),
   ['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
  ('control: weak growth below K',
   (0.7, 200, 20, 5),
   ['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
 [('control: salmon stock damped',
   (1.5, 1000, 200, 6),
   ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
  ('control: superstable r one',
   (1.0, 500, 100, 5),
   ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
  ('control: two cycle',
   (2.2, 100, 30, 6),
   ['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
  ('control: period doubling onset exactly 2',
   (2.0, 100, 40, 5),
   ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
  ('control: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
  ('regression: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
  ('regression: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
control: salmon stock damped['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]Passed
control: superstable r one['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]Passed
control: two cycle['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]Passed
control: period doubling onset exactly 2['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]Passed
control: near two['damped', [129.6553, 72.5035, 124.2836, 77.2161]]['damped', [129.6553, 72.5035, 124.2836, 77.2161]]Passed
regression: neutral['neutral', [60.0, 60.0, 60.0]]['neutral', [60.0, 60.0, 60.0]]Passed
regression: neutral empty patch['monotone', [0.0, 0.0, 0.0]]['neutral', [0.0, 0.0, 0.0]]Failed

SHA-256 / 06d7bd3a6ab55ed0a774d5d47e70c90dc04a88ed165615b7497f446a49bc1f7d

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 7 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

Deterministic bounded teaching model with a stipulated contract; not a validated scientific or public-health modelling library. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:47:33.376641+00:00.

Case digest / c402e6ae004fe9d4f562c07e868a16d7970afd6ccb1b39b867c9c59ea900975a