#!/usr/bin/env python3 """MIT. Independent sensitivity checks; Python standard library only. Download cases-v1.json and results-v1.json beside this script, then run it. """ import json import math from pathlib import Path root = Path(__file__).resolve().parent cases = json.loads((root / 'cases-v1.json').read_text())['cases'] rows = {r['id']: r for r in json.loads((root / 'results-v1.json').read_text())['results']} def model_win(cp): return 100.0 / (1.0 + math.exp(-0.00368208 * max(-1000, min(1000, cp)))) def accuracy(before, after): if after >= before: return 100.0 return max(0.0, min(100.0, 103.1668100711649 * math.exp(-0.04354415386753951 * (before - after)) - 3.166924740191411 + 1.0)) maximum_error = 0.0 for case in cases: sign = 1 if case['mover'] == 'white' else -1 before = sign * case['beforeCpWhite'] after = sign * case['afterCpWhite'] wb, wa = model_win(before), model_win(after) expected = {'beforeCpMover': before, 'afterCpMover': after, 'centipawnLoss': before-after, 'modelWinBefore': wb, 'modelWinAfter': wa, 'modelWinLoss': wb-wa, 'moveAccuracy': accuracy(wb, wa)} for key, value in expected.items(): error = abs(rows[case['id']][key] - value) maximum_error = max(maximum_error, error) assert error < 1e-10, (case['id'], key, error) for row in rows.values(): if row['group'] == 'matrix' and row['mover'] == 'white': mirror = rows[row['id'].replace('white-', 'black-', 1)] assert abs(row['moveAccuracy'] - mirror['moveAccuracy']) < 1e-10 assert len(rows) == len(cases) == 136 print(json.dumps({'passed': len(cases), 'mirrored_pairs': 66, 'maximum_absolute_error': maximum_error, 'tolerance': 1e-10})) # SPDX-License-Identifier: MIT # Copyright (c) 2026 ChessAnalysis # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE.