From 08980925c5ad66a7fe8233fd0d27561190477cfb Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 6 Nov 2026 07:15:14 -0500 Subject: [PATCH 1/5] wai-quantum: the reference implementation's T counts, as test data gridsynth_oracle.py runs pygridsynth 1.0.1, the reference implementation of the Ross-Selinger algorithm that arXiv:2506.03094 cites, on the four rotation angles of that paper's 10 x 10 Ising program at its 5e-9 and on 128 angles over (-pi, pi), at nine precisions from 1e-1 to 1e-13, and writes the angle, the precision (as the doubles both sides parse), its denominator exponent and its T count. The output is committed as tests/data/rz_gridsynth_oracle.csv. CI does not run the script and nothing depends on pygridsynth; it ran on the Linux build host. Changelog: none Co-Authored-By: Claude Opus 5.5 --- .../quantum-rz-oracle/gridsynth_oracle.py | 79 ++ .../tests/data/rz_gridsynth_oracle.csv | 1193 +++++++++++++++++ 2 files changed, 1272 insertions(+) create mode 100644 wai/tools/quantum-rz-oracle/gridsynth_oracle.py create mode 100644 wai/wai-quantum/tests/data/rz_gridsynth_oracle.csv diff --git a/wai/tools/quantum-rz-oracle/gridsynth_oracle.py b/wai/tools/quantum-rz-oracle/gridsynth_oracle.py new file mode 100644 index 000000000..e3cb907aa --- /dev/null +++ b/wai/tools/quantum-rz-oracle/gridsynth_oracle.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +"""gridsynth_oracle.py: the reference T counts that the engine's z-rotation +synthesiser (wai/wai-quantum/src/engine/synth/rz.rs) is held to. + +For each angle and precision it runs pygridsynth 1.0.1, the reference +implementation of the Ross–Selinger algorithm that arXiv:2506.03094 cites, and +prints one CSV row: the angle and the precision as the doubles both sides use +(Python's repr, which Rust parses back to the same bits), pygridsynth's +denominator exponent and its T count. The output is +wai/wai-quantum/tests/data/rz_gridsynth_oracle.csv. CI does not run this +script and nothing depends on pygridsynth: the CSV is the oracle's answer, +committed, and `engine::synth::rz`'s tests read it. + + python3 -m venv /tmp/pgs && /tmp/pgs/bin/pip install "pygridsynth==1.0.1" mpmath + /tmp/pgs/bin/python gridsynth_oracle.py > rz_gridsynth_oracle.csv + +The angles: +- the four rotation angles of the 10 × 10 Ising program of arXiv:2506.03094 + (Appendix A.10: a fourth-order product formula, Δ = 0.25, J = g = 1), at + its ε = 5·10⁻⁹ and at every precision below; +- 128 angles spread over (−π, π) by the golden ratio, θᵢ = −π + 2π·frac(i·φ), + none within 10⁻⁶ of a multiple of π/4 (those the engine writes exactly); +at ε = 10⁻¹, 10⁻², 10⁻³, 10⁻⁴, 10⁻⁵, 10⁻⁷, 10⁻⁹, 10⁻¹¹ and 10⁻¹³. +""" +import io +import math +import multiprocessing +import contextlib +import sys + +import mpmath +from pygridsynth.gridsynth import gridsynth_gates +from pygridsynth.gridsynth import gridsynth + +PRECISIONS = [1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-7, 1e-9, 1e-11, 1e-13] + + +def ising_angles(): + gamma = 1.0 / (4.0 - 4.0 ** (1.0 / 3.0)) + delta = 0.25 + mid = (1.0 - 4.0 * gamma) * delta + return [("ising zz", gamma * delta), ("ising x", 2.0 * gamma * delta), ("ising zz middle", mid), ("ising x middle", 2.0 * mid)] + + +def swept_angles(n=128): + phi = (1.0 + math.sqrt(5.0)) / 2.0 + out = [] + i = 1 + while len(out) < n: + theta = -math.pi + 2.0 * math.pi * math.fmod(i * phi, 1.0) + q = theta / (math.pi / 4.0) + if abs(q - round(q)) > 1e-6: + out.append((f"sweep {len(out) + 1}", theta)) + i += 1 + return out + + +def run(job): + name, theta, eps = job + mpmath.mp.dps = 128 + with contextlib.redirect_stdout(io.StringIO()): + u = gridsynth(theta=mpmath.mpf(theta), epsilon=mpmath.mpf(eps)) + gates = gridsynth_gates(theta=mpmath.mpf(theta), epsilon=mpmath.mpf(eps)) + return (name, repr(theta), repr(eps), u.k, gates.count("T")) + + +def main(): + jobs = [(name, theta, 5e-9) for name, theta in ising_angles()] + for eps in PRECISIONS: + jobs += [(name, theta, eps) for name, theta in ising_angles() + swept_angles()] + with multiprocessing.Pool(int(sys.argv[1]) if len(sys.argv) > 1 else 8) as pool: + rows = pool.map(run, jobs, chunksize=1) + print("name,theta,epsilon,k,t_count") + for row in rows: + print(",".join(str(x) for x in row)) + + +if __name__ == "__main__": + main() diff --git a/wai/wai-quantum/tests/data/rz_gridsynth_oracle.csv b/wai/wai-quantum/tests/data/rz_gridsynth_oracle.csv new file mode 100644 index 000000000..8810eae8e --- /dev/null +++ b/wai/wai-quantum/tests/data/rz_gridsynth_oracle.csv @@ -0,0 +1,1193 @@ +name,theta,epsilon,k,t_count +ising zz,0.10362269294859393,5e-09,44,86 +ising x,0.20724538589718786,5e-09,41,80 +ising zz middle,-0.1644907717943757,5e-09,43,84 +ising x middle,-0.3289815435887514,5e-09,42,82 +ising zz,0.10362269294859393,0.1,0,0 +ising x,0.20724538589718786,0.1,6,10 +ising zz middle,-0.1644907717943757,0.1,0,0 +ising x middle,-0.3289815435887514,0.1,5,8 +sweep 1,0.7416294238611401,0.1,6,10 +sweep 2,-1.6583338058675126,0.1,0,0 +sweep 3,2.2248882715834206,0.1,5,8 +sweep 4,-0.175074958145232,0.1,0,0 +sweep 5,-2.575038187873885,0.1,5,8 +sweep 6,1.3081838895770481,0.1,5,8 +sweep 7,-1.0917793401516045,0.1,5,8 +sweep 8,2.791442737299329,0.1,5,8 +sweep 9,0.3914795075706756,0.1,5,8 +sweep 10,-2.008483722157977,0.1,5,8 +sweep 11,1.8747383552929673,0.1,5,8 +sweep 12,-0.5252248744356964,0.1,5,8 +sweep 13,-2.9251881041643606,0.1,6,10 +sweep 14,0.9580339732865841,0.1,5,8 +sweep 15,-1.4419292564420578,0.1,0,0 +sweep 16,2.4412928210088642,0.1,5,8 +sweep 17,0.041329591280200084,0.1,0,0 +sweep 18,-2.3586336384484414,0.1,6,10 +sweep 19,1.5245884390025033,0.1,0,0 +sweep 20,-0.8753747907261609,0.1,5,8 +sweep 21,3.007847286724761,0.1,0,0 +sweep 22,0.6078840569961419,0.1,5,8 +sweep 23,-1.7920791727325223,0.1,6,10 +sweep 24,2.0911429047184003,0.1,5,8 +sweep 25,-0.30882032501026435,0.1,5,8 +sweep 26,-2.708783554738928,0.1,5,8 +sweep 27,1.1744385227120384,0.1,5,8 +sweep 28,-1.2255247070166253,0.1,5,8 +sweep 29,2.657697370434297,0.1,5,8 +sweep 30,0.25773414070567746,0.1,5,8 +sweep 31,-2.1422290890229867,0.1,5,8 +sweep 32,1.7409929884279354,0.1,0,0 +sweep 33,-0.6589702413007283,0.1,5,8 +sweep 34,-3.0589334710293925,0.1,0,0 +sweep 35,0.8242886064215744,0.1,6,10 +sweep 36,-1.5756746233070897,0.1,0,0 +sweep 37,2.3075474541438323,0.1,6,10 +sweep 38,-0.09241577558478697,0.1,0,0 +sweep 39,-2.492379005313451,0.1,5,8 +sweep 40,1.3908430721374714,0.1,0,0 +sweep 41,-1.0091201575911484,0.1,5,8 +sweep 42,2.8741019198597293,0.1,5,8 +sweep 43,0.47413869013111,0.1,5,8 +sweep 44,-1.9258245395975095,0.1,5,8 +sweep 45,1.9573975378533683,0.1,5,8 +sweep 46,-0.4425656918752514,0.1,5,8 +sweep 47,-2.84252892160396,0.1,5,8 +sweep 48,1.0406931558470065,0.1,5,8 +sweep 49,-1.3592700738816128,0.1,6,10 +sweep 50,2.5239520035692644,0.1,5,8 +sweep 51,0.12398877384064555,0.1,0,0 +sweep 52,-2.275974455888063,0.1,5,8 +sweep 53,1.6072476215629035,0.1,0,0 +sweep 54,-0.7927156081657158,0.1,6,10 +sweep 55,3.0905064692851614,0.1,0,0 +sweep 56,0.6905432395565425,0.1,5,8 +sweep 57,-1.709419990172077,0.1,0,0 +sweep 58,2.1738020872788004,0.1,5,8 +sweep 59,-0.22616114244981889,0.1,6,10 +sweep 60,-2.626124372178438,0.1,5,8 +sweep 61,1.2570977052724395,0.1,5,8 +sweep 62,-1.1428655244561803,0.1,5,8 +sweep 63,2.7403565529946974,0.1,5,8 +sweep 64,0.3403933232660781,0.1,5,8 +sweep 65,-2.0595699064625412,0.1,5,8 +sweep 66,1.8236521709883364,0.1,5,8 +sweep 67,-0.5763110587402833,0.1,5,8 +sweep 68,-2.976274288468992,0.1,0,0 +sweep 69,0.9069477889819746,0.1,5,8 +sweep 70,-1.4930154407466447,0.1,0,0 +sweep 71,2.3902066367042325,0.1,6,10 +sweep 72,-0.009756593024386362,0.1,0,0 +sweep 73,-2.409719822753006,0.1,6,10 +sweep 74,1.4735022546978715,0.1,0,0 +sweep 75,-0.9264609750307478,0.1,5,8 +sweep 76,2.956761102420219,0.1,0,0 +sweep 77,0.5567978726915102,0.1,5,8 +sweep 78,-1.8431653570371092,0.1,5,8 +sweep 79,2.0400567204137685,0.1,5,8 +sweep 80,-0.3599065093148508,0.1,5,8 +sweep 81,-2.75986973904356,0.1,5,8 +sweep 82,1.1233523384074964,0.1,5,8 +sweep 83,-1.2766108913212122,0.1,5,8 +sweep 84,2.6066111861296655,0.1,5,8 +sweep 85,0.20664795640113542,0.1,6,10 +sweep 86,-2.1933152733275736,0.1,5,8 +sweep 87,1.6899068041233045,0.1,0,0 +sweep 88,-0.710056425605226,0.1,6,10 +sweep 89,-3.1100196553339345,0.1,0,0 +sweep 90,0.7732024221169427,0.1,6,10 +sweep 91,-1.626760807611766,0.1,0,0 +sweep 92,2.2564612698392903,0.1,5,8 +sweep 93,-0.14350195988941827,0.1,0,0 +sweep 94,-2.5434651896181273,0.1,5,8 +sweep 95,1.3397568878329293,0.1,6,10 +sweep 96,-1.0602063418957797,0.1,5,8 +sweep 97,2.8230157355550975,0.1,5,8 +sweep 98,0.4230525058265675,0.1,5,8 +sweep 99,-1.976910723902141,0.1,5,8 +sweep 100,1.9063113535487366,0.1,5,8 +sweep 101,-0.49365187617979345,0.1,5,8 +sweep 102,-2.8936151059085025,0.1,5,8 +sweep 103,0.9896069715423756,0.1,5,8 +sweep 104,-1.4103562581863334,0.1,0,0 +sweep 105,2.4728658192647224,0.1,5,8 +sweep 106,0.0729025895360138,0.1,0,0 +sweep 107,-2.3270606401926948,0.1,6,10 +sweep 108,1.5561614372583614,0.1,0,0 +sweep 109,-0.8438017924703471,0.1,6,10 +sweep 110,3.0394202849805305,0.1,0,0 +sweep 111,0.639457055252,0.1,5,8 +sweep 112,-1.7605061744767085,0.1,0,0 +sweep 113,2.1227159029741687,0.1,5,8 +sweep 114,-0.2772473267543609,0.1,5,8 +sweep 115,-2.67721055648307,0.1,5,8 +sweep 116,1.2060115209678077,0.1,5,8 +sweep 117,-1.1939517087607223,0.1,5,8 +sweep 118,2.6892703686901553,0.1,5,8 +sweep 119,0.28930713896144633,0.1,5,8 +sweep 120,-2.1106560907670837,0.1,5,8 +sweep 121,1.7725659866837935,0.1,6,10 +sweep 122,-0.6273972430449146,0.1,5,8 +sweep 123,-3.0273604727736236,0.1,0,0 +sweep 124,0.8558616046774326,0.1,6,10 +sweep 125,-1.544101625051276,0.1,0,0 +sweep 126,2.3391204523996016,0.1,6,10 +sweep 127,-0.06084277732892884,0.1,0,0 +sweep 128,-2.4608060070576374,0.1,5,8 +ising zz,0.10362269294859393,0.01,10,18 +ising x,0.20724538589718786,0.01,11,20 +ising zz middle,-0.1644907717943757,0.01,11,20 +ising x middle,-0.3289815435887514,0.01,11,20 +sweep 1,0.7416294238611401,0.01,9,16 +sweep 2,-1.6583338058675126,0.01,9,16 +sweep 3,2.2248882715834206,0.01,11,20 +sweep 4,-0.175074958145232,0.01,11,20 +sweep 5,-2.575038187873885,0.01,8,14 +sweep 6,1.3081838895770481,0.01,12,22 +sweep 7,-1.0917793401516045,0.01,12,22 +sweep 8,2.791442737299329,0.01,11,20 +sweep 9,0.3914795075706756,0.01,10,18 +sweep 10,-2.008483722157977,0.01,10,18 +sweep 11,1.8747383552929673,0.01,11,20 +sweep 12,-0.5252248744356964,0.01,11,20 +sweep 13,-2.9251881041643606,0.01,12,22 +sweep 14,0.9580339732865841,0.01,10,18 +sweep 15,-1.4419292564420578,0.01,11,20 +sweep 16,2.4412928210088642,0.01,10,18 +sweep 17,0.041329591280200084,0.01,10,18 +sweep 18,-2.3586336384484414,0.01,11,20 +sweep 19,1.5245884390025033,0.01,10,18 +sweep 20,-0.8753747907261609,0.01,11,20 +sweep 21,3.007847286724761,0.01,11,20 +sweep 22,0.6078840569961419,0.01,10,18 +sweep 23,-1.7920791727325223,0.01,11,20 +sweep 24,2.0911429047184003,0.01,11,20 +sweep 25,-0.30882032501026435,0.01,11,20 +sweep 26,-2.708783554738928,0.01,10,18 +sweep 27,1.1744385227120384,0.01,10,18 +sweep 28,-1.2255247070166253,0.01,12,22 +sweep 29,2.657697370434297,0.01,11,20 +sweep 30,0.25773414070567746,0.01,12,22 +sweep 31,-2.1422290890229867,0.01,8,14 +sweep 32,1.7409929884279354,0.01,11,20 +sweep 33,-0.6589702413007283,0.01,10,18 +sweep 34,-3.0589334710293925,0.01,9,16 +sweep 35,0.8242886064215744,0.01,9,16 +sweep 36,-1.5756746233070897,0.01,0,0 +sweep 37,2.3075474541438323,0.01,9,16 +sweep 38,-0.09241577558478697,0.01,9,16 +sweep 39,-2.492379005313451,0.01,11,20 +sweep 40,1.3908430721374714,0.01,11,20 +sweep 41,-1.0091201575911484,0.01,8,14 +sweep 42,2.8741019198597293,0.01,12,22 +sweep 43,0.47413869013111,0.01,12,22 +sweep 44,-1.9258245395975095,0.01,11,20 +sweep 45,1.9573975378533683,0.01,10,18 +sweep 46,-0.4425656918752514,0.01,11,20 +sweep 47,-2.84252892160396,0.01,11,20 +sweep 48,1.0406931558470065,0.01,11,20 +sweep 49,-1.3592700738816128,0.01,11,20 +sweep 50,2.5239520035692644,0.01,10,18 +sweep 51,0.12398877384064555,0.01,10,18 +sweep 52,-2.275974455888063,0.01,10,18 +sweep 53,1.6072476215629035,0.01,10,18 +sweep 54,-0.7927156081657158,0.01,11,20 +sweep 55,3.0905064692851614,0.01,10,18 +sweep 56,0.6905432395565425,0.01,11,20 +sweep 57,-1.709419990172077,0.01,11,20 +sweep 58,2.1738020872788004,0.01,10,18 +sweep 59,-0.22616114244981889,0.01,11,20 +sweep 60,-2.626124372178438,0.01,11,20 +sweep 61,1.2570977052724395,0.01,11,20 +sweep 62,-1.1428655244561803,0.01,10,18 +sweep 63,2.7403565529946974,0.01,10,18 +sweep 64,0.3403933232660781,0.01,12,22 +sweep 65,-2.0595699064625412,0.01,11,20 +sweep 66,1.8236521709883364,0.01,12,22 +sweep 67,-0.5763110587402833,0.01,8,14 +sweep 68,-2.976274288468992,0.01,11,20 +sweep 69,0.9069477889819746,0.01,10,18 +sweep 70,-1.4930154407466447,0.01,9,16 +sweep 71,2.3902066367042325,0.01,9,16 +sweep 72,-0.009756593024386362,0.01,0,0 +sweep 73,-2.409719822753006,0.01,9,16 +sweep 74,1.4735022546978715,0.01,10,18 +sweep 75,-0.9264609750307478,0.01,11,20 +sweep 76,2.956761102420219,0.01,11,20 +sweep 77,0.5567978726915102,0.01,8,14 +sweep 78,-1.8431653570371092,0.01,12,22 +sweep 79,2.0400567204137685,0.01,11,20 +sweep 80,-0.3599065093148508,0.01,11,20 +sweep 81,-2.75986973904356,0.01,10,18 +sweep 82,1.1233523384074964,0.01,11,20 +sweep 83,-1.2766108913212122,0.01,11,20 +sweep 84,2.6066111861296655,0.01,11,20 +sweep 85,0.20664795640113542,0.01,11,20 +sweep 86,-2.1933152733275736,0.01,10,18 +sweep 87,1.6899068041233045,0.01,10,18 +sweep 88,-0.710056425605226,0.01,10,18 +sweep 89,-3.1100196553339345,0.01,10,18 +sweep 90,0.7732024221169427,0.01,11,20 +sweep 91,-1.626760807611766,0.01,10,18 +sweep 92,2.2564612698392903,0.01,11,20 +sweep 93,-0.14350195988941827,0.01,11,20 +sweep 94,-2.5434651896181273,0.01,10,18 +sweep 95,1.3397568878329293,0.01,11,20 +sweep 96,-1.0602063418957797,0.01,11,20 +sweep 97,2.8230157355550975,0.01,11,20 +sweep 98,0.4230525058265675,0.01,9,16 +sweep 99,-1.976910723902141,0.01,9,16 +sweep 100,1.9063113535487366,0.01,12,22 +sweep 101,-0.49365187617979345,0.01,10,18 +sweep 102,-2.8936151059085025,0.01,11,20 +sweep 103,0.9896069715423756,0.01,10,18 +sweep 104,-1.4103562581863334,0.01,10,18 +sweep 105,2.4728658192647224,0.01,11,20 +sweep 106,0.0729025895360138,0.01,11,20 +sweep 107,-2.3270606401926948,0.01,9,16 +sweep 108,1.5561614372583614,0.01,0,0 +sweep 109,-0.8438017924703471,0.01,9,16 +sweep 110,3.0394202849805305,0.01,10,18 +sweep 111,0.639457055252,0.01,11,20 +sweep 112,-1.7605061744767085,0.01,11,20 +sweep 113,2.1227159029741687,0.01,11,20 +sweep 114,-0.2772473267543609,0.01,12,22 +sweep 115,-2.67721055648307,0.01,11,20 +sweep 116,1.2060115209678077,0.01,11,20 +sweep 117,-1.1939517087607223,0.01,10,18 +sweep 118,2.6892703686901553,0.01,11,20 +sweep 119,0.28930713896144633,0.01,11,20 +sweep 120,-2.1106560907670837,0.01,11,20 +sweep 121,1.7725659866837935,0.01,11,20 +sweep 122,-0.6273972430449146,0.01,10,18 +sweep 123,-3.0273604727736236,0.01,10,18 +sweep 124,0.8558616046774326,0.01,10,18 +sweep 125,-1.544101625051276,0.01,12,22 +sweep 126,2.3391204523996016,0.01,11,20 +sweep 127,-0.06084277732892884,0.01,11,20 +sweep 128,-2.4608060070576374,0.01,11,20 +ising zz,0.10362269294859393,0.001,16,30 +ising x,0.20724538589718786,0.001,17,32 +ising zz middle,-0.1644907717943757,0.001,16,30 +ising x middle,-0.3289815435887514,0.001,12,22 +sweep 1,0.7416294238611401,0.001,15,28 +sweep 2,-1.6583338058675126,0.001,15,28 +sweep 3,2.2248882715834206,0.001,16,30 +sweep 4,-0.175074958145232,0.001,15,28 +sweep 5,-2.575038187873885,0.001,15,28 +sweep 6,1.3081838895770481,0.001,12,22 +sweep 7,-1.0917793401516045,0.001,16,30 +sweep 8,2.791442737299329,0.001,12,22 +sweep 9,0.3914795075706756,0.001,17,32 +sweep 10,-2.008483722157977,0.001,17,32 +sweep 11,1.8747383552929673,0.001,17,32 +sweep 12,-0.5252248744356964,0.001,16,30 +sweep 13,-2.9251881041643606,0.001,17,32 +sweep 14,0.9580339732865841,0.001,14,26 +sweep 15,-1.4419292564420578,0.001,17,32 +sweep 16,2.4412928210088642,0.001,15,28 +sweep 17,0.041329591280200084,0.001,16,30 +sweep 18,-2.3586336384484414,0.001,17,32 +sweep 19,1.5245884390025033,0.001,12,22 +sweep 20,-0.8753747907261609,0.001,12,22 +sweep 21,3.007847286724761,0.001,16,30 +sweep 22,0.6078840569961419,0.001,17,32 +sweep 23,-1.7920791727325223,0.001,15,28 +sweep 24,2.0911429047184003,0.001,16,30 +sweep 25,-0.30882032501026435,0.001,15,28 +sweep 26,-2.708783554738928,0.001,16,30 +sweep 27,1.1744385227120384,0.001,17,32 +sweep 28,-1.2255247070166253,0.001,16,30 +sweep 29,2.657697370434297,0.001,15,28 +sweep 30,0.25773414070567746,0.001,17,32 +sweep 31,-2.1422290890229867,0.001,15,28 +sweep 32,1.7409929884279354,0.001,15,28 +sweep 33,-0.6589702413007283,0.001,16,30 +sweep 34,-3.0589334710293925,0.001,15,28 +sweep 35,0.8242886064215744,0.001,16,30 +sweep 36,-1.5756746233070897,0.001,16,30 +sweep 37,2.3075474541438323,0.001,16,30 +sweep 38,-0.09241577558478697,0.001,17,32 +sweep 39,-2.492379005313451,0.001,16,30 +sweep 40,1.3908430721374714,0.001,15,28 +sweep 41,-1.0091201575911484,0.001,15,28 +sweep 42,2.8741019198597293,0.001,16,30 +sweep 43,0.47413869013111,0.001,16,30 +sweep 44,-1.9258245395975095,0.001,16,30 +sweep 45,1.9573975378533683,0.001,14,26 +sweep 46,-0.4425656918752514,0.001,17,32 +sweep 47,-2.84252892160396,0.001,16,30 +sweep 48,1.0406931558470065,0.001,13,24 +sweep 49,-1.3592700738816128,0.001,15,28 +sweep 50,2.5239520035692644,0.001,15,28 +sweep 51,0.12398877384064555,0.001,14,26 +sweep 52,-2.275974455888063,0.001,16,30 +sweep 53,1.6072476215629035,0.001,15,28 +sweep 54,-0.7927156081657158,0.001,16,30 +sweep 55,3.0905064692851614,0.001,16,30 +sweep 56,0.6905432395565425,0.001,15,28 +sweep 57,-1.709419990172077,0.001,16,30 +sweep 58,2.1738020872788004,0.001,16,30 +sweep 59,-0.22616114244981889,0.001,16,30 +sweep 60,-2.626124372178438,0.001,15,28 +sweep 61,1.2570977052724395,0.001,16,30 +sweep 62,-1.1428655244561803,0.001,16,30 +sweep 63,2.7403565529946974,0.001,16,30 +sweep 64,0.3403933232660781,0.001,18,34 +sweep 65,-2.0595699064625412,0.001,16,30 +sweep 66,1.8236521709883364,0.001,12,22 +sweep 67,-0.5763110587402833,0.001,15,28 +sweep 68,-2.976274288468992,0.001,17,32 +sweep 69,0.9069477889819746,0.001,16,30 +sweep 70,-1.4930154407466447,0.001,12,22 +sweep 71,2.3902066367042325,0.001,16,30 +sweep 72,-0.009756593024386362,0.001,17,32 +sweep 73,-2.409719822753006,0.001,16,30 +sweep 74,1.4735022546978715,0.001,16,30 +sweep 75,-0.9264609750307478,0.001,17,32 +sweep 76,2.956761102420219,0.001,16,30 +sweep 77,0.5567978726915102,0.001,16,30 +sweep 78,-1.8431653570371092,0.001,16,30 +sweep 79,2.0400567204137685,0.001,15,28 +sweep 80,-0.3599065093148508,0.001,16,30 +sweep 81,-2.75986973904356,0.001,16,30 +sweep 82,1.1233523384074964,0.001,17,32 +sweep 83,-1.2766108913212122,0.001,12,22 +sweep 84,2.6066111861296655,0.001,15,28 +sweep 85,0.20664795640113542,0.001,17,32 +sweep 86,-2.1933152733275736,0.001,14,26 +sweep 87,1.6899068041233045,0.001,17,32 +sweep 88,-0.710056425605226,0.001,16,30 +sweep 89,-3.1100196553339345,0.001,12,22 +sweep 90,0.7732024221169427,0.001,15,28 +sweep 91,-1.626760807611766,0.001,15,28 +sweep 92,2.2564612698392903,0.001,16,30 +sweep 93,-0.14350195988941827,0.001,16,30 +sweep 94,-2.5434651896181273,0.001,15,28 +sweep 95,1.3397568878329293,0.001,16,30 +sweep 96,-1.0602063418957797,0.001,19,36 +sweep 97,2.8230157355550975,0.001,16,30 +sweep 98,0.4230525058265675,0.001,15,28 +sweep 99,-1.976910723902141,0.001,15,28 +sweep 100,1.9063113535487366,0.001,14,26 +sweep 101,-0.49365187617979345,0.001,16,30 +sweep 102,-2.8936151059085025,0.001,15,28 +sweep 103,0.9896069715423756,0.001,17,32 +sweep 104,-1.4103562581863334,0.001,17,32 +sweep 105,2.4728658192647224,0.001,16,30 +sweep 106,0.0729025895360138,0.001,15,28 +sweep 107,-2.3270606401926948,0.001,16,30 +sweep 108,1.5561614372583614,0.001,17,32 +sweep 109,-0.8438017924703471,0.001,12,22 +sweep 110,3.0394202849805305,0.001,17,32 +sweep 111,0.639457055252,0.001,16,30 +sweep 112,-1.7605061744767085,0.001,15,28 +sweep 113,2.1227159029741687,0.001,15,28 +sweep 114,-0.2772473267543609,0.001,16,30 +sweep 115,-2.67721055648307,0.001,16,30 +sweep 116,1.2060115209678077,0.001,14,26 +sweep 117,-1.1939517087607223,0.001,14,26 +sweep 118,2.6892703686901553,0.001,16,30 +sweep 119,0.28930713896144633,0.001,16,30 +sweep 120,-2.1106560907670837,0.001,16,30 +sweep 121,1.7725659866837935,0.001,15,28 +sweep 122,-0.6273972430449146,0.001,12,22 +sweep 123,-3.0273604727736236,0.001,14,26 +sweep 124,0.8558616046774326,0.001,16,30 +sweep 125,-1.544101625051276,0.001,15,28 +sweep 126,2.3391204523996016,0.001,16,30 +sweep 127,-0.06084277732892884,0.001,16,30 +sweep 128,-2.4608060070576374,0.001,17,32 +ising zz,0.10362269294859393,0.0001,20,38 +ising x,0.20724538589718786,0.0001,20,38 +ising zz middle,-0.1644907717943757,0.0001,20,38 +ising x middle,-0.3289815435887514,0.0001,22,42 +sweep 1,0.7416294238611401,0.0001,21,40 +sweep 2,-1.6583338058675126,0.0001,21,40 +sweep 3,2.2248882715834206,0.0001,20,38 +sweep 4,-0.175074958145232,0.0001,22,42 +sweep 5,-2.575038187873885,0.0001,21,40 +sweep 6,1.3081838895770481,0.0001,22,42 +sweep 7,-1.0917793401516045,0.0001,20,38 +sweep 8,2.791442737299329,0.0001,21,40 +sweep 9,0.3914795075706756,0.0001,20,38 +sweep 10,-2.008483722157977,0.0001,20,38 +sweep 11,1.8747383552929673,0.0001,21,40 +sweep 12,-0.5252248744356964,0.0001,20,38 +sweep 13,-2.9251881041643606,0.0001,21,40 +sweep 14,0.9580339732865841,0.0001,21,40 +sweep 15,-1.4419292564420578,0.0001,23,44 +sweep 16,2.4412928210088642,0.0001,22,42 +sweep 17,0.041329591280200084,0.0001,21,40 +sweep 18,-2.3586336384484414,0.0001,20,38 +sweep 19,1.5245884390025033,0.0001,21,40 +sweep 20,-0.8753747907261609,0.0001,21,40 +sweep 21,3.007847286724761,0.0001,20,38 +sweep 22,0.6078840569961419,0.0001,19,36 +sweep 23,-1.7920791727325223,0.0001,19,36 +sweep 24,2.0911429047184003,0.0001,20,38 +sweep 25,-0.30882032501026435,0.0001,22,42 +sweep 26,-2.708783554738928,0.0001,21,40 +sweep 27,1.1744385227120384,0.0001,17,32 +sweep 28,-1.2255247070166253,0.0001,20,38 +sweep 29,2.657697370434297,0.0001,20,38 +sweep 30,0.25773414070567746,0.0001,20,38 +sweep 31,-2.1422290890229867,0.0001,20,38 +sweep 32,1.7409929884279354,0.0001,22,42 +sweep 33,-0.6589702413007283,0.0001,21,40 +sweep 34,-3.0589334710293925,0.0001,21,40 +sweep 35,0.8242886064215744,0.0001,21,40 +sweep 36,-1.5756746233070897,0.0001,22,42 +sweep 37,2.3075474541438323,0.0001,20,38 +sweep 38,-0.09241577558478697,0.0001,20,38 +sweep 39,-2.492379005313451,0.0001,22,42 +sweep 40,1.3908430721374714,0.0001,21,40 +sweep 41,-1.0091201575911484,0.0001,21,40 +sweep 42,2.8741019198597293,0.0001,20,38 +sweep 43,0.47413869013111,0.0001,21,40 +sweep 44,-1.9258245395975095,0.0001,22,42 +sweep 45,1.9573975378533683,0.0001,21,40 +sweep 46,-0.4425656918752514,0.0001,21,40 +sweep 47,-2.84252892160396,0.0001,20,38 +sweep 48,1.0406931558470065,0.0001,21,40 +sweep 49,-1.3592700738816128,0.0001,22,42 +sweep 50,2.5239520035692644,0.0001,21,40 +sweep 51,0.12398877384064555,0.0001,20,38 +sweep 52,-2.275974455888063,0.0001,20,38 +sweep 53,1.6072476215629035,0.0001,19,36 +sweep 54,-0.7927156081657158,0.0001,21,40 +sweep 55,3.0905064692851614,0.0001,21,40 +sweep 56,0.6905432395565425,0.0001,22,42 +sweep 57,-1.709419990172077,0.0001,20,38 +sweep 58,2.1738020872788004,0.0001,22,42 +sweep 59,-0.22616114244981889,0.0001,20,38 +sweep 60,-2.626124372178438,0.0001,21,40 +sweep 61,1.2570977052724395,0.0001,22,42 +sweep 62,-1.1428655244561803,0.0001,22,42 +sweep 63,2.7403565529946974,0.0001,21,40 +sweep 64,0.3403933232660781,0.0001,23,44 +sweep 65,-2.0595699064625412,0.0001,21,40 +sweep 66,1.8236521709883364,0.0001,21,40 +sweep 67,-0.5763110587402833,0.0001,22,42 +sweep 68,-2.976274288468992,0.0001,23,44 +sweep 69,0.9069477889819746,0.0001,20,38 +sweep 70,-1.4930154407466447,0.0001,21,40 +sweep 71,2.3902066367042325,0.0001,21,40 +sweep 72,-0.009756593024386362,0.0001,20,38 +sweep 73,-2.409719822753006,0.0001,23,44 +sweep 74,1.4735022546978715,0.0001,21,40 +sweep 75,-0.9264609750307478,0.0001,22,42 +sweep 76,2.956761102420219,0.0001,20,38 +sweep 77,0.5567978726915102,0.0001,19,36 +sweep 78,-1.8431653570371092,0.0001,19,36 +sweep 79,2.0400567204137685,0.0001,22,42 +sweep 80,-0.3599065093148508,0.0001,20,38 +sweep 81,-2.75986973904356,0.0001,21,40 +sweep 82,1.1233523384074964,0.0001,21,40 +sweep 83,-1.2766108913212122,0.0001,22,42 +sweep 84,2.6066111861296655,0.0001,18,34 +sweep 85,0.20664795640113542,0.0001,21,40 +sweep 86,-2.1933152733275736,0.0001,21,40 +sweep 87,1.6899068041233045,0.0001,21,40 +sweep 88,-0.710056425605226,0.0001,22,42 +sweep 89,-3.1100196553339345,0.0001,18,34 +sweep 90,0.7732024221169427,0.0001,19,36 +sweep 91,-1.626760807611766,0.0001,21,40 +sweep 92,2.2564612698392903,0.0001,20,38 +sweep 93,-0.14350195988941827,0.0001,21,40 +sweep 94,-2.5434651896181273,0.0001,18,34 +sweep 95,1.3397568878329293,0.0001,21,40 +sweep 96,-1.0602063418957797,0.0001,20,38 +sweep 97,2.8230157355550975,0.0001,20,38 +sweep 98,0.4230525058265675,0.0001,23,44 +sweep 99,-1.976910723902141,0.0001,20,38 +sweep 100,1.9063113535487366,0.0001,22,42 +sweep 101,-0.49365187617979345,0.0001,20,38 +sweep 102,-2.8936151059085025,0.0001,20,38 +sweep 103,0.9896069715423756,0.0001,20,38 +sweep 104,-1.4103562581863334,0.0001,22,42 +sweep 105,2.4728658192647224,0.0001,21,40 +sweep 106,0.0729025895360138,0.0001,15,28 +sweep 107,-2.3270606401926948,0.0001,20,38 +sweep 108,1.5561614372583614,0.0001,18,34 +sweep 109,-0.8438017924703471,0.0001,21,40 +sweep 110,3.0394202849805305,0.0001,21,40 +sweep 111,0.639457055252,0.0001,20,38 +sweep 112,-1.7605061744767085,0.0001,21,40 +sweep 113,2.1227159029741687,0.0001,21,40 +sweep 114,-0.2772473267543609,0.0001,20,38 +sweep 115,-2.67721055648307,0.0001,21,40 +sweep 116,1.2060115209678077,0.0001,21,40 +sweep 117,-1.1939517087607223,0.0001,20,38 +sweep 118,2.6892703686901553,0.0001,22,42 +sweep 119,0.28930713896144633,0.0001,21,40 +sweep 120,-2.1106560907670837,0.0001,19,36 +sweep 121,1.7725659866837935,0.0001,22,42 +sweep 122,-0.6273972430449146,0.0001,21,40 +sweep 123,-3.0273604727736236,0.0001,19,36 +sweep 124,0.8558616046774326,0.0001,21,40 +sweep 125,-1.544101625051276,0.0001,22,42 +sweep 126,2.3391204523996016,0.0001,21,40 +sweep 127,-0.06084277732892884,0.0001,21,40 +sweep 128,-2.4608060070576374,0.0001,22,42 +ising zz,0.10362269294859393,1e-05,25,48 +ising x,0.20724538589718786,1e-05,27,52 +ising zz middle,-0.1644907717943757,1e-05,26,50 +ising x middle,-0.3289815435887514,1e-05,25,48 +sweep 1,0.7416294238611401,1e-05,26,50 +sweep 2,-1.6583338058675126,1e-05,25,48 +sweep 3,2.2248882715834206,1e-05,27,52 +sweep 4,-0.175074958145232,1e-05,25,48 +sweep 5,-2.575038187873885,1e-05,26,50 +sweep 6,1.3081838895770481,1e-05,27,52 +sweep 7,-1.0917793401516045,1e-05,26,50 +sweep 8,2.791442737299329,1e-05,26,50 +sweep 9,0.3914795075706756,1e-05,26,50 +sweep 10,-2.008483722157977,1e-05,26,50 +sweep 11,1.8747383552929673,1e-05,26,50 +sweep 12,-0.5252248744356964,1e-05,26,50 +sweep 13,-2.9251881041643606,1e-05,25,48 +sweep 14,0.9580339732865841,1e-05,26,50 +sweep 15,-1.4419292564420578,1e-05,25,48 +sweep 16,2.4412928210088642,1e-05,27,52 +sweep 17,0.041329591280200084,1e-05,26,50 +sweep 18,-2.3586336384484414,1e-05,27,52 +sweep 19,1.5245884390025033,1e-05,27,52 +sweep 20,-0.8753747907261609,1e-05,25,48 +sweep 21,3.007847286724761,1e-05,26,50 +sweep 22,0.6078840569961419,1e-05,27,52 +sweep 23,-1.7920791727325223,1e-05,25,48 +sweep 24,2.0911429047184003,1e-05,26,50 +sweep 25,-0.30882032501026435,1e-05,26,50 +sweep 26,-2.708783554738928,1e-05,27,52 +sweep 27,1.1744385227120384,1e-05,27,52 +sweep 28,-1.2255247070166253,1e-05,25,48 +sweep 29,2.657697370434297,1e-05,26,50 +sweep 30,0.25773414070567746,1e-05,25,48 +sweep 31,-2.1422290890229867,1e-05,26,50 +sweep 32,1.7409929884279354,1e-05,26,50 +sweep 33,-0.6589702413007283,1e-05,26,50 +sweep 34,-3.0589334710293925,1e-05,27,52 +sweep 35,0.8242886064215744,1e-05,25,48 +sweep 36,-1.5756746233070897,1e-05,25,48 +sweep 37,2.3075474541438323,1e-05,27,52 +sweep 38,-0.09241577558478697,1e-05,26,50 +sweep 39,-2.492379005313451,1e-05,26,50 +sweep 40,1.3908430721374714,1e-05,26,50 +sweep 41,-1.0091201575911484,1e-05,27,52 +sweep 42,2.8741019198597293,1e-05,26,50 +sweep 43,0.47413869013111,1e-05,25,48 +sweep 44,-1.9258245395975095,1e-05,24,46 +sweep 45,1.9573975378533683,1e-05,25,48 +sweep 46,-0.4425656918752514,1e-05,27,52 +sweep 47,-2.84252892160396,1e-05,25,48 +sweep 48,1.0406931558470065,1e-05,26,50 +sweep 49,-1.3592700738816128,1e-05,27,52 +sweep 50,2.5239520035692644,1e-05,26,50 +sweep 51,0.12398877384064555,1e-05,27,52 +sweep 52,-2.275974455888063,1e-05,25,48 +sweep 53,1.6072476215629035,1e-05,26,50 +sweep 54,-0.7927156081657158,1e-05,26,50 +sweep 55,3.0905064692851614,1e-05,25,48 +sweep 56,0.6905432395565425,1e-05,26,50 +sweep 57,-1.709419990172077,1e-05,26,50 +sweep 58,2.1738020872788004,1e-05,25,48 +sweep 59,-0.22616114244981889,1e-05,26,50 +sweep 60,-2.626124372178438,1e-05,26,50 +sweep 61,1.2570977052724395,1e-05,27,52 +sweep 62,-1.1428655244561803,1e-05,25,48 +sweep 63,2.7403565529946974,1e-05,26,50 +sweep 64,0.3403933232660781,1e-05,24,46 +sweep 65,-2.0595699064625412,1e-05,26,50 +sweep 66,1.8236521709883364,1e-05,26,50 +sweep 67,-0.5763110587402833,1e-05,25,48 +sweep 68,-2.976274288468992,1e-05,28,54 +sweep 69,0.9069477889819746,1e-05,25,48 +sweep 70,-1.4930154407466447,1e-05,25,48 +sweep 71,2.3902066367042325,1e-05,26,50 +sweep 72,-0.009756593024386362,1e-05,26,50 +sweep 73,-2.409719822753006,1e-05,25,48 +sweep 74,1.4735022546978715,1e-05,26,50 +sweep 75,-0.9264609750307478,1e-05,26,50 +sweep 76,2.956761102420219,1e-05,27,52 +sweep 77,0.5567978726915102,1e-05,26,50 +sweep 78,-1.8431653570371092,1e-05,27,52 +sweep 79,2.0400567204137685,1e-05,26,50 +sweep 80,-0.3599065093148508,1e-05,26,50 +sweep 81,-2.75986973904356,1e-05,26,50 +sweep 82,1.1233523384074964,1e-05,26,50 +sweep 83,-1.2766108913212122,1e-05,22,42 +sweep 84,2.6066111861296655,1e-05,24,46 +sweep 85,0.20664795640113542,1e-05,27,52 +sweep 86,-2.1933152733275736,1e-05,26,50 +sweep 87,1.6899068041233045,1e-05,26,50 +sweep 88,-0.710056425605226,1e-05,26,50 +sweep 89,-3.1100196553339345,1e-05,26,50 +sweep 90,0.7732024221169427,1e-05,25,48 +sweep 91,-1.626760807611766,1e-05,26,50 +sweep 92,2.2564612698392903,1e-05,23,44 +sweep 93,-0.14350195988941827,1e-05,27,52 +sweep 94,-2.5434651896181273,1e-05,27,52 +sweep 95,1.3397568878329293,1e-05,26,50 +sweep 96,-1.0602063418957797,1e-05,26,50 +sweep 97,2.8230157355550975,1e-05,26,50 +sweep 98,0.4230525058265675,1e-05,31,60 +sweep 99,-1.976910723902141,1e-05,25,48 +sweep 100,1.9063113535487366,1e-05,27,52 +sweep 101,-0.49365187617979345,1e-05,26,50 +sweep 102,-2.8936151059085025,1e-05,27,52 +sweep 103,0.9896069715423756,1e-05,26,50 +sweep 104,-1.4103562581863334,1e-05,27,52 +sweep 105,2.4728658192647224,1e-05,25,48 +sweep 106,0.0729025895360138,1e-05,26,50 +sweep 107,-2.3270606401926948,1e-05,26,50 +sweep 108,1.5561614372583614,1e-05,26,50 +sweep 109,-0.8438017924703471,1e-05,24,46 +sweep 110,3.0394202849805305,1e-05,26,50 +sweep 111,0.639457055252,1e-05,27,52 +sweep 112,-1.7605061744767085,1e-05,26,50 +sweep 113,2.1227159029741687,1e-05,26,50 +sweep 114,-0.2772473267543609,1e-05,25,48 +sweep 115,-2.67721055648307,1e-05,25,48 +sweep 116,1.2060115209678077,1e-05,26,50 +sweep 117,-1.1939517087607223,1e-05,25,48 +sweep 118,2.6892703686901553,1e-05,27,52 +sweep 119,0.28930713896144633,1e-05,25,48 +sweep 120,-2.1106560907670837,1e-05,27,52 +sweep 121,1.7725659866837935,1e-05,25,48 +sweep 122,-0.6273972430449146,1e-05,25,48 +sweep 123,-3.0273604727736236,1e-05,26,50 +sweep 124,0.8558616046774326,1e-05,24,46 +sweep 125,-1.544101625051276,1e-05,25,48 +sweep 126,2.3391204523996016,1e-05,26,50 +sweep 127,-0.06084277732892884,1e-05,26,50 +sweep 128,-2.4608060070576374,1e-05,26,50 +ising zz,0.10362269294859393,1e-07,36,70 +ising x,0.20724538589718786,1e-07,35,68 +ising zz middle,-0.1644907717943757,1e-07,35,68 +ising x middle,-0.3289815435887514,1e-07,36,70 +sweep 1,0.7416294238611401,1e-07,36,70 +sweep 2,-1.6583338058675126,1e-07,36,70 +sweep 3,2.2248882715834206,1e-07,37,72 +sweep 4,-0.175074958145232,1e-07,37,72 +sweep 5,-2.575038187873885,1e-07,36,70 +sweep 6,1.3081838895770481,1e-07,36,70 +sweep 7,-1.0917793401516045,1e-07,36,70 +sweep 8,2.791442737299329,1e-07,36,70 +sweep 9,0.3914795075706756,1e-07,36,70 +sweep 10,-2.008483722157977,1e-07,37,72 +sweep 11,1.8747383552929673,1e-07,35,68 +sweep 12,-0.5252248744356964,1e-07,36,70 +sweep 13,-2.9251881041643606,1e-07,37,72 +sweep 14,0.9580339732865841,1e-07,37,72 +sweep 15,-1.4419292564420578,1e-07,36,70 +sweep 16,2.4412928210088642,1e-07,35,68 +sweep 17,0.041329591280200084,1e-07,37,72 +sweep 18,-2.3586336384484414,1e-07,35,68 +sweep 19,1.5245884390025033,1e-07,37,72 +sweep 20,-0.8753747907261609,1e-07,35,68 +sweep 21,3.007847286724761,1e-07,36,70 +sweep 22,0.6078840569961419,1e-07,36,70 +sweep 23,-1.7920791727325223,1e-07,36,70 +sweep 24,2.0911429047184003,1e-07,36,70 +sweep 25,-0.30882032501026435,1e-07,36,70 +sweep 26,-2.708783554738928,1e-07,36,70 +sweep 27,1.1744385227120384,1e-07,37,72 +sweep 28,-1.2255247070166253,1e-07,36,70 +sweep 29,2.657697370434297,1e-07,36,70 +sweep 30,0.25773414070567746,1e-07,34,66 +sweep 31,-2.1422290890229867,1e-07,37,72 +sweep 32,1.7409929884279354,1e-07,37,72 +sweep 33,-0.6589702413007283,1e-07,36,70 +sweep 34,-3.0589334710293925,1e-07,35,68 +sweep 35,0.8242886064215744,1e-07,34,66 +sweep 36,-1.5756746233070897,1e-07,35,68 +sweep 37,2.3075474541438323,1e-07,34,66 +sweep 38,-0.09241577558478697,1e-07,36,70 +sweep 39,-2.492379005313451,1e-07,36,70 +sweep 40,1.3908430721374714,1e-07,36,70 +sweep 41,-1.0091201575911484,1e-07,36,70 +sweep 42,2.8741019198597293,1e-07,36,70 +sweep 43,0.47413869013111,1e-07,37,72 +sweep 44,-1.9258245395975095,1e-07,37,72 +sweep 45,1.9573975378533683,1e-07,35,68 +sweep 46,-0.4425656918752514,1e-07,36,70 +sweep 47,-2.84252892160396,1e-07,36,70 +sweep 48,1.0406931558470065,1e-07,37,72 +sweep 49,-1.3592700738816128,1e-07,36,70 +sweep 50,2.5239520035692644,1e-07,34,66 +sweep 51,0.12398877384064555,1e-07,37,72 +sweep 52,-2.275974455888063,1e-07,35,68 +sweep 53,1.6072476215629035,1e-07,36,70 +sweep 54,-0.7927156081657158,1e-07,37,72 +sweep 55,3.0905064692851614,1e-07,36,70 +sweep 56,0.6905432395565425,1e-07,36,70 +sweep 57,-1.709419990172077,1e-07,37,72 +sweep 58,2.1738020872788004,1e-07,35,68 +sweep 59,-0.22616114244981889,1e-07,36,70 +sweep 60,-2.626124372178438,1e-07,36,70 +sweep 61,1.2570977052724395,1e-07,35,68 +sweep 62,-1.1428655244561803,1e-07,35,68 +sweep 63,2.7403565529946974,1e-07,36,70 +sweep 64,0.3403933232660781,1e-07,36,70 +sweep 65,-2.0595699064625412,1e-07,36,70 +sweep 66,1.8236521709883364,1e-07,36,70 +sweep 67,-0.5763110587402833,1e-07,36,70 +sweep 68,-2.976274288468992,1e-07,36,70 +sweep 69,0.9069477889819746,1e-07,36,70 +sweep 70,-1.4930154407466447,1e-07,36,70 +sweep 71,2.3902066367042325,1e-07,35,68 +sweep 72,-0.009756593024386362,1e-07,36,70 +sweep 73,-2.409719822753006,1e-07,36,70 +sweep 74,1.4735022546978715,1e-07,37,72 +sweep 75,-0.9264609750307478,1e-07,36,70 +sweep 76,2.956761102420219,1e-07,36,70 +sweep 77,0.5567978726915102,1e-07,35,68 +sweep 78,-1.8431653570371092,1e-07,36,70 +sweep 79,2.0400567204137685,1e-07,36,70 +sweep 80,-0.3599065093148508,1e-07,36,70 +sweep 81,-2.75986973904356,1e-07,37,72 +sweep 82,1.1233523384074964,1e-07,36,70 +sweep 83,-1.2766108913212122,1e-07,37,72 +sweep 84,2.6066111861296655,1e-07,33,64 +sweep 85,0.20664795640113542,1e-07,35,68 +sweep 86,-2.1933152733275736,1e-07,36,70 +sweep 87,1.6899068041233045,1e-07,36,70 +sweep 88,-0.710056425605226,1e-07,37,72 +sweep 89,-3.1100196553339345,1e-07,36,70 +sweep 90,0.7732024221169427,1e-07,37,72 +sweep 91,-1.626760807611766,1e-07,35,68 +sweep 92,2.2564612698392903,1e-07,36,70 +sweep 93,-0.14350195988941827,1e-07,36,70 +sweep 94,-2.5434651896181273,1e-07,37,72 +sweep 95,1.3397568878329293,1e-07,37,72 +sweep 96,-1.0602063418957797,1e-07,36,70 +sweep 97,2.8230157355550975,1e-07,37,72 +sweep 98,0.4230525058265675,1e-07,37,72 +sweep 99,-1.976910723902141,1e-07,35,68 +sweep 100,1.9063113535487366,1e-07,37,72 +sweep 101,-0.49365187617979345,1e-07,37,72 +sweep 102,-2.8936151059085025,1e-07,35,68 +sweep 103,0.9896069715423756,1e-07,37,72 +sweep 104,-1.4103562581863334,1e-07,36,70 +sweep 105,2.4728658192647224,1e-07,37,72 +sweep 106,0.0729025895360138,1e-07,35,68 +sweep 107,-2.3270606401926948,1e-07,36,70 +sweep 108,1.5561614372583614,1e-07,36,70 +sweep 109,-0.8438017924703471,1e-07,37,72 +sweep 110,3.0394202849805305,1e-07,36,70 +sweep 111,0.639457055252,1e-07,37,72 +sweep 112,-1.7605061744767085,1e-07,31,60 +sweep 113,2.1227159029741687,1e-07,36,70 +sweep 114,-0.2772473267543609,1e-07,37,72 +sweep 115,-2.67721055648307,1e-07,36,70 +sweep 116,1.2060115209678077,1e-07,34,66 +sweep 117,-1.1939517087607223,1e-07,36,70 +sweep 118,2.6892703686901553,1e-07,36,70 +sweep 119,0.28930713896144633,1e-07,35,68 +sweep 120,-2.1106560907670837,1e-07,36,70 +sweep 121,1.7725659866837935,1e-07,36,70 +sweep 122,-0.6273972430449146,1e-07,36,70 +sweep 123,-3.0273604727736236,1e-07,36,70 +sweep 124,0.8558616046774326,1e-07,36,70 +sweep 125,-1.544101625051276,1e-07,36,70 +sweep 126,2.3391204523996016,1e-07,33,64 +sweep 127,-0.06084277732892884,1e-07,37,72 +sweep 128,-2.4608060070576374,1e-07,36,70 +ising zz,0.10362269294859393,1e-09,46,90 +ising x,0.20724538589718786,1e-09,45,88 +ising zz middle,-0.1644907717943757,1e-09,47,92 +ising x middle,-0.3289815435887514,1e-09,45,88 +sweep 1,0.7416294238611401,1e-09,47,92 +sweep 2,-1.6583338058675126,1e-09,47,92 +sweep 3,2.2248882715834206,1e-09,45,88 +sweep 4,-0.175074958145232,1e-09,46,90 +sweep 5,-2.575038187873885,1e-09,44,86 +sweep 6,1.3081838895770481,1e-09,44,86 +sweep 7,-1.0917793401516045,1e-09,46,90 +sweep 8,2.791442737299329,1e-09,47,92 +sweep 9,0.3914795075706756,1e-09,46,90 +sweep 10,-2.008483722157977,1e-09,47,92 +sweep 11,1.8747383552929673,1e-09,46,90 +sweep 12,-0.5252248744356964,1e-09,46,90 +sweep 13,-2.9251881041643606,1e-09,46,90 +sweep 14,0.9580339732865841,1e-09,46,90 +sweep 15,-1.4419292564420578,1e-09,45,88 +sweep 16,2.4412928210088642,1e-09,46,90 +sweep 17,0.041329591280200084,1e-09,47,92 +sweep 18,-2.3586336384484414,1e-09,47,92 +sweep 19,1.5245884390025033,1e-09,46,90 +sweep 20,-0.8753747907261609,1e-09,45,88 +sweep 21,3.007847286724761,1e-09,46,90 +sweep 22,0.6078840569961419,1e-09,46,90 +sweep 23,-1.7920791727325223,1e-09,46,90 +sweep 24,2.0911429047184003,1e-09,47,92 +sweep 25,-0.30882032501026435,1e-09,47,92 +sweep 26,-2.708783554738928,1e-09,45,88 +sweep 27,1.1744385227120384,1e-09,46,90 +sweep 28,-1.2255247070166253,1e-09,47,92 +sweep 29,2.657697370434297,1e-09,45,88 +sweep 30,0.25773414070567746,1e-09,46,90 +sweep 31,-2.1422290890229867,1e-09,46,90 +sweep 32,1.7409929884279354,1e-09,46,90 +sweep 33,-0.6589702413007283,1e-09,47,92 +sweep 34,-3.0589334710293925,1e-09,45,88 +sweep 35,0.8242886064215744,1e-09,45,88 +sweep 36,-1.5756746233070897,1e-09,46,90 +sweep 37,2.3075474541438323,1e-09,46,90 +sweep 38,-0.09241577558478697,1e-09,45,88 +sweep 39,-2.492379005313451,1e-09,46,90 +sweep 40,1.3908430721374714,1e-09,45,88 +sweep 41,-1.0091201575911484,1e-09,46,90 +sweep 42,2.8741019198597293,1e-09,45,88 +sweep 43,0.47413869013111,1e-09,45,88 +sweep 44,-1.9258245395975095,1e-09,46,90 +sweep 45,1.9573975378533683,1e-09,46,90 +sweep 46,-0.4425656918752514,1e-09,46,90 +sweep 47,-2.84252892160396,1e-09,46,90 +sweep 48,1.0406931558470065,1e-09,47,92 +sweep 49,-1.3592700738816128,1e-09,46,90 +sweep 50,2.5239520035692644,1e-09,46,90 +sweep 51,0.12398877384064555,1e-09,46,90 +sweep 52,-2.275974455888063,1e-09,46,90 +sweep 53,1.6072476215629035,1e-09,45,88 +sweep 54,-0.7927156081657158,1e-09,45,88 +sweep 55,3.0905064692851614,1e-09,46,90 +sweep 56,0.6905432395565425,1e-09,47,92 +sweep 57,-1.709419990172077,1e-09,45,88 +sweep 58,2.1738020872788004,1e-09,44,86 +sweep 59,-0.22616114244981889,1e-09,42,82 +sweep 60,-2.626124372178438,1e-09,47,92 +sweep 61,1.2570977052724395,1e-09,47,92 +sweep 62,-1.1428655244561803,1e-09,46,90 +sweep 63,2.7403565529946974,1e-09,46,90 +sweep 64,0.3403933232660781,1e-09,44,86 +sweep 65,-2.0595699064625412,1e-09,46,90 +sweep 66,1.8236521709883364,1e-09,47,92 +sweep 67,-0.5763110587402833,1e-09,47,92 +sweep 68,-2.976274288468992,1e-09,47,92 +sweep 69,0.9069477889819746,1e-09,46,90 +sweep 70,-1.4930154407466447,1e-09,46,90 +sweep 71,2.3902066367042325,1e-09,46,90 +sweep 72,-0.009756593024386362,1e-09,46,90 +sweep 73,-2.409719822753006,1e-09,44,86 +sweep 74,1.4735022546978715,1e-09,45,88 +sweep 75,-0.9264609750307478,1e-09,45,88 +sweep 76,2.956761102420219,1e-09,45,88 +sweep 77,0.5567978726915102,1e-09,47,92 +sweep 78,-1.8431653570371092,1e-09,46,90 +sweep 79,2.0400567204137685,1e-09,45,88 +sweep 80,-0.3599065093148508,1e-09,46,90 +sweep 81,-2.75986973904356,1e-09,46,90 +sweep 82,1.1233523384074964,1e-09,46,90 +sweep 83,-1.2766108913212122,1e-09,47,92 +sweep 84,2.6066111861296655,1e-09,46,90 +sweep 85,0.20664795640113542,1e-09,46,90 +sweep 86,-2.1933152733275736,1e-09,46,90 +sweep 87,1.6899068041233045,1e-09,45,88 +sweep 88,-0.710056425605226,1e-09,45,88 +sweep 89,-3.1100196553339345,1e-09,45,88 +sweep 90,0.7732024221169427,1e-09,47,92 +sweep 91,-1.626760807611766,1e-09,46,90 +sweep 92,2.2564612698392903,1e-09,46,90 +sweep 93,-0.14350195988941827,1e-09,45,88 +sweep 94,-2.5434651896181273,1e-09,47,92 +sweep 95,1.3397568878329293,1e-09,47,92 +sweep 96,-1.0602063418957797,1e-09,47,92 +sweep 97,2.8230157355550975,1e-09,46,90 +sweep 98,0.4230525058265675,1e-09,46,90 +sweep 99,-1.976910723902141,1e-09,47,92 +sweep 100,1.9063113535487366,1e-09,47,92 +sweep 101,-0.49365187617979345,1e-09,45,88 +sweep 102,-2.8936151059085025,1e-09,46,90 +sweep 103,0.9896069715423756,1e-09,46,90 +sweep 104,-1.4103562581863334,1e-09,46,90 +sweep 105,2.4728658192647224,1e-09,45,88 +sweep 106,0.0729025895360138,1e-09,47,92 +sweep 107,-2.3270606401926948,1e-09,46,90 +sweep 108,1.5561614372583614,1e-09,46,90 +sweep 109,-0.8438017924703471,1e-09,47,92 +sweep 110,3.0394202849805305,1e-09,46,90 +sweep 111,0.639457055252,1e-09,44,86 +sweep 112,-1.7605061744767085,1e-09,46,90 +sweep 113,2.1227159029741687,1e-09,45,88 +sweep 114,-0.2772473267543609,1e-09,48,94 +sweep 115,-2.67721055648307,1e-09,46,90 +sweep 116,1.2060115209678077,1e-09,47,92 +sweep 117,-1.1939517087607223,1e-09,45,88 +sweep 118,2.6892703686901553,1e-09,47,92 +sweep 119,0.28930713896144633,1e-09,46,90 +sweep 120,-2.1106560907670837,1e-09,45,88 +sweep 121,1.7725659866837935,1e-09,45,88 +sweep 122,-0.6273972430449146,1e-09,46,90 +sweep 123,-3.0273604727736236,1e-09,46,90 +sweep 124,0.8558616046774326,1e-09,47,92 +sweep 125,-1.544101625051276,1e-09,46,90 +sweep 126,2.3391204523996016,1e-09,46,90 +sweep 127,-0.06084277732892884,1e-09,47,92 +sweep 128,-2.4608060070576374,1e-09,46,90 +ising zz,0.10362269294859393,1e-11,57,112 +ising x,0.20724538589718786,1e-11,57,112 +ising zz middle,-0.1644907717943757,1e-11,56,110 +ising x middle,-0.3289815435887514,1e-11,57,112 +sweep 1,0.7416294238611401,1e-11,56,110 +sweep 2,-1.6583338058675126,1e-11,56,110 +sweep 3,2.2248882715834206,1e-11,55,108 +sweep 4,-0.175074958145232,1e-11,56,110 +sweep 5,-2.575038187873885,1e-11,56,110 +sweep 6,1.3081838895770481,1e-11,56,110 +sweep 7,-1.0917793401516045,1e-11,54,106 +sweep 8,2.791442737299329,1e-11,57,112 +sweep 9,0.3914795075706756,1e-11,56,110 +sweep 10,-2.008483722157977,1e-11,56,110 +sweep 11,1.8747383552929673,1e-11,56,110 +sweep 12,-0.5252248744356964,1e-11,56,110 +sweep 13,-2.9251881041643606,1e-11,54,106 +sweep 14,0.9580339732865841,1e-11,55,108 +sweep 15,-1.4419292564420578,1e-11,57,112 +sweep 16,2.4412928210088642,1e-11,57,112 +sweep 17,0.041329591280200084,1e-11,55,108 +sweep 18,-2.3586336384484414,1e-11,54,106 +sweep 19,1.5245884390025033,1e-11,53,104 +sweep 20,-0.8753747907261609,1e-11,57,112 +sweep 21,3.007847286724761,1e-11,56,110 +sweep 22,0.6078840569961419,1e-11,57,112 +sweep 23,-1.7920791727325223,1e-11,57,112 +sweep 24,2.0911429047184003,1e-11,55,108 +sweep 25,-0.30882032501026435,1e-11,56,110 +sweep 26,-2.708783554738928,1e-11,55,108 +sweep 27,1.1744385227120384,1e-11,57,112 +sweep 28,-1.2255247070166253,1e-11,57,112 +sweep 29,2.657697370434297,1e-11,57,112 +sweep 30,0.25773414070567746,1e-11,54,106 +sweep 31,-2.1422290890229867,1e-11,55,108 +sweep 32,1.7409929884279354,1e-11,57,112 +sweep 33,-0.6589702413007283,1e-11,52,102 +sweep 34,-3.0589334710293925,1e-11,57,112 +sweep 35,0.8242886064215744,1e-11,56,110 +sweep 36,-1.5756746233070897,1e-11,54,106 +sweep 37,2.3075474541438323,1e-11,56,110 +sweep 38,-0.09241577558478697,1e-11,57,112 +sweep 39,-2.492379005313451,1e-11,57,112 +sweep 40,1.3908430721374714,1e-11,54,106 +sweep 41,-1.0091201575911484,1e-11,55,108 +sweep 42,2.8741019198597293,1e-11,56,110 +sweep 43,0.47413869013111,1e-11,56,110 +sweep 44,-1.9258245395975095,1e-11,58,114 +sweep 45,1.9573975378533683,1e-11,57,112 +sweep 46,-0.4425656918752514,1e-11,57,112 +sweep 47,-2.84252892160396,1e-11,57,112 +sweep 48,1.0406931558470065,1e-11,57,112 +sweep 49,-1.3592700738816128,1e-11,56,110 +sweep 50,2.5239520035692644,1e-11,56,110 +sweep 51,0.12398877384064555,1e-11,54,106 +sweep 52,-2.275974455888063,1e-11,56,110 +sweep 53,1.6072476215629035,1e-11,57,112 +sweep 54,-0.7927156081657158,1e-11,57,112 +sweep 55,3.0905064692851614,1e-11,55,108 +sweep 56,0.6905432395565425,1e-11,55,108 +sweep 57,-1.709419990172077,1e-11,57,112 +sweep 58,2.1738020872788004,1e-11,56,110 +sweep 59,-0.22616114244981889,1e-11,56,110 +sweep 60,-2.626124372178438,1e-11,57,112 +sweep 61,1.2570977052724395,1e-11,56,110 +sweep 62,-1.1428655244561803,1e-11,54,106 +sweep 63,2.7403565529946974,1e-11,56,110 +sweep 64,0.3403933232660781,1e-11,55,108 +sweep 65,-2.0595699064625412,1e-11,55,108 +sweep 66,1.8236521709883364,1e-11,57,112 +sweep 67,-0.5763110587402833,1e-11,57,112 +sweep 68,-2.976274288468992,1e-11,57,112 +sweep 69,0.9069477889819746,1e-11,57,112 +sweep 70,-1.4930154407466447,1e-11,57,112 +sweep 71,2.3902066367042325,1e-11,56,110 +sweep 72,-0.009756593024386362,1e-11,56,110 +sweep 73,-2.409719822753006,1e-11,55,108 +sweep 74,1.4735022546978715,1e-11,56,110 +sweep 75,-0.9264609750307478,1e-11,57,112 +sweep 76,2.956761102420219,1e-11,56,110 +sweep 77,0.5567978726915102,1e-11,57,112 +sweep 78,-1.8431653570371092,1e-11,55,108 +sweep 79,2.0400567204137685,1e-11,57,112 +sweep 80,-0.3599065093148508,1e-11,56,110 +sweep 81,-2.75986973904356,1e-11,56,110 +sweep 82,1.1233523384074964,1e-11,57,112 +sweep 83,-1.2766108913212122,1e-11,55,108 +sweep 84,2.6066111861296655,1e-11,57,112 +sweep 85,0.20664795640113542,1e-11,57,112 +sweep 86,-2.1933152733275736,1e-11,55,108 +sweep 87,1.6899068041233045,1e-11,55,108 +sweep 88,-0.710056425605226,1e-11,56,110 +sweep 89,-3.1100196553339345,1e-11,57,112 +sweep 90,0.7732024221169427,1e-11,55,108 +sweep 91,-1.626760807611766,1e-11,55,108 +sweep 92,2.2564612698392903,1e-11,55,108 +sweep 93,-0.14350195988941827,1e-11,56,110 +sweep 94,-2.5434651896181273,1e-11,55,108 +sweep 95,1.3397568878329293,1e-11,56,110 +sweep 96,-1.0602063418957797,1e-11,56,110 +sweep 97,2.8230157355550975,1e-11,57,112 +sweep 98,0.4230525058265675,1e-11,56,110 +sweep 99,-1.976910723902141,1e-11,57,112 +sweep 100,1.9063113535487366,1e-11,55,108 +sweep 101,-0.49365187617979345,1e-11,56,110 +sweep 102,-2.8936151059085025,1e-11,55,108 +sweep 103,0.9896069715423756,1e-11,56,110 +sweep 104,-1.4103562581863334,1e-11,57,112 +sweep 105,2.4728658192647224,1e-11,56,110 +sweep 106,0.0729025895360138,1e-11,56,110 +sweep 107,-2.3270606401926948,1e-11,55,108 +sweep 108,1.5561614372583614,1e-11,56,110 +sweep 109,-0.8438017924703471,1e-11,56,110 +sweep 110,3.0394202849805305,1e-11,52,102 +sweep 111,0.639457055252,1e-11,56,110 +sweep 112,-1.7605061744767085,1e-11,57,112 +sweep 113,2.1227159029741687,1e-11,57,112 +sweep 114,-0.2772473267543609,1e-11,55,108 +sweep 115,-2.67721055648307,1e-11,57,112 +sweep 116,1.2060115209678077,1e-11,56,110 +sweep 117,-1.1939517087607223,1e-11,57,112 +sweep 118,2.6892703686901553,1e-11,58,114 +sweep 119,0.28930713896144633,1e-11,57,112 +sweep 120,-2.1106560907670837,1e-11,54,106 +sweep 121,1.7725659866837935,1e-11,57,112 +sweep 122,-0.6273972430449146,1e-11,56,110 +sweep 123,-3.0273604727736236,1e-11,57,112 +sweep 124,0.8558616046774326,1e-11,57,112 +sweep 125,-1.544101625051276,1e-11,56,110 +sweep 126,2.3391204523996016,1e-11,55,108 +sweep 127,-0.06084277732892884,1e-11,57,112 +sweep 128,-2.4608060070576374,1e-11,56,110 +ising zz,0.10362269294859393,1e-13,67,132 +ising x,0.20724538589718786,1e-13,67,132 +ising zz middle,-0.1644907717943757,1e-13,67,132 +ising x middle,-0.3289815435887514,1e-13,65,128 +sweep 1,0.7416294238611401,1e-13,67,132 +sweep 2,-1.6583338058675126,1e-13,66,130 +sweep 3,2.2248882715834206,1e-13,65,128 +sweep 4,-0.175074958145232,1e-13,67,132 +sweep 5,-2.575038187873885,1e-13,66,130 +sweep 6,1.3081838895770481,1e-13,67,132 +sweep 7,-1.0917793401516045,1e-13,65,128 +sweep 8,2.791442737299329,1e-13,66,130 +sweep 9,0.3914795075706756,1e-13,66,130 +sweep 10,-2.008483722157977,1e-13,66,130 +sweep 11,1.8747383552929673,1e-13,67,132 +sweep 12,-0.5252248744356964,1e-13,67,132 +sweep 13,-2.9251881041643606,1e-13,66,130 +sweep 14,0.9580339732865841,1e-13,66,130 +sweep 15,-1.4419292564420578,1e-13,66,130 +sweep 16,2.4412928210088642,1e-13,68,134 +sweep 17,0.041329591280200084,1e-13,65,128 +sweep 18,-2.3586336384484414,1e-13,67,132 +sweep 19,1.5245884390025033,1e-13,67,132 +sweep 20,-0.8753747907261609,1e-13,67,132 +sweep 21,3.007847286724761,1e-13,66,130 +sweep 22,0.6078840569961419,1e-13,67,132 +sweep 23,-1.7920791727325223,1e-13,67,132 +sweep 24,2.0911429047184003,1e-13,68,134 +sweep 25,-0.30882032501026435,1e-13,66,130 +sweep 26,-2.708783554738928,1e-13,66,130 +sweep 27,1.1744385227120384,1e-13,66,130 +sweep 28,-1.2255247070166253,1e-13,67,132 +sweep 29,2.657697370434297,1e-13,66,130 +sweep 30,0.25773414070567746,1e-13,66,130 +sweep 31,-2.1422290890229867,1e-13,65,128 +sweep 32,1.7409929884279354,1e-13,67,132 +sweep 33,-0.6589702413007283,1e-13,66,130 +sweep 34,-3.0589334710293925,1e-13,67,132 +sweep 35,0.8242886064215744,1e-13,66,130 +sweep 36,-1.5756746233070897,1e-13,64,126 +sweep 37,2.3075474541438323,1e-13,65,128 +sweep 38,-0.09241577558478697,1e-13,67,132 +sweep 39,-2.492379005313451,1e-13,65,128 +sweep 40,1.3908430721374714,1e-13,67,132 +sweep 41,-1.0091201575911484,1e-13,63,124 +sweep 42,2.8741019198597293,1e-13,67,132 +sweep 43,0.47413869013111,1e-13,66,130 +sweep 44,-1.9258245395975095,1e-13,67,132 +sweep 45,1.9573975378533683,1e-13,66,130 +sweep 46,-0.4425656918752514,1e-13,64,126 +sweep 47,-2.84252892160396,1e-13,65,128 +sweep 48,1.0406931558470065,1e-13,66,130 +sweep 49,-1.3592700738816128,1e-13,65,128 +sweep 50,2.5239520035692644,1e-13,67,132 +sweep 51,0.12398877384064555,1e-13,65,128 +sweep 52,-2.275974455888063,1e-13,64,126 +sweep 53,1.6072476215629035,1e-13,68,134 +sweep 54,-0.7927156081657158,1e-13,66,130 +sweep 55,3.0905064692851614,1e-13,67,132 +sweep 56,0.6905432395565425,1e-13,68,134 +sweep 57,-1.709419990172077,1e-13,67,132 +sweep 58,2.1738020872788004,1e-13,66,130 +sweep 59,-0.22616114244981889,1e-13,64,126 +sweep 60,-2.626124372178438,1e-13,66,130 +sweep 61,1.2570977052724395,1e-13,66,130 +sweep 62,-1.1428655244561803,1e-13,67,132 +sweep 63,2.7403565529946974,1e-13,67,132 +sweep 64,0.3403933232660781,1e-13,67,132 +sweep 65,-2.0595699064625412,1e-13,67,132 +sweep 66,1.8236521709883364,1e-13,67,132 +sweep 67,-0.5763110587402833,1e-13,66,130 +sweep 68,-2.976274288468992,1e-13,65,128 +sweep 69,0.9069477889819746,1e-13,67,132 +sweep 70,-1.4930154407466447,1e-13,66,130 +sweep 71,2.3902066367042325,1e-13,67,132 +sweep 72,-0.009756593024386362,1e-13,65,128 +sweep 73,-2.409719822753006,1e-13,67,132 +sweep 74,1.4735022546978715,1e-13,67,132 +sweep 75,-0.9264609750307478,1e-13,67,132 +sweep 76,2.956761102420219,1e-13,65,128 +sweep 77,0.5567978726915102,1e-13,65,128 +sweep 78,-1.8431653570371092,1e-13,65,128 +sweep 79,2.0400567204137685,1e-13,65,128 +sweep 80,-0.3599065093148508,1e-13,66,130 +sweep 81,-2.75986973904356,1e-13,67,132 +sweep 82,1.1233523384074964,1e-13,67,132 +sweep 83,-1.2766108913212122,1e-13,66,130 +sweep 84,2.6066111861296655,1e-13,66,130 +sweep 85,0.20664795640113542,1e-13,66,130 +sweep 86,-2.1933152733275736,1e-13,66,130 +sweep 87,1.6899068041233045,1e-13,66,130 +sweep 88,-0.710056425605226,1e-13,67,132 +sweep 89,-3.1100196553339345,1e-13,67,132 +sweep 90,0.7732024221169427,1e-13,66,130 +sweep 91,-1.626760807611766,1e-13,65,128 +sweep 92,2.2564612698392903,1e-13,67,132 +sweep 93,-0.14350195988941827,1e-13,65,128 +sweep 94,-2.5434651896181273,1e-13,66,130 +sweep 95,1.3397568878329293,1e-13,66,130 +sweep 96,-1.0602063418957797,1e-13,67,132 +sweep 97,2.8230157355550975,1e-13,67,132 +sweep 98,0.4230525058265675,1e-13,65,128 +sweep 99,-1.976910723902141,1e-13,66,130 +sweep 100,1.9063113535487366,1e-13,66,130 +sweep 101,-0.49365187617979345,1e-13,65,128 +sweep 102,-2.8936151059085025,1e-13,66,130 +sweep 103,0.9896069715423756,1e-13,67,132 +sweep 104,-1.4103562581863334,1e-13,66,130 +sweep 105,2.4728658192647224,1e-13,67,132 +sweep 106,0.0729025895360138,1e-13,68,134 +sweep 107,-2.3270606401926948,1e-13,67,132 +sweep 108,1.5561614372583614,1e-13,66,130 +sweep 109,-0.8438017924703471,1e-13,66,130 +sweep 110,3.0394202849805305,1e-13,65,128 +sweep 111,0.639457055252,1e-13,66,130 +sweep 112,-1.7605061744767085,1e-13,67,132 +sweep 113,2.1227159029741687,1e-13,66,130 +sweep 114,-0.2772473267543609,1e-13,67,132 +sweep 115,-2.67721055648307,1e-13,66,130 +sweep 116,1.2060115209678077,1e-13,67,132 +sweep 117,-1.1939517087607223,1e-13,67,132 +sweep 118,2.6892703686901553,1e-13,67,132 +sweep 119,0.28930713896144633,1e-13,67,132 +sweep 120,-2.1106560907670837,1e-13,66,130 +sweep 121,1.7725659866837935,1e-13,66,130 +sweep 122,-0.6273972430449146,1e-13,66,130 +sweep 123,-3.0273604727736236,1e-13,65,128 +sweep 124,0.8558616046774326,1e-13,64,126 +sweep 125,-1.544101625051276,1e-13,65,128 +sweep 126,2.3391204523996016,1e-13,67,132 +sweep 127,-0.06084277732892884,1e-13,66,130 +sweep 128,-2.4608060070576374,1e-13,66,130 -- 2.54.0 (Apple Git-157) From f13f6cd9ed7b52de11bc78b7b889e4e4c4abec8b Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 6 Nov 2026 07:15:14 -0500 Subject: [PATCH 2/5] wai-quantum: a rotation's word takes the norm equation's cheapest solution On one of the four rotation angles of arXiv:2506.03094's Ising program the synthesiser took 84 T gates where the reference implementation, pygridsynth 1.0.1, takes 82. Both find the same u at the same denominator exponent, 42. The norm equation t't = 2^k - |u|^2 fixes t only up to a unit w^j, and the operators the units give differ by T gates: t' = w.t is T.U.T' with w taken into the second column's phase. The solver's own t was taken; it was w times the reference's, and its operator took two T gates more. Search caps were not the cause: raising the factoring budget to 2^22 and the tries per level to a million changed nothing. engine::synth::rz now writes the operator for each of t, w.t, w^2.t and w^3.t (j and j+4 are conjugate by Z, a Clifford) and keeps the fewest T gates, the solver's own on a tie. The diagonal is the same for every unit, so every word is as near its rotation as before. The tests, failing before the fix: - the_ising_angles_take_no_more_t_gates_than_the_reference: the four angles at 5e-9 took 79, 80, 81, 84 against the reference's 86, 80, 84, 82; now 79, 80, 79, 82. - never_more_t_gates_than_the_reference_over_the_sweep (release): 1,192 angles and precisions against pygridsynth 1.0.1's counts. Before, 157 took more, 530 fewer, 505 equal; now none more, 625 fewer, 567 equal. Pins that moved, every one to fewer T gates: - published_architectures: the Ising program's T gates 14,665,600 -> 14,592,000, its angles' 79, 80, 81, 84 -> 79, 80, 79, 82, and that row's text and the page. - docs/compiler.md's worked certificate: rz(1.1) at 5e-5 40 -> 38 T gates; the output's T count 78 -> 76, gates and depth 200 -> 197, its hash 65e0c256 -> a6aff9b0, phase-fold merges 41 -> 39, and the whole program's distance 7.124e-5 -> 7.270e-5, under its unchanged bound of 7.453e-5 (each rotation's distance is unchanged). No other test of the crate moved: every lib and integration test passed in release on the Linux x86_64 build host on the branch's first base; on this one, the synthesiser, published-architecture, compile, estimate and architecture tests pass in release and debug on Linux aarch64, and the regenerated page differs only in the two rows above. The published figures file takes their new guards. The resource-estimation workflow runs the synthesiser's tests in release and requires three by name. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/wai-quantum-estimate.yml | 16 +++- wai/changes/2026-11-06-rz-fewest-t-unit.md | 17 ++++ wai/wai-quantum/docs/compiler.md | 12 +-- .../docs/published-architectures.md | 8 +- wai/wai-quantum/src/engine/synth/rz.rs | 88 ++++++++++++++++++- .../src/published_architectures.rs | 6 +- .../tests/data/published_figures.tsv | 4 +- 7 files changed, 132 insertions(+), 19 deletions(-) create mode 100644 wai/changes/2026-11-06-rz-fewest-t-unit.md diff --git a/.github/workflows/wai-quantum-estimate.yml b/.github/workflows/wai-quantum-estimate.yml index fbb7b6a46..8c7ad2308 100644 --- a/.github/workflows/wai-quantum-estimate.yml +++ b/.github/workflows/wai-quantum-estimate.yml @@ -13,7 +13,9 @@ name: wai-quantum resource estimation # (quantum_arch, quantum_bicycle and the estimate job), holds every row to its # published figure (tests/data/published_figures.tsv: the digits it is printed # to, or a guard on ours) and the page docs/published-architectures.md to what -# they give. Its search over 4¹¹ Paulis runs in a release build only. +# they give. Its search over 4¹¹ Paulis runs in a release build only. So does +# the synthesiser's sweep against the reference implementation's T counts +# (engine::synth::rz), which every rotation's T count in an estimate comes from. # # In a release build the calibration test measures every point of the # decoders' table again (the rotated surface-code memory experiment, decoded @@ -112,6 +114,18 @@ jobs: grep -q "^test $t \.\.\. ok$" "$RUNNER_TEMP/published.log" || { echo "::error::$t did not run and pass"; exit 1; } done cargo run --locked --release --example published_architectures --features full + - name: Each rotation's Clifford+T word against the reference implementation's T counts + shell: bash + working-directory: wai/wai-quantum + run: | + set -euo pipefail + cargo test --locked --release --features full --lib -- engine::synth::rz:: 2>&1 | tee "$RUNNER_TEMP/rz.log" + grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed; 0 ignored' "$RUNNER_TEMP/rz.log" || { echo "::error::the synthesiser's tests did not all run and pass"; exit 1; } + for t in engine::synth::rz::tests::never_more_t_gates_than_the_reference_over_the_sweep \ + engine::synth::rz::tests::the_ising_angles_take_no_more_t_gates_than_the_reference \ + engine::synth::rz::tests::the_t_count_is_the_optimum_found_by_exhaustive_search; do + grep -q "^test $t \.\.\. ok$" "$RUNNER_TEMP/rz.log" || { echo "::error::$t did not run and pass"; exit 1; } + done - name: The engine without receipts still builds the estimate shell: bash working-directory: wai/wai-quantum diff --git a/wai/changes/2026-11-06-rz-fewest-t-unit.md b/wai/changes/2026-11-06-rz-fewest-t-unit.md new file mode 100644 index 000000000..5aab108e4 --- /dev/null +++ b/wai/changes/2026-11-06-rz-fewest-t-unit.md @@ -0,0 +1,17 @@ +### wai-quantum: a rotation's Clifford+T word takes the norm equation's cheapest solution + +- `engine::synth::rz` writes, for each solution `u` it finds, every completion `t·ωʲ` of the + norm equation `t†t = 2ᵏ − |u|²` and keeps the one whose operator takes the fewest `T` + gates. The equation fixes `t` only up to that unit, and the operators the units give + differ by `T` gates; the solver's own unit was taken before. Every word is as near its + rotation as before, and none takes more `T` gates than before. +- Its tests hold the `T` counts to pygridsynth 1.0.1's, the reference implementation, on + the Ising program of arXiv:2506.03094 and 128 angles at ε from 10⁻¹ to 10⁻¹³ + (`tests/data/rz_gridsynth_oracle.csv`, written by + `wai/tools/quantum-rz-oracle/gridsynth_oracle.py`, which CI does not run): never more. + Before this change 157 of those 1,192 took more. +- `T` counts that move: the Ising program's four angles at 5·10⁻⁹, 79, 80, 81, 84 → 79, 80, + 79, 82 (14,665,600 → 14,592,000 over the program, in the published-architecture check); + `rz(1.1)` at 5·10⁻⁵, 40 → 38, and with it the compiler's worked certificate (78 → 76 `T` + gates, 200 → 197 gates). A compiled program's output, its hash and the receipts that seal + it change wherever one of its rotations takes fewer `T` gates. diff --git a/wai/wai-quantum/docs/compiler.md b/wai/wai-quantum/docs/compiler.md index 7e09602e3..ef4987193 100644 --- a/wai/wai-quantum/docs/compiler.md +++ b/wai/wai-quantum/docs/compiler.md @@ -104,8 +104,8 @@ For `h q[0]; rz(0.3) q[0]; cx q[0], q[1]; ry(1.1) q[1];` at `--epsilon 1e-4` "level": 1, "source": { "hash": "3088646d…", "qubits": 2, "counts": { "gates": 4, "cnots": 1, "t_count": 0, "rotations": 2, "depth": 4, "…": "…" } }, - "output": { "hash": "65e0c256…", - "counts": { "gates": 200, "cnots": 1, "t_count": 78, "rotations": 0, "depth": 200, "…": "…" } }, + "output": { "hash": "a6aff9b0…", + "counts": { "gates": 197, "cnots": 1, "t_count": 76, "rotations": 0, "depth": 197, "…": "…" } }, "epsilon": { "budget": 0.0001, "rotations": 2, "each": 5e-05, "bound": 7.453429548248133e-05 }, "passes": [ { "pass": "simplify", "before": { "…": "…" }, "after": { "…": "…" }, @@ -114,16 +114,16 @@ For `h q[0]; rz(0.3) q[0]; cx q[0], q[1]; ry(1.1) q[1];` at `--epsilon 1e-4` "check": { "how": "each kind of gate against its decomposition, on its own qubits", "verdict": "exact", "checked": 1, "distance": 5.551115123125783e-17 } }, { "pass": "approximate", "…": "…", "check": { "how": "each rotation's Clifford+T word multiplied out in exact ring arithmetic, and its operator-norm distance to the rotation recomputed from the word in fixed point and rounded up", - "verdict": "approximate", "rotations": 2, "epsilon_each": 5e-05, "t_count": 78, "distance": 7.453429548248133e-05 } }, + "verdict": "approximate", "rotations": 2, "epsilon_each": 5e-05, "t_count": 76, "distance": 7.453429548248133e-05 } }, { "pass": "phase_fold", "…": "…", - "check": { "how": "the phase polynomial recomputed: … in whole eighths of a turn", "verdict": "proof", "merged": 41 } }, + "check": { "how": "the phase polynomial recomputed: … in whole eighths of a turn", "verdict": "proof", "merged": 39 } }, { "…": "…" } ], "rotations": [ { "angle": 0.3, "t_count": 38, "distance": 3.77439802702028e-05, "k": 20 }, - { "angle": 1.1, "t_count": 40, "distance": 3.679031521227853e-05, "k": 20 } + { "angle": 1.1, "t_count": 38, "distance": 3.679031521227853e-05, "k": 20 } ], - "whole": { "how": "the dense unitaries of the whole program and the whole output", "distance": 7.123665880156653e-05, "verdict": "approximate" }, + "whole": { "how": "the dense unitaries of the whole program and the whole output", "distance": 7.269652454265581e-05, "verdict": "approximate" }, "verdict": "approximate", "reading": "The output equals the program up to a global phase to within 7.453429548248133e-5 in the operator norm (the budget was 1e-4). …" } diff --git a/wai/wai-quantum/docs/published-architectures.md b/wai/wai-quantum/docs/published-architectures.md index 83bb3577b..c2a37bc42 100644 --- a/wai/wai-quantum/docs/published-architectures.md +++ b/wai/wai-quantum/docs/published-architectures.md @@ -84,7 +84,9 @@ Ising program. Its other differences are explained in their rows: capability at 10⁻³ (its own row). - Its Ising program takes 15,542,400 T gates in its tables and 19,036,800 in its text and Fig. 1. pygridsynth 1.0.1, the version it cites, gives the - 15,542,400 exactly. + 15,542,400 exactly. Our synthesiser also searches the rotations one global + phase away and takes 6.1% fewer, and no more than pygridsynth on any of the + angles and precisions its tests compare. - Its gross Ising machine of 4,817 qubits takes the adapter of the 10⁻³ factory beside the 10⁻⁴ factory it names (4,801). - The Ising program's inter-module measurements match its 946,800 with the @@ -268,8 +270,8 @@ its own formula, and so on. Its Toffoli count comes back. | in-module measurements `N_M`, two-gross | arXiv:2506.03094 Table 9, source files | 4,238,828 | 4,148,800 | -2.12% | our limit | Ours removes no repeated in-module measurement, which theirs does (§4), and takes sites in order, which it does not print. Its counts also carry the compile section's action of a shift on Z̄, which puts its gross below its two-gross; ours has them the other way round. | | automorphisms `N_U`, gross | arXiv:2506.03094 Table 9, source files | 2,270,400 | 2,728,800 | +20.19% | our limit | Ours takes the fewest shifts on a path of fewest measurements, and merges none; theirs is a compiler's. | | automorphisms `N_U`, two-gross | arXiv:2506.03094 Table 9, source files | 2,294,400 | 2,368,000 | +3.21% | our limit | Ours takes the fewest shifts on a path of fewest measurements, and merges none; theirs is a compiler's. | -| T injections `N_T` | arXiv:2506.03094 Table 9, source files | 15,542,400 | 14,665,600 | -5.64% | their model | pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives 79, 80, 81 and 84, and also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows. | -| T injections as §4 and Fig. 1(b) state | arXiv:2506.03094 §4; Fig. 1(b), source files | 1.9·10⁷ (Fig. 1(b): 19,036,800) | 14,665,600 | -22.96% | their numbers | §4 says N_T = 1.9·10⁷ and Fig. 1(b) plots 19,036,800. Table 9 and every failure probability of Table 10 take 15,542,400, which the row above compares ours with. | +| T injections `N_T` | arXiv:2506.03094 Table 9, source files | 15,542,400 | 14,592,000 | -6.11% | their model | pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives 79, 80, 79 and 82: it also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows, and of the norm equation's solutions it keeps the one whose operator takes the fewest T gates. It takes no more than the reference on any of 1,192 angles and precisions (engine::synth::rz's tests). | +| T injections as §4 and Fig. 1(b) state | arXiv:2506.03094 §4; Fig. 1(b), source files | 1.9·10⁷ (Fig. 1(b): 19,036,800) | 14,592,000 | -23.35% | their numbers | §4 says N_T = 1.9·10⁷ and Fig. 1(b) plots 19,036,800. Table 9 and every failure probability of Table 10 take 15,542,400, which the row above compares ours with. | | idles `N_I`, two-gross, from its `N_T` | arXiv:2506.03094 Table 9, source files | 41,636,714,298 | 42,100,476,000 | +1.11% | our limit | Ours: every module idles while the factory works, and otherwise never. Theirs counts the idles of its schedule. | | failure probability, gross, p = 10⁻³, its counts | arXiv:2506.03094 Table 10 | 3.33·10⁴ | 3.331e4 | +0.03% | agrees | Table 9's counts at our evaluation of Table 6's fits (Eq. (26)); the band moves the fits' parameters by their last printed digit. | | failure probability, gross, p = 10⁻⁴, its counts | arXiv:2506.03094 Table 10 | 7.97·10⁻¹ | 7.977e-1 | +0.09% | agrees | Table 9's counts at our evaluation of Table 6's fits (Eq. (26)); the band moves the fits' parameters by their last printed digit. | diff --git a/wai/wai-quantum/src/engine/synth/rz.rs b/wai/wai-quantum/src/engine/synth/rz.rs index 458579005..910eb15f4 100644 --- a/wai/wai-quantum/src/engine/synth/rz.rs +++ b/wai/wai-quantum/src/engine/synth/rz.rs @@ -14,7 +14,14 @@ //! grid problem ([`super::grid`]), each tested exactly; for each, `t†t = //! 2ᵏ − |u|²` is solved ([`super::dioph`]); the first `k` with a solution //! gives the operator, which [`super::ring::synthesize`] writes as the word -//! with the fewest `T` gates. The `T` count is about `3·log₂(1/ε)`. +//! with the fewest `T` gates. The equation fixes `t` only up to a unit `ωʲ`, +//! and the operators the units give differ by `T` gates, so each is written +//! and the fewest kept. The `T` count is about `3·log₂(1/ε)`. +//! +//! The tests hold the `T` counts to pygridsynth 1.0.1's, the reference +//! implementation, on 1,192 angles and precisions +//! (`tests/data/rz_gridsynth_oracle.csv`, written by +//! `wai/tools/quantum-rz-oracle/gridsynth_oracle.py`): never more. //! //! What is returned has been checked twice over: the word multiplies back, //! exactly, to the operator found, and its distance to `Rz(θ)` is computed @@ -84,6 +91,29 @@ pub fn word_distance(gates: &[Kind], theta: f64) -> f64 { d + d * 1e-15 + f64::MIN_POSITIVE } +/// The operator `(1/√2ᵏ)·[[u, −t'†ωˡ], [t', u†ωˡ]]` with the fewest `T` gates, +/// over the solutions `t' = ωʲ·t` of the norm equation, as a word. +/// +/// `t†t = 2ᵏ − |u|²` fixes `t` only up to a unit `ωʲ`, and the operators the +/// choices give differ by `T` gates: `t' = ω·t` is `T·U·T†` with `ω` taken +/// into the second column's phase. Their diagonals are the same, so each is +/// as near `Rz(θ)`. `j` and `j + 4` give operators conjugate by `Z`, a +/// Clifford, with one `T` count, so `j < 4` covers them. The solver's own `t` +/// comes first and is kept on a tie. +fn fewest_t_completion(u: &Zw, t: &Zw, l: i64, k: u32) -> Result { + let wl = Zw::omega(l); + let mut best: Option = None; + for j in 0..4 { + let tj = t.mul_omega(j); + let op = Mat2::new([u.clone(), tj.adj().mul(&wl).neg(), tj, u.adj().mul(&wl)], k); + let word = synthesize(&op)?; + if best.as_ref().is_none_or(|b| word.t_count < b.t_count) { + best = Some(word); + } + } + Ok(best.expect("four completions were written")) +} + /// The word for `Rz(mπ/4)` up to a phase: `T^m`. fn quarter_word(m: i64) -> Vec { match m.rem_euclid(8) { @@ -165,9 +195,7 @@ pub fn rz(theta: f64, epsilon: f64) -> Result { equations += 1; let mut budget = FACTOR_BUDGET; let Some(t) = dioph::solve(&xi, &mut budget) else { continue }; - let wl = Zw::omega(*l); - let op = Mat2::new([u.clone(), t.adj().mul(&wl).neg(), t, u.adj().mul(&wl)], k); - let word = synthesize(&op)?; + let word = fewest_t_completion(u, &t, *l, k)?; let distance = word_distance(&word.gates, theta); if distance <= epsilon { found.push((word.gates, word.t_count, distance)); @@ -340,4 +368,56 @@ mod tests { assert!(rz(0.3, 0.6).is_err()); assert!(rz(f64::NAN, 1e-3).is_err()); } + + /// The reference T counts: pygridsynth 1.0.1, run by + /// `wai/tools/quantum-rz-oracle/gridsynth_oracle.py` on the four angles of + /// the Ising program of arXiv:2506.03094 and on 128 angles over (−π, π), + /// at ε from 10⁻¹ to 10⁻¹³. Rows: name, θ, ε, its exponent, its T count. + fn oracle() -> Vec<(String, f64, f64, usize)> { + include_str!("../../../tests/data/rz_gridsynth_oracle.csv") + .lines() + .skip(1) + .map(|line| { + let f: Vec<&str> = line.split(',').collect(); + (f[0].to_string(), f[1].parse().unwrap(), f[2].parse().unwrap(), f[4].parse().unwrap()) + }) + .collect() + } + + #[test] + fn the_ising_angles_take_no_more_t_gates_than_the_reference() { + // At ε = 5·10⁻⁹ the reference takes 86, 80, 84 and 82: 15,542,400 over + // the program. Here the third took 81 and the fourth 84 while the norm + // equation's unit was taken as the solver gave it. + let rows: Vec<_> = oracle().into_iter().filter(|r| r.0.starts_with("ising") && r.2 == 5e-9).collect(); + assert_eq!(rows.iter().map(|r| r.3).collect::>(), [86, 80, 84, 82]); + let ours: Vec = rows.iter().map(|r| rz(r.1, r.2).unwrap().t_count).collect(); + for (r, t) in rows.iter().zip(&ours) { + assert!(*t <= r.3, "{}: {t} T gates, the reference {}", r.0, r.3); + } + assert_eq!(ours, [79, 80, 79, 82]); + } + + #[test] + #[cfg_attr(debug_assertions, ignore = "about twelve hundred syntheses: release only")] + fn never_more_t_gates_than_the_reference_over_the_sweep() { + let rows = oracle(); + assert_eq!(rows.len(), 1192); + let (mut fewer, mut equal, mut saved) = (0, 0, 0); + let mut worse = Vec::new(); + for (name, theta, eps, reference) in &rows { + let r = rz(*theta, *eps).unwrap(); + assert!(r.distance <= *eps, "{name}, ε {eps}: distance {}", r.distance); + match r.t_count.cmp(reference) { + std::cmp::Ordering::Less => { + fewer += 1; + saved += reference - r.t_count; + } + std::cmp::Ordering::Equal => equal += 1, + std::cmp::Ordering::Greater => worse.push(format!("{name} θ {theta} ε {eps}: {} against {reference}", r.t_count)), + } + } + eprintln!("against the reference: {fewer} fewer ({saved} T gates in all), {equal} equal, {} more", worse.len()); + assert!(worse.is_empty(), "{} rows take more T gates than the reference: {worse:#?}", worse.len()); + } } diff --git a/wai/wai-quantum/src/published_architectures.rs b/wai/wai-quantum/src/published_architectures.rs index f88fccdfd..e3cf7892a 100644 --- a/wai/wai-quantum/src/published_architectures.rs +++ b/wai/wai-quantum/src/published_architectures.rs @@ -506,7 +506,7 @@ fn ising(gross: &PauliCosts, two: &PauliCosts) -> Result { F::I, Class::TheirModel, format!( - "pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives {}, {}, {} and {}, and also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows.", + "pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives {}, {}, {} and {}: it also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows, and of the norm equation's solutions it keeps the one whose operator takes the fewest T gates. It takes no more than the reference on any of 1,192 angles and precisions (engine::synth::rz's tests).", counts[0], counts[1], counts[2], counts[3] ), ); @@ -907,8 +907,8 @@ mod tests { /// The Ising row's text names these. #[test] fn the_ising_angles_take_these_t_counts() { - assert_eq!(ising_t_counts(5e-9).unwrap(), [79, 80, 81, 84]); - assert_eq!(ising_t_count(5e-9).unwrap(), 14_665_600); + assert_eq!(ising_t_counts(5e-9).unwrap(), [79, 80, 79, 82]); + assert_eq!(ising_t_count(5e-9).unwrap(), 14_592_000); // pygridsynth 1.0.1's counts on the same angles give the source's total. assert_eq!(80 * (4 * (360 * 86 + 100 * 80) + 360 * 84 + 100 * 82), 15_542_400); } diff --git a/wai/wai-quantum/tests/data/published_figures.tsv b/wai/wai-quantum/tests/data/published_figures.tsv index 2bbd77606..8f3d5e0f1 100644 --- a/wai/wai-quantum/tests/data/published_figures.tsv +++ b/wai/wai-quantum/tests/data/published_figures.tsv @@ -104,8 +104,8 @@ table9.gross.nm arXiv:2506.03094 Table 9, source files 4,215,240 4215240 guard 4 table9.two.nm arXiv:2506.03094 Table 9, source files 4,238,828 4238828 guard 4.149e6 table9.gross.nu arXiv:2506.03094 Table 9, source files 2,270,400 2270400 guard 2.729e6 table9.two.nu arXiv:2506.03094 Table 9, source files 2,294,400 2294400 guard 2.368e6 -table9.nt arXiv:2506.03094 Table 9, source files 15,542,400 15542400 guard 1.467e7 -s4.nt arXiv:2506.03094 §4; Fig. 1(b), source files 1.9·10⁷ (Fig. 1(b): 19,036,800) 19036800 guard 1.467e7 +table9.nt arXiv:2506.03094 Table 9, source files 15,542,400 15542400 guard 1.459e7 +s4.nt arXiv:2506.03094 §4; Fig. 1(b), source files 1.9·10⁷ (Fig. 1(b): 19,036,800) 19036800 guard 1.459e7 table9.two.ni arXiv:2506.03094 Table 9, source files 41,636,714,298 41636714298 guard 4.210e10 table10.fail.gross.1e-3 arXiv:2506.03094 Table 10 3.33·10⁴ 33300.0 band 100.0 table10.fail.gross.1e-4 arXiv:2506.03094 Table 10 7.97·10⁻¹ 0.797 band 0.001 -- 2.54.0 (Apple Git-157) From ba9da0fdf31c2e9df9b9ebdf1c85b993c66f60d2 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Sat, 7 Nov 2026 03:15:58 -0500 Subject: [PATCH 3/5] wai-quantum: what the unit search does to a rotation, as it is MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The review of the synthesiser's fix found two claims that were wider than the code. The norm equation does not fix t up to a unit. Where a prime that splits in Z[ω] divides 2^k − |u|², it has other solutions, and the solver returns one of them. The search writes that solution's four unit multiples. The module, the function, the published row and the change note now say so. "Every word is as near its rotation as before" holds for each u, not for each rotation. The search runs over every u, and a u that lost may now win, with its own distance. Over the oracle's 1,192 rows, 350 words change, 57 of them at an unchanged T count, and 87 rotations end farther from Rz(θ). None ends past its ε. At an equal count none is farther. The Ising program's middle angle at 10⁻³ goes from 29 T gates at 3.50·10⁻⁴ to 27 at 6.15·10⁻⁴. The change note gives that rule, and says outputs change wherever a word does, not only where a count drops. rz_by takes the completion as an argument, so the tests compare the search with the solver's own unit: - the_unit_search_takes_no_more_t_gates_and_at_one_count_is_no_farther pins the tally over the sweep (release); - fewer_t_gates_can_end_farther_and_one_count_can_take_another_word holds the two cases above. The workflow requires both by name, and the published-architecture test refuses the old wording. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/wai-quantum-estimate.yml | 2 + wai/changes/2026-11-06-rz-fewest-t-unit.md | 22 +++-- .../docs/published-architectures.md | 2 +- wai/wai-quantum/src/engine/synth/rz.rs | 87 ++++++++++++++++--- .../src/published_architectures.rs | 4 +- 5 files changed, 94 insertions(+), 23 deletions(-) diff --git a/.github/workflows/wai-quantum-estimate.yml b/.github/workflows/wai-quantum-estimate.yml index bb684fb1c..0ffb5b0ff 100644 --- a/.github/workflows/wai-quantum-estimate.yml +++ b/.github/workflows/wai-quantum-estimate.yml @@ -123,6 +123,8 @@ jobs: grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed; 0 ignored' "$RUNNER_TEMP/rz.log" || { echo "::error::the synthesiser's tests did not all run and pass"; exit 1; } for t in engine::synth::rz::tests::never_more_t_gates_than_the_reference_over_the_sweep \ engine::synth::rz::tests::the_ising_angles_take_no_more_t_gates_than_the_reference \ + engine::synth::rz::tests::the_unit_search_takes_no_more_t_gates_and_at_one_count_is_no_farther \ + engine::synth::rz::tests::fewer_t_gates_can_end_farther_and_one_count_can_take_another_word \ engine::synth::rz::tests::the_t_count_is_the_optimum_found_by_exhaustive_search; do grep -q "^test $t \.\.\. ok$" "$RUNNER_TEMP/rz.log" || { echo "::error::$t did not run and pass"; exit 1; } done diff --git a/wai/changes/2026-11-06-rz-fewest-t-unit.md b/wai/changes/2026-11-06-rz-fewest-t-unit.md index 5aab108e4..496be822a 100644 --- a/wai/changes/2026-11-06-rz-fewest-t-unit.md +++ b/wai/changes/2026-11-06-rz-fewest-t-unit.md @@ -1,10 +1,17 @@ -### wai-quantum: a rotation's Clifford+T word takes the norm equation's cheapest solution +### wai-quantum: a rotation's Clifford+T word takes the cheapest unit of the solver's solution -- `engine::synth::rz` writes, for each solution `u` it finds, every completion `t·ωʲ` of the - norm equation `t†t = 2ᵏ − |u|²` and keeps the one whose operator takes the fewest `T` - gates. The equation fixes `t` only up to that unit, and the operators the units give - differ by `T` gates; the solver's own unit was taken before. Every word is as near its - rotation as before, and none takes more `T` gates than before. +- `engine::synth::rz` writes, for each solution `u` it finds, the four unit multiples + `ωʲ·t` of the solver's solution of the norm equation `t†t = 2ᵏ − |u|²`, and keeps the one + whose operator takes the fewest `T` gates; the solver's own unit was taken before. The + operators the units give differ by `T` gates and share a diagonal, so for one `u` the word + is exactly as near. The equation has other solutions where a prime that splits in `Z[ω]` + divides its right side; the solver returns one, and those are not tried. +- Which `u` a rotation ends on can change, since one that lost may now win: the fewest `T` + gates win, then the nearest. So no rotation takes more `T` gates than before; at an equal + `T` count it is no farther; at a lower count it can be farther, and never past its `ε`. + Over the 1,192 rows below, 350 words changed, 57 of them at an unchanged `T` count, and 87 + rotations ended farther from `Rz(θ)`; the Ising program's middle angle at `ε` = 10⁻³ goes + from 29 `T` gates at 3.50·10⁻⁴ to 27 at 6.15·10⁻⁴. - Its tests hold the `T` counts to pygridsynth 1.0.1's, the reference implementation, on the Ising program of arXiv:2506.03094 and 128 angles at ε from 10⁻¹ to 10⁻¹³ (`tests/data/rz_gridsynth_oracle.csv`, written by @@ -14,4 +21,5 @@ 79, 82 (14,665,600 → 14,592,000 over the program, in the published-architecture check); `rz(1.1)` at 5·10⁻⁵, 40 → 38, and with it the compiler's worked certificate (78 → 76 `T` gates, 200 → 197 gates). A compiled program's output, its hash and the receipts that seal - it change wherever one of its rotations takes fewer `T` gates. + it change wherever one of its rotations takes another word, at an unchanged `T` count + too, and a certificate's summed distances can rise with them, never past its budget. diff --git a/wai/wai-quantum/docs/published-architectures.md b/wai/wai-quantum/docs/published-architectures.md index c2a37bc42..760abdc42 100644 --- a/wai/wai-quantum/docs/published-architectures.md +++ b/wai/wai-quantum/docs/published-architectures.md @@ -270,7 +270,7 @@ its own formula, and so on. Its Toffoli count comes back. | in-module measurements `N_M`, two-gross | arXiv:2506.03094 Table 9, source files | 4,238,828 | 4,148,800 | -2.12% | our limit | Ours removes no repeated in-module measurement, which theirs does (§4), and takes sites in order, which it does not print. Its counts also carry the compile section's action of a shift on Z̄, which puts its gross below its two-gross; ours has them the other way round. | | automorphisms `N_U`, gross | arXiv:2506.03094 Table 9, source files | 2,270,400 | 2,728,800 | +20.19% | our limit | Ours takes the fewest shifts on a path of fewest measurements, and merges none; theirs is a compiler's. | | automorphisms `N_U`, two-gross | arXiv:2506.03094 Table 9, source files | 2,294,400 | 2,368,000 | +3.21% | our limit | Ours takes the fewest shifts on a path of fewest measurements, and merges none; theirs is a compiler's. | -| T injections `N_T` | arXiv:2506.03094 Table 9, source files | 15,542,400 | 14,592,000 | -6.11% | their model | pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives 79, 80, 79 and 82: it also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows, and of the norm equation's solutions it keeps the one whose operator takes the fewest T gates. It takes no more than the reference on any of 1,192 angles and precisions (engine::synth::rz's tests). | +| T injections `N_T` | arXiv:2506.03094 Table 9, source files | 15,542,400 | 14,592,000 | -6.11% | their model | pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives 79, 80, 79 and 82: it also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows, and of the solver's solution of the norm equation and its unit multiples it keeps the one whose operator takes the fewest T gates. It takes no more than the reference on any of 1,192 angles and precisions (engine::synth::rz's tests). | | T injections as §4 and Fig. 1(b) state | arXiv:2506.03094 §4; Fig. 1(b), source files | 1.9·10⁷ (Fig. 1(b): 19,036,800) | 14,592,000 | -23.35% | their numbers | §4 says N_T = 1.9·10⁷ and Fig. 1(b) plots 19,036,800. Table 9 and every failure probability of Table 10 take 15,542,400, which the row above compares ours with. | | idles `N_I`, two-gross, from its `N_T` | arXiv:2506.03094 Table 9, source files | 41,636,714,298 | 42,100,476,000 | +1.11% | our limit | Ours: every module idles while the factory works, and otherwise never. Theirs counts the idles of its schedule. | | failure probability, gross, p = 10⁻³, its counts | arXiv:2506.03094 Table 10 | 3.33·10⁴ | 3.331e4 | +0.03% | agrees | Table 9's counts at our evaluation of Table 6's fits (Eq. (26)); the band moves the fits' parameters by their last printed digit. | diff --git a/wai/wai-quantum/src/engine/synth/rz.rs b/wai/wai-quantum/src/engine/synth/rz.rs index 910eb15f4..1b34b3c29 100644 --- a/wai/wai-quantum/src/engine/synth/rz.rs +++ b/wai/wai-quantum/src/engine/synth/rz.rs @@ -14,9 +14,18 @@ //! grid problem ([`super::grid`]), each tested exactly; for each, `t†t = //! 2ᵏ − |u|²` is solved ([`super::dioph`]); the first `k` with a solution //! gives the operator, which [`super::ring::synthesize`] writes as the word -//! with the fewest `T` gates. The equation fixes `t` only up to a unit `ωʲ`, -//! and the operators the units give differ by `T` gates, so each is written -//! and the fewest kept. The `T` count is about `3·log₂(1/ε)`. +//! with the fewest `T` gates. Every unit multiple `ωʲ·t` of the solver's `t` +//! solves the equation too, and the operators they give differ by `T` gates, +//! so each is written and the fewest kept. (The equation has other solutions +//! where a prime that splits in `Z[ω]` divides `2ᵏ − |u|²`; the solver returns +//! one, and those are not tried.) The `T` count is about `3·log₂(1/ε)`. +//! +//! Of the words within `ε` at that `k`, the fewest `T` gates win, then the +//! nearest. So what the unit search does to a rotation is this: it never takes +//! more `T` gates than the solver's own unit would; at an equal count it is no +//! farther; at a lower count it can be farther, because a `u` that lost may now +//! win with its own distance, but never past `ε`. Its word can change at an +//! equal count too. //! //! The tests hold the `T` counts to pygridsynth 1.0.1's, the reference //! implementation, on 1,192 angles and precisions @@ -92,14 +101,15 @@ pub fn word_distance(gates: &[Kind], theta: f64) -> f64 { } /// The operator `(1/√2ᵏ)·[[u, −t'†ωˡ], [t', u†ωˡ]]` with the fewest `T` gates, -/// over the solutions `t' = ωʲ·t` of the norm equation, as a word. +/// over the unit multiples `t' = ωʲ·t` of the solver's solution of the norm +/// equation, as a word. /// -/// `t†t = 2ᵏ − |u|²` fixes `t` only up to a unit `ωʲ`, and the operators the -/// choices give differ by `T` gates: `t' = ω·t` is `T·U·T†` with `ω` taken -/// into the second column's phase. Their diagonals are the same, so each is -/// as near `Rz(θ)`. `j` and `j + 4` give operators conjugate by `Z`, a -/// Clifford, with one `T` count, so `j < 4` covers them. The solver's own `t` -/// comes first and is kept on a tie. +/// Each `ωʲ·t` solves `t†t = 2ᵏ − |u|²`, and the operators they give differ by +/// `T` gates: `t' = ω·t` is `T·U·T†` with `ω` taken into the second column's +/// phase. Their diagonals are the same, so for this `u` each is as near +/// `Rz(θ)`. `j` and `j + 4` give operators conjugate by `Z`, a Clifford, with +/// one `T` count, so `j < 4` covers them. The solver's own `t` comes first and +/// is kept on a tie. fn fewest_t_completion(u: &Zw, t: &Zw, l: i64, k: u32) -> Result { let wl = Zw::omega(l); let mut best: Option = None; @@ -132,6 +142,11 @@ fn quarter_word(m: i64) -> Vec { /// search finds at the least denominator exponent; refused for `ε` outside /// [`MIN_EPSILON`, `MAX_EPSILON`]. pub fn rz(theta: f64, epsilon: f64) -> Result { + rz_by(theta, epsilon, fewest_t_completion) +} + +/// [`rz`], each `u`'s operator written by `complete`. +fn rz_by(theta: f64, epsilon: f64, complete: fn(&Zw, &Zw, i64, u32) -> Result) -> Result { if !theta.is_finite() { return Err(format!("the angle {theta} is not a number")); } @@ -195,7 +210,7 @@ pub fn rz(theta: f64, epsilon: f64) -> Result { equations += 1; let mut budget = FACTOR_BUDGET; let Some(t) = dioph::solve(&xi, &mut budget) else { continue }; - let word = fewest_t_completion(u, &t, *l, k)?; + let word = complete(u, &t, *l, k)?; let distance = word_distance(&word.gates, theta); if distance <= epsilon { found.push((word.gates, word.t_count, distance)); @@ -387,8 +402,8 @@ mod tests { #[test] fn the_ising_angles_take_no_more_t_gates_than_the_reference() { // At ε = 5·10⁻⁹ the reference takes 86, 80, 84 and 82: 15,542,400 over - // the program. Here the third took 81 and the fourth 84 while the norm - // equation's unit was taken as the solver gave it. + // the program. Here the third took 81 and the fourth 84 while the + // solver's own unit was taken. let rows: Vec<_> = oracle().into_iter().filter(|r| r.0.starts_with("ising") && r.2 == 5e-9).collect(); assert_eq!(rows.iter().map(|r| r.3).collect::>(), [86, 80, 84, 82]); let ours: Vec = rows.iter().map(|r| rz(r.1, r.2).unwrap().t_count).collect(); @@ -420,4 +435,50 @@ mod tests { eprintln!("against the reference: {fewer} fewer ({saved} T gates in all), {equal} equal, {} more", worse.len()); assert!(worse.is_empty(), "{} rows take more T gates than the reference: {worse:#?}", worse.len()); } + + /// The operator as the solver's own `t` gives it, as [`rz`] once took it. + fn the_solver_s_own_unit(u: &Zw, t: &Zw, l: i64, k: u32) -> Result { + let wl = Zw::omega(l); + synthesize(&Mat2::new([u.clone(), t.adj().mul(&wl).neg(), t.clone(), u.adj().mul(&wl)], k)) + } + + /// Each `u` keeps its distance whatever the unit, but the search is over + /// every `u`, and one that lost may now win: fewer `T` gates can end + /// farther, and one count can take another word. + #[test] + fn fewer_t_gates_can_end_farther_and_one_count_can_take_another_word() { + // The Ising program's zz middle angle at ε = 10⁻³. + let (theta, eps) = (-0.1644907717943757, 1e-3); + let (now, before) = (rz(theta, eps).unwrap(), rz_by(theta, eps, the_solver_s_own_unit).unwrap()); + assert_eq!((before.t_count, now.t_count), (29, 27)); + assert!(now.distance > before.distance && now.distance <= eps, "{} against {}", now.distance, before.distance); + // rz(0.1) at ε = 10⁻⁹: 89 T gates both ways, another word, nearer. + let (now, before) = (rz(0.1, 1e-9).unwrap(), rz_by(0.1, 1e-9, the_solver_s_own_unit).unwrap()); + assert_eq!((before.t_count, now.t_count), (89, 89)); + assert_ne!(now.gates, before.gates); + assert!(now.distance < before.distance, "{} against {}", now.distance, before.distance); + } + + /// What the unit search can do to a rotation, over the oracle's rows: + /// never more `T` gates, no farther at an equal count, always within `ε`. + #[test] + #[cfg_attr(debug_assertions, ignore = "about twenty-four hundred syntheses: release only")] + fn the_unit_search_takes_no_more_t_gates_and_at_one_count_is_no_farther() { + let (mut changed, mut at_one_count, mut farther) = (0, 0, 0); + for (name, theta, eps, _) in &oracle() { + let (now, before) = (rz(*theta, *eps).unwrap(), rz_by(*theta, *eps, the_solver_s_own_unit).unwrap()); + assert!(now.t_count <= before.t_count, "{name}, ε {eps}: {} T gates, {} before", now.t_count, before.t_count); + assert!(now.distance <= *eps, "{name}, ε {eps}: distance {}", now.distance); + if now.t_count == before.t_count { + assert!(now.distance <= before.distance, "{name}, ε {eps}: {} against {}", now.distance, before.distance); + } + if now.gates != before.gates { + changed += 1; + at_one_count += usize::from(now.t_count == before.t_count); + } + farther += usize::from(now.distance > before.distance); + } + eprintln!("the unit search: {changed} words changed, {at_one_count} of them at one T count; {farther} rotations farther"); + assert_eq!((changed, at_one_count, farther), (350, 57, 87)); + } } diff --git a/wai/wai-quantum/src/published_architectures.rs b/wai/wai-quantum/src/published_architectures.rs index 0c059052b..b1c3f4e91 100644 --- a/wai/wai-quantum/src/published_architectures.rs +++ b/wai/wai-quantum/src/published_architectures.rs @@ -506,7 +506,7 @@ fn ising(gross: &PauliCosts, two: &PauliCosts) -> Result { F::I, Class::TheirModel, format!( - "pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives {}, {}, {} and {}: it also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows, and of the norm equation's solutions it keeps the one whose operator takes the fewest T gates. It takes no more than the reference on any of 1,192 angles and precisions (engine::synth::rz's tests).", + "pygridsynth 1.0.1, the version the source cites, run on the program's four angles at ε = 5·10⁻⁹, gives 86, 80, 84 and 82 T gates, which make 15,542,400 exactly; it approximates the rotation itself. Ours, the same Ross–Selinger method, gives {}, {}, {} and {}: it also searches the class one global phase e^(iπ/8) away, which a rotation of the pivot allows, and of the solver's solution of the norm equation and its unit multiples it keeps the one whose operator takes the fewest T gates. It takes no more than the reference on any of 1,192 angles and precisions (engine::synth::rz's tests).", counts[0], counts[1], counts[2], counts[3] ), ); @@ -874,7 +874,7 @@ mod tests { assert!(rows["fig9.chosen.gross"].why.contains("bicycle_cliffords 0.1.0")); assert!(rows["fig10a.gross_e4_5k.nt"].why.contains("bicycle_compiler 0.1.0")); let all: String = sections.iter().flat_map(|s| &s.rows).map(|r| format!("{} {} {}\n", r.quantity, r.source, r.why)).collect(); - for gone in ["not released", "Fig. 16", "shortfall", "press release", "announced", "every R ≠ I"] { + for gone in ["not released", "Fig. 16", "shortfall", "press release", "announced", "every R ≠ I", "norm equation's solutions"] { assert!(!all.contains(gone), "{gone}"); } assert!(rows["fig10a.gross_e3_5k.nt"].why.contains("Fig. 17") || rows["fig10a.gross_e3_5k.nt_undivided"].why.contains("Fig. 17")); -- 2.54.0 (Apple Git-157) From ddd12dc2ed11b6c5b5ce8cd409d571e972cb8237 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Sat, 7 Nov 2026 11:42:46 -0500 Subject: [PATCH 4/5] wai-quantum: the catalog's pins the synthesiser moves, each to fewer T gates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit engine::catalog::whole_tests pins, for each program it holds, what the engine gave before a gate stood whole. Main added it after this branch's fix, and two of its columns depend on the synthesiser: the compile's output and the estimate's counts. With the cheapest unit kept, those moved on the rows whose rotations change word. Every one moved to fewer T gates, and none rose. The compile: - c3z 1080 → 1059, c3x 1080 → 1061, c3y 1079 → 1063, c3h 1081 → 1065 - c2u 1066 → 1058, c2sx 483 → 476, ccu 1078 → 1065 - c2swap 1080 → 1061, grover6 10080 → 9828 The estimate's rotation T: - c2rx, c2ry and c2rzz 460 → 450, c2u 1647 → 1631 - c2sx 624 → 611, ccu 1807 → 1791, c2swap 720 → 705 - c2gphase 117 → 114, cp 114 → 108 The old values are main's, read from the same probe on main's tree, which gave the pinned hashes back. The state hashes, gate digests and QIR and jeff exports do not depend on the synthesiser and did not move. The table's comment says which columns moved, and why. This was the red in every energy-receipts leg and in the extension points' legs. Co-Authored-By: Claude Opus 5.5 --- .../src/engine/catalog/whole_tests.rs | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/wai/wai-quantum/src/engine/catalog/whole_tests.rs b/wai/wai-quantum/src/engine/catalog/whole_tests.rs index f4355c45f..fc4bdcc9c 100644 --- a/wai/wai-quantum/src/engine/catalog/whole_tests.rs +++ b/wai/wai-quantum/src/engine/catalog/whole_tests.rs @@ -15,31 +15,41 @@ fn hx(b: &[u8]) -> String { /// arm64 and x86_64 alike (each row taken from that commit on both): its /// standard gates and their digest, the bit-exact state hash, the compile's /// output, the QIR and jeff exports and the resource estimate's counts. +/// +/// Since the synthesiser keeps the cheapest unit multiple of the norm +/// equation's solution (`engine::synth::rz`), a rotation's word can take fewer +/// `T` gates, so the compile's output and the estimate's counts of the rows +/// with such rotations are what it gives now, every one with fewer `T` gates: +/// the compile of c3z 1080 → 1059, c3x 1080 → 1061, c3y 1079 → 1063, c3h +/// 1081 → 1065, c2u 1066 → 1058, c2sx 483 → 476, ccu 1078 → 1065, c2swap +/// 1080 → 1061 and grover6 10080 → 9828; the estimate's rotation `T` of c2rx, +/// c2ry and c2rzz 460 → 450, c2u 1647 → 1631, c2sx 624 → 611, ccu 1807 → +/// 1791, c2swap 720 → 705, c2gphase 117 → 114 and cp 114 → 108. #[rustfmt::skip] #[allow(clippy::type_complexity)] const BEFORE: &[(&str, &str, usize, &str, &str, &str, &str, &str, &str)] = &[ - ("c3z", "qubit[5] q;\nh q;\nctrl(3) @ z q[0], q[1], q[2], q[3];\n", 34, "29718f9ab500304a", "181acaa4aad01230", "f23087907c80c69d", "c8c5157978bce0e3", "5483575a012810bb", "747ea02fde8aeaca"), - ("c3x", "qubit[5] q;\nh q;\nctrl(3) @ x q[0], q[1], q[2], q[3];\n", 36, "7a786cc271f2501b", "8a504be7fc0299e8", "19be6f5bfc085d84", "0c304a3bc21ab20d", "c35804da5d616eb1", "d7c18a0142c206a0"), - ("c3y", "qubit[5] q;\nh q;\nt q[1];\nctrl(3) @ y q[0], q[1], q[2], q[3];\n", 39, "83dfa98a747a790d", "fbc90dbfada344a4", "263ae5be1f8ed271", "3248786655ef4b22", "0c039f9aa8aaf730", "9fd8aa3d94545ea2"), - ("c3h", "qubit[5] q;\nh q;\nt q[1];\nctrl(3) @ h q[0], q[1], q[2], q[3];\n", 37, "d6da69225d63f4a2", "f9fd9fa5547c7200", "de15875954d42157", "b2d92db2f0938d25", "412b56a798ee15ad", "744da0841af0f928"), + ("c3z", "qubit[5] q;\nh q;\nctrl(3) @ z q[0], q[1], q[2], q[3];\n", 34, "29718f9ab500304a", "181acaa4aad01230", "d6ac65a5d000432d", "c8c5157978bce0e3", "5483575a012810bb", "747ea02fde8aeaca"), + ("c3x", "qubit[5] q;\nh q;\nctrl(3) @ x q[0], q[1], q[2], q[3];\n", 36, "7a786cc271f2501b", "8a504be7fc0299e8", "d67b92d5f3fdb9cf", "0c304a3bc21ab20d", "c35804da5d616eb1", "d7c18a0142c206a0"), + ("c3y", "qubit[5] q;\nh q;\nt q[1];\nctrl(3) @ y q[0], q[1], q[2], q[3];\n", 39, "83dfa98a747a790d", "fbc90dbfada344a4", "55221950a66c19b9", "3248786655ef4b22", "0c039f9aa8aaf730", "9fd8aa3d94545ea2"), + ("c3h", "qubit[5] q;\nh q;\nt q[1];\nctrl(3) @ h q[0], q[1], q[2], q[3];\n", 37, "d6da69225d63f4a2", "f9fd9fa5547c7200", "0c3cd36f5611ac6d", "b2d92db2f0938d25", "412b56a798ee15ad", "744da0841af0f928"), ("c2p", "qubit[4] q;\nh q;\nctrl(2) @ p(pi / 8) q[0], q[1], q[2];\n", 17, "b076ca7327b88b22", "13346662e1739d87", "18407afca6242403", "82518b8435656332", "1ad0afc42fc8a458", "0da1476c3de0dffa"), ("c2rz", "qubit[4] q;\nh q;\nctrl(2) @ rz(pi / 4) q[0], q[1], q[2];\n", 18, "ade98300c7a91bea", "ca049c0c8dd637ed", "a4f6414c00826c92", "0f6065ef438dadba", "74d61b41579349ab", "d2f07d8d123fa85a"), - ("c2rx", "qubit[4] q;\nh q;\nctrl(2) @ rx(pi / 2) q[0], q[1], q[2];\n", 20, "6ae6ae2309534fbb", "3eab347bbdb8b27c", "5a664df2c0c8b771", "4dc76727674b23fa", "c607efaafd1b104c", "d992c105de67f83c"), - ("c2ry", "qubit[4] q;\nh q;\nctrl(2) @ ry(pi / 2) q[0], q[1], q[2];\n", 22, "27369425f1ce33f2", "94f7f25bde25caef", "947dd07eb6275558", "27aeedd8797a64c3", "92bc2218593c67d2", "b75ea5448c736963"), - ("c2u", "qubit[4] q;\nh q;\nctrl(2) @ u(pi / 2, pi / 4, pi / 8) q[0], q[1], q[2];\n", 51, "0032cafc1cf71c51", "7c43ae072ebd46be", "e8f8bdd2fd064d70", "529d746a02266c75", "c4d07e54180ae52d", "94c720252c873ede"), - ("c2sx", "qubit[4] q;\nh q;\nctrl(2) @ sx q[0], q[1], q[2];\n", 21, "3011642a37dab1c8", "378d6c6c3635da01", "e65547fe84b0d8cf", "8a53373f168fcddd", "77db3f01554b29e4", "c3e8535f252e0170"), + ("c2rx", "qubit[4] q;\nh q;\nctrl(2) @ rx(pi / 2) q[0], q[1], q[2];\n", 20, "6ae6ae2309534fbb", "3eab347bbdb8b27c", "5a664df2c0c8b771", "4dc76727674b23fa", "c607efaafd1b104c", "04e354bedaac05f0"), + ("c2ry", "qubit[4] q;\nh q;\nctrl(2) @ ry(pi / 2) q[0], q[1], q[2];\n", 22, "27369425f1ce33f2", "94f7f25bde25caef", "947dd07eb6275558", "27aeedd8797a64c3", "92bc2218593c67d2", "d06687536842afbb"), + ("c2u", "qubit[4] q;\nh q;\nctrl(2) @ u(pi / 2, pi / 4, pi / 8) q[0], q[1], q[2];\n", 51, "0032cafc1cf71c51", "7c43ae072ebd46be", "528d9ce71320056f", "529d746a02266c75", "c4d07e54180ae52d", "d52535001b3fd082"), + ("c2sx", "qubit[4] q;\nh q;\nctrl(2) @ sx q[0], q[1], q[2];\n", 21, "3011642a37dab1c8", "378d6c6c3635da01", "8054090c33152d4e", "8a53373f168fcddd", "77db3f01554b29e4", "f1b22819c6f6d640"), ("neg", "qubit[4] q;\nh q;\nnegctrl(2) @ ctrl @ s q[0], q[1], q[2], q[3];\n", 37, "64475caf52138761", "77667386517f1f09", "1c755ad6249197a1", "e46c16636e80eebd", "901334ecfa216508", "e42f39af5237beca"), - ("ccu", "qubit[4] q;\nh q;\nctrl @ cu(pi / 2, pi / 4, pi / 8, pi / 16) q[0], q[1], q[2];\n", 52, "a9f7955f0864db33", "fa538ea89cfe5c9a", "0ba490c2dda2780c", "c40db1252b470677", "5d1f6d595cdfbe0d", "b27c6c0bb9082d58"), - ("c2swap", "qubit[4] q;\nh q;\nctrl(2) @ swap q[0], q[1], q[2], q[3];\n", 37, "90d28cfbf2beef6c", "7982dfa1bd563330", "76fee435a36b077d", "f1554f2143fd5485", "0ce2bc73b4fa722f", "fe16b8d3921fa66b"), - ("c2rzz", "qubit[4] q;\nh q;\nctrl(2) @ rzz(pi / 2) q[0], q[1], q[2], q[3];\n", 20, "169448464ac572eb", "b537afe5c235346c", "c0df4fdb5cb39f1a", "e7c473ac7aced773", "9486d505cc21b5a0", "d992c105de67f83c"), - ("c2gphase", "qubit[3] q;\nh q;\nctrl(2) @ gphase(pi / 4) q[0], q[1];\n", 4, "613a1f7f53c2c634", "0e065cabc1032cc6", "eb75b70b655bedca", "87c33623c70c4586", "e5c2502f696c5154", "709224f43ac6c30e"), + ("ccu", "qubit[4] q;\nh q;\nctrl @ cu(pi / 2, pi / 4, pi / 8, pi / 16) q[0], q[1], q[2];\n", 52, "a9f7955f0864db33", "fa538ea89cfe5c9a", "4cddec462306adfb", "c40db1252b470677", "5d1f6d595cdfbe0d", "2cb9eefc64e918ec"), + ("c2swap", "qubit[4] q;\nh q;\nctrl(2) @ swap q[0], q[1], q[2], q[3];\n", 37, "90d28cfbf2beef6c", "7982dfa1bd563330", "827673a89608715b", "f1554f2143fd5485", "0ce2bc73b4fa722f", "869908729c2e89a4"), + ("c2rzz", "qubit[4] q;\nh q;\nctrl(2) @ rzz(pi / 2) q[0], q[1], q[2], q[3];\n", 20, "169448464ac572eb", "b537afe5c235346c", "c0df4fdb5cb39f1a", "e7c473ac7aced773", "9486d505cc21b5a0", "04e354bedaac05f0"), + ("c2gphase", "qubit[3] q;\nh q;\nctrl(2) @ gphase(pi / 4) q[0], q[1];\n", 4, "613a1f7f53c2c634", "0e065cabc1032cc6", "eb75b70b655bedca", "87c33623c70c4586", "e5c2502f696c5154", "f161950ccab25f70"), ("invc3t", "qubit[4] q;\nh q;\ninv @ ctrl(3) @ t q[0], q[1], q[2], q[3];\n", 33, "6d8735fa38b73015", "8ac349a04bd30ca8", "389140fbf3231c9f", "cfc33faa8c2f6e40", "ab64f2e385bb59da", "b0d2a886a160dcc2"), - ("grover6", "qubit[6] q;\nh q;\nctrl(5) @ z q[0], q[1], q[2], q[3], q[4], q[5];\nh q;\nx q;\nctrl(5) @ z q[0], q[1], q[2], q[3], q[4], q[5];\nx q;\nh q;\n", 280, "71390b8e8200400a", "9e5c239c034ba374", "9b7fb2311b984049", "384c13c05764b82d", "dcba716313b6ece1", "d164abfb32a62b0a"), + ("grover6", "qubit[6] q;\nh q;\nctrl(5) @ z q[0], q[1], q[2], q[3], q[4], q[5];\nh q;\nx q;\nctrl(5) @ z q[0], q[1], q[2], q[3], q[4], q[5];\nx q;\nh q;\n", 280, "71390b8e8200400a", "9e5c239c034ba374", "a14f0c960297a237", "384c13c05764b82d", "dcba716313b6ece1", "d164abfb32a62b0a"), ("ccx", "qubit[4] q;\nh q;\nt q[0];\nctrl(2) @ x q[0], q[1], q[2];\n", 6, "542e1352d6cd7c2e", "bc16012d7e5c98a8", "99b450e817595855", "6645931b4b759afb", "b6b70437c04ac558", "d370a78cc7e92248"), ("ccz", "qubit[4] q;\nh q;\nt q[0];\nctrl(2) @ z q[0], q[1], q[2];\n", 6, "32cc8ef799a35dc2", "b357eae18a404904", "f3b4c56a4b8d0c9d", "7a9c51e72904ac4a", "3b78a28be6428788", "d370a78cc7e92248"), ("c2y", "qubit[4] q;\nh q;\nt q[0];\nctrl(2) @ y q[0], q[1], q[2];\n", 8, "2c326695e1bde126", "59d46a5019e4d87c", "dacf9a1398e3e043", "a9ff98ce426f905d", "281d8093937d891e", "551165238caa42d2"), ("c2h", "qubit[4] q;\nh q;\nt q[0];\nctrl(2) @ h q[0], q[1], q[2];\n", 8, "ae920e55c106966c", "e61608a2117a83aa", "58443259e04d5f16", "7e9d2678d90ccadc", "ac5f279656d62dc7", "d76ade781f528b10"), - ("cp", "qubit[3] q;\nh q;\nctrl @ p(pi / 8) q[0], q[1];\n", 4, "48ca258d13245d56", "cddd783aad2071d2", "e062f8754960a2d9", "ed65712144049bea", "6db848b83c6a454c", "0e28272539b04b2a"), + ("cp", "qubit[3] q;\nh q;\nctrl @ p(pi / 8) q[0], q[1];\n", 4, "48ca258d13245d56", "cddd783aad2071d2", "e062f8754960a2d9", "ed65712144049bea", "6db848b83c6a454c", "ce8fbc7d4e31cb46"), ("cswap", "qubit[3] q;\nh q;\nctrl @ swap q[0], q[1], q[2];\n", 4, "2a5e8a545c769f54", "70fe25ec22008f86", "27282765b5abf030", "e85d174f9e4e97da", "87a240aab7d4fc0e", "694084d5478b13ed"), ("plain", "qubit[3] q;\nh q;\ncx q[0], q[1];\nrz(pi / 4) q[2];\n", 5, "8103a71b8f08fb58", "92dbd1cf0f4ce0e1", "275c3c9040292ce0", "2bd714b375f08ed0", "368eeef29b7aa1f2", "68eebfa353685fb7"), ]; -- 2.54.0 (Apple Git-157) From 059fb64f1e76d69f10085bfba5cfd36e5f3a96bd Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Sat, 7 Nov 2026 11:42:46 -0500 Subject: [PATCH 5/5] wai-quantum-cli: two first uses at once make one key, not one failure On a machine with no signing key, keys::load made one with create_new. Two processes doing so at once lost one of them: the second got AlreadyExists, or read the first's file before its text was written and found no key in it, and died. A host starting two MCP servers on a new machine does that; so do the verify tests' two MCP tests, which run in parallel on a fresh CI container. - On the old code, on a build host with a fresh HOME, verify failed 3 runs of 12, and 0 of 12 with a key already there. - Three servers started together lost 7 of 60: six to "File exists", one to "a key file holds 64 hex digits". The key is now written to a private file beside its name and linked in. A link fails if the name exists, so the file is never seen partly written, and the process that comes second reads the first's key. keys_made_at_once_are_one_key makes it from sixteen threads at once, 25 times. It fails in its first round when the old write is put back. The verify test's MCP helper kept no standard error, so the CI log showed a server that said nothing. It now panics with the server's exit status and its standard error. Co-Authored-By: Claude Opus 5.5 --- wai/wai-quantum-cli/src/keys.rs | 91 ++++++++++++++++++++++++----- wai/wai-quantum-cli/tests/verify.rs | 7 ++- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/wai/wai-quantum-cli/src/keys.rs b/wai/wai-quantum-cli/src/keys.rs index e71ffbfad..fabf78f6a 100644 --- a/wai/wai-quantum-cli/src/keys.rs +++ b/wai/wai-quantum-cli/src/keys.rs @@ -58,24 +58,57 @@ pub fn load(given: Option<&Path>, demo: bool) -> Result { None => user_path().ok_or("no HOME to keep a key in: pass --key FILE")?, }; match std::fs::read_to_string(&path) { - Ok(text) => { - let seed = parse(&text).ok_or_else(|| format!("{}: a key file holds 64 hex digits", path.display()))?; - Ok(Key { key: SigningKey::from_bytes(&seed), path: Some(path), made: false }) - } - Err(e) if e.kind() == std::io::ErrorKind::NotFound && named.is_none() => { - let mut seed = [0u8; 32]; - getrandom::fill(&mut seed).map_err(|e| format!("no random source for a new key: {e}"))?; - if let Some(dir) = path.parent() { - std::fs::create_dir_all(dir).map_err(|e| format!("{}: {e}", dir.display()))?; - } - let text: String = seed.iter().map(|b| format!("{b:02x}")).collect(); - write_private(&path, &format!("{text}\n")).map_err(|e| format!("{}: {e}", path.display()))?; - Ok(Key { key: SigningKey::from_bytes(&seed), path: Some(path), made: true }) + Ok(text) => key_from(&path, &text), + Err(e) if e.kind() == std::io::ErrorKind::NotFound && named.is_none() => make(&path), + Err(e) => Err(format!("{}: {e}", path.display())), + } +} + +fn key_from(path: &Path, text: &str) -> Result { + let seed = parse(text).ok_or_else(|| format!("{}: a key file holds 64 hex digits", path.display()))?; + Ok(Key { key: SigningKey::from_bytes(&seed), path: Some(path.to_path_buf()), made: false }) +} + +/// This user's key, made at `path` from the operating system's random source. +/// Two processes may make it at once, as two agents starting `wai-quantum mcp` +/// on a new machine do: the file is never seen partly written, and the one +/// that comes second signs with the first's key rather than failing. +fn make(path: &Path) -> Result { + let mut seed = [0u8; 32]; + getrandom::fill(&mut seed).map_err(|e| format!("no random source for a new key: {e}"))?; + if let Some(dir) = path.parent() { + std::fs::create_dir_all(dir).map_err(|e| format!("{}: {e}", dir.display()))?; + } + let text: String = seed.iter().map(|b| format!("{b:02x}")).collect(); + match publish_private(path, &format!("{text}\n")) { + Ok(()) => Ok(Key { key: SigningKey::from_bytes(&seed), path: Some(path.to_path_buf()), made: true }), + Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => { + let text = std::fs::read_to_string(path).map_err(|e| format!("{}: {e}", path.display()))?; + key_from(path, &text) } Err(e) => Err(format!("{}: {e}", path.display())), } } +/// `text` at `path`, readable by its owner only and never seen partly +/// written: it goes to a new file beside `path`, which is then linked in under +/// `path`'s name. The link fails when `path` exists, so of two writers one +/// wins and the other is told (`AlreadyExists`). A file system with no links +/// takes the text in place, as `write_private` gives it. +fn publish_private(path: &Path, text: &str) -> std::io::Result<()> { + let mut tag = [0u8; 8]; + getrandom::fill(&mut tag).map_err(|e| std::io::Error::other(e.to_string()))?; + let name = path.file_name().and_then(|n| n.to_str()).unwrap_or("key"); + let beside = path.with_file_name(format!(".{name}.{}.{:016x}", std::process::id(), u64::from_le_bytes(tag))); + write_private(&beside, text)?; + let linked = std::fs::hard_link(&beside, path); + let _ = std::fs::remove_file(&beside); + match linked { + Err(e) if e.kind() != std::io::ErrorKind::AlreadyExists => write_private(path, text), + done => done, + } +} + fn write_private(path: &Path, text: &str) -> std::io::Result<()> { use std::io::Write as _; let mut f = std::fs::OpenOptions::new(); @@ -132,4 +165,36 @@ mod tests { } let _ = std::fs::remove_dir_all(&dir); } + + /// Sixteen processes' worth of first uses at once, as when two agents start + /// `wai-quantum mcp` on a new machine: each gets a key, all the same one, + /// one of them made it, and nothing else is left beside it. + #[test] + fn keys_made_at_once_are_one_key() { + let dir = std::env::temp_dir().join(format!("wai-quantum-cli-key-race-{}", std::process::id())); + let path = dir.join("wai").join("quantum-key"); + for round in 0..25 { + let _ = std::fs::remove_dir_all(&dir); + let start = std::sync::Arc::new(std::sync::Barrier::new(16)); + let threads: Vec<_> = (0..16) + .map(|_| { + let (path, start) = (path.clone(), start.clone()); + std::thread::spawn(move || { + start.wait(); + make(&path).map(|k| (k.key.to_bytes(), k.made)) + }) + }) + .collect(); + let got: Vec<([u8; 32], bool)> = threads.into_iter().map(|t| t.join().unwrap()).collect::>().unwrap_or_else(|e| panic!("round {round}: {e}")); + assert!(got.windows(2).all(|w| w[0].0 == w[1].0), "round {round}: more than one key"); + assert_eq!(got.iter().filter(|g| g.1).count(), 1, "round {round}: one of them made it"); + assert_eq!(std::fs::read_dir(path.parent().unwrap()).unwrap().count(), 1, "round {round}: only the key is left"); + assert_eq!(load_from_file(&path), got[0].0, "round {round}: the file holds that key"); + } + let _ = std::fs::remove_dir_all(&dir); + } + + fn load_from_file(path: &Path) -> [u8; 32] { + key_from(path, &std::fs::read_to_string(path).unwrap()).unwrap().key.to_bytes() + } } diff --git a/wai/wai-quantum-cli/tests/verify.rs b/wai/wai-quantum-cli/tests/verify.rs index f393ce2ea..82bb4f3ac 100644 --- a/wai/wai-quantum-cli/tests/verify.rs +++ b/wai/wai-quantum-cli/tests/verify.rs @@ -91,14 +91,17 @@ fn json_output_is_json_on_every_kind_of_job() { /// One request to the MCP server on standard input and output. fn mcp(tool: &str, arguments: Value) -> Value { - let mut child = Command::new(BIN).arg("mcp").env_remove("WAI_QUANTUM_KEY").stdin(Stdio::piped()).stdout(Stdio::piped()).stderr(Stdio::null()).spawn().unwrap(); + let mut child = Command::new(BIN).arg("mcp").env_remove("WAI_QUANTUM_KEY").stdin(Stdio::piped()).stdout(Stdio::piped()).stderr(Stdio::piped()).spawn().unwrap(); let mut stdin = child.stdin.take().unwrap(); writeln!(stdin, "{}", json!({ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "test", "version": "0" } } })).unwrap(); writeln!(stdin, "{}", json!({ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": tool, "arguments": arguments } })).unwrap(); drop(stdin); let out = child.wait_with_output().unwrap(); let text = String::from_utf8_lossy(&out.stdout); - let answer: Value = text.lines().filter_map(|l| serde_json::from_str::(l).ok()).find(|v| v["id"] == 2).unwrap_or_else(|| panic!("{text}")); + // A server that answers nothing says why on its standard error, which the panic keeps. + let answer: Value = text.lines().filter_map(|l| serde_json::from_str::(l).ok()).find(|v| v["id"] == 2).unwrap_or_else(|| { + panic!("{tool}: no answer from the server ({}): standard output {text:?}, standard error {:?}", out.status, String::from_utf8_lossy(&out.stderr)) + }); answer["result"]["structuredContent"].clone() } -- 2.54.0 (Apple Git-157)