cirq-core 1.1.0.dev20221219200817__py3-none-any.whl → 1.2.0__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.
- cirq/__init__.py +8 -0
- cirq/_compat.py +29 -4
- cirq/_compat_test.py +24 -26
- cirq/_version.py +32 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/_block_diagram_drawer_test.py +4 -3
- cirq/circuits/circuit.py +109 -63
- cirq/circuits/circuit_operation.py +2 -3
- cirq/circuits/circuit_operation_test.py +4 -4
- cirq/circuits/circuit_test.py +11 -0
- cirq/circuits/frozen_circuit.py +13 -1
- cirq/circuits/frozen_circuit_test.py +5 -1
- cirq/circuits/moment.py +39 -14
- cirq/circuits/moment_test.py +7 -0
- cirq/circuits/text_diagram_drawer.py +1 -1
- cirq/circuits/text_diagram_drawer_test.py +3 -7
- cirq/conftest.py +8 -0
- cirq/contrib/acquaintance/bipartite.py +1 -1
- cirq/contrib/acquaintance/devices.py +2 -2
- cirq/contrib/acquaintance/executor.py +5 -2
- cirq/contrib/acquaintance/gates.py +3 -2
- cirq/contrib/acquaintance/permutation.py +13 -2
- cirq/contrib/acquaintance/testing.py +3 -5
- cirq/contrib/paulistring/recombine.py +3 -6
- cirq/contrib/qasm_import/_parser.py +17 -21
- cirq/contrib/qasm_import/_parser_test.py +30 -45
- cirq/contrib/qcircuit/qcircuit_test.py +3 -7
- cirq/contrib/quantum_volume/quantum_volume.py +3 -3
- cirq/contrib/quimb/mps_simulator.py +1 -1
- cirq/contrib/quimb/state_vector.py +2 -0
- cirq/contrib/quirk/quirk_gate.py +1 -0
- cirq/contrib/svg/svg.py +4 -7
- cirq/contrib/svg/svg_test.py +29 -1
- cirq/devices/grid_qubit.py +26 -28
- cirq/devices/grid_qubit_test.py +21 -5
- cirq/devices/line_qubit.py +10 -12
- cirq/devices/line_qubit_test.py +9 -2
- cirq/devices/named_topologies.py +1 -1
- cirq/devices/noise_model.py +4 -1
- cirq/devices/superconducting_qubits_noise_properties.py +1 -3
- cirq/experiments/n_qubit_tomography.py +1 -1
- cirq/experiments/qubit_characterizations.py +2 -2
- cirq/experiments/single_qubit_readout_calibration.py +1 -1
- cirq/experiments/t2_decay_experiment.py +1 -1
- cirq/experiments/xeb_simulation_test.py +2 -2
- cirq/interop/quirk/cells/testing.py +1 -1
- cirq/json_resolver_cache.py +1 -0
- cirq/linalg/__init__.py +2 -0
- cirq/linalg/decompositions_test.py +4 -4
- cirq/linalg/diagonalize_test.py +5 -6
- cirq/linalg/transformations.py +72 -9
- cirq/linalg/transformations_test.py +23 -7
- cirq/ops/__init__.py +4 -0
- cirq/ops/arithmetic_operation.py +4 -6
- cirq/ops/classically_controlled_operation.py +10 -3
- cirq/ops/clifford_gate.py +1 -7
- cirq/ops/common_channels.py +21 -15
- cirq/ops/common_gate_families.py +2 -3
- cirq/ops/common_gates.py +48 -11
- cirq/ops/common_gates_test.py +4 -0
- cirq/ops/controlled_gate.py +44 -18
- cirq/ops/controlled_operation.py +13 -5
- cirq/ops/dense_pauli_string.py +14 -19
- cirq/ops/diagonal_gate.py +3 -4
- cirq/ops/eigen_gate.py +8 -10
- cirq/ops/eigen_gate_test.py +6 -0
- cirq/ops/gate_operation.py +11 -6
- cirq/ops/gate_operation_test.py +11 -2
- cirq/ops/gateset.py +2 -1
- cirq/ops/gateset_test.py +38 -5
- cirq/ops/global_phase_op.py +28 -2
- cirq/ops/global_phase_op_test.py +21 -0
- cirq/ops/identity.py +1 -1
- cirq/ops/kraus_channel_test.py +2 -2
- cirq/ops/linear_combinations.py +7 -6
- cirq/ops/linear_combinations_test.py +26 -10
- cirq/ops/matrix_gates.py +8 -4
- cirq/ops/matrix_gates_test.py +25 -3
- cirq/ops/measure_util.py +13 -5
- cirq/ops/measure_util_test.py +8 -2
- cirq/ops/measurement_gate.py +1 -1
- cirq/ops/measurement_gate_test.py +9 -4
- cirq/ops/mixed_unitary_channel_test.py +4 -4
- cirq/ops/named_qubit.py +2 -4
- cirq/ops/parity_gates.py +5 -1
- cirq/ops/parity_gates_test.py +6 -0
- cirq/ops/pauli_gates.py +9 -9
- cirq/ops/pauli_string.py +4 -2
- cirq/ops/pauli_string_raw_types.py +4 -11
- cirq/ops/pauli_string_test.py +13 -13
- cirq/ops/pauli_sum_exponential.py +6 -1
- cirq/ops/qubit_manager.py +97 -0
- cirq/ops/qubit_manager_test.py +66 -0
- cirq/ops/raw_types.py +75 -33
- cirq/ops/raw_types_test.py +34 -0
- cirq/ops/three_qubit_gates.py +16 -10
- cirq/ops/three_qubit_gates_test.py +4 -2
- cirq/ops/two_qubit_diagonal_gate.py +3 -3
- cirq/ops/wait_gate.py +1 -1
- cirq/protocols/__init__.py +1 -0
- cirq/protocols/act_on_protocol.py +3 -3
- cirq/protocols/act_on_protocol_test.py +5 -5
- cirq/protocols/apply_channel_protocol.py +9 -8
- cirq/protocols/apply_mixture_protocol.py +8 -8
- cirq/protocols/apply_mixture_protocol_test.py +1 -1
- cirq/protocols/apply_unitary_protocol.py +66 -19
- cirq/protocols/apply_unitary_protocol_test.py +50 -0
- cirq/protocols/circuit_diagram_info_protocol.py +7 -9
- cirq/protocols/decompose_protocol.py +167 -125
- cirq/protocols/decompose_protocol_test.py +132 -2
- cirq/protocols/has_stabilizer_effect_protocol.py +2 -1
- cirq/protocols/inverse_protocol.py +2 -2
- cirq/protocols/json_serialization_test.py +3 -3
- cirq/protocols/json_test_data/Linspace.json +20 -7
- cirq/protocols/json_test_data/Linspace.repr +4 -1
- cirq/protocols/json_test_data/Points.json +19 -8
- cirq/protocols/json_test_data/Points.repr +4 -1
- cirq/protocols/json_test_data/Result.repr_inward +1 -1
- cirq/protocols/json_test_data/ResultDict.repr +1 -1
- cirq/protocols/json_test_data/ResultDict.repr_inward +1 -1
- cirq/protocols/json_test_data/TrialResult.repr_inward +1 -1
- cirq/protocols/json_test_data/XPowGate.json +13 -5
- cirq/protocols/json_test_data/XPowGate.repr +1 -1
- cirq/protocols/json_test_data/ZPowGate.json +13 -5
- cirq/protocols/json_test_data/ZPowGate.repr +1 -1
- cirq/protocols/json_test_data/ZipLongest.json +19 -0
- cirq/protocols/json_test_data/ZipLongest.repr +1 -0
- cirq/protocols/json_test_data/spec.py +1 -0
- cirq/protocols/kraus_protocol.py +3 -4
- cirq/protocols/measurement_key_protocol.py +3 -1
- cirq/protocols/mixture_protocol.py +3 -2
- cirq/protocols/phase_protocol.py +3 -3
- cirq/protocols/pow_protocol.py +1 -2
- cirq/protocols/qasm.py +4 -4
- cirq/protocols/qid_shape_protocol.py +8 -8
- cirq/protocols/resolve_parameters.py +8 -3
- cirq/protocols/resolve_parameters_test.py +3 -3
- cirq/protocols/unitary_protocol.py +19 -11
- cirq/protocols/unitary_protocol_test.py +37 -0
- cirq/qis/channels.py +1 -1
- cirq/qis/clifford_tableau.py +4 -5
- cirq/qis/quantum_state_representation.py +7 -9
- cirq/qis/states.py +21 -13
- cirq/qis/states_test.py +7 -0
- cirq/sim/clifford/clifford_simulator.py +3 -3
- cirq/sim/density_matrix_simulation_state.py +2 -1
- cirq/sim/density_matrix_simulator.py +1 -1
- cirq/sim/density_matrix_simulator_test.py +9 -5
- cirq/sim/density_matrix_utils.py +7 -32
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +58 -18
- cirq/sim/simulation_state_base.py +5 -2
- cirq/sim/simulation_state_test.py +121 -9
- cirq/sim/simulation_utils.py +59 -0
- cirq/sim/simulation_utils_test.py +32 -0
- cirq/sim/simulator.py +2 -1
- cirq/sim/simulator_base_test.py +3 -3
- cirq/sim/sparse_simulator.py +1 -1
- cirq/sim/sparse_simulator_test.py +5 -5
- cirq/sim/state_vector.py +7 -36
- cirq/sim/state_vector_simulation_state.py +18 -1
- cirq/sim/state_vector_simulator.py +3 -2
- cirq/sim/state_vector_simulator_test.py +24 -2
- cirq/sim/state_vector_test.py +46 -15
- cirq/study/__init__.py +1 -0
- cirq/study/flatten_expressions.py +2 -2
- cirq/study/resolver.py +2 -0
- cirq/study/resolver_test.py +1 -1
- cirq/study/result.py +1 -1
- cirq/study/sweeps.py +103 -9
- cirq/study/sweeps_test.py +64 -0
- cirq/testing/__init__.py +4 -0
- cirq/testing/circuit_compare.py +15 -18
- cirq/testing/consistent_act_on.py +4 -4
- cirq/testing/consistent_controlled_gate_op_test.py +1 -1
- cirq/testing/consistent_decomposition.py +11 -2
- cirq/testing/consistent_decomposition_test.py +8 -1
- cirq/testing/consistent_protocols.py +2 -0
- cirq/testing/consistent_protocols_test.py +8 -4
- cirq/testing/consistent_qasm.py +8 -15
- cirq/testing/consistent_specified_has_unitary.py +1 -1
- cirq/testing/consistent_unitary.py +85 -0
- cirq/testing/consistent_unitary_test.py +96 -0
- cirq/testing/equivalent_repr_eval.py +10 -10
- cirq/testing/json.py +3 -3
- cirq/testing/logs.py +1 -1
- cirq/testing/order_tester.py +4 -5
- cirq/testing/random_circuit.py +3 -5
- cirq/testing/sample_gates.py +79 -0
- cirq/testing/sample_gates_test.py +59 -0
- cirq/transformers/__init__.py +2 -0
- cirq/transformers/analytical_decompositions/__init__.py +8 -0
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +130 -0
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +58 -0
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +230 -0
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +112 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -3
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/expand_composite.py +1 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +4 -4
- cirq/transformers/measurement_transformers.py +4 -4
- cirq/transformers/merge_single_qubit_gates.py +17 -4
- cirq/transformers/routing/route_circuit_cqc.py +2 -2
- cirq/transformers/stratify.py +125 -62
- cirq/transformers/stratify_test.py +20 -16
- cirq/transformers/transformer_api.py +1 -1
- cirq/transformers/transformer_primitives.py +3 -2
- cirq/transformers/transformer_primitives_test.py +11 -0
- cirq/value/abc_alt.py +3 -2
- cirq/value/abc_alt_test.py +1 -0
- cirq/value/classical_data.py +10 -10
- cirq/value/digits.py +2 -2
- cirq/value/linear_dict.py +18 -19
- cirq/value/product_state.py +7 -6
- cirq/value/value_equality_attr.py +2 -2
- cirq/vis/heatmap.py +1 -1
- cirq/vis/heatmap_test.py +2 -2
- cirq/work/collector.py +2 -2
- cirq/work/observable_measurement_data.py +5 -5
- cirq/work/observable_readout_calibration.py +3 -1
- cirq/work/observable_settings.py +1 -1
- cirq/work/pauli_sum_collector.py +9 -8
- cirq/work/sampler.py +2 -0
- cirq/work/zeros_sampler.py +2 -2
- {cirq_core-1.1.0.dev20221219200817.dist-info → cirq_core-1.2.0.dist-info}/METADATA +7 -15
- {cirq_core-1.1.0.dev20221219200817.dist-info → cirq_core-1.2.0.dist-info}/RECORD +229 -215
- {cirq_core-1.1.0.dev20221219200817.dist-info → cirq_core-1.2.0.dist-info}/WHEEL +1 -1
- {cirq_core-1.1.0.dev20221219200817.dist-info → cirq_core-1.2.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.1.0.dev20221219200817.dist-info → cirq_core-1.2.0.dist-info}/top_level.txt +0 -0
cirq/study/sweeps_test.py
CHANGED
|
@@ -77,6 +77,64 @@ def test_zip():
|
|
|
77
77
|
assert _values(sweep, 'b') == [4, 5, 6]
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
def test_zip_longest():
|
|
81
|
+
sweep = cirq.ZipLongest(cirq.Points('a', [1, 2, 3]), cirq.Points('b', [4, 5, 6, 7]))
|
|
82
|
+
assert tuple(sweep.param_tuples()) == (
|
|
83
|
+
(('a', 1), ('b', 4)),
|
|
84
|
+
(('a', 2), ('b', 5)),
|
|
85
|
+
(('a', 3), ('b', 6)),
|
|
86
|
+
(('a', 3), ('b', 7)),
|
|
87
|
+
)
|
|
88
|
+
assert sweep.keys == ['a', 'b']
|
|
89
|
+
assert (
|
|
90
|
+
str(sweep) == 'ZipLongest(cirq.Points(\'a\', [1, 2, 3]), cirq.Points(\'b\', [4, 5, 6, 7]))'
|
|
91
|
+
)
|
|
92
|
+
assert (
|
|
93
|
+
repr(sweep)
|
|
94
|
+
== 'cirq_google.ZipLongest(cirq.Points(\'a\', [1, 2, 3]), cirq.Points(\'b\', [4, 5, 6, 7]))'
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_zip_longest_compatibility():
|
|
99
|
+
sweep = cirq.Zip(cirq.Points('a', [1, 2, 3]), cirq.Points('b', [4, 5, 6]))
|
|
100
|
+
sweep_longest = cirq.ZipLongest(cirq.Points('a', [1, 2, 3]), cirq.Points('b', [4, 5, 6]))
|
|
101
|
+
assert tuple(sweep.param_tuples()) == tuple(sweep_longest.param_tuples())
|
|
102
|
+
|
|
103
|
+
sweep = cirq.Zip(
|
|
104
|
+
(cirq.Points('a', [1, 3]) * cirq.Points('b', [2, 4])), cirq.Points('c', [4, 5, 6, 7])
|
|
105
|
+
)
|
|
106
|
+
sweep_longest = cirq.ZipLongest(
|
|
107
|
+
(cirq.Points('a', [1, 3]) * cirq.Points('b', [2, 4])), cirq.Points('c', [4, 5, 6, 7])
|
|
108
|
+
)
|
|
109
|
+
assert tuple(sweep.param_tuples()) == tuple(sweep_longest.param_tuples())
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_empty_zip():
|
|
113
|
+
assert len(cirq.ZipLongest()) == 0
|
|
114
|
+
with pytest.raises(ValueError, match='non-empty'):
|
|
115
|
+
_ = cirq.ZipLongest(cirq.Points('e', []), cirq.Points('a', [1, 2, 3]))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_zip_eq():
|
|
119
|
+
et = cirq.testing.EqualsTester()
|
|
120
|
+
point_sweep1 = cirq.Points('a', [1, 2, 3])
|
|
121
|
+
point_sweep2 = cirq.Points('b', [4, 5, 6, 7])
|
|
122
|
+
point_sweep3 = cirq.Points('c', [1, 2])
|
|
123
|
+
|
|
124
|
+
et.add_equality_group(cirq.ZipLongest(), cirq.ZipLongest())
|
|
125
|
+
|
|
126
|
+
et.add_equality_group(
|
|
127
|
+
cirq.ZipLongest(point_sweep1, point_sweep2), cirq.ZipLongest(point_sweep1, point_sweep2)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
et.add_equality_group(cirq.ZipLongest(point_sweep3, point_sweep2))
|
|
131
|
+
et.add_equality_group(cirq.ZipLongest(point_sweep2, point_sweep1))
|
|
132
|
+
et.add_equality_group(cirq.ZipLongest(point_sweep1, point_sweep2, point_sweep3))
|
|
133
|
+
|
|
134
|
+
et.add_equality_group(cirq.Zip(point_sweep1, point_sweep2, point_sweep3))
|
|
135
|
+
et.add_equality_group(cirq.Zip(point_sweep1, point_sweep2))
|
|
136
|
+
|
|
137
|
+
|
|
80
138
|
def test_product():
|
|
81
139
|
sweep = cirq.Points('a', [1, 2, 3]) * cirq.Points('b', [4, 5, 6, 7])
|
|
82
140
|
assert len(sweep) == 12
|
|
@@ -215,6 +273,12 @@ def test_repr():
|
|
|
215
273
|
)
|
|
216
274
|
cirq.testing.assert_equivalent_repr(cirq.Points('zero&pi', [0, 3.14159]))
|
|
217
275
|
cirq.testing.assert_equivalent_repr(cirq.Linspace('I/10', 0, 1, 10))
|
|
276
|
+
cirq.testing.assert_equivalent_repr(
|
|
277
|
+
cirq.Points('zero&pi', [0, 3.14159], metadata='example str')
|
|
278
|
+
)
|
|
279
|
+
cirq.testing.assert_equivalent_repr(
|
|
280
|
+
cirq.Linspace('for_q0', 0, 1, 10, metadata=cirq.LineQubit(0))
|
|
281
|
+
)
|
|
218
282
|
|
|
219
283
|
|
|
220
284
|
def test_zip_product_str():
|
cirq/testing/__init__.py
CHANGED
|
@@ -107,3 +107,7 @@ from cirq.testing.routing_devices import (
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
from cirq.testing.sample_circuits import nonoptimal_toffoli_circuit
|
|
110
|
+
|
|
111
|
+
from cirq.testing.sample_gates import PhaseUsingCleanAncilla, PhaseUsingDirtyAncilla
|
|
112
|
+
|
|
113
|
+
from cirq.testing.consistent_unitary import assert_unitary_is_consistent
|
cirq/testing/circuit_compare.py
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
|
|
15
16
|
|
|
16
17
|
from collections import defaultdict
|
|
@@ -175,10 +176,10 @@ def assert_circuits_with_terminal_measurements_are_equivalent(
|
|
|
175
176
|
"Circuit's effect differs from the reference circuit.\n"
|
|
176
177
|
'\n'
|
|
177
178
|
'Diagram of actual circuit:\n'
|
|
178
|
-
'{}\n'
|
|
179
|
+
f'{actual}\n'
|
|
179
180
|
'\n'
|
|
180
181
|
'Diagram of reference circuit with desired function:\n'
|
|
181
|
-
'{}\n'
|
|
182
|
+
f'{reference}\n'
|
|
182
183
|
)
|
|
183
184
|
|
|
184
185
|
|
|
@@ -195,20 +196,20 @@ def assert_same_circuits(
|
|
|
195
196
|
"Actual circuit differs from expected circuit.\n"
|
|
196
197
|
"\n"
|
|
197
198
|
"Diagram of actual circuit:\n"
|
|
198
|
-
"{}\n"
|
|
199
|
+
f"{actual}\n"
|
|
199
200
|
"\n"
|
|
200
201
|
"Diagram of expected circuit:\n"
|
|
201
|
-
"{}\n"
|
|
202
|
+
f"{expected}\n"
|
|
202
203
|
"\n"
|
|
203
204
|
"Index of first differing moment:\n"
|
|
204
|
-
"{}\n"
|
|
205
|
+
f"{_first_differing_moment_index(actual, expected)}\n"
|
|
205
206
|
"\n"
|
|
206
207
|
"Full repr of actual circuit:\n"
|
|
207
|
-
"{!r}\n"
|
|
208
|
+
f"{actual!r}\n"
|
|
208
209
|
"\n"
|
|
209
210
|
"Full repr of expected circuit:\n"
|
|
210
|
-
"{!r}\n"
|
|
211
|
-
)
|
|
211
|
+
f"{expected!r}\n"
|
|
212
|
+
)
|
|
212
213
|
|
|
213
214
|
|
|
214
215
|
def _first_differing_moment_index(
|
|
@@ -237,7 +238,7 @@ def assert_circuits_have_same_unitary_given_final_permutation(
|
|
|
237
238
|
ValueError: if 'qubit_map' does not have the same set of keys and values.
|
|
238
239
|
"""
|
|
239
240
|
if set(qubit_map.keys()) != set(qubit_map.values()):
|
|
240
|
-
raise ValueError("'qubit_map' must have the same set of
|
|
241
|
+
raise ValueError("'qubit_map' must have the same set of keys and values.")
|
|
241
242
|
|
|
242
243
|
if not set(qubit_map.keys()).issubset(actual.all_qubits()):
|
|
243
244
|
raise ValueError(
|
|
@@ -275,17 +276,13 @@ def assert_has_diagram(
|
|
|
275
276
|
"Circuit's text diagram differs from the desired diagram.\n"
|
|
276
277
|
'\n'
|
|
277
278
|
'Diagram of actual circuit:\n'
|
|
278
|
-
'{}\n'
|
|
279
|
+
f'{actual_diagram}\n'
|
|
279
280
|
'\n'
|
|
280
281
|
'Desired text diagram:\n'
|
|
281
|
-
'{}\n'
|
|
282
|
+
f'{desired_diagram}\n'
|
|
282
283
|
'\n'
|
|
283
284
|
'Highlighted differences:\n'
|
|
284
|
-
'{}\n'
|
|
285
|
-
actual_diagram,
|
|
286
|
-
desired_diagram,
|
|
287
|
-
highlight_text_differences(actual_diagram, desired_diagram),
|
|
288
|
-
)
|
|
285
|
+
f'{highlight_text_differences(actual_diagram, desired_diagram)}\n'
|
|
289
286
|
)
|
|
290
287
|
|
|
291
288
|
|
|
@@ -329,7 +326,7 @@ def assert_has_consistent_apply_unitary(val: Any, *, atol: float = 1e-8) -> None
|
|
|
329
326
|
# If you applied a unitary, it should match the one you say you have.
|
|
330
327
|
if actual is not None:
|
|
331
328
|
assert expected is not None
|
|
332
|
-
n = np.
|
|
329
|
+
n = np.prod([2, *qid_shape])
|
|
333
330
|
np.testing.assert_allclose(actual.reshape(n, n), expected, atol=atol)
|
|
334
331
|
|
|
335
332
|
|
|
@@ -373,7 +370,7 @@ def assert_has_consistent_apply_channel(val: Any, *, atol: float = 1e-8) -> None
|
|
|
373
370
|
# If you applied a channel, it should match the superoperator you say you have.
|
|
374
371
|
if actual is not None:
|
|
375
372
|
assert expected is not None
|
|
376
|
-
n = np.
|
|
373
|
+
n = np.prod(qid_shape) ** 2
|
|
377
374
|
np.testing.assert_allclose(actual.reshape((n, n)), expected, atol=atol)
|
|
378
375
|
|
|
379
376
|
|
|
@@ -68,7 +68,7 @@ def assert_all_implemented_act_on_effects_match_unitary(
|
|
|
68
68
|
Checks that act_on with CliffordTableau or StabilizerStateCHForm behaves
|
|
69
69
|
consistently with act_on through final state vector. Does not work with
|
|
70
70
|
Operations or Gates expecting non-qubit Qids. If either of the
|
|
71
|
-
assert_*
|
|
71
|
+
assert_*_implemented args is true, fails if the corresponding method is not
|
|
72
72
|
implemented for the test circuit.
|
|
73
73
|
|
|
74
74
|
Args:
|
|
@@ -95,7 +95,7 @@ def assert_all_implemented_act_on_effects_match_unitary(
|
|
|
95
95
|
"Could not assert if any act_on methods were "
|
|
96
96
|
"implemented. Operating on qudits or with a "
|
|
97
97
|
"non-unitary or parameterized operation is "
|
|
98
|
-
"unsupported.\n\nval: {!r}"
|
|
98
|
+
f"unsupported.\n\nval: {val!r}"
|
|
99
99
|
)
|
|
100
100
|
return None
|
|
101
101
|
|
|
@@ -124,7 +124,7 @@ def assert_all_implemented_act_on_effects_match_unitary(
|
|
|
124
124
|
state_vector_has_stabilizer(state_vector, stab) for stab in tableau.stabilizers()
|
|
125
125
|
), (
|
|
126
126
|
"act_on clifford tableau is not consistent with "
|
|
127
|
-
"final_state_vector simulation.\n\nval: {!r}"
|
|
127
|
+
f"final_state_vector simulation.\n\nval: {val!r}"
|
|
128
128
|
)
|
|
129
129
|
|
|
130
130
|
stabilizer_ch_form = _final_stabilizer_state_ch_form(circuit, qubit_map)
|
|
@@ -133,7 +133,7 @@ def assert_all_implemented_act_on_effects_match_unitary(
|
|
|
133
133
|
"Failed to generate final "
|
|
134
134
|
"stabilizer state CH form "
|
|
135
135
|
"for the test circuit."
|
|
136
|
-
"\n\nval: {!r}"
|
|
136
|
+
f"\n\nval: {val!r}"
|
|
137
137
|
)
|
|
138
138
|
else:
|
|
139
139
|
np.testing.assert_allclose(
|
|
@@ -49,7 +49,7 @@ class BadGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
|
49
49
|
|
|
50
50
|
def controlled(
|
|
51
51
|
self,
|
|
52
|
-
num_controls: int = None,
|
|
52
|
+
num_controls: Optional[int] = None,
|
|
53
53
|
control_values: Optional[
|
|
54
54
|
Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
|
|
55
55
|
] = None,
|
|
@@ -40,8 +40,17 @@ def assert_decompose_is_consistent_with_unitary(val: Any, ignoring_global_phase:
|
|
|
40
40
|
# If there's no decomposition, it's vacuously consistent.
|
|
41
41
|
return
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
c = circuits.Circuit(dec)
|
|
44
|
+
if len(c.all_qubits().difference(qubits)):
|
|
45
|
+
# The decomposition contains ancilla qubits.
|
|
46
|
+
ancilla = tuple(c.all_qubits().difference(qubits))
|
|
47
|
+
qubit_order = ancilla + qubits
|
|
48
|
+
actual = c.unitary(qubit_order=qubit_order)
|
|
49
|
+
qid_shape = protocols.qid_shape(qubits)
|
|
50
|
+
vol = np.prod(qid_shape, dtype=np.int64)
|
|
51
|
+
actual = actual[:vol, :vol]
|
|
52
|
+
else:
|
|
53
|
+
actual = c.unitary(qubit_order=qubits)
|
|
45
54
|
if ignoring_global_phase:
|
|
46
55
|
lin_alg_utils.assert_allclose_up_to_global_phase(actual, expected, atol=1e-8)
|
|
47
56
|
else:
|
|
@@ -43,6 +43,14 @@ def test_assert_decompose_is_consistent_with_unitary():
|
|
|
43
43
|
GoodGateDecompose().on(cirq.NamedQubit('q'))
|
|
44
44
|
)
|
|
45
45
|
|
|
46
|
+
cirq.testing.assert_decompose_is_consistent_with_unitary(
|
|
47
|
+
cirq.testing.PhaseUsingCleanAncilla(theta=0.1, ancilla_bitsize=3)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
cirq.testing.assert_decompose_is_consistent_with_unitary(
|
|
51
|
+
cirq.testing.PhaseUsingDirtyAncilla(phase_state=1, ancilla_bitsize=4)
|
|
52
|
+
)
|
|
53
|
+
|
|
46
54
|
with pytest.raises(AssertionError):
|
|
47
55
|
cirq.testing.assert_decompose_is_consistent_with_unitary(BadGateDecompose())
|
|
48
56
|
|
|
@@ -83,7 +91,6 @@ class ParameterizedGate(cirq.Gate):
|
|
|
83
91
|
|
|
84
92
|
|
|
85
93
|
def test_assert_decompose_ends_at_default_gateset():
|
|
86
|
-
|
|
87
94
|
cirq.testing.assert_decompose_ends_at_default_gateset(GateDecomposesToDefaultGateset())
|
|
88
95
|
cirq.testing.assert_decompose_ends_at_default_gateset(
|
|
89
96
|
GateDecomposesToDefaultGateset().on(*cirq.LineQubit.range(2))
|
|
@@ -37,6 +37,7 @@ from cirq.testing.consistent_resolve_parameters import assert_consistent_resolve
|
|
|
37
37
|
from cirq.testing.consistent_specified_has_unitary import assert_specifies_has_unitary_if_unitary
|
|
38
38
|
from cirq.testing.equivalent_repr_eval import assert_equivalent_repr
|
|
39
39
|
from cirq.testing.consistent_controlled_gate_op import assert_controlled_and_controlled_by_identical
|
|
40
|
+
from cirq.testing.consistent_unitary import assert_unitary_is_consistent
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
def assert_implements_consistent_protocols(
|
|
@@ -153,6 +154,7 @@ def _assert_meets_standards_helper(
|
|
|
153
154
|
assert_qasm_is_consistent_with_unitary(val)
|
|
154
155
|
assert_has_consistent_trace_distance_bound(val)
|
|
155
156
|
assert_decompose_is_consistent_with_unitary(val, ignoring_global_phase=ignoring_global_phase)
|
|
157
|
+
assert_unitary_is_consistent(val, ignoring_global_phase=ignoring_global_phase)
|
|
156
158
|
if not ignore_decompose_to_default_gateset:
|
|
157
159
|
assert_decompose_ends_at_default_gateset(val)
|
|
158
160
|
assert_phase_by_is_consistent_with_unitary(val)
|
|
@@ -186,8 +186,10 @@ class GoodEigenGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
|
186
186
|
return [(0, np.diag([1, 0])), (1, np.diag([0, 1]))]
|
|
187
187
|
|
|
188
188
|
def __repr__(self):
|
|
189
|
-
return
|
|
190
|
-
|
|
189
|
+
return (
|
|
190
|
+
'GoodEigenGate('
|
|
191
|
+
f'exponent={proper_repr(self._exponent)}, '
|
|
192
|
+
f'global_shift={self._global_shift!r})'
|
|
191
193
|
)
|
|
192
194
|
|
|
193
195
|
|
|
@@ -196,8 +198,10 @@ class BadEigenGate(GoodEigenGate):
|
|
|
196
198
|
return [0, 0]
|
|
197
199
|
|
|
198
200
|
def __repr__(self):
|
|
199
|
-
return
|
|
200
|
-
|
|
201
|
+
return (
|
|
202
|
+
'BadEigenGate('
|
|
203
|
+
f'exponent={proper_repr(self._exponent)}, '
|
|
204
|
+
f'global_shift={self._global_shift!r})'
|
|
201
205
|
)
|
|
202
206
|
|
|
203
207
|
|
cirq/testing/consistent_qasm.py
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
import warnings
|
|
15
16
|
from typing import Any, List, Sequence, Optional
|
|
16
17
|
|
|
@@ -90,21 +91,13 @@ qreg q[{num_qubits}];
|
|
|
90
91
|
p_qasm_unitary = None
|
|
91
92
|
raise AssertionError(
|
|
92
93
|
'QASM not consistent with cirq.unitary(op) up to global phase.\n\n'
|
|
93
|
-
'op:\n{}\n\n'
|
|
94
|
-
'cirq.unitary(op):\n{}\n\n'
|
|
95
|
-
'Generated QASM:\n\n{}\n\n'
|
|
96
|
-
'Unitary of generated QASM:\n{}\n\n'
|
|
97
|
-
'Phased matched cirq.unitary(op):\n{}\n\n'
|
|
98
|
-
'Phased matched unitary of generated QASM:\n{}\n\n'
|
|
99
|
-
'Underlying error:\n{}'
|
|
100
|
-
_indent(repr(op)),
|
|
101
|
-
_indent(repr(unitary)),
|
|
102
|
-
_indent(qasm),
|
|
103
|
-
_indent(repr(qasm_unitary)),
|
|
104
|
-
_indent(repr(p_unitary)),
|
|
105
|
-
_indent(repr(p_qasm_unitary)),
|
|
106
|
-
_indent(str(ex)),
|
|
107
|
-
)
|
|
94
|
+
f'op:\n{_indent(repr(op))}\n\n'
|
|
95
|
+
f'cirq.unitary(op):\n{_indent(repr(unitary))}\n\n'
|
|
96
|
+
f'Generated QASM:\n\n{_indent(qasm)}\n\n'
|
|
97
|
+
f'Unitary of generated QASM:\n{_indent(repr(qasm_unitary))}\n\n'
|
|
98
|
+
f'Phased matched cirq.unitary(op):\n{_indent(repr(p_unitary))}\n\n'
|
|
99
|
+
f'Phased matched unitary of generated QASM:\n{_indent(repr(p_qasm_unitary))}\n\n'
|
|
100
|
+
f'Underlying error:\n{_indent(str(ex))}'
|
|
108
101
|
)
|
|
109
102
|
|
|
110
103
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Copyright 2023 The Cirq Developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from typing import Any
|
|
17
|
+
import cirq
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def assert_unitary_is_consistent(val: Any, ignoring_global_phase: bool = False):
|
|
22
|
+
if not isinstance(val, (cirq.Operation, cirq.Gate)):
|
|
23
|
+
return
|
|
24
|
+
|
|
25
|
+
if not cirq.has_unitary(val):
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
# Ensure that `u` is a unitary.
|
|
29
|
+
u = cirq.unitary(val)
|
|
30
|
+
assert not (u is None or u is NotImplemented)
|
|
31
|
+
assert cirq.is_unitary(u)
|
|
32
|
+
|
|
33
|
+
if isinstance(val, cirq.Operation):
|
|
34
|
+
qubits = val.qubits
|
|
35
|
+
decomposition = cirq.decompose_once(val, default=None)
|
|
36
|
+
else:
|
|
37
|
+
qubits = tuple(cirq.LineQid.for_gate(val))
|
|
38
|
+
decomposition = cirq.decompose_once_with_qubits(val, qubits, default=None)
|
|
39
|
+
|
|
40
|
+
if decomposition is None or decomposition is NotImplemented:
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
c = cirq.Circuit(decomposition)
|
|
44
|
+
if len(c.all_qubits().difference(qubits)) == 0:
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
clean_qubits = tuple(q for q in c.all_qubits() if isinstance(q, cirq.ops.CleanQubit))
|
|
48
|
+
borrowable_qubits = tuple(q for q in c.all_qubits() if isinstance(q, cirq.ops.BorrowableQubit))
|
|
49
|
+
qubit_order = clean_qubits + borrowable_qubits + qubits
|
|
50
|
+
|
|
51
|
+
# Check that the decomposition uses all data qubits in addition to
|
|
52
|
+
# clean and/or borrowable qubits.
|
|
53
|
+
assert set(qubit_order) == c.all_qubits()
|
|
54
|
+
|
|
55
|
+
qid_shape = cirq.qid_shape(qubit_order)
|
|
56
|
+
full_unitary = cirq.apply_unitaries(
|
|
57
|
+
decomposition,
|
|
58
|
+
qubits=qubit_order,
|
|
59
|
+
args=cirq.ApplyUnitaryArgs.for_unitary(qid_shape=qid_shape),
|
|
60
|
+
default=None,
|
|
61
|
+
)
|
|
62
|
+
if full_unitary is None:
|
|
63
|
+
raise ValueError(f'apply_unitaries failed on the decomposition of {val}')
|
|
64
|
+
vol = np.prod(qid_shape, dtype=np.int64)
|
|
65
|
+
full_unitary = full_unitary.reshape((vol, vol))
|
|
66
|
+
|
|
67
|
+
vol = np.prod(cirq.qid_shape(borrowable_qubits + qubits), dtype=np.int64)
|
|
68
|
+
|
|
69
|
+
# Extract the submatrix acting on the |0..0> subspace of clean qubits.
|
|
70
|
+
# This submatirx must be a unitary.
|
|
71
|
+
clean_qubits_zero_subspace = full_unitary[:vol, :vol]
|
|
72
|
+
|
|
73
|
+
# If the borrowable qubits are restored to their initial state, then
|
|
74
|
+
# the decomposition's effect on it is the identity matrix.
|
|
75
|
+
# This means that the `clean_qubits_zero_subspace` must be I \otimes u.
|
|
76
|
+
# So checking that `clean_qubits_zero_subspace` is I \otimes u checks correctness
|
|
77
|
+
# for both clean and borrowable qubits at the same time.
|
|
78
|
+
expected = np.kron(np.eye(2 ** len(borrowable_qubits), dtype=np.complex128), u)
|
|
79
|
+
|
|
80
|
+
if ignoring_global_phase:
|
|
81
|
+
cirq.testing.assert_allclose_up_to_global_phase(
|
|
82
|
+
clean_qubits_zero_subspace, expected, atol=1e-8
|
|
83
|
+
)
|
|
84
|
+
else:
|
|
85
|
+
np.testing.assert_allclose(clean_qubits_zero_subspace, expected, atol=1e-8)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright 2023 The Cirq Developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import cirq
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class InconsistentGate(cirq.Gate):
|
|
22
|
+
def _num_qubits_(self) -> int:
|
|
23
|
+
return 1
|
|
24
|
+
|
|
25
|
+
def _unitary_(self) -> np.ndarray:
|
|
26
|
+
return np.eye(2, dtype=np.complex128)
|
|
27
|
+
|
|
28
|
+
def _decompose_with_context_(self, qubits, *, context):
|
|
29
|
+
(q,) = context.qubit_manager.qalloc(1)
|
|
30
|
+
yield cirq.X(q)
|
|
31
|
+
yield cirq.CNOT(q, qubits[0])
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class FailsOnDecompostion(cirq.Gate):
|
|
35
|
+
def _num_qubits_(self) -> int:
|
|
36
|
+
return 1
|
|
37
|
+
|
|
38
|
+
def _unitary_(self) -> np.ndarray:
|
|
39
|
+
return np.eye(2, dtype=np.complex128)
|
|
40
|
+
|
|
41
|
+
def _has_unitary_(self) -> bool:
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
def _decompose_with_context_(self, qubits, *, context):
|
|
45
|
+
(q,) = context.qubit_manager.qalloc(1)
|
|
46
|
+
yield cirq.X(q)
|
|
47
|
+
yield cirq.measure(qubits[0])
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CleanCorrectButBorrowableIncorrectGate(cirq.Gate):
|
|
51
|
+
"""Ancilla type determines if the decomposition is correct or not."""
|
|
52
|
+
|
|
53
|
+
def __init__(self, use_clean_ancilla: bool) -> None:
|
|
54
|
+
self.ancillas_are_clean = use_clean_ancilla
|
|
55
|
+
|
|
56
|
+
def _num_qubits_(self):
|
|
57
|
+
return 2
|
|
58
|
+
|
|
59
|
+
def _decompose_with_context_(self, qubits, *, context):
|
|
60
|
+
if self.ancillas_are_clean:
|
|
61
|
+
anc = context.qubit_manager.qalloc(1)
|
|
62
|
+
else:
|
|
63
|
+
anc = context.qubit_manager.qborrow(1)
|
|
64
|
+
yield cirq.CCNOT(*qubits, *anc)
|
|
65
|
+
yield cirq.Z(*anc)
|
|
66
|
+
yield cirq.CCNOT(*qubits, *anc)
|
|
67
|
+
context.qubit_manager.qfree(anc)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.mark.parametrize('ignore_phase', [False, True])
|
|
71
|
+
@pytest.mark.parametrize(
|
|
72
|
+
'g,is_consistent',
|
|
73
|
+
[
|
|
74
|
+
(cirq.testing.PhaseUsingCleanAncilla(theta=0.1, ancilla_bitsize=3), True),
|
|
75
|
+
(cirq.testing.PhaseUsingDirtyAncilla(phase_state=1, ancilla_bitsize=4), True),
|
|
76
|
+
(InconsistentGate(), False),
|
|
77
|
+
(CleanCorrectButBorrowableIncorrectGate(use_clean_ancilla=True), True),
|
|
78
|
+
(CleanCorrectButBorrowableIncorrectGate(use_clean_ancilla=False), False),
|
|
79
|
+
],
|
|
80
|
+
)
|
|
81
|
+
def test_assert_unitary_is_consistent(g, ignore_phase, is_consistent):
|
|
82
|
+
if is_consistent:
|
|
83
|
+
cirq.testing.assert_unitary_is_consistent(g, ignore_phase)
|
|
84
|
+
cirq.testing.assert_unitary_is_consistent(g.on(*cirq.LineQid.for_gate(g)), ignore_phase)
|
|
85
|
+
else:
|
|
86
|
+
with pytest.raises(AssertionError):
|
|
87
|
+
cirq.testing.assert_unitary_is_consistent(g, ignore_phase)
|
|
88
|
+
with pytest.raises(AssertionError):
|
|
89
|
+
cirq.testing.assert_unitary_is_consistent(g.on(*cirq.LineQid.for_gate(g)), ignore_phase)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_failed_decomposition():
|
|
93
|
+
with pytest.raises(ValueError):
|
|
94
|
+
cirq.testing.assert_unitary_is_consistent(FailsOnDecompostion())
|
|
95
|
+
|
|
96
|
+
_ = cirq.testing.assert_unitary_is_consistent(cirq.Circuit())
|
|
@@ -52,10 +52,10 @@ def assert_equivalent_repr(
|
|
|
52
52
|
raise AssertionError(
|
|
53
53
|
'eval(repr(value)) raised an exception.\n'
|
|
54
54
|
'\n'
|
|
55
|
-
'setup_code={}\n'
|
|
56
|
-
'type(value): {}\n'
|
|
57
|
-
'value={!r}\n'
|
|
58
|
-
'error={!r}'
|
|
55
|
+
f'setup_code={setup_code}\n'
|
|
56
|
+
f'type(value): {type(value)}\n'
|
|
57
|
+
f'value={value!r}\n'
|
|
58
|
+
f'error={ex!r}'
|
|
59
59
|
)
|
|
60
60
|
|
|
61
61
|
assert eval_repr_value == value, (
|
|
@@ -87,14 +87,14 @@ def assert_equivalent_repr(
|
|
|
87
87
|
a = eval(f'{value!r}.__class__', global_vals, local_vals)
|
|
88
88
|
except Exception:
|
|
89
89
|
raise AssertionError(
|
|
90
|
-
"The repr of a value of type {} wasn't 'dottable'.\n"
|
|
91
|
-
"{!r}.XXX must be equivalent to ({!r}).XXX, "
|
|
92
|
-
"but it raised an error instead."
|
|
90
|
+
f"The repr of a value of type {type(value)} wasn't 'dottable'.\n"
|
|
91
|
+
f"{value!r}.XXX must be equivalent to ({value!r}).XXX, "
|
|
92
|
+
"but it raised an error instead."
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
b = eval(f'({value!r}).__class__', global_vals, local_vals)
|
|
96
96
|
assert a == b, (
|
|
97
|
-
"The repr of a value of type {} wasn't 'dottable'.\n"
|
|
98
|
-
"{!r}.XXX must be equivalent to ({!r}).XXX, "
|
|
99
|
-
"but it wasn't."
|
|
97
|
+
f"The repr of a value of type {type(value)} wasn't 'dottable'.\n"
|
|
98
|
+
f"{value!r}.XXX must be equivalent to ({value!r}).XXX, "
|
|
99
|
+
"but it wasn't."
|
|
100
100
|
)
|
cirq/testing/json.py
CHANGED
|
@@ -95,11 +95,11 @@ class ModuleJsonTestSpec:
|
|
|
95
95
|
|
|
96
96
|
return result
|
|
97
97
|
|
|
98
|
-
def get_resolver_cache_types(self):
|
|
98
|
+
def get_resolver_cache_types(self) -> Set[Tuple[str, Type]]:
|
|
99
99
|
result: Set[Tuple[str, Type]] = set()
|
|
100
100
|
for k, v in self.resolver_cache.items():
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
if isinstance(v, type):
|
|
102
|
+
result.add((k, v))
|
|
103
103
|
return result
|
|
104
104
|
|
|
105
105
|
def get_all_names(self) -> Iterator[str]:
|
cirq/testing/logs.py
CHANGED
|
@@ -48,7 +48,7 @@ def assert_logs(
|
|
|
48
48
|
module for valid levels. By default this captures at the
|
|
49
49
|
`logging.WARNING` level and above, so this does not capture `logging.INFO`
|
|
50
50
|
or `logging.DEBUG` logs by default.
|
|
51
|
-
max_level: The
|
|
51
|
+
max_level: The maximum level at which to capture the logs. See the python logging
|
|
52
52
|
module for valid levels. By default this captures to the `logging.CRITICAL` level
|
|
53
53
|
thus, all the errors and critical messages will be captured as well.
|
|
54
54
|
capture_warnings: Whether warnings from the python's `warnings` module
|
cirq/testing/order_tester.py
CHANGED
|
@@ -50,10 +50,9 @@ class OrderTester:
|
|
|
50
50
|
expected = cmp_func(0, sign)
|
|
51
51
|
actual = cmp_func(a, b)
|
|
52
52
|
assert expected == actual, (
|
|
53
|
-
"Ordering constraint violated. Expected X={}
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
)
|
|
53
|
+
f"Ordering constraint violated. Expected X={a} "
|
|
54
|
+
f"to {['be more than', 'equal', 'be less than'][sign + 1]} Y={b}, "
|
|
55
|
+
f"but X {cmp_name} Y returned {actual}"
|
|
57
56
|
)
|
|
58
57
|
|
|
59
58
|
def _verify_ordering(self, a: Any, b: Any, sign: int):
|
|
@@ -74,7 +73,7 @@ class OrderTester:
|
|
|
74
73
|
" if not isinstance(other, type(self)):\n"
|
|
75
74
|
" return NotImplemented\n"
|
|
76
75
|
"\n"
|
|
77
|
-
"That rule is being violated by this value: {!r}"
|
|
76
|
+
f"That rule is being violated by this value: {item!r}"
|
|
78
77
|
) from ex
|
|
79
78
|
|
|
80
79
|
def add_ascending(self, *items: Any):
|
cirq/testing/random_circuit.py
CHANGED
|
@@ -114,9 +114,7 @@ def random_circuit(
|
|
|
114
114
|
free_qubits = set(qubits)
|
|
115
115
|
while len(free_qubits) >= max_arity:
|
|
116
116
|
gate, arity = gate_arity_pairs[prng.randint(num_gates)]
|
|
117
|
-
op_qubits = prng.choice(
|
|
118
|
-
sorted(free_qubits), size=arity, replace=False # type: ignore[arg-type]
|
|
119
|
-
)
|
|
117
|
+
op_qubits = prng.choice(sorted(free_qubits), size=arity, replace=False)
|
|
120
118
|
free_qubits.difference_update(op_qubits)
|
|
121
119
|
if prng.rand() <= op_density:
|
|
122
120
|
operations.append(gate(*op_qubits))
|
|
@@ -127,8 +125,8 @@ def random_circuit(
|
|
|
127
125
|
|
|
128
126
|
def random_two_qubit_circuit_with_czs(
|
|
129
127
|
num_czs: int = 3,
|
|
130
|
-
q0: Qid = None,
|
|
131
|
-
q1: Qid = None,
|
|
128
|
+
q0: Optional[Qid] = None,
|
|
129
|
+
q1: Optional[Qid] = None,
|
|
132
130
|
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
133
131
|
) -> circuits.Circuit:
|
|
134
132
|
"""Creates a random two qubit circuit with the given number of CNOTs.
|