100 lines
4.1 KiB
Python
100 lines
4.1 KiB
Python
"""Stage 22 - the comparison a practitioner actually faces.
|
|
|
|
Every comparison so far gave the constant an oracle: the best mu of a grid,
|
|
chosen with knowledge of the scenario and the noise profile. That is the
|
|
right bar for "can measurement beat perfect tuning?", and the answer is no,
|
|
0 of 12.
|
|
|
|
But reporting only that bar is its own distortion, the mirror image of
|
|
reporting only a bar we pass. A deployable controller does not know the
|
|
scenario. The question a practitioner faces is: I must pick mu once, for a
|
|
device that will meet conditions I have not seen - how does a fixed choice
|
|
compare with measuring?
|
|
|
|
So this file asks the same twelve cells a different, and equally
|
|
pre-registered, question:
|
|
|
|
a single mu, fixed across ALL cells (as a shipped device would have),
|
|
against the similarity rule, which is fixed across all cells too because
|
|
it has nothing to fix.
|
|
|
|
The constant is still given an advantage: it is the best single value over
|
|
the whole grid, chosen with hindsight over all twelve cells - a device maker
|
|
who guessed perfectly on the first try. What it is not given is a different
|
|
value per scenario.
|
|
|
|
Both bars are reported together. Neither alone is the answer.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
|
|
from anc.rules import CosineSimilarity, Fixed, KwongJohnston, Measured
|
|
from simroot.pure import PURE_SIMS
|
|
from stage20_prediction import MU_GRID, PROFILES, SIGNALS, score
|
|
|
|
CELLS = [(sig, gen, pn, prof, kind)
|
|
for sig, gen in SIGNALS for pn, prof, kind in PROFILES]
|
|
|
|
|
|
def member(name):
|
|
r = CosineSimilarity()
|
|
r.S = None if name is None else PURE_SIMS[name]
|
|
return r
|
|
|
|
|
|
def per_cell(rule):
|
|
return [score(rule, gen, prof) for _s, gen, _pn, prof, _k in CELLS]
|
|
|
|
|
|
def main():
|
|
print(__doc__.split("Both bars")[0])
|
|
print("=" * 90)
|
|
|
|
sim = per_cell(member("cbrt"))
|
|
var = per_cell(Measured())
|
|
kj = per_cell(KwongJohnston())
|
|
fixed = {mu: per_cell(Fixed(mu)) for mu in MU_GRID}
|
|
|
|
# bar 1: the per-cell oracle - a different constant for every scenario
|
|
oracle_cell = [max(fixed[mu][i] for mu in MU_GRID) for i in range(len(CELLS))]
|
|
# bar 2: the best SINGLE constant across all cells, chosen with hindsight
|
|
best_single_mu = max(MU_GRID, key=lambda mu: sum(fixed[mu]))
|
|
single = fixed[best_single_mu]
|
|
|
|
print(f"{'signal':11s}{'profile':17s}{'per-cell oracle':>17s}"
|
|
f"{'best single mu':>16s}{'similarity':>12s}{'KJ':>8s}")
|
|
print("-" * 90)
|
|
for i, (s, _g, pn, _p, _k) in enumerate(CELLS):
|
|
print(f"{s:11s}{pn:17s}{oracle_cell[i]:>17.2f}{single[i]:>16.2f}"
|
|
f"{sim[i]:>12.2f}{kj[i]:>8.2f}", flush=True)
|
|
print("-" * 90)
|
|
n = len(CELLS)
|
|
print(f"{'mean':28s}{sum(oracle_cell) / n:>17.2f}{sum(single) / n:>16.2f}"
|
|
f"{sum(sim) / n:>12.2f}{sum(kj) / n:>8.2f}")
|
|
print(f"\n the best single constant over all twelve cells is "
|
|
f"mu = {best_single_mu:g}")
|
|
|
|
w_oracle = sum(1 for i in range(n) if sim[i] > oracle_cell[i])
|
|
w_single = sum(1 for i in range(n) if sim[i] > single[i])
|
|
w_kj = sum(1 for i in range(n) if sim[i] > kj[i])
|
|
w_var = sum(1 for i in range(n) if sim[i] > var[i])
|
|
print(f"\n similarity beats the per-cell oracle on {w_oracle:>2d}/{n}"
|
|
f" (mean margin {sum(sim[i] - oracle_cell[i] for i in range(n)) / n:+.2f} dB)")
|
|
print(f" similarity beats the best single constant on {w_single:>2d}/{n}"
|
|
f" (mean margin {sum(sim[i] - single[i] for i in range(n)) / n:+.2f} dB)")
|
|
print(f" similarity beats Kwong-Johnston on {w_kj:>2d}/{n}"
|
|
f" (mean margin {sum(sim[i] - kj[i] for i in range(n)) / n:+.2f} dB)")
|
|
print(f" similarity beats the variance rule on {w_var:>2d}/{n}"
|
|
f" (mean margin {sum(sim[i] - var[i] for i in range(n)) / n:+.2f} dB)")
|
|
|
|
print("\n Every arbitrary constant, cell by cell:")
|
|
print(f" {'mu':>6s}{'mean dB':>10s}{'cells where similarity wins':>30s}")
|
|
for mu in MU_GRID:
|
|
w = sum(1 for i in range(n) if sim[i] > fixed[mu][i])
|
|
print(f" {mu:>6g}{sum(fixed[mu]) / n:>10.2f}{w:>25d}/{n}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|