widths.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. # metrics/widths.py — width metrics (Py3.8 safe typing)
  2. import math
  3. from typing import List, Dict, Any
  4. def ci_radius_hoeffding(n: int, delta: float = 0.1) -> float:
  5. if n <= 0:
  6. return 1.0
  7. return math.sqrt(0.5 * math.log(2.0 / delta) / n)
  8. def _widths_for_details_single_pair(det: Dict[str, Any], delta: float) -> List[float]:
  9. alloc = det.get("alloc_by_path", {}) or {}
  10. est = det.get("est_fid_by_path", {}) or {}
  11. widths: List[float] = []
  12. for pid, m in est.items():
  13. n = int(alloc.get(pid, 0))
  14. r = ci_radius_hoeffding(n, delta)
  15. lb = max(0.0, float(m) - r)
  16. ub = min(1.0, float(m) + r)
  17. widths.append(ub - lb)
  18. return widths
  19. def sum_widths_all_links(per_pair_details: List[Dict[str, Any]], delta: float = 0.1) -> float:
  20. s = 0.0
  21. for det in per_pair_details:
  22. for w in _widths_for_details_single_pair(det, delta):
  23. s += float(w)
  24. return s
  25. def sum_minwidths_perpair(per_pair_details: List[Dict[str, Any]], delta: float = 0.1) -> float:
  26. s = 0.0
  27. for det in per_pair_details:
  28. widths = _widths_for_details_single_pair(det, delta)
  29. if widths:
  30. s += float(min(widths))
  31. else:
  32. s += 1.0 # 未推定ペアは1.0を加算(保守的)
  33. return s
  34. def sum_weighted_widths_all_links(per_pair_details: List[Dict[str, Any]], importance_list: List[float], delta: float = 0.1) -> float:
  35. s = 0.0
  36. for d, det in enumerate(per_pair_details):
  37. I = float(importance_list[d]) if d < len(importance_list) else 1.0
  38. for w in _widths_for_details_single_pair(det, delta):
  39. s += I * float(w)
  40. return s
  41. def sum_weighted_min_widths_perpair(per_pair_details: List[Dict[str, Any]], importance_list: List[float], delta: float = 0.1) -> float:
  42. s = 0.0
  43. for d, det in enumerate(per_pair_details):
  44. I = float(importance_list[d]) if d < len(importance_list) else 1.0
  45. widths = _widths_for_details_single_pair(det, delta)
  46. if widths:
  47. s += I * float(min(widths))
  48. else:
  49. s += I * 1.0
  50. return s