cirq-core 1.5.0.dev20241219205221__py3-none-any.whl → 1.5.0.dev20241221000556__py3-none-any.whl
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.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/experiments/z_phase_calibration.py +84 -2
- cirq/experiments/z_phase_calibration_test.py +31 -0
- cirq/ops/fsim_gate.py +39 -0
- cirq/ops/fsim_gate_test.py +21 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +128 -16
- cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling.py +151 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +85 -1
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +37 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +30 -0
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/RECORD +17 -17
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/top_level.txt +0 -0
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Provides a method to do z-phase calibration for excitation-preserving gates."""
|
|
16
|
-
from typing import Union, Optional, Sequence, Tuple, Dict, TYPE_CHECKING, Any
|
|
16
|
+
from typing import Union, Optional, Sequence, Tuple, Dict, TYPE_CHECKING, Any, List
|
|
17
17
|
import multiprocessing
|
|
18
18
|
import multiprocessing.pool
|
|
19
19
|
|
|
@@ -22,7 +22,8 @@ import numpy as np
|
|
|
22
22
|
|
|
23
23
|
from cirq.experiments import xeb_fitting
|
|
24
24
|
from cirq.experiments.two_qubit_xeb import parallel_xeb_workflow
|
|
25
|
-
from cirq import
|
|
25
|
+
from cirq.transformers import transformer_api
|
|
26
|
+
from cirq import ops, circuits, protocols
|
|
26
27
|
|
|
27
28
|
if TYPE_CHECKING:
|
|
28
29
|
import cirq
|
|
@@ -283,3 +284,84 @@ def plot_z_phase_calibration_result(
|
|
|
283
284
|
ax.set_title('-'.join(str(q) for q in pair))
|
|
284
285
|
ax.legend()
|
|
285
286
|
return axes
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) -> Tuple[float, float, float]:
|
|
290
|
+
"""Computes a set of possible 3 z-phases that result in the change in gamma, zeta, and chi."""
|
|
291
|
+
# This procedure is the inverse of PhasedFSimGate.from_fsim_rz
|
|
292
|
+
delta_gamma = new.gamma - old.gamma
|
|
293
|
+
delta_zeta = new.zeta - old.zeta
|
|
294
|
+
delta_chi = new.chi - old.chi
|
|
295
|
+
return (-delta_gamma + delta_chi, -delta_gamma - delta_zeta, delta_zeta - delta_chi)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@transformer_api.transformer
|
|
299
|
+
class CalibrationTransformer:
|
|
300
|
+
|
|
301
|
+
def __init__(
|
|
302
|
+
self,
|
|
303
|
+
target: 'cirq.Gate',
|
|
304
|
+
calibration_map: Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate'],
|
|
305
|
+
):
|
|
306
|
+
"""Create a CalibrationTransformer.
|
|
307
|
+
|
|
308
|
+
The transformer adds 3 ZPowGates around each calibrated gate to cancel the
|
|
309
|
+
effect of z-phases.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
target: The target gate. Any gate matching this
|
|
313
|
+
will be replaced based on the content of `calibration_map`.
|
|
314
|
+
calibration_map:
|
|
315
|
+
A map mapping qubit pairs to calibrated gates. This is the output of
|
|
316
|
+
calling `calibrate_z_phases`.
|
|
317
|
+
"""
|
|
318
|
+
self.target = target
|
|
319
|
+
if isinstance(target, ops.PhasedFSimGate):
|
|
320
|
+
self.target_as_fsim = target
|
|
321
|
+
elif (gate := ops.PhasedFSimGate.from_matrix(protocols.unitary(target))) is not None:
|
|
322
|
+
self.target_as_fsim = gate
|
|
323
|
+
else:
|
|
324
|
+
raise ValueError(f"{target} is not equivalent to a PhasedFSimGate")
|
|
325
|
+
self.calibration_map = calibration_map
|
|
326
|
+
|
|
327
|
+
def __call__(
|
|
328
|
+
self,
|
|
329
|
+
circuit: 'cirq.AbstractCircuit',
|
|
330
|
+
*,
|
|
331
|
+
context: Optional[transformer_api.TransformerContext] = None,
|
|
332
|
+
) -> 'cirq.Circuit':
|
|
333
|
+
"""Adds 3 ZPowGates around each calibrated gate to cancel the effect of Z phases.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
circuit: Circuit to transform.
|
|
337
|
+
context: Optional transformer context (not used).
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
New circuit with the extra ZPowGates.
|
|
341
|
+
"""
|
|
342
|
+
new_moments: List[Union[List[cirq.Operation], 'cirq.Moment']] = []
|
|
343
|
+
for moment in circuit:
|
|
344
|
+
before = []
|
|
345
|
+
after = []
|
|
346
|
+
for op in moment:
|
|
347
|
+
if op.gate != self.target:
|
|
348
|
+
# not a target.
|
|
349
|
+
continue
|
|
350
|
+
assert len(op.qubits) == 2
|
|
351
|
+
gate = self.calibration_map.get(op.qubits, None) or self.calibration_map.get(
|
|
352
|
+
op.qubits[::-1], None
|
|
353
|
+
)
|
|
354
|
+
if gate is None:
|
|
355
|
+
# no calibration available.
|
|
356
|
+
continue
|
|
357
|
+
angles = np.array(_z_angles(self.target_as_fsim, gate)) / np.pi
|
|
358
|
+
angles = -angles # Take the negative to cancel the effect.
|
|
359
|
+
before.append(ops.Z(op.qubits[0]) ** angles[0])
|
|
360
|
+
before.append(ops.Z(op.qubits[1]) ** angles[1])
|
|
361
|
+
after.append(ops.Z(op.qubits[0]) ** angles[2])
|
|
362
|
+
if before:
|
|
363
|
+
new_moments.append(before)
|
|
364
|
+
new_moments.append(moment)
|
|
365
|
+
if after:
|
|
366
|
+
new_moments.append(after)
|
|
367
|
+
return circuits.Circuit.from_moments(*new_moments)
|
|
@@ -22,6 +22,7 @@ from cirq.experiments.z_phase_calibration import (
|
|
|
22
22
|
calibrate_z_phases,
|
|
23
23
|
z_phase_calibration_workflow,
|
|
24
24
|
plot_z_phase_calibration_result,
|
|
25
|
+
CalibrationTransformer,
|
|
25
26
|
)
|
|
26
27
|
from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions
|
|
27
28
|
|
|
@@ -205,3 +206,33 @@ def test_plot_z_phase_calibration_result():
|
|
|
205
206
|
np.testing.assert_allclose(axes[1].lines[0].get_xdata().astype(float), [1, 2, 3])
|
|
206
207
|
np.testing.assert_allclose(axes[1].lines[0].get_ydata().astype(float), [0.6, 0.4, 0.1])
|
|
207
208
|
np.testing.assert_allclose(axes[1].lines[1].get_ydata().astype(float), [0.7, 0.77, 0.8])
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@pytest.mark.parametrize('angles', 2 * np.pi * np.random.random((10, 10)))
|
|
212
|
+
def test_transform_circuit(angles):
|
|
213
|
+
theta, phi = angles[:2]
|
|
214
|
+
old_zs = angles[2:6]
|
|
215
|
+
new_zs = angles[6:]
|
|
216
|
+
gate = cirq.PhasedFSimGate.from_fsim_rz(theta, phi, old_zs[:2], old_zs[2:])
|
|
217
|
+
fsim = cirq.PhasedFSimGate.from_fsim_rz(theta, phi, new_zs[:2], new_zs[2:])
|
|
218
|
+
c = cirq.Circuit(gate(cirq.q(0), cirq.q(1)))
|
|
219
|
+
replacement_map = {(cirq.q(1), cirq.q(0)): fsim}
|
|
220
|
+
|
|
221
|
+
new_circuit = CalibrationTransformer(gate, replacement_map)(c)
|
|
222
|
+
|
|
223
|
+
# we replace the old gate with the `fsim` gate the result should be that the overall
|
|
224
|
+
# unitary equals the unitary of the original (ideal) gate.
|
|
225
|
+
circuit_with_replacement_gate = cirq.Circuit(
|
|
226
|
+
op if op.gate != gate else fsim(*op.qubits) for op in new_circuit.all_operations()
|
|
227
|
+
)
|
|
228
|
+
np.testing.assert_allclose(cirq.unitary(circuit_with_replacement_gate), cirq.unitary(c))
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def test_transform_circuit_invalid_gate_raises():
|
|
232
|
+
with pytest.raises(ValueError, match="is not equivalent to a PhasedFSimGate"):
|
|
233
|
+
_ = CalibrationTransformer(cirq.XX, {})
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def test_transform_circuit_uncalibrated_gates_pass():
|
|
237
|
+
c = cirq.Circuit(cirq.CZ(cirq.q(0), cirq.q(1)), cirq.measure(cirq.q(0)))
|
|
238
|
+
assert c == CalibrationTransformer(cirq.CZ, {})(c)
|
cirq/ops/fsim_gate.py
CHANGED
|
@@ -347,6 +347,45 @@ class PhasedFSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
347
347
|
chi = (b0 - b1 - a0 + a1) / 2.0
|
|
348
348
|
return PhasedFSimGate(theta, zeta, chi, gamma, phi)
|
|
349
349
|
|
|
350
|
+
@staticmethod
|
|
351
|
+
def from_matrix(u: np.ndarray) -> Optional['PhasedFSimGate']:
|
|
352
|
+
"""Contruct a PhasedFSimGate from unitary.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
u: A unitary matrix representing a PhasedFSimGate.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
- Either PhasedFSimGate with the given unitary or None if
|
|
359
|
+
the matrix is not unitary or if doesn't represent a PhasedFSimGate.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
gamma = np.angle(u[1, 1] * u[2, 2] - u[1, 2] * u[2, 1]) / -2
|
|
363
|
+
phi = -np.angle(u[3, 3]) - 2 * gamma
|
|
364
|
+
phased_cos_theta_2 = u[1, 1] * u[2, 2]
|
|
365
|
+
if phased_cos_theta_2 == 0:
|
|
366
|
+
# The zeta phase is multiplied with cos(theta),
|
|
367
|
+
# so if cos(theta) is zero then any value is possible.
|
|
368
|
+
zeta = 0
|
|
369
|
+
else:
|
|
370
|
+
zeta = np.angle(u[2, 2] / u[1, 1]) / 2
|
|
371
|
+
|
|
372
|
+
phased_sin_theta_2 = u[1, 2] * u[2, 1]
|
|
373
|
+
if phased_sin_theta_2 == 0:
|
|
374
|
+
# The chi phase is multiplied with sin(theta),
|
|
375
|
+
# so if sin(theta) is zero then any value is possible.
|
|
376
|
+
chi = 0
|
|
377
|
+
else:
|
|
378
|
+
chi = np.angle(u[1, 2] / u[2, 1]) / 2
|
|
379
|
+
|
|
380
|
+
theta = np.angle(
|
|
381
|
+
np.exp(1j * (gamma + zeta)) * u[1, 1] - np.exp(1j * (gamma - chi)) * u[1, 2]
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
gate = PhasedFSimGate(theta=theta, phi=phi, chi=chi, zeta=zeta, gamma=gamma)
|
|
385
|
+
if np.allclose(u, protocols.unitary(gate)):
|
|
386
|
+
return gate
|
|
387
|
+
return None
|
|
388
|
+
|
|
350
389
|
@property
|
|
351
390
|
def rz_angles_before(self) -> Tuple['cirq.TParamVal', 'cirq.TParamVal']:
|
|
352
391
|
"""Returns 2-tuple of phase angles applied to qubits before FSimGate."""
|
cirq/ops/fsim_gate_test.py
CHANGED
|
@@ -797,3 +797,24 @@ def test_phased_fsim_json_dict():
|
|
|
797
797
|
assert cirq.PhasedFSimGate(
|
|
798
798
|
theta=0.12, zeta=0.34, chi=0.56, gamma=0.78, phi=0.9
|
|
799
799
|
)._json_dict_() == {'theta': 0.12, 'zeta': 0.34, 'chi': 0.56, 'gamma': 0.78, 'phi': 0.9}
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
@pytest.mark.parametrize(
|
|
803
|
+
'gate',
|
|
804
|
+
[
|
|
805
|
+
cirq.CZ,
|
|
806
|
+
cirq.SQRT_ISWAP,
|
|
807
|
+
cirq.SQRT_ISWAP_INV,
|
|
808
|
+
cirq.ISWAP,
|
|
809
|
+
cirq.ISWAP_INV,
|
|
810
|
+
cirq.cphase(0.1),
|
|
811
|
+
cirq.CZ**0.2,
|
|
812
|
+
],
|
|
813
|
+
)
|
|
814
|
+
def test_phase_fsim_from_matrix(gate):
|
|
815
|
+
u = cirq.unitary(gate)
|
|
816
|
+
np.testing.assert_allclose(cirq.unitary(cirq.PhasedFSimGate.from_matrix(u)), u, atol=1e-8)
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def test_phase_fsim_from_matrix_not_fsim_returns_none():
|
|
820
|
+
assert cirq.PhasedFSimGate.from_matrix(np.ones((4, 4))) is None
|
|
@@ -24,22 +24,134 @@ from cirq import ops
|
|
|
24
24
|
|
|
25
25
|
CZGaugeSelector = GaugeSelector(
|
|
26
26
|
gauges=[
|
|
27
|
-
ConstantGauge(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
ConstantGauge(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
ConstantGauge(
|
|
28
|
+
two_qubit_gate=CZ,
|
|
29
|
+
pre_q0=ops.I,
|
|
30
|
+
pre_q1=ops.I,
|
|
31
|
+
post_q0=ops.I,
|
|
32
|
+
post_q1=ops.I,
|
|
33
|
+
support_sweep=True,
|
|
34
|
+
),
|
|
35
|
+
ConstantGauge(
|
|
36
|
+
two_qubit_gate=CZ,
|
|
37
|
+
pre_q0=ops.I,
|
|
38
|
+
pre_q1=ops.X,
|
|
39
|
+
post_q0=ops.Z,
|
|
40
|
+
post_q1=ops.X,
|
|
41
|
+
support_sweep=True,
|
|
42
|
+
),
|
|
43
|
+
ConstantGauge(
|
|
44
|
+
two_qubit_gate=CZ,
|
|
45
|
+
pre_q0=ops.I,
|
|
46
|
+
pre_q1=ops.Y,
|
|
47
|
+
post_q0=ops.Z,
|
|
48
|
+
post_q1=ops.Y,
|
|
49
|
+
support_sweep=True,
|
|
50
|
+
),
|
|
51
|
+
ConstantGauge(
|
|
52
|
+
two_qubit_gate=CZ,
|
|
53
|
+
pre_q0=ops.I,
|
|
54
|
+
pre_q1=ops.Z,
|
|
55
|
+
post_q0=ops.I,
|
|
56
|
+
post_q1=ops.Z,
|
|
57
|
+
support_sweep=True,
|
|
58
|
+
),
|
|
59
|
+
ConstantGauge(
|
|
60
|
+
two_qubit_gate=CZ,
|
|
61
|
+
pre_q0=ops.X,
|
|
62
|
+
pre_q1=ops.I,
|
|
63
|
+
post_q0=ops.X,
|
|
64
|
+
post_q1=ops.Z,
|
|
65
|
+
support_sweep=True,
|
|
66
|
+
),
|
|
67
|
+
ConstantGauge(
|
|
68
|
+
two_qubit_gate=CZ,
|
|
69
|
+
pre_q0=ops.X,
|
|
70
|
+
pre_q1=ops.X,
|
|
71
|
+
post_q0=ops.Y,
|
|
72
|
+
post_q1=ops.Y,
|
|
73
|
+
support_sweep=True,
|
|
74
|
+
),
|
|
75
|
+
ConstantGauge(
|
|
76
|
+
two_qubit_gate=CZ,
|
|
77
|
+
pre_q0=ops.X,
|
|
78
|
+
pre_q1=ops.Y,
|
|
79
|
+
post_q0=ops.Y,
|
|
80
|
+
post_q1=ops.X,
|
|
81
|
+
support_sweep=True,
|
|
82
|
+
),
|
|
83
|
+
ConstantGauge(
|
|
84
|
+
two_qubit_gate=CZ,
|
|
85
|
+
pre_q0=ops.X,
|
|
86
|
+
pre_q1=ops.Z,
|
|
87
|
+
post_q0=ops.X,
|
|
88
|
+
post_q1=ops.I,
|
|
89
|
+
support_sweep=True,
|
|
90
|
+
),
|
|
91
|
+
ConstantGauge(
|
|
92
|
+
two_qubit_gate=CZ,
|
|
93
|
+
pre_q0=ops.Y,
|
|
94
|
+
pre_q1=ops.I,
|
|
95
|
+
post_q0=ops.Y,
|
|
96
|
+
post_q1=ops.Z,
|
|
97
|
+
support_sweep=True,
|
|
98
|
+
),
|
|
99
|
+
ConstantGauge(
|
|
100
|
+
two_qubit_gate=CZ,
|
|
101
|
+
pre_q0=ops.Y,
|
|
102
|
+
pre_q1=ops.X,
|
|
103
|
+
post_q0=ops.X,
|
|
104
|
+
post_q1=ops.Y,
|
|
105
|
+
support_sweep=True,
|
|
106
|
+
),
|
|
107
|
+
ConstantGauge(
|
|
108
|
+
two_qubit_gate=CZ,
|
|
109
|
+
pre_q0=ops.Y,
|
|
110
|
+
pre_q1=ops.Y,
|
|
111
|
+
post_q0=ops.X,
|
|
112
|
+
post_q1=ops.X,
|
|
113
|
+
support_sweep=True,
|
|
114
|
+
),
|
|
115
|
+
ConstantGauge(
|
|
116
|
+
two_qubit_gate=CZ,
|
|
117
|
+
pre_q0=ops.Y,
|
|
118
|
+
pre_q1=ops.Z,
|
|
119
|
+
post_q0=ops.Y,
|
|
120
|
+
post_q1=ops.I,
|
|
121
|
+
support_sweep=True,
|
|
122
|
+
),
|
|
123
|
+
ConstantGauge(
|
|
124
|
+
two_qubit_gate=CZ,
|
|
125
|
+
pre_q0=ops.Z,
|
|
126
|
+
pre_q1=ops.I,
|
|
127
|
+
post_q0=ops.Z,
|
|
128
|
+
post_q1=ops.I,
|
|
129
|
+
support_sweep=True,
|
|
130
|
+
),
|
|
131
|
+
ConstantGauge(
|
|
132
|
+
two_qubit_gate=CZ,
|
|
133
|
+
pre_q0=ops.Z,
|
|
134
|
+
pre_q1=ops.X,
|
|
135
|
+
post_q0=ops.I,
|
|
136
|
+
post_q1=ops.X,
|
|
137
|
+
support_sweep=True,
|
|
138
|
+
),
|
|
139
|
+
ConstantGauge(
|
|
140
|
+
two_qubit_gate=CZ,
|
|
141
|
+
pre_q0=ops.Z,
|
|
142
|
+
pre_q1=ops.Y,
|
|
143
|
+
post_q0=ops.I,
|
|
144
|
+
post_q1=ops.Y,
|
|
145
|
+
support_sweep=True,
|
|
146
|
+
),
|
|
147
|
+
ConstantGauge(
|
|
148
|
+
two_qubit_gate=CZ,
|
|
149
|
+
pre_q0=ops.Z,
|
|
150
|
+
pre_q1=ops.Z,
|
|
151
|
+
post_q0=ops.Z,
|
|
152
|
+
post_q1=ops.Z,
|
|
153
|
+
support_sweep=True,
|
|
154
|
+
),
|
|
43
155
|
]
|
|
44
156
|
)
|
|
45
157
|
|
|
@@ -14,17 +14,24 @@
|
|
|
14
14
|
|
|
15
15
|
"""Creates the abstraction for gauge compiling as a cirq transformer."""
|
|
16
16
|
|
|
17
|
-
from typing import Callable, Tuple, Optional, Sequence, Union, List
|
|
17
|
+
from typing import Callable, Dict, Tuple, Optional, Sequence, Union, List
|
|
18
|
+
from itertools import count
|
|
19
|
+
from dataclasses import dataclass
|
|
18
20
|
import abc
|
|
19
21
|
import itertools
|
|
20
22
|
import functools
|
|
23
|
+
import sympy
|
|
21
24
|
|
|
22
|
-
from dataclasses import dataclass
|
|
23
25
|
from attrs import frozen, field
|
|
24
26
|
import numpy as np
|
|
25
27
|
|
|
26
28
|
from cirq.transformers import transformer_api
|
|
27
29
|
from cirq import ops, circuits
|
|
30
|
+
from cirq.study import sweepable
|
|
31
|
+
from cirq.protocols import unitary_protocol
|
|
32
|
+
from cirq.protocols.has_unitary_protocol import has_unitary
|
|
33
|
+
from cirq.study.sweeps import Points, Zip
|
|
34
|
+
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
|
|
28
35
|
|
|
29
36
|
|
|
30
37
|
class Gauge(abc.ABC):
|
|
@@ -72,6 +79,7 @@ class ConstantGauge(Gauge):
|
|
|
72
79
|
default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
|
|
73
80
|
)
|
|
74
81
|
swap_qubits: bool = False
|
|
82
|
+
support_sweep: bool = False
|
|
75
83
|
|
|
76
84
|
def sample(self, gate: ops.Gate, prng: np.random.Generator) -> "ConstantGauge":
|
|
77
85
|
return self
|
|
@@ -201,6 +209,100 @@ class GaugeTransformer:
|
|
|
201
209
|
new_moments.extend(_build_moments(right))
|
|
202
210
|
return circuits.Circuit.from_moments(*new_moments)
|
|
203
211
|
|
|
212
|
+
def as_sweep(
|
|
213
|
+
self,
|
|
214
|
+
circuit: circuits.AbstractCircuit,
|
|
215
|
+
*,
|
|
216
|
+
N: int,
|
|
217
|
+
context: Optional[transformer_api.TransformerContext] = None,
|
|
218
|
+
prng: Optional[np.random.Generator] = None,
|
|
219
|
+
) -> Tuple[circuits.AbstractCircuit, sweepable.Sweepable]:
|
|
220
|
+
"""Generates a parameterized circuit with *N* sets of sweepable parameters.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
circuit: The input circuit to be processed by gauge compiling.
|
|
224
|
+
N: The number of parameter sets to generate.
|
|
225
|
+
context: A `cirq.TransformerContext` storing common configurable options for
|
|
226
|
+
the transformers.
|
|
227
|
+
prng: A pseudo-random number generator to select a gauge within a gauge cluster.
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
rng = np.random.default_rng() if prng is None else prng
|
|
231
|
+
if context is None:
|
|
232
|
+
context = transformer_api.TransformerContext(deep=False)
|
|
233
|
+
if context.deep:
|
|
234
|
+
raise ValueError('GaugeTransformer cannot be used with deep=True')
|
|
235
|
+
new_moments: List[List[ops.Operation]] = [] # Store parameterized circuits.
|
|
236
|
+
values_by_params: Dict[str, List[float]] = {} # map from symbol name to N values.
|
|
237
|
+
symbol_count = count()
|
|
238
|
+
# Map from "((pre|post),$qid,$moment_id)" to gate parameters.
|
|
239
|
+
# E.g. {(post,q1,2): {"x_exponent": "x1", "z_exponent": "z1", "axis_phase": "a1"}}
|
|
240
|
+
symbols_by_loc: Dict[Tuple[str, ops.Qid, int], Dict[str, sympy.Symbol]] = {}
|
|
241
|
+
|
|
242
|
+
def single_qubit_next_symbol() -> Dict[str, sympy.Symbol]:
|
|
243
|
+
sid = next(symbol_count)
|
|
244
|
+
return _parameterize(1, sid)
|
|
245
|
+
|
|
246
|
+
# Build parameterized circuit.
|
|
247
|
+
for moment_id, moment in enumerate(circuit):
|
|
248
|
+
center_moment: List[ops.Operation] = []
|
|
249
|
+
left_moment: List[ops.Operation] = []
|
|
250
|
+
right_moment: List[ops.Operation] = []
|
|
251
|
+
for op in moment:
|
|
252
|
+
if isinstance(op, ops.TaggedOperation) and set(op.tags).intersection(
|
|
253
|
+
context.tags_to_ignore
|
|
254
|
+
):
|
|
255
|
+
center_moment.append(op)
|
|
256
|
+
continue
|
|
257
|
+
if op.gate is not None and op in self.target:
|
|
258
|
+
# Build symbols for the gauge, for a 2-qubit gauge, symbols will be built for
|
|
259
|
+
# pre/post q0/q1 and the new 2-qubit gate if the 2-qubit gate is updated in
|
|
260
|
+
# the gauge compiling.
|
|
261
|
+
center_moment.append(op)
|
|
262
|
+
for prefix, q in itertools.product(["pre", "post"], op.qubits):
|
|
263
|
+
xza_by_symbols = single_qubit_next_symbol() # xza in phased xz gate.
|
|
264
|
+
loc = (prefix, q, moment_id)
|
|
265
|
+
symbols_by_loc[loc] = xza_by_symbols
|
|
266
|
+
new_op = ops.PhasedXZGate(**xza_by_symbols).on(q)
|
|
267
|
+
for symbol in xza_by_symbols.values():
|
|
268
|
+
values_by_params.update({str(symbol): []})
|
|
269
|
+
if prefix == "pre":
|
|
270
|
+
left_moment.append(new_op)
|
|
271
|
+
else:
|
|
272
|
+
right_moment.append(new_op)
|
|
273
|
+
else:
|
|
274
|
+
center_moment.append(op)
|
|
275
|
+
new_moments.extend(
|
|
276
|
+
[moment for moment in [left_moment, center_moment, right_moment] if moment]
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
# Assign values for parameters via randomly chosen GaugeSelector.
|
|
280
|
+
for _ in range(N):
|
|
281
|
+
for moment_id, moment in enumerate(circuit):
|
|
282
|
+
for op in moment:
|
|
283
|
+
if isinstance(op, ops.TaggedOperation) and set(op.tags).intersection(
|
|
284
|
+
context.tags_to_ignore
|
|
285
|
+
):
|
|
286
|
+
continue
|
|
287
|
+
if op.gate is not None and len(op.qubits) == 2 and op in self.target:
|
|
288
|
+
gauge = self.gauge_selector(rng).sample(op.gate, rng)
|
|
289
|
+
if not gauge.support_sweep:
|
|
290
|
+
raise NotImplementedError(
|
|
291
|
+
f"as_sweep isn't supported for {gauge.two_qubit_gate} gauge"
|
|
292
|
+
)
|
|
293
|
+
# Get the params of pre/post q0/q1 gates.
|
|
294
|
+
for pre_or_post, idx in itertools.product(["pre", "post"], [0, 1]):
|
|
295
|
+
symbols = symbols_by_loc[(pre_or_post, op.qubits[idx], moment_id)]
|
|
296
|
+
gates = getattr(gauge, f"{pre_or_post}_q{idx}")
|
|
297
|
+
phxz_params = _gate_sequence_to_phxz_params(gates, symbols)
|
|
298
|
+
for key, value in phxz_params.items():
|
|
299
|
+
values_by_params[key].append(value)
|
|
300
|
+
sweeps: List[Points] = [
|
|
301
|
+
Points(key=key, points=values) for key, values in values_by_params.items()
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
return circuits.Circuit.from_moments(*new_moments), Zip(*sweeps)
|
|
305
|
+
|
|
204
306
|
|
|
205
307
|
def _build_moments(operation_by_qubits: List[List[ops.Operation]]) -> List[List[ops.Operation]]:
|
|
206
308
|
"""Builds moments from a list of operations grouped by qubits.
|
|
@@ -212,3 +314,50 @@ def _build_moments(operation_by_qubits: List[List[ops.Operation]]) -> List[List[
|
|
|
212
314
|
for moment in itertools.zip_longest(*operation_by_qubits):
|
|
213
315
|
moments.append([op for op in moment if op is not None])
|
|
214
316
|
return moments
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def _parameterize(num_qubits: int, symbol_id: int) -> Dict[str, sympy.Symbol]:
|
|
320
|
+
"""Returns symbolized parameters for the gate."""
|
|
321
|
+
|
|
322
|
+
if num_qubits == 1: # Convert single qubit gate to parameterized PhasedXZGate.
|
|
323
|
+
phased_xz_params = {
|
|
324
|
+
"x_exponent": sympy.Symbol(f"x{symbol_id}"),
|
|
325
|
+
"z_exponent": sympy.Symbol(f"z{symbol_id}"),
|
|
326
|
+
"axis_phase_exponent": sympy.Symbol(f"a{symbol_id}"),
|
|
327
|
+
}
|
|
328
|
+
return phased_xz_params
|
|
329
|
+
raise NotImplementedError("parameterization for non single qubit gates is not supported yet")
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _gate_sequence_to_phxz_params(
|
|
333
|
+
gates: Tuple[ops.Gate, ...], xza_by_symbols: Dict[str, sympy.Symbol]
|
|
334
|
+
) -> Dict[str, float]:
|
|
335
|
+
for gate in gates:
|
|
336
|
+
if not has_unitary(gate) or gate.num_qubits() != 1:
|
|
337
|
+
raise ValueError(
|
|
338
|
+
"Invalid gate sequence to be converted to PhasedXZGate."
|
|
339
|
+
f"Found incompatiable gate {gate} in sequence."
|
|
340
|
+
)
|
|
341
|
+
phxz = (
|
|
342
|
+
single_qubit_decompositions.single_qubit_matrix_to_phxz(
|
|
343
|
+
functools.reduce(
|
|
344
|
+
np.matmul, [unitary_protocol.unitary(gate) for gate in reversed(gates)]
|
|
345
|
+
)
|
|
346
|
+
)
|
|
347
|
+
or ops.I
|
|
348
|
+
)
|
|
349
|
+
if phxz is ops.I: # Identity gate
|
|
350
|
+
return {
|
|
351
|
+
str(xza_by_symbols["x_exponent"]): 0.0,
|
|
352
|
+
str(xza_by_symbols["z_exponent"]): 0.0,
|
|
353
|
+
str(xza_by_symbols["axis_phase_exponent"]): 0.0,
|
|
354
|
+
}
|
|
355
|
+
# Check the gate type, needs to be a PhasedXZ gate.
|
|
356
|
+
if not isinstance(phxz, ops.PhasedXZGate):
|
|
357
|
+
raise ValueError("Failed to convert the gate sequence to a PhasedXZ gate.")
|
|
358
|
+
if phxz is not None:
|
|
359
|
+
return {
|
|
360
|
+
str(xza_by_symbols["x_exponent"]): phxz.x_exponent,
|
|
361
|
+
str(xza_by_symbols["z_exponent"]): phxz.z_exponent,
|
|
362
|
+
str(xza_by_symbols["axis_phase_exponent"]): phxz.axis_phase_exponent,
|
|
363
|
+
}
|
|
@@ -12,10 +12,17 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
import unittest.mock
|
|
15
16
|
import pytest
|
|
16
17
|
import numpy as np
|
|
17
18
|
import cirq
|
|
18
|
-
from cirq.transformers.gauge_compiling import
|
|
19
|
+
from cirq.transformers.gauge_compiling import (
|
|
20
|
+
GaugeTransformer,
|
|
21
|
+
CZGaugeTransformer,
|
|
22
|
+
ConstantGauge,
|
|
23
|
+
GaugeSelector,
|
|
24
|
+
)
|
|
25
|
+
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
|
|
19
26
|
|
|
20
27
|
|
|
21
28
|
def test_deep_transformation_not_supported():
|
|
@@ -25,10 +32,19 @@ def test_deep_transformation_not_supported():
|
|
|
25
32
|
cirq.Circuit(), context=cirq.TransformerContext(deep=True)
|
|
26
33
|
)
|
|
27
34
|
|
|
35
|
+
with pytest.raises(ValueError, match="cannot be used with deep=True"):
|
|
36
|
+
_ = GaugeTransformer(target=cirq.CZ, gauge_selector=lambda _: None).as_sweep(
|
|
37
|
+
cirq.Circuit(), context=cirq.TransformerContext(deep=True), N=1
|
|
38
|
+
)
|
|
39
|
+
|
|
28
40
|
|
|
29
41
|
def test_ignore_tags():
|
|
30
42
|
c = cirq.Circuit(cirq.CZ(*cirq.LineQubit.range(2)).with_tags('foo'))
|
|
31
43
|
assert c == CZGaugeTransformer(c, context=cirq.TransformerContext(tags_to_ignore={"foo"}))
|
|
44
|
+
parameterized_circuit, _ = CZGaugeTransformer.as_sweep(
|
|
45
|
+
c, context=cirq.TransformerContext(tags_to_ignore={"foo"}), N=1
|
|
46
|
+
)
|
|
47
|
+
assert c == parameterized_circuit
|
|
32
48
|
|
|
33
49
|
|
|
34
50
|
def test_target_can_be_gateset():
|
|
@@ -39,3 +55,71 @@ def test_target_can_be_gateset():
|
|
|
39
55
|
)
|
|
40
56
|
want = cirq.Circuit(cirq.Y.on_each(qs), cirq.CZ(*qs), cirq.X.on_each(qs))
|
|
41
57
|
assert transformer(c, prng=np.random.default_rng(0)) == want
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_as_sweep_multi_pre_or_multi_post():
|
|
61
|
+
transformer = GaugeTransformer(
|
|
62
|
+
target=cirq.CZ,
|
|
63
|
+
gauge_selector=GaugeSelector(
|
|
64
|
+
gauges=[
|
|
65
|
+
ConstantGauge(
|
|
66
|
+
two_qubit_gate=cirq.CZ,
|
|
67
|
+
support_sweep=True,
|
|
68
|
+
pre_q0=[cirq.X, cirq.X],
|
|
69
|
+
post_q0=[cirq.Z],
|
|
70
|
+
pre_q1=[cirq.Y],
|
|
71
|
+
post_q1=[cirq.Y, cirq.Y, cirq.Y],
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
qs = cirq.LineQubit.range(2)
|
|
77
|
+
input_circuit = cirq.Circuit(cirq.CZ(*qs))
|
|
78
|
+
parameterized_circuit, sweeps = transformer.as_sweep(input_circuit, N=1)
|
|
79
|
+
|
|
80
|
+
for params in sweeps:
|
|
81
|
+
compiled_circuit = cirq.resolve_parameters(parameterized_circuit, params)
|
|
82
|
+
cirq.testing.assert_circuits_have_same_unitary_given_final_permutation(
|
|
83
|
+
input_circuit, compiled_circuit, qubit_map={q: q for q in input_circuit.all_qubits()}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_as_sweep_invalid_gauge_sequence():
|
|
88
|
+
transfomer = GaugeTransformer(
|
|
89
|
+
target=cirq.CZ,
|
|
90
|
+
gauge_selector=GaugeSelector(
|
|
91
|
+
gauges=[
|
|
92
|
+
ConstantGauge(
|
|
93
|
+
two_qubit_gate=cirq.CZ,
|
|
94
|
+
support_sweep=True,
|
|
95
|
+
pre_q0=[cirq.measure],
|
|
96
|
+
post_q0=[cirq.Z],
|
|
97
|
+
pre_q1=[cirq.X],
|
|
98
|
+
post_q1=[cirq.Z],
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
qs = cirq.LineQubit.range(2)
|
|
104
|
+
c = cirq.Circuit(cirq.CZ(*qs))
|
|
105
|
+
with pytest.raises(ValueError, match="Invalid gate sequence to be converted to PhasedXZGate."):
|
|
106
|
+
transfomer.as_sweep(c, N=1)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_as_sweep_convert_to_phxz_failed():
|
|
110
|
+
qs = cirq.LineQubit.range(2)
|
|
111
|
+
c = cirq.Circuit(cirq.CZ(*qs))
|
|
112
|
+
|
|
113
|
+
def mock_single_qubit_matrix_to_phxz(*args, **kwargs):
|
|
114
|
+
# Return an non PhasedXZ gate, so we expect errors from as_sweep().
|
|
115
|
+
return cirq.X
|
|
116
|
+
|
|
117
|
+
with unittest.mock.patch.object(
|
|
118
|
+
single_qubit_decompositions,
|
|
119
|
+
"single_qubit_matrix_to_phxz",
|
|
120
|
+
new=mock_single_qubit_matrix_to_phxz,
|
|
121
|
+
):
|
|
122
|
+
with pytest.raises(
|
|
123
|
+
ValueError, match="Failed to convert the gate sequence to a PhasedXZ gate."
|
|
124
|
+
):
|
|
125
|
+
_ = CZGaugeTransformer.as_sweep(c, context=cirq.TransformerContext(), N=1)
|
|
@@ -27,6 +27,7 @@ class GaugeTester:
|
|
|
27
27
|
two_qubit_gate: cirq.Gate
|
|
28
28
|
gauge_transformer: GaugeTransformer
|
|
29
29
|
must_fail: bool = False
|
|
30
|
+
sweep_must_pass: bool = False
|
|
30
31
|
|
|
31
32
|
@pytest.mark.parametrize(
|
|
32
33
|
['generation_seed', 'transformation_seed'],
|
|
@@ -73,6 +74,42 @@ class GaugeTester:
|
|
|
73
74
|
else:
|
|
74
75
|
_check_equivalent_with_error_message(c, nc, gauge)
|
|
75
76
|
|
|
77
|
+
def test_sweep(self):
|
|
78
|
+
qubits = cirq.LineQubit.range(3)
|
|
79
|
+
|
|
80
|
+
if not self.sweep_must_pass:
|
|
81
|
+
with pytest.raises(NotImplementedError):
|
|
82
|
+
self.gauge_transformer.as_sweep(
|
|
83
|
+
cirq.Circuit(cirq.Moment(self.two_qubit_gate(*qubits[:2]))), N=1
|
|
84
|
+
)
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
input_circuit = cirq.Circuit(
|
|
88
|
+
cirq.Moment(cirq.H(qubits[0])),
|
|
89
|
+
cirq.Moment(self.two_qubit_gate(*qubits[:2])),
|
|
90
|
+
cirq.Moment(self.two_qubit_gate(*qubits[1:])),
|
|
91
|
+
cirq.Moment([cirq.H(q) for q in qubits]),
|
|
92
|
+
cirq.Moment([cirq.measure(q) for q in qubits]),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
n_samples = 5
|
|
96
|
+
parameterized_circuit, sweeps = self.gauge_transformer.as_sweep(input_circuit, N=n_samples)
|
|
97
|
+
|
|
98
|
+
# Check the parameterized circuit and N set of parameters.
|
|
99
|
+
assert cirq.is_parameterized(parameterized_circuit)
|
|
100
|
+
simulator = cirq.Simulator()
|
|
101
|
+
results = simulator.run_sweep(parameterized_circuit, sweeps)
|
|
102
|
+
assert len(results) == n_samples
|
|
103
|
+
|
|
104
|
+
# Check compilied circuits have the same unitary as the orig circuit.
|
|
105
|
+
for params in sweeps:
|
|
106
|
+
compiled_circuit = cirq.resolve_parameters(parameterized_circuit, params)
|
|
107
|
+
cirq.testing.assert_circuits_have_same_unitary_given_final_permutation(
|
|
108
|
+
input_circuit[:-1],
|
|
109
|
+
compiled_circuit[:-1],
|
|
110
|
+
qubit_map={q: q for q in input_circuit.all_qubits()},
|
|
111
|
+
)
|
|
112
|
+
|
|
76
113
|
|
|
77
114
|
def _check_equivalent_with_error_message(c: cirq.AbstractCircuit, nc: cirq.AbstractCircuit, gauge):
|
|
78
115
|
try:
|
|
@@ -26,7 +26,15 @@ class ExampleGate(cirq.testing.TwoQubitGate):
|
|
|
26
26
|
return self.unitary
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
class ExampleSweepGate(cirq.testing.TwoQubitGate):
|
|
30
|
+
unitary = cirq.unitary(cirq.CZ)
|
|
31
|
+
|
|
32
|
+
def _unitary_(self) -> np.ndarray:
|
|
33
|
+
return self.unitary
|
|
34
|
+
|
|
35
|
+
|
|
29
36
|
_EXAMPLE_TARGET = ExampleGate()
|
|
37
|
+
_EXAMPLE_SWEEP_TARGET = ExampleSweepGate()
|
|
30
38
|
|
|
31
39
|
_GOOD_TRANSFORMER = GaugeTransformer(
|
|
32
40
|
target=_EXAMPLE_TARGET,
|
|
@@ -40,6 +48,22 @@ _BAD_TRANSFORMER = GaugeTransformer(
|
|
|
40
48
|
),
|
|
41
49
|
)
|
|
42
50
|
|
|
51
|
+
_TRANSFORMER_WITH_SWEEP = GaugeTransformer(
|
|
52
|
+
target=_EXAMPLE_SWEEP_TARGET,
|
|
53
|
+
gauge_selector=GaugeSelector(
|
|
54
|
+
gauges=[
|
|
55
|
+
ConstantGauge(
|
|
56
|
+
two_qubit_gate=_EXAMPLE_SWEEP_TARGET,
|
|
57
|
+
pre_q0=cirq.Z,
|
|
58
|
+
pre_q1=cirq.Z,
|
|
59
|
+
post_q0=cirq.Z,
|
|
60
|
+
post_q1=cirq.Z,
|
|
61
|
+
support_sweep=True,
|
|
62
|
+
)
|
|
63
|
+
]
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
|
|
43
67
|
|
|
44
68
|
class TestValidTransformer(GaugeTester):
|
|
45
69
|
two_qubit_gate = _EXAMPLE_TARGET
|
|
@@ -50,3 +74,9 @@ class TestInvalidTransformer(GaugeTester):
|
|
|
50
74
|
two_qubit_gate = _EXAMPLE_TARGET
|
|
51
75
|
gauge_transformer = _BAD_TRANSFORMER
|
|
52
76
|
must_fail = True
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class TestSweep(GaugeTester):
|
|
80
|
+
two_qubit_gate = _EXAMPLE_SWEEP_TARGET
|
|
81
|
+
gauge_transformer = _TRANSFORMER_WITH_SWEEP
|
|
82
|
+
sweep_must_pass = True
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cirq-core
|
|
3
|
-
Version: 1.5.0.
|
|
3
|
+
Version: 1.5.0.dev20241221000556
|
|
4
4
|
Summary: A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
|
|
5
5
|
Home-page: http://github.com/quantumlib/cirq
|
|
6
6
|
Author: The Cirq Developers
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/RECORD
RENAMED
|
@@ -4,8 +4,8 @@ cirq/_compat_test.py,sha256=Qq3ZcfgD-Nb81cEppQdJqhAyrVqXKtfXZYGXT0p-Wh0,34718
|
|
|
4
4
|
cirq/_doc.py,sha256=yDyWUD_2JDS0gShfGRb-rdqRt9-WeL7DhkqX7np0Nko,2879
|
|
5
5
|
cirq/_import.py,sha256=p9gMHJscbtDDkfHOaulvd3Aer0pwUF5AXpL89XR8dNw,8402
|
|
6
6
|
cirq/_import_test.py,sha256=6K_v0riZJXOXUphHNkGA8MY-JcmGlezFaGmvrNhm3OQ,1015
|
|
7
|
-
cirq/_version.py,sha256=
|
|
8
|
-
cirq/_version_test.py,sha256=
|
|
7
|
+
cirq/_version.py,sha256=OqoCeE--Ab9NG2PKQn-oiComWbF_Pgw1sRYHYc8sEY0,1206
|
|
8
|
+
cirq/_version_test.py,sha256=UMG2gtNTe_70vsxwkOgm2BvpCnF9uav4WLuoPUqXTjY,147
|
|
9
9
|
cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
|
|
10
10
|
cirq/json_resolver_cache.py,sha256=03MVo6Y-UYrzt9CKHmwpiBLN2ixL6uSU-OWnKZXfG7k,13302
|
|
11
11
|
cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
|
|
@@ -203,8 +203,8 @@ cirq/experiments/xeb_sampling.py,sha256=6ZOidGi7Kt6p4cMQCjK7qQuIUXVHCYl47B2GnL8M
|
|
|
203
203
|
cirq/experiments/xeb_sampling_test.py,sha256=0XkQGvcURsug3IblE_wZrHVDoOQV3WuQilrqCJbDHjI,6784
|
|
204
204
|
cirq/experiments/xeb_simulation.py,sha256=yML2NAnYTRFG1wsQHvxtNEGEMXuExbWjrE2JYuCqnrk,5076
|
|
205
205
|
cirq/experiments/xeb_simulation_test.py,sha256=YWFKXPdtBFuZNhQoG06W1EetVhXighc3zyXwhKfGAeo,5652
|
|
206
|
-
cirq/experiments/z_phase_calibration.py,sha256=
|
|
207
|
-
cirq/experiments/z_phase_calibration_test.py,sha256=
|
|
206
|
+
cirq/experiments/z_phase_calibration.py,sha256=2mkpmtY60hQuaB91If6eAL_q_nW88hwJ2Pqdq9R_iTE,15152
|
|
207
|
+
cirq/experiments/z_phase_calibration_test.py,sha256=BJ88waxTxRUsKSoFnkYkvhKxKwBNSmYCuZII6X-R36g,8904
|
|
208
208
|
cirq/interop/__init__.py,sha256=Xt1xU9UegP_jBNa9xaeOFSgtC0lYb_HNHq4hQQ0J20k,784
|
|
209
209
|
cirq/interop/quirk/__init__.py,sha256=W11jqaExSgvoUkjM_d0Kik4R8bqETF9Ezo27CDEB3iw,1237
|
|
210
210
|
cirq/interop/quirk/url_to_circuit.py,sha256=1ToWnFJdJIhCko9q62BEvOoCGxCpOUl8891IdCa52MM,14211
|
|
@@ -292,8 +292,8 @@ cirq/ops/eigen_gate.py,sha256=eQ6-MOknop7CrejsTuQ0KZWf4mZnQBi8wEaTQXw4KSQ,18334
|
|
|
292
292
|
cirq/ops/eigen_gate_test.py,sha256=-7l6GmAd1EYzHoGREQN1n7J1VOQKbThH2mA88TRODs8,13928
|
|
293
293
|
cirq/ops/fourier_transform.py,sha256=pynO07OcZSVCeL8L0pNQ9m_y5_wrpTWOMf99BHpjXdU,7579
|
|
294
294
|
cirq/ops/fourier_transform_test.py,sha256=PIK4bWnCIy2TuX0fgclHeU1CBDT6zRVoQpv1v1jt62c,6220
|
|
295
|
-
cirq/ops/fsim_gate.py,sha256=
|
|
296
|
-
cirq/ops/fsim_gate_test.py,sha256=
|
|
295
|
+
cirq/ops/fsim_gate.py,sha256=Avzlcb_O201K0_tBmNR5m9fWkpBM7Nby0MfJjNJ9g_8,20136
|
|
296
|
+
cirq/ops/fsim_gate_test.py,sha256=4kFk0ALzTmaskQURHPl6JerNvw8gbZn49nt1_WAjpdY,25671
|
|
297
297
|
cirq/ops/gate_features.py,sha256=414mSi3kgKSwLOeAG_WEZKn8ZMaLtOowed7os1qSnM4,1049
|
|
298
298
|
cirq/ops/gate_features_test.py,sha256=mnlqJnSpllcOnTUdvmUs_ssnPRhAIgHhKIAK2Z86Dfg,2347
|
|
299
299
|
cirq/ops/gate_operation.py,sha256=IGCyqe9YguIlajnQ3EV61Y0vUxOT_SrRxvNEFwKtUak,13720
|
|
@@ -1092,12 +1092,12 @@ cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py,sha256=85Mbu
|
|
|
1092
1092
|
cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py,sha256=F_XpM4ApYHxV6hbWnV3C7Ud9L1BnpvBHBXShPh2mP3k,25397
|
|
1093
1093
|
cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py,sha256=eKOzjWkR7xs-CL2oPj__nWXR0LL9oO42wEHibnvWq-o,20618
|
|
1094
1094
|
cirq/transformers/gauge_compiling/__init__.py,sha256=ZF53ZtYRJeKsVJYjKc_QrAqE1pyd8FFmmb6Wo8JdgQs,1385
|
|
1095
|
-
cirq/transformers/gauge_compiling/cz_gauge.py,sha256=
|
|
1096
|
-
cirq/transformers/gauge_compiling/cz_gauge_test.py,sha256=
|
|
1097
|
-
cirq/transformers/gauge_compiling/gauge_compiling.py,sha256=
|
|
1098
|
-
cirq/transformers/gauge_compiling/gauge_compiling_test.py,sha256=
|
|
1099
|
-
cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py,sha256=
|
|
1100
|
-
cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py,sha256=
|
|
1095
|
+
cirq/transformers/gauge_compiling/cz_gauge.py,sha256=pJ41uVaUltigKLIayxr0XMqTYEs0zUDnaWD-tp65pPk,4198
|
|
1096
|
+
cirq/transformers/gauge_compiling/cz_gauge_test.py,sha256=sHEgEEI_z9-Ka5ChN2JmtoYcEHhNYHysOjGJzaaKkoA,881
|
|
1097
|
+
cirq/transformers/gauge_compiling/gauge_compiling.py,sha256=MyzYcgr0vl0pzOq41jkzmrM6COsDg7e2iU_xQcUoQ20,15063
|
|
1098
|
+
cirq/transformers/gauge_compiling/gauge_compiling_test.py,sha256=Nm0Uxqrq1Y5puQep9UpKXK2zg9a3Dx2NSFArIxeawUg,4444
|
|
1099
|
+
cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py,sha256=7RNZ6-xQ1iKjoNWTokgok7xTCeAnrQUzbpdBhdJZEfY,4933
|
|
1100
|
+
cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py,sha256=cWEAP1EWbpHNp7wQPXLyT413raoG3aIg8aFod_aXAtQ,2340
|
|
1101
1101
|
cirq/transformers/gauge_compiling/iswap_gauge.py,sha256=UGJ_061h65Rfgb9LWREjxC8OSt01ZqP9TGnacL8VAuk,3500
|
|
1102
1102
|
cirq/transformers/gauge_compiling/iswap_gauge_test.py,sha256=HEIIwKlX5ixau1e_etSUj5NvYOVTT-Gc3kuHcyKAeJ4,866
|
|
1103
1103
|
cirq/transformers/gauge_compiling/spin_inversion_gauge.py,sha256=gfjSlQdo13GfBPlrkQoHPWWzouiV7yYr7JAaB85NSGY,1086
|
|
@@ -1189,8 +1189,8 @@ cirq/work/sampler.py,sha256=bE5tmVkcR6cZZMLETxDfHehdsYUMbx2RvBeIBetehI4,19187
|
|
|
1189
1189
|
cirq/work/sampler_test.py,sha256=hL2UWx3dz2ukZVNxWftiKVvJcQoLplLZdQm-k1QcA40,13282
|
|
1190
1190
|
cirq/work/zeros_sampler.py,sha256=x1C7cup66a43n-3tm8QjhiqJa07qcJW10FxNp9jJ59Q,2356
|
|
1191
1191
|
cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
|
|
1192
|
-
cirq_core-1.5.0.
|
|
1193
|
-
cirq_core-1.5.0.
|
|
1194
|
-
cirq_core-1.5.0.
|
|
1195
|
-
cirq_core-1.5.0.
|
|
1196
|
-
cirq_core-1.5.0.
|
|
1192
|
+
cirq_core-1.5.0.dev20241221000556.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
1193
|
+
cirq_core-1.5.0.dev20241221000556.dist-info/METADATA,sha256=P70dL9Vm3tnlLFwyneVhZiRBS6axK3zAqZcEOrgNckg,1992
|
|
1194
|
+
cirq_core-1.5.0.dev20241221000556.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
1195
|
+
cirq_core-1.5.0.dev20241221000556.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
|
|
1196
|
+
cirq_core-1.5.0.dev20241221000556.dist-info/RECORD,,
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/LICENSE
RENAMED
|
File without changes
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241221000556.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|