FAILURE MAP
← Case archive

FA-84441 / Betting odds conversion / Open access

Power-method bisection stops too early · case 01

Power-method fair probabilities are off in the third or fourth decimal.

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

ROOT CAUSE

The bisection runs only a handful of iterations.

VERIFIED REPAIR

Run the stipulated 60 bisection steps.

Unsuccessful approach: Twelve steps still leave a bracket too wide for four-decimal output.

Case contract

Remove the bookmaker margin from decimal prices (implied p = 1/d, book = sum p > 1 assumed). multiplicative: p / book. additive: p - (book - 1) / n; if any result is negative return "additive infeasible". power: p ** k with k found by 60 bisection steps on [1, 10] so that the powered probabilities sum to 1 (k = midpoint of the final bracket). Any other method returns "invalid method". Return the fair probabilities formatted "%.4f".

Why this case matters

Pricing models strip margins differently; favourite-longshot bias makes the method matter.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(6):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in fair]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['2.25', '2.59', '6.02', '4.98'], 'power'),
   ['0.3898', '0.3310', '0.1243', '0.1549']),
  ('variant scenario 1', (['2.21', '5.97', '5.73', '4.37'], 'shin'), 'invalid method'),
  ('variant scenario 2',
   (['5.60', '2.48', '3.06', '8.98', '6.08'], 'power'),
   ['0.1432', '0.3590', '0.2832', '0.0841', '0.1305'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations', (['2.08', '1.53'], 'power'), ['0.4068', '0.5932']),
  ('variant scenario 1', (['1.73', '1.75'], 'additive'), ['0.5033', '0.4967']),
  ('variant scenario 2', (['4.18', '3.37', '21.01', '1.64'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['4.47', '4.38', '6.81', '5.54', '4.19'], 'power'),
   ['0.2199', '0.2245', '0.1437', '0.1770', '0.2348']),
  ('variant scenario 1', (['7.72', '1.13'], 'additive'), ['0.1223', '0.8777']),
  ('variant scenario 2', (['3.94', '3.80', '3.70', '27.86', '3.84'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['4.42', '5.10', '2.85', '2.90', '22.13'], 'power'),
   ['0.1905', '0.1624', '0.3108', '0.3048', '0.0316']),
  ('variant scenario 1', (['2.69', '6.86', '1.50'], 'shin'), 'invalid method'),
  ('variant scenario 2', (['7.14', '1.15'], 'additive'), ['0.1352', '0.8648'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['1.71', '10.88', '2.39'], 'power'),
   ['0.5505', '0.0702', '0.3793']),
  ('variant scenario 1',
   (['5.00', '2.76', '7.09', '5.56', '4.51'], 'additive'),
   ['0.1790', '0.3413', '0.1201', '0.1589', '0.2007']),
  ('variant scenario 2', (['4.59', '2.91', '1.91'], 'power'), ['0.1912', '0.3136', '0.4953'])]]
for label, args, expected in cases[N - 1]:
    check(label, run(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 multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5331', '0.4762']['0.5285', '0.4715']Failed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: power iterations['0.3746', '0.3159', '0.1138', '0.1431']['0.3898', '0.3310', '0.1243', '0.1549']Failed
variant scenario 1invalid methodinvalid methodPassed
variant scenario 2['0.1582', '0.3783', '0.3021', '0.0954', '0.1449']['0.1432', '0.3590', '0.2832', '0.0841', '0.1305']Failed

SHA-256 / 3b071c38d88b11c06ec0915c64e8b2346419c6b6b19631a49ebba17ee1964074

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(12):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in fair]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['2.25', '2.59', '6.02', '4.98'], 'power'),
   ['0.3898', '0.3310', '0.1243', '0.1549']),
  ('variant scenario 1', (['2.21', '5.97', '5.73', '4.37'], 'shin'), 'invalid method'),
  ('variant scenario 2',
   (['5.60', '2.48', '3.06', '8.98', '6.08'], 'power'),
   ['0.1432', '0.3590', '0.2832', '0.0841', '0.1305'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations', (['2.08', '1.53'], 'power'), ['0.4068', '0.5932']),
  ('variant scenario 1', (['1.73', '1.75'], 'additive'), ['0.5033', '0.4967']),
  ('variant scenario 2', (['4.18', '3.37', '21.01', '1.64'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['4.47', '4.38', '6.81', '5.54', '4.19'], 'power'),
   ['0.2199', '0.2245', '0.1437', '0.1770', '0.2348']),
  ('variant scenario 1', (['7.72', '1.13'], 'additive'), ['0.1223', '0.8777']),
  ('variant scenario 2', (['3.94', '3.80', '3.70', '27.86', '3.84'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['4.42', '5.10', '2.85', '2.90', '22.13'], 'power'),
   ['0.1905', '0.1624', '0.3108', '0.3048', '0.0316']),
  ('variant scenario 1', (['2.69', '6.86', '1.50'], 'shin'), 'invalid method'),
  ('variant scenario 2', (['7.14', '1.15'], 'additive'), ['0.1352', '0.8648'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['1.71', '10.88', '2.39'], 'power'),
   ['0.5505', '0.0702', '0.3793']),
  ('variant scenario 1',
   (['5.00', '2.76', '7.09', '5.56', '4.51'], 'additive'),
   ['0.1790', '0.3413', '0.1201', '0.1589', '0.2007']),
  ('variant scenario 2', (['4.59', '2.91', '1.91'], 'power'), ['0.1912', '0.3136', '0.4953'])]]
for label, args, expected in cases[N - 1]:
    check(label, run(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 multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5286', '0.4715']['0.5285', '0.4715']Failed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: power iterations['0.3899', '0.3311', '0.1243', '0.1549']['0.3898', '0.3310', '0.1243', '0.1549']Failed
variant scenario 1invalid methodinvalid methodPassed
variant scenario 2['0.1431', '0.3588', '0.2830', '0.0840', '0.1304']['0.1432', '0.3590', '0.2832', '0.0841', '0.1305']Failed

SHA-256 / 1d377d4cb5dade60ce98936ae690f9c306a2b7881f26913335114696710e8cee

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in fair]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['2.25', '2.59', '6.02', '4.98'], 'power'),
   ['0.3898', '0.3310', '0.1243', '0.1549']),
  ('variant scenario 1', (['2.21', '5.97', '5.73', '4.37'], 'shin'), 'invalid method'),
  ('variant scenario 2',
   (['5.60', '2.48', '3.06', '8.98', '6.08'], 'power'),
   ['0.1432', '0.3590', '0.2832', '0.0841', '0.1305'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations', (['2.08', '1.53'], 'power'), ['0.4068', '0.5932']),
  ('variant scenario 1', (['1.73', '1.75'], 'additive'), ['0.5033', '0.4967']),
  ('variant scenario 2', (['4.18', '3.37', '21.01', '1.64'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['4.47', '4.38', '6.81', '5.54', '4.19'], 'power'),
   ['0.2199', '0.2245', '0.1437', '0.1770', '0.2348']),
  ('variant scenario 1', (['7.72', '1.13'], 'additive'), ['0.1223', '0.8777']),
  ('variant scenario 2', (['3.94', '3.80', '3.70', '27.86', '3.84'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['4.42', '5.10', '2.85', '2.90', '22.13'], 'power'),
   ['0.1905', '0.1624', '0.3108', '0.3048', '0.0316']),
  ('variant scenario 1', (['2.69', '6.86', '1.50'], 'shin'), 'invalid method'),
  ('variant scenario 2', (['7.14', '1.15'], 'additive'), ['0.1352', '0.8648'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power iterations',
   (['1.71', '10.88', '2.39'], 'power'),
   ['0.5505', '0.0702', '0.3793']),
  ('variant scenario 1',
   (['5.00', '2.76', '7.09', '5.56', '4.51'], 'additive'),
   ['0.1790', '0.3413', '0.1201', '0.1589', '0.2007']),
  ('variant scenario 2', (['4.59', '2.91', '1.91'], 'power'), ['0.1912', '0.3136', '0.4953'])]]
for label, args, expected in cases[N - 1]:
    check(label, run(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 multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5285', '0.4715']['0.5285', '0.4715']Passed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: power iterations['0.3898', '0.3310', '0.1243', '0.1549']['0.3898', '0.3310', '0.1243', '0.1549']Passed
variant scenario 1invalid methodinvalid methodPassed
variant scenario 2['0.1432', '0.3590', '0.2832', '0.0841', '0.1305']['0.1432', '0.3590', '0.2832', '0.0841', '0.1305']Passed

SHA-256 / 0b3e4a0e9fc71c171bb6067840e1676cddbdd5f9635fe50f8f8fee4cf029fd2e

Verification & scope

Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any operator, exchange or regulator rule set. 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:50:31.026000+00:00.

Case digest / 741764ff9a1810cb1bda731bec3f933666928c0bcb4ac4829b93d852904aeda8