"""Offline numerical comparison; timings are local measurements, not API latency.""" from dataclasses import replace import json import math from pathlib import Path from statistics import median import sys from time import perf_counter from mcm26b.geometry import (Measurement, solve, smallest_enclosing_circle, first_bearing_candidate_disk) from mcm26b.geometry.localization import _enclosing_circle_reference ROOT = Path(__file__).resolve().parents[1] def timed(function, points, repeats): durations = [] for _ in range(repeats): start = perf_counter() result = function(points) durations.append(perf_counter()-start) return result, median(durations)*1000 def main(): timings = [] for size in [4, 20, 60]: points = [(20*math.cos(i*math.tau/size), 20*math.sin(i*math.tau/size)) for i in range(size)] old, old_ms = timed(_enclosing_circle_reference, points, 3) new, new_ms = timed(smallest_enclosing_circle, points, 11) timings.append(dict(vertices=size, reference_ms=old_ms, incremental_ms=new_ms, speedup=old_ms/new_ms, radius_difference_m=abs(old[1]-new[1]))) source = next((ROOT/'output/q1/practice').glob('*_observations.json')) rows = json.loads(source.read_text(encoding='utf-8'))['measurements'] observations = [Measurement(**m) for m in rows] sensitivity = [] for margin in [0, 0.005]: ms = [replace(m, half_angle_deg=m.half_angle_deg+margin) for m in observations] result, duration = timed(solve, ms, 31) cert = result['clearance_certificate'] sensitivity.append(dict(additional_half_angle_deg=margin, solve_ms=duration, diameter_m=result['diameter_m'], mec_radius_m=result['minimum_enclosing_circle']['radius_m'], diameter_circle_excess_m=result['diameter_circle']['max_excess_m'], clearance_margin_m=cert['remaining_margin_m'])) report = dict( python=sys.version.split()[0], timing_method='median perf_counter; warm local process', timing_scope='MEC only; not whole solver speedup or simulator/network performance', circle_benchmarks=timings, practice_sensitivity=sensitivity, q2_first_bearing_certificate=first_bearing_candidate_disk(Measurement(0, 0, 0, 1.005))) output = ROOT/'output/q1/optimization_report.json' output.write_text( json.dumps(report, ensure_ascii=False, indent=2, allow_nan=False)+'\n', encoding='utf-8') print(json.dumps(report, ensure_ascii=False, indent=2)) if __name__ == '__main__': main()