"""
How many times can you actually recirculate light through a photonic circuit?

The transcript computes LOSS correctly (0.9^10 ~ 35%, 0.9^100 ~ 0.0027%) but loss is not
the binding constraint -- PRECISION is. And exp03 just measured where the precision floor
sits for this kind of network: ~4 bits.

SNR -> ENOB:  ENOB = (SNR_dB - 1.76) / 6.02
"""
import math
def snr_of(enob): return 6.02 * enob + 1.76
def enob_of(snr): return (snr - 1.76) / 6.02

B0 = 6.0                     # starting ENOB of a good photonic datapath
B_FLOOR = 4.0                # <- measured in exp03: below this, quality falls off a cliff
budget_db = snr_of(B0) - snr_of(B_FLOOR)

print("=" * 76)
print("1. THE PASS BUDGET IS SET BY exp03's 4-BIT FLOOR, NOT BY LOSS")
print("=" * 76)
print(f"""
  start   ENOB {B0:.1f} bits  ->  SNR {snr_of(B0):.1f} dB
  floor   ENOB {B_FLOOR:.1f} bits  ->  SNR {snr_of(B_FLOOR):.1f} dB
  budget  {budget_db:.1f} dB of SNR to spend on recirculation
""")
print(f"{'regime':>44} | {'dB lost/pass':>13} | {'max passes':>11}")
print("-" * 76)
# (a) amplified loop: ASE from n cascaded quantum-limited amplifiers -> OSNR ~ 1/n
n_amp = 10 ** (budget_db / 10)
print(f"{'amplified loop (ideal 3dB-NF, OSNR ~ 1/n)':>44} | {'10log10(n)':>13} | {n_amp:>11.0f}")
# (b) passive loop, thermal/TIA-noise-limited detection: SNR ~ power
for eta in (0.95, 0.90, 0.80):
    db_pass = -10 * math.log10(eta)
    print(f"{'passive loop, eta=%.2f (thermal-limited)' % eta:>44} | {db_pass:>13.3f} | "
          f"{budget_db/db_pass:>11.0f}")
# (c) shot-noise-limited: SNR ~ sqrt(power) -> half the dB penalty
for eta in (0.95, 0.90):
    db_pass = -5 * math.log10(eta)
    print(f"{'passive loop, eta=%.2f (shot-limited)' % eta:>44} | {db_pass:>13.3f} | "
          f"{budget_db/db_pass:>11.0f}")

print(f"""
  So the honest range is roughly {budget_db/(-10*math.log10(0.90)):.0f}-{budget_db/(-5*math.log10(0.95)):.0f} circulations before the datapath falls
  through the 4-bit floor -- NOT hundreds, and nowhere near "1,000 operator applications".
  Amplification does not rescue it: it converts a loss problem into an ASE-noise problem
  with the SAME order of magnitude of headroom.
""")

print("=" * 76)
print("2. AND WHAT ~16-50 PASSES BUYS IS THE THING exp03 SAYS NOT TO BUY")
print("=" * 76)
print("""
  n circulations through ONE physical operator = recurrent depth with a SHARED weight
  matrix. That is exactly exp03's k=1 arm -- the worst use of a memory budget at every
  budget tested except ternary:

      hard k=1 @ 12 bits (72 KiB): 1.8659      <- one operator, reused
      hard k=3 @  4 bits (72 KiB): 1.7085      <- same bytes, three distinct operators
      hard k=6 @  4 bits (144 KiB): 1.6313     <- fully distinct

  The proposal's own fix is correct and is the right lesson from exp03: instantiate a
  DICTIONARY (32-64 operators) and route through it, rather than looping one operator.

  But note what that costs optically: routing among k operators needs an optical switch
  stage per pass -- more insertion loss per pass, which shrinks the pass budget above,
  and a switch reconfiguration per pass.

  And if the route is INPUT-DEPENDENT ("the path of the light is the program"), it hits
  the trilemma in GATE5: you cannot select among operators without measuring something,
  and measuring is the conversion the loop existed to avoid. If the route is FIXED per
  position -- a static program -- it is fine, and it is exactly exp04's `hard` arm,
  which is running now.
""")
