ultraqse 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.4
2
+ Name: ultraqse
3
+ Version: 1.0.0
4
+ Summary: Von Neumann Entropy of CNOT circuits via Walsh-Hadamard transforms over GF(2)
5
+ Author-email: Ozgurooozer <ozigoca@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/Ozgurooozer/ultraqse
8
+ Keywords: quantum,entropy,von neumann,walsh hadamard,gf2,cnot,entanglement,quantum circuits
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Scientific/Engineering :: Physics
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Operating System :: OS Independent
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: numpy>=1.21
20
+
21
+ # QSE Theorem Reference
22
+
23
+ **Convention:** `Rx(θ)|0⟩ = cos(θ/2)|0⟩ − i·sin(θ/2)|1⟩`
24
+ **Ry convention:** `Ry(θ)|0⟩ = cos(θ/2)|0⟩ − sin(θ/2)|1⟩`
25
+ **Φ_M(s)** = ∏_{i: (M^T s)_i = 1} cos(θᵢ)
26
+ **M** ∈ F₂^{NB×NA}: M[b][a] = 1 iff CNOT(ctrl=a, tgt=b) is present
27
+ **Qubit layout:** A-qubits = bits 0..NA−1, B-qubits = bits NA..NA+NB−1
28
+
29
+ ---
30
+
31
+ ## Core Theorems
32
+
33
+ | ID | Name | Formula | max_err |
34
+ |----|------|---------|---------|
35
+ | **T14** | Walsh-Hadamard Master | `P_b = (1/2^NB) Σ_s (−1)^{b·s} Φ_M(s)`, `VNE = H({P_b})` | < 7e-16 |
36
+ | **T-UNIVERSAL** | Diagonal Mixed Input | `P_b = Σ_{x: Mx=b} ρ_A[x,x]` (works for any diagonal ρ_A) | < 5e-16 |
37
+ | **T-UNIVERSAL-GEN** | Nonlinear Gates | `P_b = Σ_{x: f(x)=b} |ψ[x]|²` | < 3e-16 |
38
+ | **T16** | Phase Invariance | VNE depends only on {|cos(θᵢ/2)|²}, not on U(1) phases | < 7e-16 |
39
+
40
+ ---
41
+
42
+ ## Structural Theorems
43
+
44
+ | ID | Name | Key Result | max_err |
45
+ |----|------|-----------|---------|
46
+ | **T17** | Blindness | VNE = 0 ↔ rank_F₂(M) = 0 | exact |
47
+ | **T-RANK** | Rank Upper Bound | `VNE(B) ≤ rank_F₂(M)` | exact |
48
+ | **T-OPT** | Rank Saturation | θ = π/2 ⟹ `VNE = rank_F₂(M)` exactly | exact |
49
+ | **T-SUB** | Monotone Substructure | Adding CNOT → rank nondecreasing → VNE nondecreasing | exact |
50
+
51
+ ---
52
+
53
+ ## Gate Extensions
54
+
55
+ | ID | Name | Key Result | max_err |
56
+ |----|------|-----------|---------|
57
+ | **T-BINIT** | B-Init Independence | T14 formula unchanged for any product-state B init (full-rank M) | < 7e-16 |
58
+ | **CZ-T14** | CZ Equivalence | CZ + \|+⟩_A = CNOT + \|0⟩_A (same VNE) | < 6e-16 |
59
+ | **T-fSim** | fSim Gate (NA=1) | λ± = (1 ± √D)/2, D = 1 − sin²(2α)sin⁴(θ/2); φ-invariant | < 2e-15 |
60
+ | **T-FSIM-PRODUCT** | fSim Product Gates | NA independent fSim gates (qubit i ↔ B-qubit i): `VNE = Σᵢ H(λ±ᵢ)` | < 4e-14 |
61
+ | **iSWAP** | Full iSWAP | iSWAP + Rx(θ)\|0⟩_B → product state → VNE = 0 | < 4e-16 |
62
+ | **T-SWAP** | SWAP via 3 CNOTs | SWAP(A_a, B_b) via CNOT→CNOT→CNOT → VNE(B) = 0 | < 7e-16 |
63
+
64
+ ---
65
+
66
+ ## Symmetry & Invariance Theorems
67
+
68
+ | ID | Name | Key Result | max_err |
69
+ |----|------|-----------|---------|
70
+ | **T-RY-EQ** | Ry = Rx Symmetry | VNE(Ry(θ) circuit) = VNE(Rx(θ) circuit) for same θ and M | < 8e-16 |
71
+ | **T-MIRROR** | Schmidt Symmetry | VNE(A) = VNE(B) for any pure bipartite state \|Ψ⟩_AB | < 8e-16 |
72
+ | **T-COHERENCE-DIAG** | Off-diagonal ρ_A Blindness | Off-diagonal ρ_A elements do not affect VNE(B); ρ_B always diagonal; VNE depends only on diag(ρ_A) | 0 |
73
+
74
+ **T-COHERENCE-DIAG note:** This is a non-trivial result. Even if A is in a coherent superposition
75
+ (off-diagonal ρ_A ≠ 0), the partial trace over A produces a strictly diagonal ρ_B, so
76
+ the CNOT circuit acts as a classical channel at the level of B's entropy.
77
+
78
+ ---
79
+
80
+ ## Gradient Theorems
81
+
82
+ | ID | Name | Formula | max_err |
83
+ |----|------|---------|---------|
84
+ | **T-GRAD** | Rx VNE Gradient | `d(VNE)/dθᵢ = −Σ_b (dP_b/dθᵢ)·log₂(P_b)` where `dP_b/dθᵢ = (1/2^NB) Σ_{s: (M^T s)_i=1} (−1)^{b·s}·(−tan θᵢ)·Φ_M(s)` | < 2e-10 (FD limit) |
85
+
86
+ **T-GRAD note:** The 2e-10 error is the finite-difference floor, not an analytic error.
87
+ The closed-form formula is exact; verification uses 4th-order central differences (h=1e-5).
88
+
89
+ ---
90
+
91
+ ## Information-Theoretic Theorems
92
+
93
+ | ID | Name | Formula | max_err |
94
+ |----|------|---------|---------|
95
+ | **T-MUTUAL** | Mutual Information | `I(A;B) = 2·VNE(B)` for pure state | exact |
96
+ | **T-MI** | MI Non-Negativity | `I(B₁;B₂) ≥ 0` | analytical |
97
+ | **T-PAULI** | Pauli Representation | `Φ_M(s) = ⟨Z^{M^T s}⟩_A` (Pauli expectation value form) | exact |
98
+
99
+ ---
100
+
101
+ ## Dynamics
102
+
103
+ | ID | Name | Key Result | max_err |
104
+ |----|------|-----------|---------|
105
+ | **T15A** | k-Layer Circuits | `M_eff = M₁ ⊕ M₂ ⊕ ... ⊕ Mₖ (mod 2)` | < 8e-16 |
106
+ | **T18** | Period-2 | Even number of identical CNOT layers → M_eff = 0 → VNE = 0 | < 4e-16 |
107
+ | **T-BIDIR** | Bidirectional Circuits | Alternating A→B and B→A CNOT layers reduce to T14(M_eff) | < 2e-15 |
108
+
109
+ **T-BIDIR details:**
110
+
111
+ For circuits with interleaved A→B layers (CNOTs ctrl=a, tgt=B_b) and B→A layers
112
+ (CNOTs ctrl=B_b, tgt=a), the effective M matrix is:
113
+
114
+ ```
115
+ M_eff[b, :] = M_raw[b, :] @ T_cum (mod 2)
116
+ ```
117
+
118
+ where T_cum ∈ F₂^{NA×NA} is the cumulative A-space shear transformation accumulated
119
+ from all B→A CNOTs seen so far. Update rule after CNOT(ctrl=B_b, tgt=A_a):
120
+
121
+ ```
122
+ T_cum[a, :] ^= M_eff[b_abs, :] (row XOR, not matrix multiply)
123
+ ```
124
+
125
+ **Invertibility condition:** T_cum must have full GF(2) rank (= NA). When T_cum is
126
+ singular, multiple x-values map to the same A-state with different B-states, creating
127
+ off-diagonal ρ_B elements (quantum coherences) that break the T14 assumption. The
128
+ theorem applies only to circuits where T_cum remains invertible throughout.
129
+
130
+ ---
131
+
132
+ ## Noise Theorems
133
+
134
+ | ID | Name | Formula | max_err |
135
+ |----|------|---------|---------|
136
+ | **T-NOISE** | Amplitude Damping | After AD_γ on B: `P₀ → P₀+γP₁`, `P₁ → (1−γ)P₁`; `VNE_noisy = H(P₀+γP₁, (1−γ)P₁)` | < 3e-16 |
137
+ | **S2** | k-Round Transfer Matrix | `T = S_AD_A · S_CNOT · S_AD_B · S_CNOT` (16×16 superoperator); `vec(ρₖ) = Tᵏ·vec(ρ₀)` | < 7e-16 |
138
+
139
+ ---
140
+
141
+ ## Moment & Rényi Theory
142
+
143
+ | ID | Name | Formula | max_err |
144
+ |----|------|---------|---------|
145
+ | **T22** | Rényi Moments | `Tr(ρᵅ) = (1/2^{(α−1)NB}) Σ_{s₁..s_{α−1}} ∏Φ_M(sᵢ)·Φ_M(⊕sᵢ)` | < 2e-15 |
146
+ | **T29** | Newton-Girard Spectrum | Power-sum moments (T22) → Newton-Girard identities → all eigenvalues of ρ_B | < 7e-7 |
147
+ | **T-RENYI-DERIV** | Rényi Derivative | `dS_α/dα\|_{α=1} = −(ln2/2)·Var_P[log₂ P_b]` where `Var_P = Σ_b P_b(log₂ P_b)² − VNE²` | < 4e-10 (4th-order FD) |
148
+ | **T-RENYI-CONV** | Rényi→VNE Convergence | `S_α → VNE` as `α → 1` | 0 |
149
+
150
+ **T-RENYI-DERIV note:** Derived by Taylor-expanding `log Tr(ρᵅ)` around α=1 using T22
151
+ moments. The `(ln2/2)·Var` coefficient follows from the second cumulant of the log-probability
152
+ distribution. Verified with 4th-order central differences (h=1e-3) to avoid FD floor.
153
+
154
+ ---
155
+
156
+ ## Random Circuit Statistics
157
+
158
+ | ID | Name | Key Result | max_err |
159
+ |----|------|-----------|---------|
160
+ | **T-RANDOM-VNE** | Expected VNE = Expected GF(2) Rank | `E[VNE(θ=π/2)] = E[rank_GF₂(M)]` over uniform random M ∈ F₂^{NB×NA} | 0 |
161
+
162
+ **Gaussian binomial formula:**
163
+
164
+ ```
165
+ E[rank_GF₂(M)] = (1/2^{NA·NB}) · Σ_{r=1}^{min(NA,NB)} r · [NB choose r]₂ · ∏_{j<r}(2^NA − 2^j)
166
+
167
+ [n choose k]₂ = ∏_{j=0}^{k-1}(2^n − 2^j) / ∏_{j=0}^{k-1}(2^k − 2^j) (Gaussian binomial)
168
+ ```
169
+
170
+ The formula is exact over integers (no floating-point error).
171
+
172
+ ---
173
+
174
+ ## Inter-Theorem Connections
175
+
176
+ | ID | Connection | max_err |
177
+ |----|-----------|---------|
178
+ | **B1** | T22(α=2) = Parseval: `Σ P_b² = (1/2^NB) Σ Φ(s)²` | < 3e-16 |
179
+ | **B2** | `Φ_M(s) = E_{x~P_A}[(−1)^{(M^T s)·x}]` — Walsh-Fourier characteristic function of P_A | < 5e-16 |
180
+ | **B3** | T14 = α→1 limit of T22 Rényi hierarchy (T-RENYI-CONV) | analytical |
181
+ | **B4** | T17+T-RANK+T-OPT+T-SUB = F₂ linear matroid rank structure | analytical |
182
+ | **B5** | T22 = α-point Pauli correlation function (via T-PAULI) | analytical |
183
+ | **B6** | VNE(θ) monotone in [0, rank_F₂(M)] for uniform θ ∈ [0, π/2] | 500/500 |
184
+ | **B7** | T14 = H(f*(P_A)): VNE is Shannon entropy of the classical pushforward of P_A under M | < 4e-16 |
185
+
186
+ ---
187
+
188
+ ## Resolved Open Problems
189
+
190
+ | ID | Problem | Resolution | Theorem |
191
+ |----|---------|-----------|---------|
192
+ | **O1** | Closed-form for bidirectional circuits | M_eff = M_raw·T_cum (GF(2)), invertible T_cum required | T-BIDIR |
193
+ | **O2a** | T-fSim eigenvalue formula (NA=1) | D = 1 − sin²(2α)sin⁴(θ/2); φ-invariant | T-fSim |
194
+ | **O2b** | T-fSim for NA > 1 | VNE additivity for independent fSim gates | T-FSIM-PRODUCT |
195
+ | **O3** | Gradient d(VNE)/dθᵢ for Ry/Rz input | Ry gives same VNE as Rx (T-RY-EQ); Rx gradient in closed form (T-GRAD) | T-RY-EQ, T-GRAD |
196
+ | **O4** | Rényi approximation error bound | dS_α/dα\|₁ = −(ln2/2)·Var_P[log₂ P_b] | T-RENYI-DERIV |
197
+ | **O5** | Non-diagonal ρ_A extension | Off-diagonal ρ_A does not affect VNE; ρ_B always diagonal | T-COHERENCE-DIAG |
198
+ | **O6** | Random circuit VNE via F₂ matroid counting | E[VNE] = E[rank_GF₂] via Gaussian binomial | T-RANDOM-VNE |
199
+
200
+ ---
201
+
202
+ ## Scaling & Performance
203
+
204
+ Tested on NA=12, NB=6 (2^18 = 262,144 amplitudes):
205
+
206
+ | Operation | Complexity | Measured |
207
+ |-----------|-----------|---------|
208
+ | `t14_Pb` (WHT formula) | O(2^{2NB}) | **12 ms** |
209
+ | `vne_gradient_rx` | O(NA · 2^{2NB}) | **195 ms** |
210
+ | `exact_rho_B` (vectorized) | O(2^{NA+NB} · 2^{NB}) | **8 ms** |
211
+ | `exact_rho_B` (old O(n²) loop) | O(4^{NA+NB}) | ~hours |
212
+
213
+ **Key insight:** T14 complexity depends only on NB (the B register size), not NA.
214
+ Growing NA to 100+ costs nothing for the WHT formula — only the statevector
215
+ simulation and gradient scale with NA.
216
+
217
+ **Vectorized partial trace** (`exact_rho_B`):
218
+
219
+ ```python
220
+ # Old: O(4^{NA+NB}) double loop — infeasible for NA > 6
221
+ # New: O(2^{NA+NB}) reshape + matmul
222
+ A = amps.reshape(2**NB, 2**NA) # B-bits as rows, A-bits as cols
223
+ rho_B = A @ A.conj().T # traces out A exactly
224
+ ```
225
+
226
+ Index layout: `amps[a_bits | (b_bits << NA)]` — low NA bits are A, high NB bits are B.
227
+ Reshape naturally groups B as rows and A as columns, making the matmul correct.
228
+
229
+ ---
230
+
231
+ ## Package API (`qse/`)
232
+
233
+ ```python
234
+ from qse import (
235
+ # Core — T14 machinery
236
+ build_M, phi_dict, t14_Pb, t_universal,
237
+ vne_from_Pb, renyi_entropy, f2_rank,
238
+ t22_moment, newton_girard,
239
+
240
+ # States — simulation ground truth
241
+ product_state, product_state_ry,
242
+ exact_rho_B, exact_rho_B_mixed, vne_exact,
243
+
244
+ # Gates — statevector operations
245
+ apply_cnot, apply_fsim, apply_swap,
246
+
247
+ # Gradients
248
+ vne_gradient_rx,
249
+
250
+ # Noise
251
+ amplitude_damping_kraus, superop,
252
+ noise_transfer_Pb, build_cnot_ad_transfer,
253
+
254
+ # Random circuits
255
+ gaussian_binom_2, expected_gf2_rank, enumerate_vne,
256
+ )
257
+ ```
258
+
259
+ ---
260
+
261
+ ## Test Suite
262
+
263
+ Run `python qse_tests.py` — **34/34 tests** pass at machine precision (max_err < 1e-8).
264
+
265
+ | Phase | Tests | Notes |
266
+ |-------|-------|-------|
267
+ | Initial commit | 23/23 | Core + noise + moment theory |
268
+ | Katman 0 (bug fixes) | 23/23 | T-fSim formula fix, T-BINIT full-rank check, T18 generalization |
269
+ | Katman 1 (open problems) | 33/33 | O2b–O6 resolved; T-SWAP, T-MIRROR added |
270
+ | Katman 2 (new theorems) | 34/34 | T-BIDIR (O1) completed |
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ultraqse"
7
+ version = "1.0.0"
8
+ description = "Von Neumann Entropy of CNOT circuits via Walsh-Hadamard transforms over GF(2)"
9
+ authors = [{ name = "Ozgurooozer", email = "ozigoca@gmail.com" }]
10
+ license = "MIT"
11
+ readme = "qse_reference.md"
12
+ requires-python = ">=3.9"
13
+ dependencies = ["numpy>=1.21"]
14
+ keywords = [
15
+ "quantum", "entropy", "von neumann", "walsh hadamard",
16
+ "gf2", "cnot", "entanglement", "quantum circuits"
17
+ ]
18
+ classifiers = [
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Scientific/Engineering :: Physics",
25
+ "Intended Audience :: Science/Research",
26
+ "Operating System :: OS Independent",
27
+ ]
28
+
29
+ [project.urls]
30
+ Repository = "https://github.com/Ozgurooozer/ultraqse"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["."]
34
+ include = ["qse"]
@@ -0,0 +1,74 @@
1
+ """
2
+ QSE Framework — Von Neumann Entropy via Walsh-Hadamard transforms over GF(2).
3
+
4
+ Quick start::
5
+
6
+ from qse import t14_Pb, vne_from_Pb, f2_rank
7
+
8
+ thetas = [0.8, 1.2] # Rx rotation angles for A-qubits
9
+ pairs = [(0, 0), (1, 0)] # CNOT(ctrl=0,tgt=B0), CNOT(ctrl=1,tgt=B0)
10
+ NA, NB = 2, 1
11
+
12
+ Pb, _ = t14_Pb(thetas, pairs, NA, NB)
13
+ vne = vne_from_Pb(Pb)
14
+
15
+ Submodules:
16
+ core — phi_dict, t14_Pb, t_universal, vne_from_Pb, renyi_entropy,
17
+ f2_rank, t22_moment, newton_girard, build_M
18
+ states — product_state, product_state_ry, exact_rho_B,
19
+ exact_rho_B_mixed, vne_exact
20
+ gates — apply_cnot, apply_fsim, apply_swap
21
+ gradients — vne_gradient_rx
22
+ noise — amplitude_damping_kraus, superop, noise_transfer_Pb,
23
+ build_cnot_ad_transfer
24
+ random_circuits — gaussian_binom_2, expected_gf2_rank, enumerate_vne
25
+ """
26
+
27
+ __version__ = "1.0.0"
28
+
29
+ from qse.core import (
30
+ build_M,
31
+ phi_dict,
32
+ t14_Pb,
33
+ t_universal,
34
+ vne_from_Pb,
35
+ renyi_entropy,
36
+ f2_rank,
37
+ t22_moment,
38
+ newton_girard,
39
+ )
40
+ from qse.states import (
41
+ product_state,
42
+ product_state_ry,
43
+ exact_rho_B,
44
+ exact_rho_B_mixed,
45
+ vne_exact,
46
+ )
47
+ from qse.gates import apply_cnot, apply_fsim, apply_swap
48
+ from qse.gradients import vne_gradient_rx
49
+ from qse.noise import (
50
+ amplitude_damping_kraus,
51
+ superop,
52
+ noise_transfer_Pb,
53
+ build_cnot_ad_transfer,
54
+ )
55
+ from qse.random_circuits import gaussian_binom_2, expected_gf2_rank, enumerate_vne
56
+
57
+ __all__ = [
58
+ # core
59
+ "build_M", "phi_dict", "t14_Pb", "t_universal",
60
+ "vne_from_Pb", "renyi_entropy", "f2_rank",
61
+ "t22_moment", "newton_girard",
62
+ # states
63
+ "product_state", "product_state_ry",
64
+ "exact_rho_B", "exact_rho_B_mixed", "vne_exact",
65
+ # gates
66
+ "apply_cnot", "apply_fsim", "apply_swap",
67
+ # gradients
68
+ "vne_gradient_rx",
69
+ # noise
70
+ "amplitude_damping_kraus", "superop", "noise_transfer_Pb",
71
+ "build_cnot_ad_transfer",
72
+ # random_circuits
73
+ "gaussian_binom_2", "expected_gf2_rank", "enumerate_vne",
74
+ ]
@@ -0,0 +1,217 @@
1
+ """
2
+ qse/core.py — Core QSE computations: WHT formula, GF(2) algebra, entropy.
3
+
4
+ Key formulas:
5
+ T14: P_b = (1/2^NB) sum_s (-1)^{b·s} Phi_M(s)
6
+ T-UNIVERSAL: P_b = sum_{x: Mx=b} rho_A[x,x]
7
+ VNE: H(P) = -sum_b P_b log2(P_b)
8
+ """
9
+
10
+ import numpy as np
11
+ from math import cos, log2, sin
12
+
13
+ # ── Building blocks ───────────────────────────────────────────────────────────
14
+
15
+ def build_M(pairs, NA, NB):
16
+ """Build GF(2) connectivity matrix M ∈ F2^{NB×NA} from CNOT pairs.
17
+
18
+ pairs: list of (a, b) meaning CNOT(ctrl=a, tgt=b), a ∈ [0,NA), b ∈ [0,NB).
19
+ XOR for repeated pairs (mod-2 cancellation).
20
+ """
21
+ M = np.zeros((NB, NA), dtype=int)
22
+ for a, b in pairs:
23
+ M[b][a] ^= 1
24
+ return M
25
+
26
+
27
+ def phi_dict(thetas, pairs, NA, NB):
28
+ """Phi_M(s) = prod_{i: (M^T s)_i = 1} cos(theta_i) for all s ∈ {0..2^NB-1}.
29
+
30
+ Returns: (phi dict {s: float}, M matrix)
31
+ """
32
+ M = build_M(pairs, NA, NB)
33
+ cos_t = [cos(t) for t in thetas]
34
+ phi = {}
35
+ for s in range(2**NB):
36
+ sv = np.array([(s >> j) & 1 for j in range(NB)])
37
+ MTs = np.mod(M.T @ sv, 2)
38
+ phi[s] = float(np.prod([cos_t[i] for i in range(NA) if MTs[i] == 1]))
39
+ return phi, M
40
+
41
+
42
+ # ── T14: Walsh-Hadamard master theorem ───────────────────────────────────────
43
+
44
+ def t14_Pb(thetas, pairs, NA, NB):
45
+ """T14: P_b = (1/2^NB) sum_s (-1)^{b·s} Phi_M(s).
46
+
47
+ Returns: (Pb dict {b: float}, phi dict {s: float})
48
+ """
49
+ phi, _ = phi_dict(thetas, pairs, NA, NB)
50
+ Pb = {}
51
+ for b in range(2**NB):
52
+ bv = np.array([(b >> j) & 1 for j in range(NB)])
53
+ Pb[b] = sum(
54
+ (-1) ** int(np.dot(bv, np.array([(s >> j) & 1 for j in range(NB)]) % 2))
55
+ * phi[s]
56
+ for s in range(2**NB)
57
+ ) / (2**NB)
58
+ return Pb, phi
59
+
60
+
61
+ # ── T-UNIVERSAL: diagonal mixed input ────────────────────────────────────────
62
+
63
+ def t_universal(rho_A, pairs, NA, NB):
64
+ """T-UNIVERSAL: P_b = sum_{x: Mx=b} rho_A[x,x].
65
+
66
+ Works for any diagonal (or full) density matrix rho_A.
67
+ """
68
+ M = build_M(pairs, NA, NB)
69
+ Pb = {}
70
+ for b in range(2**NB):
71
+ Pb[b] = 0.0
72
+ for x in range(2**NA):
73
+ bx = 0
74
+ for i in range(NA):
75
+ if (x >> i) & 1:
76
+ for j in range(NB):
77
+ if M[j][i]:
78
+ bx ^= 1 << j
79
+ if bx == b:
80
+ Pb[b] += rho_A[x, x].real
81
+ return Pb
82
+
83
+
84
+ # ── Entropy functions ─────────────────────────────────────────────────────────
85
+
86
+ def vne_from_Pb(Pb):
87
+ """Von Neumann entropy H(P) = -sum_b P_b log2(P_b), clipped at 1e-14."""
88
+ return float(sum(-v * log2(max(v, 1e-14)) for v in Pb.values() if v > 1e-14))
89
+
90
+
91
+ def renyi_entropy(Pb, alpha):
92
+ """S_alpha = (1/(1-alpha)) * log2(sum_b P_b^alpha). Returns VNE for alpha≈1."""
93
+ if abs(alpha - 1.0) < 1e-9:
94
+ return vne_from_Pb(Pb)
95
+ tr_rho_alpha = sum(max(v, 0) ** alpha for v in Pb.values())
96
+ return log2(max(tr_rho_alpha, 1e-300)) / (1 - alpha)
97
+
98
+
99
+ # ── GF(2) rank ────────────────────────────────────────────────────────────────
100
+
101
+ def f2_rank(pairs, NA, NB):
102
+ """Compute GF(2) rank of M via Gaussian elimination over F2."""
103
+ M = build_M(pairs, NA, NB)
104
+ mat = M.copy()
105
+ rank = 0
106
+ for col in range(NA):
107
+ pivot = next((r for r in range(rank, NB) if mat[r, col]), None)
108
+ if pivot is None:
109
+ continue
110
+ mat[[rank, pivot]] = mat[[pivot, rank]]
111
+ for row in range(NB):
112
+ if row != rank and mat[row, col]:
113
+ mat[row] = (mat[row] + mat[rank]) % 2
114
+ rank += 1
115
+ return rank
116
+
117
+
118
+ # ── Moment theory ─────────────────────────────────────────────────────────────
119
+
120
+ def t22_moment(thetas, pairs, NA, NB, alpha):
121
+ """T22: Tr(rho_B^alpha) = (1/2^{(alpha-1)*NB}) sum_{s1,...,s_{alpha-1}} prod Phi_M(s_i) * Phi_M(s1^...^s_{alpha-1})."""
122
+ from itertools import product as iproduct
123
+ phi, _ = phi_dict(thetas, pairs, NA, NB)
124
+ if alpha == 1:
125
+ return 1.0
126
+ total = 0.0
127
+ for combo in iproduct(range(2**NB), repeat=alpha - 1):
128
+ xor_all = 0
129
+ for c in combo:
130
+ xor_all ^= c
131
+ total += float(np.prod([phi[c] for c in combo])) * phi[xor_all]
132
+ return total / (2 ** ((alpha - 1) * NB))
133
+
134
+
135
+ def newton_girard(moments):
136
+ """Recover eigenvalues from power-sum moments via Newton-Girard identities."""
137
+ n = len(moments)
138
+ e = [0.0] * (n + 1)
139
+ e[0] = 1.0
140
+ for k in range(1, n + 1):
141
+ total = sum(((-1) ** (i - 1)) * e[k - i] * moments[i - 1]
142
+ for i in range(1, k + 1) if k - i <= n)
143
+ e[k] = total / k
144
+ coeffs = [(-1) ** k * e[k] for k in range(n + 1)]
145
+ return sorted(np.roots(coeffs).real, reverse=True)
146
+
147
+
148
+ # ── Gradient computation (T-GRAD) ─────────────────────────────────────────────
149
+
150
+ def vne_gradient_rx(thetas, pairs, NA, NB):
151
+ """Analytic gradient d(VNE)/d(theta_i) for Rx product state input via T14.
152
+
153
+ Derivation:
154
+ Phi_M(s) = prod_{j: (M^T s)_j=1} cos(theta_j)
155
+ d Phi_M(s)/d theta_i = -tan(theta_i) * Phi_M(s) if (M^T s)_i = 1, else 0
156
+ d P_b / d theta_i = (1/2^NB) sum_s (-1)^{b.s} * d Phi_M(s)/d theta_i
157
+ d VNE / d theta_i = -sum_b (d P_b/d theta_i) * log2(P_b)
158
+ [normalization sum_b d P_b/d theta_i = 0 eliminates the -1/ln2 term]
159
+ """
160
+ phi, M = phi_dict(thetas, pairs, NA, NB)
161
+ Pb, _ = t14_Pb(thetas, pairs, NA, NB)
162
+ grad = []
163
+ for i in range(NA):
164
+ tan_i = sin(thetas[i]) / cos(thetas[i])
165
+ dPb = {}
166
+ for b in range(2**NB):
167
+ bv = np.array([(b >> j) & 1 for j in range(NB)])
168
+ val = 0.0
169
+ for s in range(2**NB):
170
+ sv = np.array([(s >> j) & 1 for j in range(NB)])
171
+ MTs = np.mod(M.T @ sv, 2)
172
+ if MTs[i] == 1:
173
+ sign = (-1) ** int(np.dot(bv, sv) % 2)
174
+ val += sign * (-tan_i * phi[s])
175
+ dPb[b] = val / (2**NB)
176
+ dvne = sum(-dPb[b] * log2(max(Pb[b], 1e-14)) for b in range(2**NB) if Pb[b] > 1e-14)
177
+ grad.append(dvne)
178
+ return grad
179
+
180
+
181
+ # ── Renyi entropy derivative (T-RENYI-DERIV) ──────────────────────────────────
182
+
183
+ def t_renyi_deriv(Pb):
184
+ """T-RENYI-DERIV: d(S_alpha)/d(alpha)|_{alpha=1} = -ln(2)/2 * Var[log2 P_b].
185
+
186
+ Measures convergence speed: positive = converging, negative = diverging.
187
+ """
188
+ import math
189
+ vne = vne_from_Pb(Pb)
190
+ second_moment = sum(v * log2(max(v, 1e-14))**2 for v in Pb.values() if v > 1e-14)
191
+ var_log = second_moment - vne**2
192
+ return -math.log(2) / 2.0 * var_log
193
+
194
+
195
+ # ── Gaussian binomial coefficients ────────────────────────────────────────────
196
+
197
+ def gaussian_binom_2(n, k):
198
+ """Gaussian binomial [n choose k]_2 over GF(2)."""
199
+ if k < 0 or k > n:
200
+ return 0
201
+ num = 1
202
+ for j in range(k):
203
+ num *= (2**n - 2**j)
204
+ den = 1
205
+ for j in range(k):
206
+ den *= (2**k - 2**j)
207
+ return num // den
208
+
209
+
210
+ def expected_gf2_rank(NA, NB):
211
+ """E[rank] for NB×NA uniform-random GF(2) matrix via Gaussian binomial formula."""
212
+ total_matrices = 2 ** (NA * NB)
213
+ total = sum(
214
+ r * gaussian_binom_2(NB, r) * int(np.prod([2**NA - 2**j for j in range(r)]))
215
+ for r in range(1, min(NA, NB) + 1)
216
+ )
217
+ return total / total_matrices
@@ -0,0 +1,52 @@
1
+ """
2
+ qse/gates.py — Quantum gate applications on statevectors.
3
+
4
+ All gates operate on flat complex numpy arrays. Qubit index k = bit k of the
5
+ integer index. A-qubits occupy bits 0..NA-1, B-qubits bits NA..NA+NB-1.
6
+ """
7
+
8
+ import numpy as np
9
+ from math import cos, sin
10
+
11
+
12
+ def apply_cnot(amps, ctrl, tgt):
13
+ """Apply CNOT(ctrl, tgt) to statevector `amps` in-place (returns new array).
14
+
15
+ Flips bit `tgt` of each basis state where bit `ctrl` is 1.
16
+ """
17
+ new = np.zeros_like(amps)
18
+ for idx in range(len(amps)):
19
+ new[idx ^ (1 << tgt) if (idx >> ctrl) & 1 else idx] += amps[idx]
20
+ return new
21
+
22
+
23
+ def apply_fsim(amps, q1, q2, alpha, phi):
24
+ """Apply fSim(alpha, phi) gate on qubits q1 and q2 of statevector.
25
+
26
+ fSim acts as:
27
+ |00⟩ → |00⟩
28
+ |01⟩ → cos(α)|01⟩ − i·sin(α)|10⟩
29
+ |10⟩ → cos(α)|10⟩ − i·sin(α)|01⟩
30
+ |11⟩ → e^{−iφ}|11⟩
31
+ """
32
+ new = amps.copy()
33
+ cos_a = cos(alpha)
34
+ sin_a = sin(alpha)
35
+ for idx in range(len(amps)):
36
+ b1 = (idx >> q1) & 1
37
+ b2 = (idx >> q2) & 1
38
+ if b1 == 1 and b2 == 1:
39
+ new[idx] = np.exp(-1j * phi) * amps[idx]
40
+ elif b1 == 0 and b2 == 1:
41
+ idx10 = idx ^ (1 << q1) ^ (1 << q2)
42
+ new[idx] = cos_a * amps[idx] - 1j * sin_a * amps[idx10]
43
+ new[idx10] = cos_a * amps[idx10] - 1j * sin_a * amps[idx]
44
+ return new
45
+
46
+
47
+ def apply_swap(amps, q1, q2):
48
+ """Apply SWAP(q1, q2) via three CNOTs: CNOT(q1→q2), CNOT(q2→q1), CNOT(q1→q2)."""
49
+ amps = apply_cnot(amps, q1, q2)
50
+ amps = apply_cnot(amps, q2, q1)
51
+ amps = apply_cnot(amps, q1, q2)
52
+ return amps
@@ -0,0 +1,46 @@
1
+ """
2
+ qse/gradients.py — Analytic VNE gradients via T14.
3
+
4
+ T-GRAD: d(VNE)/d(θ_i) closed form for Rx product-state inputs.
5
+
6
+ Derivation:
7
+ Φ_M(s) = prod_{j: (M^T s)_j=1} cos(θ_j)
8
+ d Φ_M(s)/d θ_i = −tan(θ_i)·Φ_M(s) if (M^T s)_i = 1, else 0
9
+ d P_b / d θ_i = (1/2^NB) sum_s (−1)^{b·s} · d Φ_M(s)/d θ_i
10
+ d VNE / d θ_i = −sum_b (d P_b/d θ_i) · log2(P_b)
11
+ (normalization sum_b d P_b/d θ_i = 0 eliminates the −1/ln2 term)
12
+ """
13
+
14
+ import numpy as np
15
+ from math import sin, cos, log2
16
+
17
+ from qse.core import phi_dict, t14_Pb
18
+
19
+
20
+ def vne_gradient_rx(thetas, pairs, NA, NB):
21
+ """Analytic gradient d(VNE)/d(θ_i) for Rx product-state input.
22
+
23
+ Returns a list of length NA with the gradient for each A-qubit angle.
24
+ """
25
+ phi, M = phi_dict(thetas, pairs, NA, NB)
26
+ Pb, _ = t14_Pb(thetas, pairs, NA, NB)
27
+ grad = []
28
+ for i in range(NA):
29
+ tan_i = sin(thetas[i]) / cos(thetas[i])
30
+ dPb = {}
31
+ for b in range(2**NB):
32
+ bv = np.array([(b >> j) & 1 for j in range(NB)])
33
+ val = 0.0
34
+ for s in range(2**NB):
35
+ sv = np.array([(s >> j) & 1 for j in range(NB)])
36
+ MTs = np.mod(M.T @ sv, 2)
37
+ if MTs[i] == 1:
38
+ sign = (-1) ** int(np.dot(bv, sv) % 2)
39
+ val += sign * (-tan_i * phi[s])
40
+ dPb[b] = val / (2**NB)
41
+ dvne = sum(
42
+ -dPb[b] * log2(max(Pb[b], 1e-14))
43
+ for b in range(2**NB) if Pb[b] > 1e-14
44
+ )
45
+ grad.append(dvne)
46
+ return grad