pyqrack-cpu 2.3.1__tar.gz → 2.4.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.
- {pyqrack_cpu-2.3.1/pyqrack_cpu.egg-info → pyqrack_cpu-2.4.0}/PKG-INFO +1 -1
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/scripts/optimize_bseq_correction.py +95 -22
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0/pyqrack_cpu.egg-info}/PKG-INFO +1 -1
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/setup.py +1 -1
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/LICENSE +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/MANIFEST.in +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/Makefile +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/README.md +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyproject.toml +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_ace_backend.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack_cpu.egg-info/SOURCES.txt +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack_cpu.egg-info/dependency_links.txt +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack_cpu.egg-info/not-zip-safe +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack_cpu.egg-info/requires.txt +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/pyqrack_cpu.egg-info/top_level.txt +0 -0
- {pyqrack_cpu-2.3.1 → pyqrack_cpu-2.4.0}/setup.cfg +0 -0
|
@@ -124,20 +124,27 @@ def compute_S(shots, **kwargs):
|
|
|
124
124
|
return e_ab + e_abp + e_apb - e_apbp
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
def compute_bell_pair_stats(
|
|
127
|
+
def compute_bell_pair_stats(
|
|
128
|
+
n_constructions, shots, width=3, long_range_columns=1, ancillae=True, control=0
|
|
129
|
+
):
|
|
128
130
|
"""Simpler, plain Bell-pair statistic (matching bell_state.py): for
|
|
129
|
-
each of n_constructions independent
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
each of n_constructions independent constructions, put qubit
|
|
132
|
+
`control` into superposition and CNOT from it onto the other qubit
|
|
133
|
+
(control=0: h(0); cx(0,1), matching bell_state.py exactly;
|
|
134
|
+
control=1: h(1); cx(1,0), the mirrored direction -- qubit 1 is the
|
|
135
|
+
boundary qubit in this 3-qubit, long_range_columns=1 topology, so
|
|
136
|
+
these two directions exercise genuinely different code paths, not
|
|
137
|
+
just relabeled qubits). Samples shots measurements and tracks the
|
|
138
|
+
0/1 (agreement-side) balance and overall correlation. Returns
|
|
139
|
+
(mean_correlation, mean_balance, stdev_balance).
|
|
134
140
|
"""
|
|
141
|
+
target = 1 - control
|
|
135
142
|
total_correlated = 0
|
|
136
143
|
balance_vals = []
|
|
137
144
|
for _ in range(n_constructions):
|
|
138
145
|
s = QrackAceBackend(width, long_range_columns=long_range_columns, bseq_ancillae=ancillae)
|
|
139
|
-
s.h(
|
|
140
|
-
s.cx(
|
|
146
|
+
s.h(control)
|
|
147
|
+
s.cx(control, target)
|
|
141
148
|
results = s.measure_shots([0, 1], shots)
|
|
142
149
|
zero = sum(1 for r in results if r == 0)
|
|
143
150
|
three = sum(1 for r in results if r == 3)
|
|
@@ -164,6 +171,46 @@ def bell_pair_score(params, n_constructions=200, shots=24, ancillae=True, **kwar
|
|
|
164
171
|
return mean_corr - abs(mean_bal - 0.5) - 0.5 * stdev_bal
|
|
165
172
|
|
|
166
173
|
|
|
174
|
+
def bell_correlation_score(params, n_constructions=200, shots=24, ancillae=True, **kwargs):
|
|
175
|
+
"""A simpler reward: just the mean Bell-pair correlation itself
|
|
176
|
+
(matching bell_state.py's printed "Correlation:" metric exactly --
|
|
177
|
+
correlated/shots, averaged over many independent constructions),
|
|
178
|
+
with no balance-centering or variance penalty. Note: unlike
|
|
179
|
+
bell_pair_score, this has no guard against the optimizer finding a
|
|
180
|
+
correction that pushes correlation up by forcing deterministic
|
|
181
|
+
agreement between the two qubits rather than by improving genuine
|
|
182
|
+
entanglement fidelity -- it is the more direct, but less
|
|
183
|
+
constrained, objective."""
|
|
184
|
+
set_correction(params, ancillae=ancillae)
|
|
185
|
+
mean_corr, _, _ = compute_bell_pair_stats(n_constructions, shots, ancillae=ancillae, **kwargs)
|
|
186
|
+
return mean_corr
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def bell_correlation_symmetric_score(
|
|
190
|
+
params, n_constructions=200, shots=24, ancillae=True, **kwargs
|
|
191
|
+
):
|
|
192
|
+
"""Like bell_correlation_score, but fit simultaneously, with equal
|
|
193
|
+
weight, against BOTH CNOT directions: control=0 (h(0); cx(0,1),
|
|
194
|
+
the original bell_state.py case) and control=1 (h(1); cx(1,0), the
|
|
195
|
+
mirrored case). Returns the unweighted average of the two
|
|
196
|
+
directions' mean correlations, so a correction that helps one
|
|
197
|
+
direction while hurting the other equally is NOT rewarded --
|
|
198
|
+
direct testing showed the correction trained on control=0 alone
|
|
199
|
+
actively hurts control=1 (correlation dropping to ~0.17, well
|
|
200
|
+
below the ~0.5 chance baseline), confirming the two directions
|
|
201
|
+
exercise genuinely different code paths (qubit 1 is the boundary
|
|
202
|
+
qubit in this topology) and need to be fit together, not assumed
|
|
203
|
+
symmetric."""
|
|
204
|
+
set_correction(params, ancillae=ancillae)
|
|
205
|
+
mean_corr_0, _, _ = compute_bell_pair_stats(
|
|
206
|
+
n_constructions, shots, ancillae=ancillae, control=0, **kwargs
|
|
207
|
+
)
|
|
208
|
+
mean_corr_1, _, _ = compute_bell_pair_stats(
|
|
209
|
+
n_constructions, shots, ancillae=ancillae, control=1, **kwargs
|
|
210
|
+
)
|
|
211
|
+
return (mean_corr_0 + mean_corr_1) / 2
|
|
212
|
+
|
|
213
|
+
|
|
167
214
|
def set_correction(params, ancillae=True):
|
|
168
215
|
"""params is a 3-tuple (theta, phi, lambda) for the u layer alone
|
|
169
216
|
when ancillae=False, or a 7-tuple (theta, phi, lambda, mcu_theta,
|
|
@@ -203,7 +250,7 @@ def optimize(
|
|
|
203
250
|
initial_step=PI / 4,
|
|
204
251
|
step_decay=0.8,
|
|
205
252
|
decay_every=10,
|
|
206
|
-
target="
|
|
253
|
+
target="correlation_symmetric",
|
|
207
254
|
ancillae=True,
|
|
208
255
|
):
|
|
209
256
|
"""Gradient-free random-walk search over the correction angles,
|
|
@@ -218,12 +265,21 @@ def optimize(
|
|
|
218
265
|
parameters and constructs with bseq_ancillae=False (no ancilla
|
|
219
266
|
qubits allocated at all).
|
|
220
267
|
|
|
221
|
-
target: "
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
268
|
+
target: "correlation_symmetric" (default) maximizes mean Bell-pair
|
|
269
|
+
correlation, fit simultaneously with EQUAL weight against both
|
|
270
|
+
CNOT directions (control=0, the original bell_state.py case,
|
|
271
|
+
and control=1, the mirrored case h(1); cx(1,0)) -- a correction
|
|
272
|
+
that helps one direction while hurting the other is not
|
|
273
|
+
rewarded. Direct testing showed these two directions are NOT
|
|
274
|
+
symmetric in this architecture (qubit 1 is the boundary qubit
|
|
275
|
+
in the 3-qubit, long_range_columns=1 topology): a correction
|
|
276
|
+
fit only on control=0 actively harmed control=1 (correlation
|
|
277
|
+
dropping to ~0.17, below the ~0.5 chance baseline). "correlation"
|
|
278
|
+
optimizes only the original control=0 direction. "bell_pair"
|
|
279
|
+
optimizes a composite of correlation, balance-centering, and
|
|
280
|
+
low variance (control=0 only). "S" optimizes the CHSH S
|
|
281
|
+
statistic directly. In direct testing, "S" did not show a
|
|
282
|
+
consistent improvement.
|
|
227
283
|
"""
|
|
228
284
|
if seed is not None:
|
|
229
285
|
random.seed(seed)
|
|
@@ -236,8 +292,21 @@ def optimize(
|
|
|
236
292
|
p, n_constructions=n_repeats * 32, shots=shots, ancillae=ancillae
|
|
237
293
|
)
|
|
238
294
|
label = "bell_pair_score"
|
|
295
|
+
elif target == "correlation":
|
|
296
|
+
reward_fn = lambda p: bell_correlation_score(
|
|
297
|
+
p, n_constructions=n_repeats * 32, shots=shots, ancillae=ancillae
|
|
298
|
+
)
|
|
299
|
+
label = "mean_correlation"
|
|
300
|
+
elif target == "correlation_symmetric":
|
|
301
|
+
reward_fn = lambda p: bell_correlation_symmetric_score(
|
|
302
|
+
p, n_constructions=n_repeats * 32, shots=shots, ancillae=ancillae
|
|
303
|
+
)
|
|
304
|
+
label = "mean_correlation_symmetric"
|
|
239
305
|
else:
|
|
240
|
-
raise ValueError(
|
|
306
|
+
raise ValueError(
|
|
307
|
+
f"unknown target: {target!r} (expected 'S', 'bell_pair', "
|
|
308
|
+
"'correlation', or 'correlation_symmetric')"
|
|
309
|
+
)
|
|
241
310
|
|
|
242
311
|
n_params = 7 if ancillae else 3
|
|
243
312
|
best_params = tuple(0.0 for _ in range(n_params))
|
|
@@ -328,12 +397,16 @@ def main():
|
|
|
328
397
|
parser.add_argument("--seed", type=int, default=None)
|
|
329
398
|
parser.add_argument(
|
|
330
399
|
"--target",
|
|
331
|
-
choices=["S", "bell_pair"],
|
|
332
|
-
default="
|
|
333
|
-
help="Optimization objective:
|
|
334
|
-
"Bell-pair correlation
|
|
335
|
-
"
|
|
336
|
-
"
|
|
400
|
+
choices=["S", "bell_pair", "correlation", "correlation_symmetric"],
|
|
401
|
+
default="correlation_symmetric",
|
|
402
|
+
help="Optimization objective: 'correlation_symmetric' (default) "
|
|
403
|
+
"maximizes mean Bell-pair correlation, fit with equal weight "
|
|
404
|
+
"against both CNOT directions (control=0 and control=1, which "
|
|
405
|
+
"are NOT symmetric in this architecture); 'correlation' fits "
|
|
406
|
+
"only the original control=0 direction; 'bell_pair' optimizes "
|
|
407
|
+
"a composite of correlation, balance-centering, and low "
|
|
408
|
+
"variance (control=0 only); 'S' optimizes the CHSH S "
|
|
409
|
+
"statistic directly.",
|
|
337
410
|
)
|
|
338
411
|
parser.add_argument(
|
|
339
412
|
"--no-ancillae",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|