cirq-core 1.5.0.dev20250403060241__py3-none-any.whl → 1.5.0.dev20250403161251__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/_import.py +1 -1
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/circuit.py +2 -2
- cirq/circuits/circuit_test.py +0 -13
- cirq/circuits/insert_strategy_test.py +1 -0
- cirq/circuits/optimization_pass.py +3 -3
- cirq/circuits/qasm_output.py +1 -1
- cirq/circuits/qasm_output_test.py +5 -0
- cirq/circuits/text_diagram_drawer.py +1 -1
- cirq/contrib/acquaintance/bipartite_test.py +11 -0
- cirq/contrib/acquaintance/devices_test.py +5 -0
- cirq/contrib/acquaintance/executor_test.py +1 -0
- cirq/contrib/acquaintance/inspection_utils_test.py +5 -0
- cirq/contrib/acquaintance/shift.py +1 -1
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +6 -4
- cirq/contrib/graph_device/graph_device.py +3 -3
- cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +0 -1
- cirq/contrib/paulistring/recombine_test.py +1 -1
- cirq/contrib/qcircuit/qcircuit_pdf.py +11 -8
- cirq/contrib/qcircuit/qcircuit_pdf_test.py +21 -0
- cirq/contrib/qcircuit/qcircuit_test.py +1 -1
- cirq/contrib/quantum_volume/quantum_volume.py +1 -6
- cirq/contrib/quimb/mps_simulator.py +2 -2
- cirq/contrib/quimb/mps_simulator_test.py +5 -0
- cirq/contrib/routing/greedy_test.py +3 -1
- cirq/contrib/svg/svg.py +1 -1
- cirq/contrib/svg/svg_test.py +3 -2
- cirq/devices/unconstrained_device_test.py +6 -0
- cirq/experiments/qubit_characterizations.py +4 -2
- cirq/experiments/random_quantum_circuit_generation.py +2 -3
- cirq/experiments/readout_confusion_matrix.py +4 -4
- cirq/linalg/combinators_test.py +3 -0
- cirq/linalg/decompositions_test.py +0 -5
- cirq/linalg/predicates.py +1 -1
- cirq/ops/clifford_gate.py +5 -16
- cirq/ops/common_gates.py +8 -8
- cirq/ops/common_gates_test.py +5 -0
- cirq/ops/control_values.py +1 -1
- cirq/ops/controlled_gate.py +1 -1
- cirq/ops/controlled_operation.py +1 -1
- cirq/ops/controlled_operation_test.py +6 -2
- cirq/ops/dense_pauli_string.py +1 -1
- cirq/ops/eigen_gate.py +1 -1
- cirq/ops/fourier_transform.py +0 -2
- cirq/ops/gate_operation.py +1 -1
- cirq/ops/gate_operation_test.py +1 -0
- cirq/ops/gateset_test.py +7 -0
- cirq/ops/greedy_qubit_manager_test.py +5 -0
- cirq/ops/kraus_channel_test.py +1 -0
- cirq/ops/mixed_unitary_channel_test.py +1 -0
- cirq/ops/op_tree_test.py +4 -0
- cirq/ops/pauli_measurement_gate_test.py +1 -0
- cirq/ops/pauli_string.py +3 -80
- cirq/ops/pauli_string_test.py +46 -0
- cirq/ops/phased_x_gate.py +1 -1
- cirq/ops/random_gate_channel_test.py +0 -6
- cirq/ops/raw_types.py +1 -1
- cirq/ops/raw_types_test.py +26 -1
- cirq/protocols/decompose_protocol_test.py +1 -1
- cirq/protocols/has_unitary_protocol_test.py +8 -7
- cirq/protocols/json_serialization_test.py +7 -6
- cirq/protocols/kraus_protocol.py +2 -2
- cirq/protocols/measurement_key_protocol_test.py +7 -7
- cirq/protocols/unitary_protocol_test.py +1 -1
- cirq/qis/channels_test.py +0 -9
- cirq/qis/measures.py +2 -1
- cirq/qis/measures_test.py +7 -0
- cirq/qis/states.py +1 -1
- cirq/sim/clifford/clifford_simulator.py +2 -1
- cirq/sim/clifford/clifford_simulator_test.py +32 -9
- cirq/sim/density_matrix_simulator.py +2 -1
- cirq/sim/density_matrix_simulator_test.py +10 -2
- cirq/sim/simulation_state.py +1 -1
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulator_test.py +1 -1
- cirq/sim/sparse_simulator.py +2 -1
- cirq/sim/sparse_simulator_test.py +10 -2
- cirq/sim/state_vector_simulation_state_test.py +1 -1
- cirq/study/resolver.py +0 -4
- cirq/study/resolver_test.py +10 -1
- cirq/study/sweeps_test.py +18 -0
- cirq/testing/circuit_compare_test.py +6 -6
- cirq/testing/consistent_pauli_expansion_test.py +1 -1
- cirq/testing/consistent_qasm.py +1 -1
- cirq/testing/equals_tester.py +1 -1
- cirq/testing/equals_tester_test.py +5 -5
- cirq/testing/gate_features_test.py +5 -0
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +1 -1
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +1 -1
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/transformer_api_test.py +8 -0
- cirq/transformers/transformer_primitives_test.py +2 -2
- cirq/value/condition.py +1 -1
- cirq/value/duration.py +1 -1
- cirq/value/periodic_value_test.py +5 -0
- cirq/value/value_equality_attr_test.py +1 -1
- cirq/vis/heatmap_test.py +1 -1
- cirq/work/observable_settings.py +2 -1
- cirq/work/observable_settings_test.py +1 -0
- {cirq_core-1.5.0.dev20250403060241.dist-info → cirq_core-1.5.0.dev20250403161251.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20250403060241.dist-info → cirq_core-1.5.0.dev20250403161251.dist-info}/RECORD +106 -105
- {cirq_core-1.5.0.dev20250403060241.dist-info → cirq_core-1.5.0.dev20250403161251.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250403060241.dist-info → cirq_core-1.5.0.dev20250403161251.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20250403060241.dist-info → cirq_core-1.5.0.dev20250403161251.dist-info}/top_level.txt +0 -0
cirq/ops/common_gates.py
CHANGED
|
@@ -177,7 +177,7 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
177
177
|
return SingleQubitCliffordGate.X.on(*qubits)
|
|
178
178
|
if self.exponent % 2 == 1.5:
|
|
179
179
|
return SingleQubitCliffordGate.X_nsqrt.on(*qubits)
|
|
180
|
-
return NotImplemented
|
|
180
|
+
return NotImplemented # pragma: no cover
|
|
181
181
|
|
|
182
182
|
def _trace_distance_bound_(self) -> Optional[float]:
|
|
183
183
|
if self._is_parameterized_() or self._dimension != 2:
|
|
@@ -259,7 +259,7 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
259
259
|
|
|
260
260
|
def _pauli_expansion_(self) -> value.LinearDict[str]:
|
|
261
261
|
if self._dimension != 2:
|
|
262
|
-
return NotImplemented
|
|
262
|
+
return NotImplemented # pragma: no cover
|
|
263
263
|
phase = 1j ** (2 * self._exponent * (self._global_shift + 0.5))
|
|
264
264
|
lib = sympy if protocols.is_parameterized(self) else np
|
|
265
265
|
angle = lib.pi * self._exponent / 2
|
|
@@ -451,7 +451,7 @@ class YPowGate(eigen_gate.EigenGate):
|
|
|
451
451
|
return SingleQubitCliffordGate.Y.on(*qubits)
|
|
452
452
|
if self.exponent % 2 == 1.5:
|
|
453
453
|
return SingleQubitCliffordGate.Y_nsqrt.on(*qubits)
|
|
454
|
-
return NotImplemented
|
|
454
|
+
return NotImplemented # pragma: no cover
|
|
455
455
|
|
|
456
456
|
def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
|
|
457
457
|
return [
|
|
@@ -656,7 +656,7 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
656
656
|
return SingleQubitCliffordGate.Z.on(*qubits)
|
|
657
657
|
if self.exponent % 2 == 1.5:
|
|
658
658
|
return SingleQubitCliffordGate.Z_nsqrt.on(*qubits)
|
|
659
|
-
return NotImplemented
|
|
659
|
+
return NotImplemented # pragma: no cover
|
|
660
660
|
|
|
661
661
|
def in_su2(self) -> 'Rz':
|
|
662
662
|
"""Returns an equal-up-global-phase gate from the group SU2."""
|
|
@@ -765,7 +765,7 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
765
765
|
|
|
766
766
|
def _pauli_expansion_(self) -> value.LinearDict[str]:
|
|
767
767
|
if self._dimension != 2:
|
|
768
|
-
return NotImplemented
|
|
768
|
+
return NotImplemented # pragma: no cover
|
|
769
769
|
phase = 1j ** (2 * self._exponent * (self._global_shift + 0.5))
|
|
770
770
|
lib = sympy if protocols.is_parameterized(self) else np
|
|
771
771
|
angle = lib.pi * self._exponent / 2
|
|
@@ -982,7 +982,7 @@ class HPowGate(eigen_gate.EigenGate):
|
|
|
982
982
|
return SingleQubitCliffordGate.H.on(*qubits)
|
|
983
983
|
if self.exponent % 2 == 0:
|
|
984
984
|
return []
|
|
985
|
-
return NotImplemented
|
|
985
|
+
return NotImplemented # pragma: no cover
|
|
986
986
|
|
|
987
987
|
def _apply_unitary_(self, args: 'protocols.ApplyUnitaryArgs') -> Optional[np.ndarray]:
|
|
988
988
|
if self._exponent != 1:
|
|
@@ -1080,7 +1080,7 @@ class CZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
1080
1080
|
return PauliInteractionGate.CZ.on(*qubits)
|
|
1081
1081
|
if self.exponent % 2 == 0:
|
|
1082
1082
|
return []
|
|
1083
|
-
return NotImplemented
|
|
1083
|
+
return NotImplemented # pragma: no cover
|
|
1084
1084
|
|
|
1085
1085
|
def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
|
|
1086
1086
|
return [(0, np.diag([1, 1, 1, 0])), (1, np.diag([0, 0, 0, 1]))]
|
|
@@ -1275,7 +1275,7 @@ class CXPowGate(eigen_gate.EigenGate):
|
|
|
1275
1275
|
return PauliInteractionGate.CNOT.on(*qubits)
|
|
1276
1276
|
if self.exponent % 2 == 0:
|
|
1277
1277
|
return []
|
|
1278
|
-
return NotImplemented
|
|
1278
|
+
return NotImplemented # pragma: no cover
|
|
1279
1279
|
|
|
1280
1280
|
def _decompose_(self, qubits):
|
|
1281
1281
|
c, t = qubits
|
cirq/ops/common_gates_test.py
CHANGED
|
@@ -307,6 +307,11 @@ def test_h_str():
|
|
|
307
307
|
assert str(cirq.H**0.5) == 'H**0.5'
|
|
308
308
|
|
|
309
309
|
|
|
310
|
+
def test_phase_exponent():
|
|
311
|
+
assert cirq.XPowGate(exponent=0.5).phase_exponent == 0.0
|
|
312
|
+
assert cirq.YPowGate(exponent=0.5).phase_exponent == 0.5
|
|
313
|
+
|
|
314
|
+
|
|
310
315
|
def test_x_act_on_tableau():
|
|
311
316
|
with pytest.raises(TypeError, match="Failed to act"):
|
|
312
317
|
cirq.act_on(cirq.X, ExampleSimulationState(), qubits=())
|
cirq/ops/control_values.py
CHANGED
|
@@ -275,7 +275,7 @@ class SumOfProducts(AbstractControlValues):
|
|
|
275
275
|
|
|
276
276
|
if len(self._conjunctions) == 1:
|
|
277
277
|
# Use a simpler diagram if there's only 1 term.
|
|
278
|
-
return protocols.CircuitDiagramInfo(
|
|
278
|
+
return protocols.CircuitDiagramInfo( # pragma: no cover
|
|
279
279
|
wire_symbols=["@" if x == 1 else f"({x})" for x in self._conjunctions[0]]
|
|
280
280
|
)
|
|
281
281
|
|
cirq/ops/controlled_gate.py
CHANGED
|
@@ -314,7 +314,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
314
314
|
return None
|
|
315
315
|
u = protocols.unitary(self.sub_gate, default=None)
|
|
316
316
|
if u is None:
|
|
317
|
-
return NotImplemented
|
|
317
|
+
return NotImplemented # pragma: no cover
|
|
318
318
|
angle_list = np.append(np.angle(np.linalg.eigvals(u)), 0)
|
|
319
319
|
return protocols.trace_distance_from_angle_list(angle_list)
|
|
320
320
|
|
cirq/ops/controlled_operation.py
CHANGED
|
@@ -297,7 +297,7 @@ class ControlledOperation(raw_types.Operation):
|
|
|
297
297
|
return None
|
|
298
298
|
u = protocols.unitary(self.sub_operation, default=None)
|
|
299
299
|
if u is None:
|
|
300
|
-
return NotImplemented
|
|
300
|
+
return NotImplemented # pragma: no cover
|
|
301
301
|
angle_list = np.append(np.angle(np.linalg.eigvals(u)), 0)
|
|
302
302
|
return protocols.trace_distance_from_angle_list(angle_list)
|
|
303
303
|
|
|
@@ -159,7 +159,7 @@ def test_str():
|
|
|
159
159
|
return ()
|
|
160
160
|
|
|
161
161
|
def with_qubits(self, *new_qubits: cirq.Qid):
|
|
162
|
-
|
|
162
|
+
return self
|
|
163
163
|
|
|
164
164
|
def __str__(self):
|
|
165
165
|
return "Op(q2)"
|
|
@@ -170,7 +170,11 @@ def test_str():
|
|
|
170
170
|
assert str(cirq.ControlledOperation([c1, c2], SingleQubitOp())) == "CC(c1, c2, Op(q2))"
|
|
171
171
|
|
|
172
172
|
assert (
|
|
173
|
-
str(
|
|
173
|
+
str(
|
|
174
|
+
cirq.ControlledOperation(
|
|
175
|
+
[c1, c2.with_dimension(3)], SingleQubitOp().with_qubits(cirq.q(1))
|
|
176
|
+
)
|
|
177
|
+
)
|
|
174
178
|
== "CC(c1, c2 (d=3), Op(q2))"
|
|
175
179
|
)
|
|
176
180
|
|
cirq/ops/dense_pauli_string.py
CHANGED
|
@@ -627,7 +627,7 @@ def _attempt_value_to_pauli_index(v: 'cirq.Operation') -> Optional[Tuple[int, in
|
|
|
627
627
|
return None
|
|
628
628
|
|
|
629
629
|
if not isinstance(v.gate, pauli_gates.Pauli):
|
|
630
|
-
return None
|
|
630
|
+
return None # pragma: no cover
|
|
631
631
|
|
|
632
632
|
q = v.qubits[0]
|
|
633
633
|
from cirq import devices
|
cirq/ops/eigen_gate.py
CHANGED
|
@@ -302,7 +302,7 @@ class EigenGate(raw_types.Gate):
|
|
|
302
302
|
def __pow__(self, exponent: Union[float, sympy.Symbol]) -> 'EigenGate':
|
|
303
303
|
new_exponent = protocols.mul(self._exponent, exponent, NotImplemented)
|
|
304
304
|
if new_exponent is NotImplemented:
|
|
305
|
-
return NotImplemented
|
|
305
|
+
return NotImplemented # pragma: no cover
|
|
306
306
|
return self._with_exponent(exponent=new_exponent)
|
|
307
307
|
|
|
308
308
|
@property
|
cirq/ops/fourier_transform.py
CHANGED
|
@@ -170,8 +170,6 @@ class PhaseGradientGate(raw_types.Gate):
|
|
|
170
170
|
self, resolver: 'cirq.ParamResolver', recursive: bool
|
|
171
171
|
) -> 'PhaseGradientGate':
|
|
172
172
|
new_exponent = cirq.resolve_parameters(self.exponent, resolver, recursive)
|
|
173
|
-
if new_exponent is self.exponent:
|
|
174
|
-
return self
|
|
175
173
|
return PhaseGradientGate(num_qubits=self._num_qubits, exponent=new_exponent)
|
|
176
174
|
|
|
177
175
|
def __str__(self) -> str:
|
cirq/ops/gate_operation.py
CHANGED
|
@@ -302,7 +302,7 @@ class GateOperation(raw_types.Operation):
|
|
|
302
302
|
def _decompose_into_clifford_(self):
|
|
303
303
|
sub = getattr(self.gate, '_decompose_into_clifford_with_qubits_', None)
|
|
304
304
|
if sub is None:
|
|
305
|
-
return NotImplemented
|
|
305
|
+
return NotImplemented # pragma: no cover
|
|
306
306
|
return sub(self.qubits)
|
|
307
307
|
|
|
308
308
|
def _trace_distance_bound_(self) -> float:
|
cirq/ops/gate_operation_test.py
CHANGED
|
@@ -454,6 +454,7 @@ def test_is_parameterized():
|
|
|
454
454
|
return True
|
|
455
455
|
|
|
456
456
|
q = cirq.LineQubit(0)
|
|
457
|
+
assert No1().num_qubits() == 1
|
|
457
458
|
assert not cirq.is_parameterized(No1().on(q))
|
|
458
459
|
assert not cirq.is_parameterized(No2().on(q))
|
|
459
460
|
assert cirq.is_parameterized(Yes().on(q))
|
cirq/ops/gateset_test.py
CHANGED
|
@@ -443,3 +443,10 @@ def test_gateset_contains_with_tags():
|
|
|
443
443
|
# Both tags to accept and tags to ignore
|
|
444
444
|
assert op in cirq.Gateset(gf_accept, gf_ignore)
|
|
445
445
|
assert op_with_tag in cirq.Gateset(gf_accept, gf_ignore)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def test_gateset_contains_op_with_no_gate():
|
|
449
|
+
gf = cirq.GateFamily(cirq.ZPowGate)
|
|
450
|
+
op = cirq.X(cirq.q(1)).with_classical_controls('a')
|
|
451
|
+
assert op.gate is None
|
|
452
|
+
assert op not in gf
|
|
@@ -90,6 +90,11 @@ ancilla_1: ───X───X───
|
|
|
90
90
|
)
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
def test_empty_qubits():
|
|
94
|
+
qm = cirq.GreedyQubitManager(prefix="anc")
|
|
95
|
+
assert qm.qalloc(0) == []
|
|
96
|
+
|
|
97
|
+
|
|
93
98
|
def test_greedy_qubit_manager_preserves_order():
|
|
94
99
|
qm = cirq.GreedyQubitManager(prefix="anc")
|
|
95
100
|
ancillae = [cirq.q(f"anc_{i}") for i in range(100)]
|
cirq/ops/kraus_channel_test.py
CHANGED
|
@@ -54,6 +54,7 @@ def test_kraus_channel_remap_keys():
|
|
|
54
54
|
kc_x = cirq.KrausChannel.from_channel(dp, key='x')
|
|
55
55
|
assert cirq.with_measurement_key_mapping(kc_x, {'a': 'b'}) is kc_x
|
|
56
56
|
assert cirq.measurement_key_name(cirq.with_key_path(kc_x, ('path',))) == 'path:x'
|
|
57
|
+
assert cirq.measurement_key_name(cirq.with_key_path_prefix(kc_x, ('path',))) == 'path:x'
|
|
57
58
|
|
|
58
59
|
kc_a = cirq.KrausChannel.from_channel(dp, key='a')
|
|
59
60
|
kc_b = cirq.KrausChannel.from_channel(dp, key='b')
|
|
@@ -55,6 +55,7 @@ def test_matrix_mixture_remap_keys():
|
|
|
55
55
|
mm_x = cirq.MixedUnitaryChannel.from_mixture(dp, key='x')
|
|
56
56
|
assert cirq.with_measurement_key_mapping(mm_x, {'a': 'b'}) is mm_x
|
|
57
57
|
assert cirq.measurement_key_name(cirq.with_key_path(mm_x, ('path',))) == 'path:x'
|
|
58
|
+
assert cirq.measurement_key_name(cirq.with_key_path_prefix(mm_x, ('path',))) == 'path:x'
|
|
58
59
|
|
|
59
60
|
mm_a = cirq.MixedUnitaryChannel.from_mixture(dp, key='a')
|
|
60
61
|
mm_b = cirq.MixedUnitaryChannel.from_mixture(dp, key='b')
|
cirq/ops/op_tree_test.py
CHANGED
|
@@ -135,6 +135,10 @@ def test_transform_leaves():
|
|
|
135
135
|
# Just an item.
|
|
136
136
|
assert move_tree_left_freeze(operations[0]) == expected[0]
|
|
137
137
|
|
|
138
|
+
# Just a moment
|
|
139
|
+
m = cirq.Moment(cirq.X(cirq.q(1)))
|
|
140
|
+
assert cirq.transform_op_tree(m, preserve_moments=True) is m
|
|
141
|
+
|
|
138
142
|
# Flat list.
|
|
139
143
|
assert move_tree_left_freeze(operations) == tuple(expected)
|
|
140
144
|
|
cirq/ops/pauli_string.py
CHANGED
|
@@ -311,7 +311,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
311
311
|
)
|
|
312
312
|
|
|
313
313
|
if isinstance(other, raw_types.Operation) and isinstance(other.gate, identity.IdentityGate):
|
|
314
|
-
return self
|
|
314
|
+
return self # pragma: no cover
|
|
315
315
|
|
|
316
316
|
# Note: PauliString case handled by __mul__.
|
|
317
317
|
return NotImplemented
|
|
@@ -462,7 +462,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
462
462
|
fused = prefix + '*'.join(factors)
|
|
463
463
|
if len(factors) > 1:
|
|
464
464
|
return f'({fused})'
|
|
465
|
-
return fused
|
|
465
|
+
return fused # pragma: no cover
|
|
466
466
|
|
|
467
467
|
def __str__(self) -> str:
|
|
468
468
|
ordered_qubits = sorted(self.qubits)
|
|
@@ -1646,88 +1646,11 @@ def _decompose_into_cliffords(op: 'cirq.Operation') -> List['cirq.Operation']:
|
|
|
1646
1646
|
if decomposed is not None:
|
|
1647
1647
|
return [out for sub_op in decomposed for out in _decompose_into_cliffords(sub_op)]
|
|
1648
1648
|
|
|
1649
|
-
raise TypeError(
|
|
1649
|
+
raise TypeError( # pragma: no cover
|
|
1650
1650
|
f'Operation is not a known Clifford and did not decompose into known Cliffords: {op!r}'
|
|
1651
1651
|
)
|
|
1652
1652
|
|
|
1653
1653
|
|
|
1654
|
-
def _pass_operation_over(
|
|
1655
|
-
pauli_map: Dict[TKey, pauli_gates.Pauli], op: 'cirq.Operation', after_to_before: bool = False
|
|
1656
|
-
) -> bool:
|
|
1657
|
-
if isinstance(op, gate_operation.GateOperation):
|
|
1658
|
-
gate = op.gate
|
|
1659
|
-
if isinstance(gate, clifford_gate.SingleQubitCliffordGate):
|
|
1660
|
-
return _pass_single_clifford_gate_over(
|
|
1661
|
-
pauli_map, gate, cast(TKey, op.qubits[0]), after_to_before=after_to_before
|
|
1662
|
-
)
|
|
1663
|
-
if isinstance(gate, pauli_interaction_gate.PauliInteractionGate):
|
|
1664
|
-
return _pass_pauli_interaction_gate_over(
|
|
1665
|
-
pauli_map,
|
|
1666
|
-
gate,
|
|
1667
|
-
cast(TKey, op.qubits[0]),
|
|
1668
|
-
cast(TKey, op.qubits[1]),
|
|
1669
|
-
after_to_before=after_to_before,
|
|
1670
|
-
)
|
|
1671
|
-
raise NotImplementedError(f'Unsupported operation: {op!r}')
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
def _pass_single_clifford_gate_over(
|
|
1675
|
-
pauli_map: Dict[TKey, pauli_gates.Pauli],
|
|
1676
|
-
gate: clifford_gate.SingleQubitCliffordGate,
|
|
1677
|
-
qubit: TKey,
|
|
1678
|
-
after_to_before: bool = False,
|
|
1679
|
-
) -> bool:
|
|
1680
|
-
if qubit not in pauli_map:
|
|
1681
|
-
return False # pragma: no cover
|
|
1682
|
-
if not after_to_before:
|
|
1683
|
-
gate **= -1
|
|
1684
|
-
pauli, inv = gate.pauli_tuple(pauli_map[qubit])
|
|
1685
|
-
pauli_map[qubit] = pauli
|
|
1686
|
-
return inv
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
def _pass_pauli_interaction_gate_over(
|
|
1690
|
-
pauli_map: Dict[TKey, pauli_gates.Pauli],
|
|
1691
|
-
gate: pauli_interaction_gate.PauliInteractionGate,
|
|
1692
|
-
qubit0: TKey,
|
|
1693
|
-
qubit1: TKey,
|
|
1694
|
-
after_to_before: bool = False,
|
|
1695
|
-
) -> bool:
|
|
1696
|
-
def merge_and_kickback(
|
|
1697
|
-
qubit: TKey,
|
|
1698
|
-
pauli_left: Optional[pauli_gates.Pauli],
|
|
1699
|
-
pauli_right: Optional[pauli_gates.Pauli],
|
|
1700
|
-
inv: bool,
|
|
1701
|
-
) -> int:
|
|
1702
|
-
assert pauli_left is not None or pauli_right is not None
|
|
1703
|
-
if pauli_left is None or pauli_right is None:
|
|
1704
|
-
pauli_map[qubit] = cast(pauli_gates.Pauli, pauli_left or pauli_right)
|
|
1705
|
-
return 0
|
|
1706
|
-
if pauli_left == pauli_right:
|
|
1707
|
-
del pauli_map[qubit]
|
|
1708
|
-
return 0
|
|
1709
|
-
|
|
1710
|
-
pauli_map[qubit] = pauli_left.third(pauli_right)
|
|
1711
|
-
if (pauli_left < pauli_right) ^ after_to_before:
|
|
1712
|
-
return int(inv) * 2 + 1
|
|
1713
|
-
|
|
1714
|
-
return int(inv) * 2 - 1
|
|
1715
|
-
|
|
1716
|
-
quarter_kickback = 0
|
|
1717
|
-
if qubit0 in pauli_map and not protocols.commutes(pauli_map[qubit0], gate.pauli0):
|
|
1718
|
-
quarter_kickback += merge_and_kickback(
|
|
1719
|
-
qubit1, gate.pauli1, pauli_map.get(qubit1), gate.invert1
|
|
1720
|
-
)
|
|
1721
|
-
if qubit1 in pauli_map and not protocols.commutes(pauli_map[qubit1], gate.pauli1):
|
|
1722
|
-
quarter_kickback += merge_and_kickback(
|
|
1723
|
-
qubit0, pauli_map.get(qubit0), gate.pauli0, gate.invert0
|
|
1724
|
-
)
|
|
1725
|
-
assert (
|
|
1726
|
-
quarter_kickback % 2 == 0
|
|
1727
|
-
), 'Impossible condition. quarter_kickback is either incremented twice or never.'
|
|
1728
|
-
return quarter_kickback % 4 == 2
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
1654
|
# Mypy has extreme difficulty with these constants for some reason.
|
|
1732
1655
|
_i = cast(identity.IdentityGate, identity.I) # type: ignore
|
|
1733
1656
|
_x = cast(pauli_gates.Pauli, pauli_gates.X) # type: ignore
|
cirq/ops/pauli_string_test.py
CHANGED
|
@@ -1889,6 +1889,48 @@ def test_mutable_pauli_string_inplace_conjugate_by():
|
|
|
1889
1889
|
p2 = p.inplace_after(cirq.S(a))
|
|
1890
1890
|
assert p2 is p and p == cirq.X(a)
|
|
1891
1891
|
|
|
1892
|
+
# After sqrt-X and back.
|
|
1893
|
+
p2 = p.inplace_before(cirq.X(a) ** 0.5)
|
|
1894
|
+
assert p2 is p and p == cirq.X(a)
|
|
1895
|
+
p2 = p.inplace_after(cirq.X(a) ** 0.5)
|
|
1896
|
+
assert p2 is p and p == cirq.X(a)
|
|
1897
|
+
|
|
1898
|
+
# After sqrt-Y and back.
|
|
1899
|
+
p2 = p.inplace_before(cirq.Y(a) ** 0.5)
|
|
1900
|
+
assert p2 is p and p == cirq.Z(a)
|
|
1901
|
+
p2 = p.inplace_after(cirq.Y(a) ** 0.5)
|
|
1902
|
+
assert p2 is p and p == cirq.X(a)
|
|
1903
|
+
|
|
1904
|
+
# After inv-sqrt-Y and back.
|
|
1905
|
+
p2 = p.inplace_before(cirq.Y(a) ** 1.5)
|
|
1906
|
+
assert p2 is p and p == -cirq.Z(a)
|
|
1907
|
+
p2 = p.inplace_after(cirq.Y(a) ** 1.5)
|
|
1908
|
+
assert p2 is p and p == cirq.X(a)
|
|
1909
|
+
|
|
1910
|
+
# After X**0 and back.
|
|
1911
|
+
p2 = p.inplace_before(cirq.X(a) ** 0)
|
|
1912
|
+
assert p2 is p and p == cirq.X(a)
|
|
1913
|
+
p2 = p.inplace_after(cirq.X(a) ** 0)
|
|
1914
|
+
assert p2 is p and p == cirq.X(a)
|
|
1915
|
+
|
|
1916
|
+
# After Y**0 and back.
|
|
1917
|
+
p2 = p.inplace_before(cirq.Y(a) ** 0)
|
|
1918
|
+
assert p2 is p and p == cirq.X(a)
|
|
1919
|
+
p2 = p.inplace_after(cirq.Y(a) ** 0)
|
|
1920
|
+
assert p2 is p and p == cirq.X(a)
|
|
1921
|
+
|
|
1922
|
+
# After Z**0 and back.
|
|
1923
|
+
p2 = p.inplace_before(cirq.Z(a) ** 0)
|
|
1924
|
+
assert p2 is p and p == cirq.X(a)
|
|
1925
|
+
p2 = p.inplace_after(cirq.Z(a) ** 0)
|
|
1926
|
+
assert p2 is p and p == cirq.X(a)
|
|
1927
|
+
|
|
1928
|
+
# After H**0 and back.
|
|
1929
|
+
p2 = p.inplace_before(cirq.H(a) ** 0)
|
|
1930
|
+
assert p2 is p and p == cirq.X(a)
|
|
1931
|
+
p2 = p.inplace_after(cirq.H(a) ** 0)
|
|
1932
|
+
assert p2 is p and p == cirq.X(a)
|
|
1933
|
+
|
|
1892
1934
|
# After inverse S and back.
|
|
1893
1935
|
p2 = p.inplace_after(cirq.S(a) ** -1)
|
|
1894
1936
|
assert p2 is p and p == -cirq.Y(a)
|
|
@@ -1900,6 +1942,10 @@ def test_mutable_pauli_string_inplace_conjugate_by():
|
|
|
1900
1942
|
assert p2 is p and p == cirq.X(a)
|
|
1901
1943
|
|
|
1902
1944
|
# Two qubit operation.
|
|
1945
|
+
p2 = p.inplace_after(cirq.CX(a, b) ** 0)
|
|
1946
|
+
assert p2 is p and p == cirq.X(a)
|
|
1947
|
+
p2 = p.inplace_after(cirq.CZ(a, b) ** 0)
|
|
1948
|
+
assert p2 is p and p == cirq.X(a)
|
|
1903
1949
|
p2 = p.inplace_after(cirq.CZ(a, b))
|
|
1904
1950
|
assert p2 is p and p == cirq.X(a) * cirq.Z(b)
|
|
1905
1951
|
p2 = p.inplace_after(cirq.CZ(a, c))
|
cirq/ops/phased_x_gate.py
CHANGED
|
@@ -116,7 +116,7 @@ class PhasedXPowGate(raw_types.Gate):
|
|
|
116
116
|
def __pow__(self, exponent: Union[float, sympy.Expr]) -> 'PhasedXPowGate':
|
|
117
117
|
new_exponent = protocols.mul(self._exponent, exponent, NotImplemented)
|
|
118
118
|
if new_exponent is NotImplemented:
|
|
119
|
-
return NotImplemented
|
|
119
|
+
return NotImplemented # pragma: no cover
|
|
120
120
|
return PhasedXPowGate(
|
|
121
121
|
phase_exponent=self._phase_exponent,
|
|
122
122
|
exponent=new_exponent,
|
|
@@ -150,12 +150,6 @@ def test_mixture():
|
|
|
150
150
|
assert {p for p, _ in m} == {7 / 8, 1 / 32, 3 / 32}
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
def assert_channel_sums_to_identity(val):
|
|
154
|
-
m = cirq.kraus(val)
|
|
155
|
-
s = sum(np.conj(e.T) @ e for e in m)
|
|
156
|
-
np.testing.assert_allclose(s, np.eye(np.prod(cirq.qid_shape(val), dtype=np.int64)), atol=1e-8)
|
|
157
|
-
|
|
158
|
-
|
|
159
153
|
def test_channel():
|
|
160
154
|
class NoDetailsGate(cirq.Gate):
|
|
161
155
|
def num_qubits(self) -> int:
|
cirq/ops/raw_types.py
CHANGED
|
@@ -902,7 +902,7 @@ class TaggedOperation(Operation):
|
|
|
902
902
|
sub = getattr(self.sub_operation, "_is_measurement_", None)
|
|
903
903
|
if sub is not None:
|
|
904
904
|
return sub()
|
|
905
|
-
return NotImplemented
|
|
905
|
+
return NotImplemented # pragma: no cover
|
|
906
906
|
|
|
907
907
|
@cached_method
|
|
908
908
|
def _is_parameterized_(self) -> bool:
|
cirq/ops/raw_types_test.py
CHANGED
|
@@ -77,6 +77,13 @@ def test_wrapped_qid():
|
|
|
77
77
|
'dimension': 3,
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
assert not ValidQubit('zz') == 4
|
|
81
|
+
assert ValidQubit('zz') != 4
|
|
82
|
+
assert ValidQubit('zz') > ValidQubit('aa')
|
|
83
|
+
assert ValidQubit('zz') <= ValidQubit('zz')
|
|
84
|
+
assert ValidQubit('zz') >= ValidQubit('zz')
|
|
85
|
+
assert ValidQubit('zz') >= ValidQubit('aa')
|
|
86
|
+
|
|
80
87
|
|
|
81
88
|
def test_qid_dimension():
|
|
82
89
|
assert ValidQubit('a').dimension == 2
|
|
@@ -210,6 +217,21 @@ def test_default_validation_and_inverse():
|
|
|
210
217
|
cirq.testing.assert_implements_consistent_protocols(i, local_vals={'TestGate': TestGate})
|
|
211
218
|
|
|
212
219
|
|
|
220
|
+
def test_default_no_qubits():
|
|
221
|
+
class TestOp(cirq.Operation):
|
|
222
|
+
def with_qubits(self, *new_qubits):
|
|
223
|
+
raise NotImplementedError()
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def qubits(self):
|
|
227
|
+
pass
|
|
228
|
+
|
|
229
|
+
op = TestOp()
|
|
230
|
+
assert op.controlled_by(*[]) is op
|
|
231
|
+
op = TestOp().with_tags("abc")
|
|
232
|
+
assert op.classical_controls == frozenset()
|
|
233
|
+
|
|
234
|
+
|
|
213
235
|
def test_default_inverse():
|
|
214
236
|
class TestGate(cirq.Gate):
|
|
215
237
|
def _num_qubits_(self):
|
|
@@ -357,7 +379,7 @@ def test_gate_shape_protocol():
|
|
|
357
379
|
def test_operation_shape():
|
|
358
380
|
class FixedQids(cirq.Operation):
|
|
359
381
|
def with_qubits(self, *new_qids):
|
|
360
|
-
raise NotImplementedError
|
|
382
|
+
raise NotImplementedError
|
|
361
383
|
|
|
362
384
|
class QubitOp(FixedQids):
|
|
363
385
|
@property
|
|
@@ -659,6 +681,9 @@ def test_tagged_operation_forwards_protocols():
|
|
|
659
681
|
assert isinstance(controlled_y, cirq.Operation)
|
|
660
682
|
assert not isinstance(controlled_y, cirq.TaggedOperation)
|
|
661
683
|
classically_controlled_y = tagged_y.with_classical_controls("a")
|
|
684
|
+
assert classically_controlled_y.classical_controls == frozenset(
|
|
685
|
+
{cirq.KeyCondition(cirq.MeasurementKey(name='a'))}
|
|
686
|
+
)
|
|
662
687
|
assert classically_controlled_y == y.with_classical_controls("a")
|
|
663
688
|
assert isinstance(classically_controlled_y, cirq.Operation)
|
|
664
689
|
assert not isinstance(classically_controlled_y, cirq.TaggedOperation)
|
|
@@ -80,7 +80,8 @@ def test_via_apply_unitary():
|
|
|
80
80
|
|
|
81
81
|
class No4: # A non-operation non-gate.
|
|
82
82
|
def _apply_unitary_(self, args):
|
|
83
|
-
|
|
83
|
+
# Because has_unitary doesn't understand how to call.
|
|
84
|
+
assert False # pragma: no cover
|
|
84
85
|
|
|
85
86
|
class Yes1(EmptyOp):
|
|
86
87
|
def _apply_unitary_(self, args):
|
|
@@ -155,13 +156,13 @@ def test_order():
|
|
|
155
156
|
return True
|
|
156
157
|
|
|
157
158
|
def _decompose_(self):
|
|
158
|
-
assert False
|
|
159
|
+
assert False # pragma: no cover
|
|
159
160
|
|
|
160
161
|
def _apply_unitary_(self, args):
|
|
161
|
-
assert False
|
|
162
|
+
assert False # pragma: no cover
|
|
162
163
|
|
|
163
164
|
def _unitary_(self):
|
|
164
|
-
assert False
|
|
165
|
+
assert False # pragma: no cover
|
|
165
166
|
|
|
166
167
|
class Yes2(EmptyOp):
|
|
167
168
|
def _has_unitary_(self):
|
|
@@ -171,10 +172,10 @@ def test_order():
|
|
|
171
172
|
return []
|
|
172
173
|
|
|
173
174
|
def _apply_unitary_(self, args):
|
|
174
|
-
assert False
|
|
175
|
+
assert False # pragma: no cover
|
|
175
176
|
|
|
176
177
|
def _unitary_(self):
|
|
177
|
-
assert False
|
|
178
|
+
assert False # pragma: no cover
|
|
178
179
|
|
|
179
180
|
class Yes3(EmptyOp):
|
|
180
181
|
def _has_unitary_(self):
|
|
@@ -187,7 +188,7 @@ def test_order():
|
|
|
187
188
|
return args.target_tensor
|
|
188
189
|
|
|
189
190
|
def _unitary_(self):
|
|
190
|
-
assert False
|
|
191
|
+
assert False # pragma: no cover
|
|
191
192
|
|
|
192
193
|
class Yes4(EmptyOp):
|
|
193
194
|
def _has_unitary_(self):
|
|
@@ -84,20 +84,20 @@ def test_deprecated_cirq_type_in_json_dict():
|
|
|
84
84
|
__module__ = 'test.noncirq.namespace'
|
|
85
85
|
|
|
86
86
|
def __eq__(self, other):
|
|
87
|
-
return isinstance(other, HasOldJsonDict)
|
|
87
|
+
return isinstance(other, HasOldJsonDict) # pragma: no cover
|
|
88
88
|
|
|
89
89
|
def _json_dict_(self):
|
|
90
90
|
return {'cirq_type': 'test.noncirq.namespace.HasOldJsonDict'}
|
|
91
91
|
|
|
92
92
|
@classmethod
|
|
93
93
|
def _from_json_dict_(cls, **kwargs):
|
|
94
|
-
return cls()
|
|
94
|
+
return cls() # pragma: no cover
|
|
95
95
|
|
|
96
96
|
with pytest.raises(ValueError, match='not a Cirq type'):
|
|
97
97
|
_ = cirq.json_cirq_type(HasOldJsonDict)
|
|
98
98
|
|
|
99
99
|
def custom_resolver(name):
|
|
100
|
-
if name == 'test.noncirq.namespace.HasOldJsonDict':
|
|
100
|
+
if name == 'test.noncirq.namespace.HasOldJsonDict': # pragma: no cover
|
|
101
101
|
return HasOldJsonDict
|
|
102
102
|
|
|
103
103
|
test_resolvers = [custom_resolver] + cirq.DEFAULT_RESOLVERS
|
|
@@ -283,6 +283,7 @@ def test_builtins():
|
|
|
283
283
|
def test_numpy():
|
|
284
284
|
x = np.ones(1)[0]
|
|
285
285
|
|
|
286
|
+
assert_json_roundtrip_works(np.bool_(True))
|
|
286
287
|
assert_json_roundtrip_works(x.astype(np.int8))
|
|
287
288
|
assert_json_roundtrip_works(x.astype(np.int16))
|
|
288
289
|
assert_json_roundtrip_works(x.astype(np.int32))
|
|
@@ -367,7 +368,7 @@ class SBKImpl(cirq.SerializableByKey):
|
|
|
367
368
|
|
|
368
369
|
def __eq__(self, other):
|
|
369
370
|
if not isinstance(other, SBKImpl):
|
|
370
|
-
return False
|
|
371
|
+
return False # pragma: no cover
|
|
371
372
|
return (
|
|
372
373
|
self.name == other.name
|
|
373
374
|
and self.data_list == other.data_list
|
|
@@ -542,7 +543,7 @@ def test_type_serialization(mod_spec: ModuleJsonTestSpec, cirq_obj_name: str, cl
|
|
|
542
543
|
return pytest.xfail(reason="Not serializable (yet)")
|
|
543
544
|
|
|
544
545
|
if cls is None:
|
|
545
|
-
pytest.skip(f'No serialization for None-mapped type: {cirq_obj_name}')
|
|
546
|
+
pytest.skip(f'No serialization for None-mapped type: {cirq_obj_name}') # pragma: no cover
|
|
546
547
|
|
|
547
548
|
try:
|
|
548
549
|
typename = cirq.json_cirq_type(cls)
|
|
@@ -614,7 +615,7 @@ def _eval_repr_data_file(path: pathlib.Path, deprecation_deadline: Optional[str]
|
|
|
614
615
|
|
|
615
616
|
for deprecation in TESTED_MODULES.values():
|
|
616
617
|
if deprecation is not None and deprecation.old_name in content:
|
|
617
|
-
ctx_managers.append(deprecation.deprecation_assertion)
|
|
618
|
+
ctx_managers.append(deprecation.deprecation_assertion) # pragma: no cover
|
|
618
619
|
|
|
619
620
|
imports = {'cirq': cirq, 'pd': pd, 'sympy': sympy, 'np': np, 'datetime': datetime, 'nx': nx}
|
|
620
621
|
|
cirq/protocols/kraus_protocol.py
CHANGED
|
@@ -132,7 +132,7 @@ def kraus(
|
|
|
132
132
|
"""
|
|
133
133
|
channel_getter = getattr(val, '_channel_', None)
|
|
134
134
|
if channel_getter is not None:
|
|
135
|
-
warnings.warn(
|
|
135
|
+
warnings.warn( # pragma: no cover
|
|
136
136
|
'_channel_ is deprecated and will be removed in cirq 0.13, rename to _kraus_',
|
|
137
137
|
DeprecationWarning,
|
|
138
138
|
)
|
|
@@ -154,7 +154,7 @@ def kraus(
|
|
|
154
154
|
|
|
155
155
|
channel_result = NotImplemented if channel_getter is None else channel_getter()
|
|
156
156
|
if channel_result is not NotImplemented:
|
|
157
|
-
return tuple(channel_result)
|
|
157
|
+
return tuple(channel_result) # pragma: no cover
|
|
158
158
|
|
|
159
159
|
if default is not RaiseTypeErrorIfNotProvided:
|
|
160
160
|
return default
|