FA-65366 / Ecological population dynamics / Open access
Ricker map trajectory and dynamic regime: period-doubling onset · case 01
The first period-doubling at r=2 is reported as a damped approach.
ROOT CAUSE
The damped band includes r=2.
VERIFIED REPAIR
Restore the period-doubling onset rule: `elif r < 2:`.
Unsuccessful approach: Rounding r to one decimal pushes values just below 2 into the cycle band.
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 == 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]]),
('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]])],
[('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
('control: 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)],
[('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
('control: 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: 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: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
('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]]),
('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 |
| regression: period doubling onset exactly 2 | ['damped', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]] | ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]] | Failed |
| regression: near two | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | Passed |
| control: chaotic | ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]] | ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]] | Passed |
| control: neutral | ['neutral', [60.0, 60.0, 60.0]] | ['neutral', [60.0, 60.0, 60.0]] | Passed |
SHA-256 / 5a25b665eb0b8d3225ed2a905853de132f0b31b2ae4a156d0f419e8430aa27d8
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:
regime = 'neutral'
elif r <= 1:
regime = 'monotone'
elif round(r, 1) < 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]]),
('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]])],
[('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
('control: 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)],
[('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
('control: 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: 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: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
('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]]),
('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 |
| regression: 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 |
| regression: near two | ['cycle2', [129.6553, 72.5035, 124.2836, 77.2161]] | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | Failed |
| control: chaotic | ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]] | ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]] | Passed |
| control: neutral | ['neutral', [60.0, 60.0, 60.0]] | ['neutral', [60.0, 60.0, 60.0]] | Passed |
SHA-256 / d3d4a9d86fd0581104abd392d61a9962ed460afe10529549e51a24314d60434c
3 / The verified repair
Exit 0"""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:
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]]),
('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]])],
[('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
('control: 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)],
[('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.0]]),
('control: 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: 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: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: near two', (1.96, 100, 40, 4), ['damped', [129.6553, 72.5035, 124.2836, 77.2161]]),
('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]]),
('regression: period doubling onset exactly 2',
(2.0, 100, 40, 5),
['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]]),
('regression: 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]]),
('control: neutral', (0.0, 100, 60, 3), ['neutral', [60.0, 60.0, 60.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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 |
| regression: 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 |
| regression: near two | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | Passed |
| control: chaotic | ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]] | ['complex', [148.7973, 34.421, 246.1736, 3.0674, 56.1939]] | Passed |
| control: neutral | ['neutral', [60.0, 60.0, 60.0]] | ['neutral', [60.0, 60.0, 60.0]] | Passed |
SHA-256 / 07b01479e51dcead1f86078996a16d5c8aa089d5f5edf2c89480fbd942c1c48f
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.330882+00:00.
Case digest / c2d2401a016243d20572468ad6617c98cb089d6e5794c6b3d6630425f4661f68