FA-65371 / Ecological population dynamics / Open access
Ricker map trajectory and dynamic regime: exponent grouping · case 01
Populations above carrying capacity turn negative instead of being pulled down smoothly.
ROOT CAUSE
The density term multiplies exp(r) instead of sitting inside the exponent.
VERIFIED REPAIR
Restore the exponent grouping rule: `math.exp(r * (1 - n / k))`.
Unsuccessful approach: Dividing (1-N) by K inside the exponent misplaces the crowding term.
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 = [[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: 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: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('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]]),
('regression: 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]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('regression: 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: 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]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('regression: 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: weak growth above K',
(0.5, 200, 350, 5),
['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
('regression: weak growth below K',
(0.7, 200, 20, 5),
['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: two cycle',
(2.2, 100, 30, 6),
['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('control: invalid capacity', (1.0, 0, 10, 3), None),
('regression: weak growth above K',
(0.5, 200, 350, 5),
['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
('regression: weak growth below K',
(0.7, 200, 20, 5),
['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: 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: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('control: invalid capacity', (1.0, 0, 10, 3), None)]]
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 |
|---|---|---|---|
| regression: salmon stock damped | ['damped', [717.0703, 909.2473, 369.8138, 1044.4646, -208.1372, -1126.9578]] | ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]] | Failed |
| regression: superstable r one | ['monotone', [217.4625, 334.0296, 301.3978, 325.4233, 308.8584]] | ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]] | Failed |
| regression: two cycle | ['cycle2', [189.5253, -1531.3015, -225446.152, -4589085079.6969, -1.9006409780069967e+18, -3.2602284814540045e+35]] | ['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]] | Failed |
| regression: period doubling onset exactly 2 | ['cycle2', [177.3373, -1013.3942, -83371.2616, -514212127.2252, -1.953771085285938e+16]] | ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]] | Failed |
| regression: near two | ['damped', [170.3838, -851.3706, -57502.3401, -235148834.2026]] | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | Failed |
| control: neutral empty patch | ['neutral', [0.0, 0.0, 0.0]] | ['neutral', [0.0, 0.0, 0.0]] | Passed |
| control: invalid capacity | None | None | Passed |
SHA-256 / 74ee5a4995d035e20f84eb873a2e227ee9106e450ad9a16939a52a3c2c58aebb
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 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 = [[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: 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: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('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]]),
('regression: 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]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('regression: 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: 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]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('regression: 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: weak growth above K',
(0.5, 200, 350, 5),
['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
('regression: weak growth below K',
(0.7, 200, 20, 5),
['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: two cycle',
(2.2, 100, 30, 6),
['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('control: invalid capacity', (1.0, 0, 10, 3), None),
('regression: weak growth above K',
(0.5, 200, 350, 5),
['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
('regression: weak growth below K',
(0.7, 200, 20, 5),
['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: 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: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('control: invalid capacity', (1.0, 0, 10, 3), None)]]
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 |
|---|---|---|---|
| regression: salmon stock damped | ['damped', [148.3861, 118.9542, 99.6642, 85.9539, 75.6699, 67.6519]] | ['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]] | Failed |
| regression: superstable r one | ['monotone', [82.037, 69.7625, 60.7989, 53.9455, 48.5252]] | ['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]] | Failed |
| regression: two cycle | ['cycle2', [15.8504, 11.4328, 9.0881, 7.6067, 6.5777, 5.8181]] | ['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]] | Failed |
| regression: period doubling onset exactly 2 | ['cycle2', [18.3362, 12.9637, 10.205, 8.4891, 7.3082]] | ['cycle2', [132.8047, 68.9089, 128.3303, 72.8208, 125.4096]] | Failed |
| regression: near two | ['damped', [18.6245, 13.1845, 10.3836, 8.6392]] | ['damped', [129.6553, 72.5035, 124.2836, 77.2161]] | Failed |
| control: neutral empty patch | ['neutral', [0.0, 0.0, 0.0]] | ['neutral', [0.0, 0.0, 0.0]] | Passed |
| control: invalid capacity | None | None | Passed |
SHA-256 / 4268ef614bc2522ee58d44f509d2b55d2c56ccf2b394661b75958bc00a26ad89
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 = [[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: 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: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('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]]),
('regression: 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]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('regression: 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: 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]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('regression: 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: weak growth above K',
(0.5, 200, 350, 5),
['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
('regression: weak growth below K',
(0.7, 200, 20, 5),
['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: two cycle',
(2.2, 100, 30, 6),
['cycle2', [139.9377, 58.1234, 146.0361, 53.0407, 149.0324, 50.6759]]),
('control: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('control: invalid capacity', (1.0, 0, 10, 3), None),
('regression: weak growth above K',
(0.5, 200, 350, 5),
['monotone', [240.5512, 217.36, 208.1284, 203.9417, 201.9419]]),
('regression: weak growth below K',
(0.7, 200, 20, 5),
['monotone', [37.5522, 66.3073, 105.8713, 147.1827, 177.0682]])],
[('regression: salmon stock damped',
(1.5, 1000, 200, 6),
['damped', [664.0234, 1099.1389, 947.2604, 1025.2415, 987.1493, 1006.3622]]),
('regression: superstable r one',
(1.0, 500, 100, 5),
['monotone', [222.5541, 387.6342, 485.3128, 499.78, 500.0]]),
('regression: 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: neutral empty patch', (0.0, 100, 0, 3), ['neutral', [0.0, 0.0, 0.0]]),
('control: invalid capacity', (1.0, 0, 10, 3), None)]]
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 |
|---|---|---|---|
| regression: 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 |
| regression: 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 |
| regression: 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: neutral empty patch | ['neutral', [0.0, 0.0, 0.0]] | ['neutral', [0.0, 0.0, 0.0]] | Passed |
| control: invalid capacity | None | None | Passed |
SHA-256 / 011b53be07787226d3b6afee4e4f427b23214e4b5eb5c2e69535f3ffa45bd73a
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.330675+00:00.
Case digest / 5f45115eb9c8b36c7d104e0024048a794cfaeea50e2f0bb5153a6e6579488b55