diff --git a/research/unitary-cycle-optimal-conditioning/README.md b/research/unitary-cycle-optimal-conditioning/README.md new file mode 100644 index 0000000000..a2f36e8bf5 --- /dev/null +++ b/research/unitary-cycle-optimal-conditioning/README.md @@ -0,0 +1,214 @@ +# Best conditioning of a unitary-coupled observation cycle + +This contribution was produced by Nick Petalas. Apache-2.0. + +For any number of banks `W>=2`, internal dimension `d>=1`, and real +`00`. The full condition number is at +least the condition number within any one such root orbit. We minimize one +orbit first, then characterize when every orbit can attain the minimum. + +### Even number of banks + +The orbit is closed under negation. Let `t` be the angular distance of its +nearest point to `+1`, with `0<=t<=δ=π/W`. Its extreme cosines are +`cos(t)` and `-cos(t)`. Its squared condition number is + +\[ + R(t)=\frac{a+b\cos t}{a-b\cos t}. +\] + +It decreases strictly on this interval away from zero and is minimized +uniquely at `t=δ`. The root orbit then satisfies `z^W=-1`. The minimum is +`(a+bc)/(a-bc)`. This reasoning also covers `W=2`, where `c=0`. + +### Odd number of banks + +Here `W>=3`. With the same `t` and `δ`, the distance of the nearest orbit +point to `-1` is `δ-t`. The squared condition number is + +\[ + R(t)=\frac{a+b\cos t}{a-b\cos(\delta-t)}. +\] + +The sign of its derivative is the sign of + +\[ + a\{\sin(\delta-t)-\sin t\}+b\sin\delta + =2a\cos(\delta/2)\sin(\delta/2-t)+b\sin\delta. +\] + +The last expression is strictly decreasing on `[0,δ]`, is positive at zero, +and negative at `δ`, since `a>b>0`. Thus the sole interior stationary point +is a maximum, and the minimum lies at an endpoint. The endpoint values are + +\[ + R(0)=\frac{a+b}{a-bc},\qquad R(\delta)=\frac{a+bc}{a-b}. +\] + +Their denominators are positive, and +`(a+bc)(a-bc)-(a+b)(a-b)=b²(1-c²)>0`. +Therefore `R(δ)>R(0)` and zero is the unique minimizer. Its root orbit has +`z^W=1`, giving the stated odd formula. + +### Attainment and equality for arbitrary dimension + +If the complete matrix attains the lower bound, every individual root orbit +must do so too: each orbit's largest-to-smallest ratio lies between one and +the full ratio, and is already bounded below by the optimum. The unique +one-orbit minimizers force every eigenvalue of `H` to be `-1` for even `W`, +or `+1` for odd `W`. A unitary matrix with only that eigenvalue is the +corresponding scalar matrix. Conversely that scalar `H` makes all the root +orbits identical, so it attains the bound. + +For any prescribed first `W-1` unitary edges, choose + +\[ + U_{W-1}=(U_0\cdots U_{W-2})^*\,\sigma I, + \qquad \sigma=(-1)^{W+1}. +\] + +Then `H=σI` and the optimum is attained. This is an explicit algebraic +construction; it does not assert that a source native port can implement the +changed closing edge at its existing price. + +## Reproduction and finite evidence + +From the repository root, with the Python standard library only: + +```sh +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -I -W error -B research/unitary-cycle-optimal-conditioning/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -I -O -W error -B research/unitary-cycle-optimal-conditioning/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/research_package.py --package research/unitary-cycle-optimal-conditioning +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/check_research_commit.py --package research/unitary-cycle-optimal-conditioning --check-source-history +``` + +Any CPython 3.12 executable can replace the displayed interpreter. The direct +verifier computes complete rational Gram characteristic polynomials from +literal bank matrices, independently of the root-orbit formula. It compares +them with Chebyshev predictions, checks exact attaining fixtures, exercises +noncommuting edges and nonmonomial rational orthogonal edges, and rejects +boundary mutations. Its generated JSON receipt binds all package sources by +SHA256. Use `--receipt PATH` to save it outside the checkout. +The exact enumeration checks 756 scalar cycles, including 378 attaining +products, and 576 two-dimensional cycles, including 72 attainers. Forty-two +noncommuting rational gauge fixtures and eleven boundary controls pass. The +all-size and arbitrary-complex claims depend on the written proof, rather +than the finite fixtures. See `TASK.json` for the exact verification domain. + +## Scope, budget and limitations + +The original `complex-rank-shape-decoder` card is changed to a local conditioning +result for a specified observation interface. Current source binding, rather +than the card's historical packing baseline, is the orientation control. The +source-bound positive control passed on base +`624de9dc66858af0945e5f8a0942488d62280d43`, priority revision 7. +The independent inquiry is the changed-coupling optimum; no predecessor audit +is its deliverable. Live PRs, recent claims, local reservations, merged searches +and distinctive main-tree README searches found no same optimum in their stated +coverage. Sparse notes, unsearched diffs and unpublished work limit coverage. +[Advance claim](https://github.com/CrocSwap/integer-mult-bounds/discussions/1166#discussioncomment-19134008). + +This result assumes equal edge magnitudes `r`, Euclidean bank norms and unitary +edge factors. It does not optimize unequal gains, bank-dependent weighting, +nonunitary couplings, or intermediate execution norms. The norm formula applies +to the completed observation matrix only. Source-compatible native emission, +dirty-bank ownership/restoration, full caller costs, stock, compiler, physical +storage/tape, rounding and analytic recovery remain open and unpriced. Lean, +Docker, predecessor scientific replays and selected-frontier replay are unrun. +Independent human and formal proof-kernel review are unclaimed. + +Power-of-ten inspection: no recursion; every computation is bounded by fixed +fixture limits `W<=13,d<=2` and matrix size at most 26. Functions stay below 60 +lines. Explicit exceptions enforce scientific checks under optimized Python. +Python's rational arithmetic and collection allocation are a managed-runtime +deviation from fixed steady-state allocation; finite fixture sizes bound live +matrix storage, while exact coefficient sizes are determined by the fixed +rational inputs. There is no external runtime input except an optional receipt +path. Warning-strict ordinary and optimized runs are registered. + +## Open next questions + +- Can one actual native port change its closing coupling to the attaining + product while retaining all independent targets and restoring dirty state? + Start with a literal three-bank word and its complete paid invoice. A + source-compatible realization is missing; the algebra alone does not provide it. +- Does a nonuniform gain profile improve the complete interface after paying + its normalization and precision costs? First fix those physical prices and + one concrete gain vector. Equal-gain spectral normality does not settle that + different problem, and no expansion is justified without that ledger. diff --git a/research/unitary-cycle-optimal-conditioning/SOURCES.json b/research/unitary-cycle-optimal-conditioning/SOURCES.json new file mode 100644 index 0000000000..80f74a60e2 --- /dev/null +++ b/research/unitary-cycle-optimal-conditioning/SOURCES.json @@ -0,0 +1,18 @@ +{ + "schema_version": 1, + "base_commit": "624de9dc66858af0945e5f8a0942488d62280d43", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "c35482cd9035843b15a634cc8276a7e1e40e8395", + "sha256": "6fe0a099b89aa2aed796a13c3a21dafc63f3388ebf397464e44e0451893b9375" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "f126dd2e2dad2b669e75d1d0d0bd05c600725602", + "sha256": "f7a48bfa2659b88378282a8eee7d9fe52cdf505594124c4d1686b58510fffd72" + } + ] +} diff --git a/research/unitary-cycle-optimal-conditioning/TASK.json b/research/unitary-cycle-optimal-conditioning/TASK.json new file mode 100644 index 0000000000..77c73f5f33 --- /dev/null +++ b/research/unitary-cycle-optimal-conditioning/TASK.json @@ -0,0 +1,159 @@ +{ + "schema_version": 1, + "task_id": "complex-rank-shape-decoder", + "priority_revision": 7, + "base_commit": "624de9dc66858af0945e5f8a0942488d62280d43", + "original_card": { + "id": "complex-rank-shape-decoder", + "question": "Can a decoder deliver the local paid mass in fewer, larger-rank children (block frame climbs instead of rank-1 to rank-3 steps)?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/complex-local-word-ceiling/README.md", + "research/complex-decoder-field-extension-seed44/README.md", + "research/complex-frame-pair-decoders/README.md", + "research/selected-k8-unrestricted-ends/README.md", + "research/eisenstein-reduction-copy-floor/README.md" + ], + "methods": [ + "Find one exact small decoding identity whose frame path climbs in blocks, and price its complete per-call profile.", + "Bound the best effective child rank achievable for one fixed support alphabet, including copies, frames and restoration." + ], + "acceptance_gate": "A per-call local profile, with all copied information, frames and restoration counted, whose ceiling exceeds the selected word's by at least 5%; masked or overcomplete supports must change an assumption of the eight-term all-pairs bound. A scoped local result may be retained without a complete supplier. Expanding it into further construction rounds requires the family-level budget and obligation gate in research-family-status.md; an optimistic passing relaxation alone is not acceptance.", + "first_step": { + "command": [ + "python3", + "-B", + "research/complex-local-word-ceiling/verify.py" + ], + "expected": "PASS_COMPLEX_LOCAL_WORD_CEILING", + "inspect": "Read the selected word's per-call local profile, its packing ceiling and the lever table; run levers.py for the ideal budget of the lever you target.", + "scope": "Positive control and planning budget only; this is not a new construction or full cold replay." + }, + "first_experiment": "Before any synthesis, write the candidate per-call local profile (and centre charge / unpaid coordinates if changed) and screen it with ceiling.ceiling(); reject it if even the ideal ceiling does not beat the selected word's by your stated margin. Ideal budget: rank-16 delivery is 2.31x (levers.py).", + "bottleneck_link": "Rank-1 children are about half of recursive cost; the selected word's effective child rank is about 3.9. Larger-rank delivery lowers recursive cost per unit of paid mass.", + "allowed_variations": [ + "One masked, overcomplete or block decoder family with exact labels and supports.", + "A scoped lower bound on effective rank for one alphabet.", + "If the coverage law, template or guard changes, derive an applicable fully charged replacement bound instead of applying the incumbent ceiling outside its scope." + ], + "scope_change_triggers": [ + "Repacking idle remainders of an unchanged word (covered by the packing ceiling).", + "Repeating the eight-term all-pairs search inside its proved scope.", + "Only changing helper terminal subspaces and monotone frames within the fixed scalar word, entrances and cleanup contract already covered by #1995/#2013.", + "Searching below C=40 in the #2017 Eisenstein binary scalar-rectangle or fixed-support block-linear additive pairing model; specify a changed premise instead. This bound does not cover every complex decoder.", + "Continuing a partial cost improvement while leaving the same unpriced consumer, restoration or central-readout obligation unresolved; refresh the family expansion decision first. Local product-retiming evidence has a narrow scope and is not a ban on changed graphs or contracts." + ], + "overlap_terms": [ + "rank shape", + "block climb", + "masked decoder", + "overcomplete", + "effective rank" + ] + }, + "scope_status": "changed", + "actual_scope": "Exact minimum Euclidean condition number of I+rS over all unitary-coupled W-bank cycles, including equality cases and an attaining changed three-bank interface.", + "scope_change_reason": "The card is narrowed to an original algebraic conditioning step for changed cyclic observation interfaces, following the distinct complete-cascade setting in Clear1nsight PR4842. No paid-profile gain or predecessor audit is the deliverable.", + "bottleneck_link": "A changed complete observation interface needs a precision budget. The exact optimum distinguishes achievable conditioning by changing couplings from free bankwise basis changes; actual native cost remains unknown.", + "budget_minutes": 60, + "stop_rule": "Ship the first proved optimum with bounded exact corroboration; do not expand native synthesis or optimize unequal gains.", + "outcome": "completed", + "evidence": "README proof for every W>=2,d>=1,0 None: + if not condition: + raise ValueError(message) + + +def eye(n: int) -> Matrix: + require(1 <= n <= MAX_BANKS * MAX_INTERNAL, 'matrix dimension') + return tuple(tuple(F(i == j) for j in range(n)) for i in range(n)) + + +def transpose(a: Matrix) -> Matrix: + return tuple(zip(*a)) + + +def multiply(a: Matrix, b: Matrix) -> Matrix: + bt = transpose(b) + return tuple(tuple(sum((x * y for x, y in zip(row, col)), F(0)) + for col in bt) for row in a) + + +def scaled(a: Matrix, c: F) -> Matrix: + return tuple(tuple(c * x for x in row) for row in a) + + +def add(a: Matrix, b: Matrix) -> Matrix: + return tuple(tuple(x + y for x, y in zip(ar, br)) for ar, br in zip(a, b)) + + +def trace(a: Matrix) -> F: + return sum((a[i][i] for i in range(len(a))), F(0)) + + +def trim(p: Poly) -> Poly: + q = list(p) + for _ in range(len(q) - 1): + if q[-1]: + break + q.pop() + return tuple(q) + + +def padd(p: Poly, q: Poly) -> Poly: + n = max(len(p), len(q)) + return trim(tuple((p[i] if i < len(p) else F(0)) + + (q[i] if i < len(q) else F(0)) for i in range(n))) + + +def pscale(p: Poly, c: F) -> Poly: + return trim(tuple(x * c for x in p)) + + +def pmul(p: Poly, q: Poly) -> Poly: + out = [F(0)] * (len(p) + len(q) - 1) + for i, x in enumerate(p): + for j, y in enumerate(q): + out[i + j] += x * y + return trim(tuple(out)) + + +def peval(p: Poly, x: F) -> F: + out = F(0) + for c in reversed(p): + out = out * x + c + return out + + +def pdiv(p: Poly, q: Poly) -> tuple[Poly, Poly]: + require(q != (F(0),), 'zero polynomial divisor') + rem = list(p) + out = [F(0)] * max(1, len(p) - len(q) + 1) + for _ in range(max(0, len(p) - len(q) + 1)): + rem = list(trim(tuple(rem))) + if len(rem) < len(q) or rem == [F(0)]: + break + k, c = len(rem) - len(q), rem[-1] / q[-1] + out[k] = c + for j, a in enumerate(q): + rem[j + k] -= c * a + return trim(tuple(out)), trim(tuple(rem)) + + +def derivative(p: Poly) -> Poly: + return trim(tuple(F(i) * p[i] for i in range(1, len(p))) or (F(0),)) + + +def squarefree(p: Poly) -> Poly: + a, b = p, derivative(p) + for _ in range(len(p)): + if b == (F(0),): + break + _, rem = pdiv(a, b) + a, b = b, rem + require(b == (F(0),), 'polynomial gcd budget') + q, rem = pdiv(p, a) + require(rem == (F(0),), 'squarefree exact division') + return pscale(q, 1 / q[-1]) + + +def sturm(p: Poly) -> tuple[Poly, ...]: + p = squarefree(p) + chain = [p, derivative(p)] + for _ in range(len(p)): + if chain[-1] == (F(0),): + chain.pop() + break + _, rem = pdiv(chain[-2], chain[-1]) + chain.append(pscale(rem, F(-1))) + require(chain[-1] != (F(0),), 'Sturm budget') + return tuple(chain) + + +def variations(chain: tuple[Poly, ...], x: F) -> int: + signs = [1 if y > 0 else -1 for p in chain if (y := peval(p, x))] + return sum(signs[i] != signs[i - 1] for i in range(1, len(signs))) + + +@lru_cache(maxsize=128) +def extreme_roots(p: Poly, r: F) -> tuple[F, F, F, F]: + chain = sturm(p) + left, right = F(0), (1 + r) ** 2 + 1 + v0 = variations(chain, left) + count = v0 - variations(chain, right) + require(count >= 1, 'positive Gram roots') + bounds = [] + for target in (1, count): + lo, hi = left, right + for _ in range(48): + mid = (lo + hi) / 2 + if v0 - variations(chain, mid) >= target: + hi = mid + else: + lo = mid + bounds.extend((lo, hi)) + require(bounds[0] > 0, 'positive minimum root bracket') + return tuple(bounds) + + +def characteristic(a: Matrix) -> Poly: + """Faddeev-LeVerrier on the literal matrix, without cycle information.""" + n = len(a) + ident = eye(n) + b = ident + descending = [F(1)] + for k in range(1, n + 1): + ab = multiply(a, b) + c = -trace(ab) / k + descending.append(c) + b = add(ab, scaled(ident, c)) + require(b == scaled(ident, F(0)), 'Cayley-Hamilton residual') + return tuple(reversed(descending)) + + +def validate(edges: tuple[Matrix, ...], r: F) -> int: + require(2 <= len(edges) <= MAX_BANKS, 'bank count') + require(0 < r < 1, 'coupling magnitude') + d = len(edges[0]) + require(1 <= d <= MAX_INTERNAL, 'internal dimension') + for u in edges: + require(len(u) == d and all(len(row) == d for row in u), 'edge shape') + require(multiply(transpose(u), u) == eye(d), 'unitary edge') + return d + + +def literal(edges: tuple[Matrix, ...], r: F) -> tuple[Matrix, Matrix, Matrix]: + d = validate(edges, r) + w, n = len(edges), len(edges) * d + s = [[F(0)] * n for _ in range(n)] + h = eye(d) + for j, u in enumerate(edges): + h = multiply(h, u) + for a in range(d): + for b in range(d): + s[j * d + a][((j + 1) % w) * d + b] = u[a][b] + s = tuple(tuple(row) for row in s) + require(multiply(transpose(s), s) == eye(n), 'whole-cycle unitarity') + a = add(eye(n), scaled(s, r)) + gram = multiply(transpose(a), a) + return s, gram, h + + +def predicted(w: int, r: F, h: Matrix) -> Poly: + """det(2*r^W*T_W((t-a)/(2r))*I-r^W*(H+H^T)).""" + x = (-(1 + r * r) / (2 * r), 1 / (2 * r)) + t0, t1 = (F(1),), x + for _ in range(2, w + 1): + t0, t1 = t1, padd(pscale(pmul(x, t1), F(2)), pscale(t0, F(-1))) + base = pscale(t1, 2 * r ** w) + c = scaled(add(h, transpose(h)), r ** w) + if len(h) == 1: + return padd(base, (-c[0][0],)) + determinant = c[0][0] * c[1][1] - c[0][1] * c[1][0] + return padd(padd(pmul(base, base), pscale(base, -trace(c))), (determinant,)) + + +def inspect(edges: tuple[Matrix, ...], r: F) -> tuple[Poly, Matrix, Matrix]: + _, gram, h = literal(edges, r) + direct = characteristic(gram) + require(direct == predicted(len(edges), r, h), 'cycle spectrum polynomial') + return direct, gram, h + + +def orthogonal_group() -> tuple[Matrix, ...]: + out = [] + for perm in itertools.permutations(range(2)): + for signs in itertools.product((-1, 1), repeat=2): + out.append(tuple(tuple(F(signs[i] if j == perm[i] else 0) + for j in range(2)) for i in range(2))) + require(len(set(out)) == 8, 'complete signed-permutation alphabet') + return tuple(out) + + +def exact_small_optimum(poly: Poly, gram: Matrix, h: Matrix, w: int, r: F) -> bool: + sigma = F(-1 if w % 2 == 0 else 1) + attaining = h == scaled(eye(len(h)), sigma) + a = 1 + r * r + if attaining: + if w == 2: + require(gram == scaled(eye(len(gram)), a), 'even perfect conditioning') + else: + high, low = a + 2 * r, a - r + ident = eye(len(gram)) + residual = multiply(add(gram, scaled(ident, -high)), + add(gram, scaled(ident, -low))) + require(residual == scaled(ident, F(0)), 'odd attaining Gram polynomial') + require(gram != scaled(ident, high) and gram != scaled(ident, low), + 'both extremal eigenspaces occur') + return True + low_lo, low_hi, high_lo, _ = extreme_roots(poly, r) + optimum_squared = F(1) if w == 2 else (1 + r) ** 2 / (a - r) + require(low_lo > 0 and high_lo / low_hi > optimum_squared, + 'strict nonattaining condition-number gap') + return False + + +def scalar_census() -> dict[str, int]: + fixtures = winners = 0 + for w in range(2, 8): + for r in (F(1, 3), F(1, 2), F(3, 4)): + for signs in itertools.product((-1, 1), repeat=w): + edges = tuple(((F(s),),) for s in signs) + p, gram, h = inspect(edges, r) + fixtures += 1 + winners += h == ((F((-1) ** (w + 1)),),) + if w <= 3: + exact_small_optimum(p, gram, h, w, r) + return {'scalar_fixtures': fixtures, 'scalar_attaining_products': winners} + + +def matrix_census() -> dict[str, int]: + fixtures = winners = 0 + for w in (2, 3): + for edges in itertools.product(orthogonal_group(), repeat=w): + p, gram, h = inspect(edges, F(1, 2)) + winners += exact_small_optimum(p, gram, h, w, F(1, 2)) + fixtures += 1 + return {'matrix_fixtures': fixtures, 'matrix_attainers': winners} + + +def gauge_fixtures() -> int: + rot = ((F(3, 5), F(-4, 5)), (F(4, 5), F(3, 5))) + flip = ((F(1), F(0)), (F(0), F(-1))) + fixtures = 0 + for w in (*range(2, 8), 13): + q = tuple(rot if j % 3 == 0 else flip if j % 3 == 1 else eye(2) + for j in range(w)) + for h in (scaled(eye(2), F((-1) ** (w + 1))), rot, flip): + edges = tuple(multiply(q[j], transpose(q[j + 1])) for j in range(w - 1)) + edges += (multiply(multiply(q[-1], h), transpose(q[0])),) + for r in (F(1, 3), F(1, 2)): + p, _, product = inspect(edges, r) + require(product == multiply(multiply(q[0], h), transpose(q[0])), + 'ordered-product gauge conjugation') + if w <= 3: + _, gram, _ = literal(edges, r) + exact_small_optimum(p, gram, product, w, r) + fixtures += 1 + require(multiply(rot, flip) != multiply(flip, rot), 'noncommuting fixture') + return fixtures + + +def rejected(call, message: str) -> None: + try: + call() + except ValueError: + return + raise ValueError('control was accepted: ' + message) + + +def controls() -> int: + unit = (((F(1),),),) * 3 + for r in (F(0), F(1), F(-1, 2)): + rejected(lambda: literal(unit, r), 'invalid gain') + rejected(lambda: literal(unit[:1], F(1, 2)), 'one bank') + rejected(lambda: literal(((), ()) , F(1, 2)), 'zero dimension') + rejected(lambda: literal((eye(1), eye(2)), F(1, 2)), 'unequal dimensions') + rejected(lambda: literal((((F(1), F(0)),),) * 2, F(1, 2)), 'nonsquare') + rejected(lambda: literal((((F(2),),),) * 2, F(1, 2)), 'nonunitary') + p, gram, _ = inspect(unit, F(1, 2)) + require(p == (F(-81, 64), F(63, 16), F(-15, 4), F(1)), 'three-bank fixture') + corrupt = add(gram, scaled(eye(3), F(1, 8))) + require(characteristic(corrupt) != p, 'Gram mutation detected') + require(F(81, 49) < 3, 'loop-only number cannot certify changed fixture') + bad = tuple(((-F(1),),) for _ in range(3)) + bp, bg, bh = inspect(bad, F(1, 2)) + require(not exact_small_optimum(bp, bg, bh, 3, F(1, 2)), 'odd product sign') + return 11 + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--receipt', type=Path) + args = parser.parse_args() + stats = scalar_census() | matrix_census() + stats['gauge_fixtures'] = gauge_fixtures() + stats['controls'] = controls() + require(stats['scalar_fixtures'] == 756, 'scalar enumeration completeness') + require(stats['matrix_fixtures'] == 576, 'matrix enumeration completeness') + package = Path(__file__).resolve().parent + receipt = {'schema': 'unitary-cycle-optimal-conditioning/v1', + 'claim_type': 'scoped algebraic proof with exact finite corroboration', + 'no_new_kappa': True, 'statistics': stats, + 'sha256': {name: hashlib.sha256((package / name).read_bytes()).hexdigest() + for name in SOURCE_NAMES}} + data = json.dumps(receipt, indent=2, sort_keys=True) + '\n' + if args.receipt is not None: + require(not args.receipt.resolve().is_relative_to(package), + 'receipt must be outside the package') + written = args.receipt.write_text(data) + require(written == len(data), 'complete receipt write') + print(data, end='') + print('PASS_UNITARY_CYCLE_OPTIMAL_CONDITIONING', + ' '.join(f'{k}={v}' for k, v in stats.items()), 'no_new_kappa') + + +if __name__ == '__main__': + main()