pyqrack-cuda-complex128 2.2.1__tar.gz → 2.2.2__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_cuda_complex128-2.2.1/pyqrack_cuda_complex128.egg-info → pyqrack_cuda_complex128-2.2.2}/PKG-INFO +1 -1
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_ace_backend.py +380 -104
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2/pyqrack_cuda_complex128.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/setup.py +1 -1
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/LICENSE +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/MANIFEST.in +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/Makefile +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/README.md +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyproject.toml +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack_cuda_complex128.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack_cuda_complex128.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack_cuda_complex128.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack_cuda_complex128.egg-info/requires.txt +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack_cuda_complex128.egg-info/top_level.txt +0 -0
- {pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/setup.cfg +0 -0
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_ace_backend.py
RENAMED
|
@@ -29,6 +29,169 @@ except ImportError:
|
|
|
29
29
|
_IS_QISKIT_AER_AVAILABLE = False
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
# Initial stub and concept produced through conversation with Elara
|
|
33
|
+
# (the custom OpenAI GPT)
|
|
34
|
+
class LHVQubit:
|
|
35
|
+
def __init__(self, to_clone=None):
|
|
36
|
+
# Initial state in "Bloch vector" terms, defaults to |0⟩
|
|
37
|
+
if to_clone:
|
|
38
|
+
self.bloch = to_clone.bloch.copy()
|
|
39
|
+
else:
|
|
40
|
+
self.reset()
|
|
41
|
+
|
|
42
|
+
def reset(self):
|
|
43
|
+
self.bloch = [0.0, 0.0, 1.0]
|
|
44
|
+
|
|
45
|
+
def h(self):
|
|
46
|
+
# Hadamard: rotate around Y-axis then X-axis (simplified for LHV)
|
|
47
|
+
x, y, z = self.bloch
|
|
48
|
+
self.bloch = [(x + z) / math.sqrt(2), y, (z - x) / math.sqrt(2)]
|
|
49
|
+
|
|
50
|
+
def x(self):
|
|
51
|
+
x, y, z = self.bloch
|
|
52
|
+
self.bloch = [x, y, -z]
|
|
53
|
+
|
|
54
|
+
def y(self):
|
|
55
|
+
x, y, z = self.bloch
|
|
56
|
+
self.bloch = [-x, y, z]
|
|
57
|
+
|
|
58
|
+
def z(self):
|
|
59
|
+
x, y, z = self.bloch
|
|
60
|
+
self.bloch = [x, -y, z]
|
|
61
|
+
|
|
62
|
+
def rx(self, theta):
|
|
63
|
+
# Rotate Bloch vector around X-axis by angle theta
|
|
64
|
+
x, y, z = self.bloch
|
|
65
|
+
cos_theta = math.cos(theta)
|
|
66
|
+
sin_theta = math.sin(theta)
|
|
67
|
+
new_y = cos_theta * y - sin_theta * z
|
|
68
|
+
new_z = sin_theta * y + cos_theta * z
|
|
69
|
+
self.bloch = [x, new_y, new_z]
|
|
70
|
+
|
|
71
|
+
def ry(self, theta):
|
|
72
|
+
# Rotate Bloch vector around Y-axis by angle theta
|
|
73
|
+
x, y, z = self.bloch
|
|
74
|
+
cos_theta = math.cos(theta)
|
|
75
|
+
sin_theta = math.sin(theta)
|
|
76
|
+
new_x = cos_theta * x + sin_theta * z
|
|
77
|
+
new_z = -sin_theta * x + cos_theta * z
|
|
78
|
+
self.bloch = [new_x, y, new_z]
|
|
79
|
+
|
|
80
|
+
def rz(self, theta):
|
|
81
|
+
# Rotate Bloch vector around Z-axis by angle theta (in radians)
|
|
82
|
+
x, y, z = self.bloch
|
|
83
|
+
cos_theta = math.cos(theta)
|
|
84
|
+
sin_theta = math.sin(theta)
|
|
85
|
+
new_x = cos_theta * x - sin_theta * y
|
|
86
|
+
new_y = sin_theta * x + cos_theta * y
|
|
87
|
+
self.bloch = [new_x, new_y, z]
|
|
88
|
+
|
|
89
|
+
def s(self):
|
|
90
|
+
self.rz(math.pi / 2)
|
|
91
|
+
|
|
92
|
+
def adjs(self):
|
|
93
|
+
self.rz(-math.pi / 2)
|
|
94
|
+
|
|
95
|
+
def t(self):
|
|
96
|
+
self.rz(math.pi / 4)
|
|
97
|
+
|
|
98
|
+
def adjt(self):
|
|
99
|
+
self.rz(-math.pi / 4)
|
|
100
|
+
|
|
101
|
+
def u(self, theta, phi, lam):
|
|
102
|
+
# Apply general single-qubit unitary gate
|
|
103
|
+
self.rz(lam)
|
|
104
|
+
self.ry(theta)
|
|
105
|
+
self.rz(phi)
|
|
106
|
+
|
|
107
|
+
# Provided verbatim by Elara (the custom OpenAI GPT):
|
|
108
|
+
def mtrx(self, matrix):
|
|
109
|
+
"""
|
|
110
|
+
Apply a 2x2 unitary matrix to the LHV Bloch vector using only standard math/cmath.
|
|
111
|
+
Matrix format: [a, b, c, d] for [[a, b], [c, d]]
|
|
112
|
+
"""
|
|
113
|
+
a, b, c, d = matrix
|
|
114
|
+
|
|
115
|
+
# Current Bloch vector
|
|
116
|
+
x, y, z = self.bloch
|
|
117
|
+
|
|
118
|
+
# Convert to density matrix ρ = ½ (I + xσx + yσy + zσz)
|
|
119
|
+
rho = [[(1 + z) / 2, (x - 1j * y) / 2], [(x + 1j * y) / 2, (1 - z) / 2]]
|
|
120
|
+
|
|
121
|
+
# Compute U * ρ
|
|
122
|
+
u_rho = [
|
|
123
|
+
[a * rho[0][0] + b * rho[1][0], a * rho[0][1] + b * rho[1][1]],
|
|
124
|
+
[c * rho[0][0] + d * rho[1][0], c * rho[0][1] + d * rho[1][1]],
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
# Compute (U * ρ) * U†
|
|
128
|
+
rho_prime = [
|
|
129
|
+
[
|
|
130
|
+
u_rho[0][0] * a.conjugate() + u_rho[0][1] * b.conjugate(),
|
|
131
|
+
u_rho[0][0] * c.conjugate() + u_rho[0][1] * d.conjugate(),
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
u_rho[1][0] * a.conjugate() + u_rho[1][1] * b.conjugate(),
|
|
135
|
+
u_rho[1][0] * c.conjugate() + u_rho[1][1] * d.conjugate(),
|
|
136
|
+
],
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
# Extract Bloch components: Tr(ρ'σi) = 2 * Re[...]
|
|
140
|
+
new_x = 2 * rho_prime[0][1].real + 2 * rho_prime[1][0].real
|
|
141
|
+
new_y = 2 * (rho_prime[0][1].imag - rho_prime[1][0].imag)
|
|
142
|
+
new_z = 2 * rho_prime[0][0].real - 1 # since Tr(ρ') = 1
|
|
143
|
+
|
|
144
|
+
p = math.sqrt(new_x**2 + new_y**2 + new_z**2)
|
|
145
|
+
|
|
146
|
+
new_x /= p
|
|
147
|
+
new_y /= p
|
|
148
|
+
new_z /= p
|
|
149
|
+
|
|
150
|
+
self.bloch = [new_x, new_y, new_z]
|
|
151
|
+
|
|
152
|
+
def prob(self, basis=Pauli.PauliZ):
|
|
153
|
+
"""Sample a classical outcome from the current 'quantum' state"""
|
|
154
|
+
if basis == Pauli.PauliZ:
|
|
155
|
+
prob_1 = (1 - self.bloch[2]) / 2
|
|
156
|
+
elif basis == Pauli.PauliX:
|
|
157
|
+
prob_1 = (1 - self.bloch[0]) / 2
|
|
158
|
+
elif basis == Pauli.PauliY:
|
|
159
|
+
prob_1 = (1 - self.bloch[1]) / 2
|
|
160
|
+
else:
|
|
161
|
+
raise ValueError(f"Unsupported basis: {basis}")
|
|
162
|
+
return prob_1
|
|
163
|
+
|
|
164
|
+
def m(self):
|
|
165
|
+
result = random.random() < self.prob()
|
|
166
|
+
self.reset()
|
|
167
|
+
if result:
|
|
168
|
+
self.x()
|
|
169
|
+
return result
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# Provided by Elara (the custom OpenAI GPT)
|
|
173
|
+
def _cpauli_lhv(prob, targ, axis, anti, theta=math.pi):
|
|
174
|
+
"""
|
|
175
|
+
Apply a 'soft' controlled-Pauli gate: rotate target qubit
|
|
176
|
+
proportionally to control's Z expectation value.
|
|
177
|
+
|
|
178
|
+
theta: full rotation angle if control in |1⟩
|
|
179
|
+
"""
|
|
180
|
+
# Control influence is (1 - ctrl.bloch[2]) / 2 = P(|1⟩)
|
|
181
|
+
# BUT we avoid collapse by using the expectation value:
|
|
182
|
+
control_influence = (1 - prob) if anti else prob
|
|
183
|
+
|
|
184
|
+
effective_theta = control_influence * theta
|
|
185
|
+
|
|
186
|
+
# Apply partial rotation to target qubit:
|
|
187
|
+
if axis == Pauli.PauliX:
|
|
188
|
+
targ.rx(effective_theta)
|
|
189
|
+
elif axis == Pauli.PauliY:
|
|
190
|
+
targ.ry(effective_theta)
|
|
191
|
+
elif axis == Pauli.PauliZ:
|
|
192
|
+
targ.rz(effective_theta)
|
|
193
|
+
|
|
194
|
+
|
|
32
195
|
class QrackAceBackend:
|
|
33
196
|
"""A back end for elided quantum error correction
|
|
34
197
|
|
|
@@ -113,18 +276,6 @@ class QrackAceBackend:
|
|
|
113
276
|
self._is_row_long_range[-1] = False
|
|
114
277
|
sim_count = col_patch_count * row_patch_count
|
|
115
278
|
|
|
116
|
-
# Boundary qubits no longer carry a private classical LHV proxy.
|
|
117
|
-
# Instead, every boundary site (row- and/or column-boundary alike)
|
|
118
|
-
# gets a real qubit in one single, shared "crossbar" QrackSimulator.
|
|
119
|
-
# That simulator's own greedy elision (set_sdrp) is trusted to
|
|
120
|
-
# automatically factor apart whatever boundary sites turn out to be
|
|
121
|
-
# separable (e.g. disjoint rails, rail intersections), exactly the
|
|
122
|
-
# same way it already factors apart unentangled subspaces within
|
|
123
|
-
# any other single QrackSimulator instance. We don't need to special
|
|
124
|
-
# -case "crossbar intersections" by hand; the elision does it for us.
|
|
125
|
-
boundary_sim_id = sim_count
|
|
126
|
-
boundary_count = 0
|
|
127
|
-
|
|
128
279
|
self._qubits = []
|
|
129
280
|
sim_counts = [0] * sim_count
|
|
130
281
|
sim_id = 0
|
|
@@ -139,8 +290,9 @@ class QrackAceBackend:
|
|
|
139
290
|
qubit.append((t_sim_id, sim_counts[t_sim_id]))
|
|
140
291
|
sim_counts[t_sim_id] += 1
|
|
141
292
|
|
|
142
|
-
qubit.append(
|
|
143
|
-
|
|
293
|
+
qubit.append(
|
|
294
|
+
LHVQubit(to_clone=(to_clone._qubits[tot_qubits][2] if to_clone else None))
|
|
295
|
+
)
|
|
144
296
|
|
|
145
297
|
if (not c) and (not r):
|
|
146
298
|
t_sim_id = (sim_id + col_patch_count) % sim_count
|
|
@@ -157,23 +309,8 @@ class QrackAceBackend:
|
|
|
157
309
|
self._qubits.append(qubit)
|
|
158
310
|
tot_qubits += 1
|
|
159
311
|
|
|
160
|
-
# The crossbar's size is fixed by how many boundary sites exist.
|
|
161
|
-
# When there are none (e.g. a grid small enough, relative to
|
|
162
|
-
# long_range_rows/columns, that the whole thing is "fully
|
|
163
|
-
# connected" with no QEC boundary at all), we must NOT allocate a
|
|
164
|
-
# 0-qubit QrackSimulator for the crossbar: a 0-qubit QrackSimulator
|
|
165
|
-
# can be constructed, but calling .clone() on one crashes the
|
|
166
|
-
# native Qrack core (segfault), and clone() is called routinely by
|
|
167
|
-
# measure_shots()/clone(). So the boundary sim is only created when
|
|
168
|
-
# boundary_count > 0, exactly mirroring how the original LHV-based
|
|
169
|
-
# code never instantiated anything for the boundary case when
|
|
170
|
-
# there were no boundary sites.
|
|
171
|
-
has_boundary = boundary_count > 0
|
|
172
|
-
if has_boundary:
|
|
173
|
-
sim_counts.append(boundary_count)
|
|
174
|
-
|
|
175
312
|
self.sim = []
|
|
176
|
-
for i in range(sim_count
|
|
313
|
+
for i in range(sim_count):
|
|
177
314
|
self.sim.append(
|
|
178
315
|
to_clone.sim[i].clone()
|
|
179
316
|
if to_clone
|
|
@@ -189,16 +326,18 @@ class QrackAceBackend:
|
|
|
189
326
|
)
|
|
190
327
|
)
|
|
191
328
|
|
|
192
|
-
# You can still "
|
|
193
|
-
if "QRACK_QUNIT_SEPARABILITY_THRESHOLD" not in os.environ:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
self._boundary_sim_id = boundary_sim_id if has_boundary else None
|
|
329
|
+
# You can still call "set_sdrp," after the constructor.
|
|
330
|
+
# if "QRACK_QUNIT_SEPARABILITY_THRESHOLD" not in os.environ:
|
|
331
|
+
# # (1 - 1 / sqrt(2)) / 4 (but empirically tuned)
|
|
332
|
+
# self.sim[i].set_sdrp(0.073223304703363119)
|
|
198
333
|
|
|
199
334
|
def clone(self):
|
|
200
335
|
return QrackAceBackend(to_clone=self)
|
|
201
336
|
|
|
337
|
+
def set_sdrp(self, sdrp):
|
|
338
|
+
for sim in self.sim:
|
|
339
|
+
sim.set_sdrp(sdrp)
|
|
340
|
+
|
|
202
341
|
def measure_shots_consensus(self, q, s, n_instances=3, threshold=0.1):
|
|
203
342
|
# Consensus measurement across n_instances independent clones.
|
|
204
343
|
#
|
|
@@ -333,23 +472,35 @@ class QrackAceBackend:
|
|
|
333
472
|
|
|
334
473
|
@staticmethod
|
|
335
474
|
def _get_qb_lhv_indices(hq):
|
|
336
|
-
|
|
337
|
-
# classical LHVQubit proxy and had to be special-cased everywhere.
|
|
338
|
-
# It is now an ordinary (sim_id, idx) tuple into the shared
|
|
339
|
-
# boundary "crossbar" QrackSimulator, so it is just one more
|
|
340
|
-
# coupling target like every other index. We keep this helper's
|
|
341
|
-
# name and signature for minimal call-site churn; "lhv" is now
|
|
342
|
-
# always -1 (no index needs special-casing any more).
|
|
475
|
+
qb = []
|
|
343
476
|
if len(hq) < 2:
|
|
344
477
|
qb = [0]
|
|
478
|
+
lhv = -1
|
|
345
479
|
elif len(hq) < 4:
|
|
346
|
-
qb = [0, 1
|
|
480
|
+
qb = [0, 1]
|
|
481
|
+
lhv = 2
|
|
347
482
|
else:
|
|
348
|
-
qb = [0, 1,
|
|
349
|
-
|
|
483
|
+
qb = [0, 1, 3, 4]
|
|
484
|
+
lhv = 2
|
|
350
485
|
|
|
351
486
|
return qb, lhv
|
|
352
487
|
|
|
488
|
+
@staticmethod
|
|
489
|
+
def _get_lhv_bloch_angles(sim):
|
|
490
|
+
# Z axis
|
|
491
|
+
z = sim.bloch[2]
|
|
492
|
+
|
|
493
|
+
# X axis
|
|
494
|
+
x = sim.bloch[0]
|
|
495
|
+
|
|
496
|
+
# Y axis
|
|
497
|
+
y = sim.bloch[1]
|
|
498
|
+
|
|
499
|
+
inclination = math.atan2(math.sqrt(x**2 + y**2), z)
|
|
500
|
+
azimuth = math.atan2(y, x)
|
|
501
|
+
|
|
502
|
+
return azimuth, inclination
|
|
503
|
+
|
|
353
504
|
def _get_bloch_angles(self, hq):
|
|
354
505
|
sim = self.sim[hq[0]].clone()
|
|
355
506
|
q = hq[1]
|
|
@@ -392,25 +543,42 @@ class QrackAceBackend:
|
|
|
392
543
|
|
|
393
544
|
sim.mtrx([m00, m01, m10, m11], q)
|
|
394
545
|
|
|
546
|
+
@staticmethod
|
|
547
|
+
def _rotate_lhv_to_bloch(sim, delta_azimuth, delta_inclination):
|
|
548
|
+
# Apply rotation as "Azimuth, Inclination" (AI)
|
|
549
|
+
cosA = math.cos(delta_azimuth)
|
|
550
|
+
sinA = math.sin(delta_azimuth)
|
|
551
|
+
cosI = math.cos(delta_inclination / 2)
|
|
552
|
+
sinI = math.sin(delta_inclination / 2)
|
|
553
|
+
|
|
554
|
+
m00 = complex(cosI, 0)
|
|
555
|
+
m01 = complex(-cosA, sinA) * sinI
|
|
556
|
+
m10 = complex(cosA, sinA) * sinI
|
|
557
|
+
m11 = complex(cosI, 0)
|
|
558
|
+
|
|
559
|
+
sim.mtrx([m00, m01, m10, m11])
|
|
560
|
+
|
|
395
561
|
def _correct(self, lq, phase=False, skip_rotation=False):
|
|
396
562
|
hq = self._unpack(lq)
|
|
397
563
|
|
|
398
564
|
if len(hq) == 1:
|
|
399
565
|
return
|
|
400
566
|
|
|
401
|
-
qb,
|
|
567
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
402
568
|
|
|
403
569
|
if phase:
|
|
404
570
|
for q in qb:
|
|
405
571
|
b = hq[q]
|
|
406
572
|
self.sim[b[0]].h(b[1])
|
|
573
|
+
b = hq[lhv]
|
|
574
|
+
b.h()
|
|
407
575
|
|
|
408
576
|
if len(hq) == 5:
|
|
409
577
|
# RMS
|
|
410
578
|
p = [
|
|
411
579
|
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
412
580
|
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
413
|
-
|
|
581
|
+
hq[2].prob(),
|
|
414
582
|
self.sim[hq[3][0]].prob(hq[3][1]),
|
|
415
583
|
self.sim[hq[4][0]].prob(hq[4][1]),
|
|
416
584
|
]
|
|
@@ -426,7 +594,12 @@ class QrackAceBackend:
|
|
|
426
594
|
)
|
|
427
595
|
/ 7
|
|
428
596
|
)
|
|
429
|
-
|
|
597
|
+
eff_prob = (prms + (1 - qrms)) / 2
|
|
598
|
+
result = (
|
|
599
|
+
(random.random() < 0.5)
|
|
600
|
+
if (eff_prob - 0.5) == 0.0
|
|
601
|
+
else (eff_prob > 0.5)
|
|
602
|
+
)
|
|
430
603
|
syndrome = (
|
|
431
604
|
[1 - p[0], 1 - p[1], 1 - p[2], 1 - p[3], 1 - p[4]]
|
|
432
605
|
if result
|
|
@@ -434,52 +607,91 @@ class QrackAceBackend:
|
|
|
434
607
|
)
|
|
435
608
|
for q in range(5):
|
|
436
609
|
if syndrome[q] > (0.5 + self._epsilon):
|
|
437
|
-
|
|
610
|
+
if q == 2:
|
|
611
|
+
hq[q].x()
|
|
612
|
+
else:
|
|
613
|
+
self.sim[hq[q][0]].x(hq[q][1])
|
|
438
614
|
|
|
439
615
|
if not skip_rotation:
|
|
440
616
|
a, i = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]
|
|
441
617
|
a[0], i[0] = self._get_bloch_angles(hq[0])
|
|
442
618
|
a[1], i[1] = self._get_bloch_angles(hq[1])
|
|
443
|
-
a[2], i[2] =
|
|
619
|
+
a[2], i[2] = QrackAceBackend._get_lhv_bloch_angles(hq[2])
|
|
444
620
|
a[3], i[3] = self._get_bloch_angles(hq[3])
|
|
445
621
|
a[4], i[4] = self._get_bloch_angles(hq[4])
|
|
446
622
|
|
|
447
|
-
a_target =
|
|
448
|
-
i_target =
|
|
623
|
+
a_target = 0
|
|
624
|
+
i_target = 0
|
|
625
|
+
for x in range(5):
|
|
626
|
+
if x == 2:
|
|
627
|
+
continue
|
|
628
|
+
a_target += a[x]
|
|
629
|
+
i_target += i[x]
|
|
630
|
+
|
|
631
|
+
a_target /= 5
|
|
632
|
+
i_target /= 5
|
|
449
633
|
for x in range(5):
|
|
450
|
-
|
|
634
|
+
if x == 2:
|
|
635
|
+
QrackAceBackend._rotate_lhv_to_bloch(
|
|
636
|
+
hq[x], a_target - a[x], i_target - i[x]
|
|
637
|
+
)
|
|
638
|
+
else:
|
|
639
|
+
self._rotate_to_bloch(hq[x], a_target - a[x], i_target - i[x])
|
|
451
640
|
|
|
452
641
|
else:
|
|
453
642
|
# RMS
|
|
454
643
|
p = [
|
|
455
644
|
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
456
645
|
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
457
|
-
|
|
646
|
+
hq[2].prob(),
|
|
458
647
|
]
|
|
459
648
|
# Balancing suggestion from Elara (the custom OpenAI GPT)
|
|
460
649
|
prms = math.sqrt((p[0] ** 2 + p[1] ** 2 + p[2] ** 2) / 3)
|
|
461
650
|
qrms = math.sqrt(((1 - p[0]) ** 2 + (1 - p[1]) ** 2 + (1 - p[2]) ** 2) / 3)
|
|
462
|
-
|
|
651
|
+
eff_prob = (prms + (1 - qrms)) / 2
|
|
652
|
+
result = (
|
|
653
|
+
(random.random() < 0.5)
|
|
654
|
+
if (eff_prob - 0.5) == 0.0
|
|
655
|
+
else (eff_prob > 0.5)
|
|
656
|
+
)
|
|
463
657
|
syndrome = [1 - p[0], 1 - p[1], 1 - p[2]] if result else [p[0], p[1], p[2]]
|
|
464
658
|
for q in range(3):
|
|
465
659
|
if syndrome[q] > (0.5 + self._epsilon):
|
|
466
|
-
|
|
660
|
+
if q == 2:
|
|
661
|
+
hq[q].x()
|
|
662
|
+
else:
|
|
663
|
+
self.sim[hq[q][0]].x(hq[q][1])
|
|
467
664
|
|
|
468
665
|
if not skip_rotation:
|
|
469
666
|
a, i = [0, 0, 0], [0, 0, 0]
|
|
470
667
|
a[0], i[0] = self._get_bloch_angles(hq[0])
|
|
471
668
|
a[1], i[1] = self._get_bloch_angles(hq[1])
|
|
472
|
-
a[2], i[2] =
|
|
669
|
+
a[2], i[2] = QrackAceBackend._get_lhv_bloch_angles(hq[2])
|
|
670
|
+
|
|
671
|
+
a_target = 0
|
|
672
|
+
i_target = 0
|
|
673
|
+
for x in range(3):
|
|
674
|
+
if x == 2:
|
|
675
|
+
continue
|
|
676
|
+
a_target += a[x]
|
|
677
|
+
i_target += i[x]
|
|
473
678
|
|
|
474
|
-
a_target
|
|
475
|
-
i_target
|
|
679
|
+
a_target /= 3
|
|
680
|
+
i_target /= 3
|
|
476
681
|
for x in range(3):
|
|
477
|
-
|
|
682
|
+
if x == 2:
|
|
683
|
+
QrackAceBackend._rotate_lhv_to_bloch(
|
|
684
|
+
hq[x], a_target - a[x], i_target - i[x]
|
|
685
|
+
)
|
|
686
|
+
else:
|
|
687
|
+
self._rotate_to_bloch(hq[x], a_target - a[x], i_target - i[x])
|
|
478
688
|
|
|
479
689
|
if phase:
|
|
480
690
|
for q in qb:
|
|
481
691
|
b = hq[q]
|
|
482
692
|
self.sim[b[0]].h(b[1])
|
|
693
|
+
b = hq[lhv]
|
|
694
|
+
b.h()
|
|
483
695
|
|
|
484
696
|
def apply_magnetic_bias(self, q, b):
|
|
485
697
|
if b == 0:
|
|
@@ -487,13 +699,22 @@ class QrackAceBackend:
|
|
|
487
699
|
b = math.exp(b)
|
|
488
700
|
for x in q:
|
|
489
701
|
hq = self._unpack(x)
|
|
490
|
-
for
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
h
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
702
|
+
for c in range(len(hq)):
|
|
703
|
+
h = hq[c]
|
|
704
|
+
if c == 2:
|
|
705
|
+
a, i = QrackAceBackend._get_lhv_bloch_angles(h)
|
|
706
|
+
QrackAceBackend._rotate_lhv_to_bloch(
|
|
707
|
+
h,
|
|
708
|
+
math.atan(math.tan(a) * b) - a,
|
|
709
|
+
math.atan(math.tan(i) * b) - i,
|
|
710
|
+
)
|
|
711
|
+
else:
|
|
712
|
+
a, i = self._get_bloch_angles(h)
|
|
713
|
+
self._rotate_to_bloch(
|
|
714
|
+
h,
|
|
715
|
+
math.atan(math.tan(a) * b) - a,
|
|
716
|
+
math.atan(math.tan(i) * b) - i,
|
|
717
|
+
)
|
|
497
718
|
|
|
498
719
|
def u(self, lq, th, ph, lm):
|
|
499
720
|
hq = self._unpack(lq)
|
|
@@ -502,12 +723,15 @@ class QrackAceBackend:
|
|
|
502
723
|
self.sim[b[0]].u(b[1], th, ph, lm)
|
|
503
724
|
return
|
|
504
725
|
|
|
505
|
-
qb,
|
|
726
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
506
727
|
|
|
507
728
|
for q in qb:
|
|
508
729
|
b = hq[q]
|
|
509
730
|
self.sim[b[0]].u(b[1], th, ph, lm)
|
|
510
731
|
|
|
732
|
+
b = hq[lhv]
|
|
733
|
+
b.u(th, ph, lm)
|
|
734
|
+
|
|
511
735
|
# Correction deferred to next 2-qubit gate (_cpauli calls _correct)
|
|
512
736
|
|
|
513
737
|
def r(self, p, th, lq):
|
|
@@ -517,12 +741,20 @@ class QrackAceBackend:
|
|
|
517
741
|
self.sim[b[0]].r(p, th, b[1])
|
|
518
742
|
return
|
|
519
743
|
|
|
520
|
-
qb,
|
|
744
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
521
745
|
|
|
522
746
|
for q in qb:
|
|
523
747
|
b = hq[q]
|
|
524
748
|
self.sim[b[0]].r(p, th, b[1])
|
|
525
749
|
|
|
750
|
+
b = hq[lhv]
|
|
751
|
+
if p == Pauli.PauliX:
|
|
752
|
+
b.rx(th)
|
|
753
|
+
elif p == Pauli.PauliY:
|
|
754
|
+
b.ry(th)
|
|
755
|
+
elif p == Pauli.PauliZ:
|
|
756
|
+
b.rz(th)
|
|
757
|
+
|
|
526
758
|
# Correction deferred to next 2-qubit gate (_cpauli calls _correct)
|
|
527
759
|
|
|
528
760
|
def h(self, lq):
|
|
@@ -534,12 +766,15 @@ class QrackAceBackend:
|
|
|
534
766
|
|
|
535
767
|
self._correct(lq)
|
|
536
768
|
|
|
537
|
-
qb,
|
|
769
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
538
770
|
|
|
539
771
|
for q in qb:
|
|
540
772
|
b = hq[q]
|
|
541
773
|
self.sim[b[0]].h(b[1])
|
|
542
774
|
|
|
775
|
+
b = hq[lhv]
|
|
776
|
+
b.h()
|
|
777
|
+
|
|
543
778
|
# Correction deferred to next 2-qubit gate (_cpauli calls _correct)
|
|
544
779
|
|
|
545
780
|
def s(self, lq):
|
|
@@ -549,12 +784,15 @@ class QrackAceBackend:
|
|
|
549
784
|
self.sim[b[0]].s(b[1])
|
|
550
785
|
return
|
|
551
786
|
|
|
552
|
-
qb,
|
|
787
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
553
788
|
|
|
554
789
|
for q in qb:
|
|
555
790
|
b = hq[q]
|
|
556
791
|
self.sim[b[0]].s(b[1])
|
|
557
792
|
|
|
793
|
+
b = hq[lhv]
|
|
794
|
+
b.s()
|
|
795
|
+
|
|
558
796
|
def adjs(self, lq):
|
|
559
797
|
hq = self._unpack(lq)
|
|
560
798
|
if len(hq) < 2:
|
|
@@ -562,12 +800,15 @@ class QrackAceBackend:
|
|
|
562
800
|
self.sim[b[0]].adjs(b[1])
|
|
563
801
|
return
|
|
564
802
|
|
|
565
|
-
qb,
|
|
803
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
566
804
|
|
|
567
805
|
for q in qb:
|
|
568
806
|
b = hq[q]
|
|
569
807
|
self.sim[b[0]].adjs(b[1])
|
|
570
808
|
|
|
809
|
+
b = hq[lhv]
|
|
810
|
+
b.adjs()
|
|
811
|
+
|
|
571
812
|
def x(self, lq):
|
|
572
813
|
hq = self._unpack(lq)
|
|
573
814
|
if len(hq) < 2:
|
|
@@ -575,12 +816,15 @@ class QrackAceBackend:
|
|
|
575
816
|
self.sim[b[0]].x(b[1])
|
|
576
817
|
return
|
|
577
818
|
|
|
578
|
-
qb,
|
|
819
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
579
820
|
|
|
580
821
|
for q in qb:
|
|
581
822
|
b = hq[q]
|
|
582
823
|
self.sim[b[0]].x(b[1])
|
|
583
824
|
|
|
825
|
+
b = hq[lhv]
|
|
826
|
+
b.x()
|
|
827
|
+
|
|
584
828
|
def y(self, lq):
|
|
585
829
|
hq = self._unpack(lq)
|
|
586
830
|
if len(hq) < 2:
|
|
@@ -588,12 +832,15 @@ class QrackAceBackend:
|
|
|
588
832
|
self.sim[b[0]].y(b[1])
|
|
589
833
|
return
|
|
590
834
|
|
|
591
|
-
qb,
|
|
835
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
592
836
|
|
|
593
837
|
for q in qb:
|
|
594
838
|
b = hq[q]
|
|
595
839
|
self.sim[b[0]].y(b[1])
|
|
596
840
|
|
|
841
|
+
b = hq[lhv]
|
|
842
|
+
b.y()
|
|
843
|
+
|
|
597
844
|
def z(self, lq):
|
|
598
845
|
hq = self._unpack(lq)
|
|
599
846
|
if len(hq) < 2:
|
|
@@ -601,12 +848,15 @@ class QrackAceBackend:
|
|
|
601
848
|
self.sim[b[0]].z(b[1])
|
|
602
849
|
return
|
|
603
850
|
|
|
604
|
-
qb,
|
|
851
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
605
852
|
|
|
606
853
|
for q in qb:
|
|
607
854
|
b = hq[q]
|
|
608
855
|
self.sim[b[0]].z(b[1])
|
|
609
856
|
|
|
857
|
+
b = hq[lhv]
|
|
858
|
+
b.z()
|
|
859
|
+
|
|
610
860
|
def t(self, lq):
|
|
611
861
|
hq = self._unpack(lq)
|
|
612
862
|
if len(hq) < 2:
|
|
@@ -614,12 +864,15 @@ class QrackAceBackend:
|
|
|
614
864
|
self.sim[b[0]].t(b[1])
|
|
615
865
|
return
|
|
616
866
|
|
|
617
|
-
qb,
|
|
867
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
618
868
|
|
|
619
869
|
for q in qb:
|
|
620
870
|
b = hq[q]
|
|
621
871
|
self.sim[b[0]].t(b[1])
|
|
622
872
|
|
|
873
|
+
b = hq[lhv]
|
|
874
|
+
b.t()
|
|
875
|
+
|
|
623
876
|
def adjt(self, lq):
|
|
624
877
|
hq = self._unpack(lq)
|
|
625
878
|
if len(hq) < 2:
|
|
@@ -627,12 +880,15 @@ class QrackAceBackend:
|
|
|
627
880
|
self.sim[b[0]].adjt(b[1])
|
|
628
881
|
return
|
|
629
882
|
|
|
630
|
-
qb,
|
|
883
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
631
884
|
|
|
632
885
|
for q in qb:
|
|
633
886
|
b = hq[q]
|
|
634
887
|
self.sim[b[0]].adjt(b[1])
|
|
635
888
|
|
|
889
|
+
b = hq[lhv]
|
|
890
|
+
b.adjt()
|
|
891
|
+
|
|
636
892
|
def _get_gate(self, pauli, anti, sim_id):
|
|
637
893
|
gate = None
|
|
638
894
|
shadow = None
|
|
@@ -671,11 +927,15 @@ class QrackAceBackend:
|
|
|
671
927
|
|
|
672
928
|
return connected, boundary
|
|
673
929
|
|
|
674
|
-
def _apply_coupling(self, pauli, anti, qb1, hq1, qb2, hq2, lq1_lr):
|
|
930
|
+
def _apply_coupling(self, pauli, anti, qb1, lhv1, hq1, qb2, lhv2, hq2, lq1_lr):
|
|
675
931
|
for q1 in qb1:
|
|
932
|
+
if q1 == lhv1:
|
|
933
|
+
continue
|
|
676
934
|
b1 = hq1[q1]
|
|
677
935
|
gate_fn, shadow_fn = self._get_gate(pauli, anti, b1[0])
|
|
678
936
|
for q2 in qb2:
|
|
937
|
+
if q2 == lhv2:
|
|
938
|
+
continue
|
|
679
939
|
b2 = hq2[q2]
|
|
680
940
|
if b1[0] == b2[0]:
|
|
681
941
|
gate_fn([b1[1]], b2[1])
|
|
@@ -696,11 +956,18 @@ class QrackAceBackend:
|
|
|
696
956
|
|
|
697
957
|
self._correct(lq1)
|
|
698
958
|
|
|
699
|
-
qb1,
|
|
700
|
-
qb2,
|
|
701
|
-
# Apply cross coupling on
|
|
702
|
-
|
|
703
|
-
|
|
959
|
+
qb1, lhv1 = QrackAceBackend._get_qb_lhv_indices(hq1)
|
|
960
|
+
qb2, lhv2 = QrackAceBackend._get_qb_lhv_indices(hq2)
|
|
961
|
+
# Apply cross coupling on hardware qubits first
|
|
962
|
+
self._apply_coupling(pauli, anti, qb1, lhv1, hq1, qb2, lhv2, hq2, lq1_lr)
|
|
963
|
+
# Apply coupling to the local-hidden-variable target
|
|
964
|
+
if lhv2 >= 0:
|
|
965
|
+
_cpauli_lhv(
|
|
966
|
+
hq1[lhv1].prob() if lhv1 >= 0 else self.sim[hq1[0][0]].prob(hq1[0][1]),
|
|
967
|
+
hq2[lhv2],
|
|
968
|
+
pauli,
|
|
969
|
+
anti,
|
|
970
|
+
)
|
|
704
971
|
|
|
705
972
|
self._correct(lq1, True)
|
|
706
973
|
if pauli != Pauli.PauliZ:
|
|
@@ -797,7 +1064,7 @@ class QrackAceBackend:
|
|
|
797
1064
|
p = [
|
|
798
1065
|
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
799
1066
|
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
800
|
-
|
|
1067
|
+
hq[2].prob(),
|
|
801
1068
|
self.sim[hq[3][0]].prob(hq[3][1]),
|
|
802
1069
|
self.sim[hq[4][0]].prob(hq[4][1]),
|
|
803
1070
|
]
|
|
@@ -818,7 +1085,7 @@ class QrackAceBackend:
|
|
|
818
1085
|
p = [
|
|
819
1086
|
self.sim[hq[0][0]].prob(hq[0][1]),
|
|
820
1087
|
self.sim[hq[1][0]].prob(hq[1][1]),
|
|
821
|
-
|
|
1088
|
+
hq[2].prob(),
|
|
822
1089
|
]
|
|
823
1090
|
# Balancing suggestion from Elara (the custom OpenAI GPT)
|
|
824
1091
|
prms = math.sqrt((p[0] ** 2 + p[1] ** 2 + p[2] ** 2) / 3)
|
|
@@ -835,7 +1102,7 @@ class QrackAceBackend:
|
|
|
835
1102
|
p = self.prob(lq)
|
|
836
1103
|
result = ((p + self._epsilon) >= 1) or (random.random() < p)
|
|
837
1104
|
|
|
838
|
-
qb,
|
|
1105
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
839
1106
|
|
|
840
1107
|
for q in qb:
|
|
841
1108
|
b = hq[q]
|
|
@@ -846,6 +1113,11 @@ class QrackAceBackend:
|
|
|
846
1113
|
else:
|
|
847
1114
|
self.sim[b[0]].force_m(b[1], result)
|
|
848
1115
|
|
|
1116
|
+
b = hq[lhv]
|
|
1117
|
+
b.reset()
|
|
1118
|
+
if result:
|
|
1119
|
+
b.x()
|
|
1120
|
+
|
|
849
1121
|
return result
|
|
850
1122
|
|
|
851
1123
|
def force_m(self, lq, result):
|
|
@@ -856,7 +1128,7 @@ class QrackAceBackend:
|
|
|
856
1128
|
|
|
857
1129
|
self._correct(lq)
|
|
858
1130
|
|
|
859
|
-
qb,
|
|
1131
|
+
qb, lhv = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
860
1132
|
|
|
861
1133
|
for q in qb:
|
|
862
1134
|
b = hq[q]
|
|
@@ -867,6 +1139,11 @@ class QrackAceBackend:
|
|
|
867
1139
|
else:
|
|
868
1140
|
self.sim[b[0]].force_m(b[1], result)
|
|
869
1141
|
|
|
1142
|
+
b = hq[lhv]
|
|
1143
|
+
b.reset()
|
|
1144
|
+
if result:
|
|
1145
|
+
b.x()
|
|
1146
|
+
|
|
870
1147
|
return result
|
|
871
1148
|
|
|
872
1149
|
def m_all(self):
|
|
@@ -1232,22 +1509,25 @@ class QrackAceBackend:
|
|
|
1232
1509
|
return self._coupling_map
|
|
1233
1510
|
|
|
1234
1511
|
coupling_map = set()
|
|
1235
|
-
|
|
1512
|
+
# self._row_length is the number of qubits per row (the row's span,
|
|
1513
|
+
# i.e. the column count); self._col_length is the number of rows.
|
|
1514
|
+
num_rows, num_cols = self._col_length, self._row_length
|
|
1236
1515
|
|
|
1237
|
-
#
|
|
1516
|
+
# Row-major logical index, strided by the actual row span.
|
|
1238
1517
|
def logical_index(row, col):
|
|
1239
|
-
return row *
|
|
1518
|
+
return row * num_cols + col
|
|
1240
1519
|
|
|
1241
|
-
for
|
|
1242
|
-
|
|
1243
|
-
for
|
|
1244
|
-
|
|
1520
|
+
for row in range(num_rows):
|
|
1521
|
+
connected_rows, _ = self._get_connected(row, True)
|
|
1522
|
+
for col in range(num_cols):
|
|
1523
|
+
connected_cols, _ = self._get_connected(col, False)
|
|
1245
1524
|
a = logical_index(row, col)
|
|
1246
|
-
for
|
|
1247
|
-
for
|
|
1525
|
+
for r in connected_rows:
|
|
1526
|
+
for c in connected_cols:
|
|
1248
1527
|
b = logical_index(r, c)
|
|
1249
1528
|
if a != b:
|
|
1250
1529
|
coupling_map.add((a, b))
|
|
1530
|
+
coupling_map.add((b, a))
|
|
1251
1531
|
|
|
1252
1532
|
self._coupling_map = sorted(coupling_map)
|
|
1253
1533
|
|
|
@@ -1261,9 +1541,11 @@ class QrackAceBackend:
|
|
|
1261
1541
|
)
|
|
1262
1542
|
noise_model = NoiseModel()
|
|
1263
1543
|
|
|
1264
|
-
# Single-qubit depolarizing only on boundary qubits
|
|
1265
1544
|
boundary_qubits = set()
|
|
1266
1545
|
for a, b in self.get_logical_coupling_map():
|
|
1546
|
+
if a > b:
|
|
1547
|
+
#Skip duplicates
|
|
1548
|
+
continue
|
|
1267
1549
|
col_a = a % self._row_length
|
|
1268
1550
|
col_b = b % self._row_length
|
|
1269
1551
|
is_long_a = self._is_col_long_range[col_a]
|
|
@@ -1274,12 +1556,6 @@ class QrackAceBackend:
|
|
|
1274
1556
|
if not is_long_b:
|
|
1275
1557
|
boundary_qubits.add(b)
|
|
1276
1558
|
|
|
1277
|
-
for q in boundary_qubits:
|
|
1278
|
-
for gate in ["u", "u1", "u2", "u3", "h", "x", "y", "z",
|
|
1279
|
-
"s", "sdg", "t", "tdg", "rx", "ry", "rz"]:
|
|
1280
|
-
noise_model.add_quantum_error(
|
|
1281
|
-
depolarizing_error(x, 1), gate, [q])
|
|
1282
|
-
|
|
1283
1559
|
# Two-qubit depolarizing on boundary-crossing and boundary-adjacent gates
|
|
1284
1560
|
for a, b in self.get_logical_coupling_map():
|
|
1285
1561
|
col_a = a % self._row_length
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/neuron_activation_fn.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_neuron_torch_layer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_system/__init__.py
RENAMED
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/qrack_system/qrack_system.py
RENAMED
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/quimb_circuit_type.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/stats/load_quantized_data.py
RENAMED
|
File without changes
|
{pyqrack_cuda_complex128-2.2.1 → pyqrack_cuda_complex128-2.2.2}/pyqrack/stats/quantize_by_range.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|