cirq-core 1.1.0.dev20221220224914__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.
Files changed (228) hide show
  1. cirq/__init__.py +8 -0
  2. cirq/_compat.py +29 -4
  3. cirq/_compat_test.py +24 -26
  4. cirq/_version.py +32 -1
  5. cirq/_version_test.py +1 -1
  6. cirq/circuits/_block_diagram_drawer_test.py +4 -3
  7. cirq/circuits/circuit.py +109 -63
  8. cirq/circuits/circuit_operation.py +2 -3
  9. cirq/circuits/circuit_operation_test.py +4 -4
  10. cirq/circuits/circuit_test.py +11 -0
  11. cirq/circuits/frozen_circuit.py +13 -1
  12. cirq/circuits/frozen_circuit_test.py +5 -1
  13. cirq/circuits/moment.py +39 -14
  14. cirq/circuits/moment_test.py +7 -0
  15. cirq/circuits/text_diagram_drawer.py +1 -1
  16. cirq/circuits/text_diagram_drawer_test.py +3 -7
  17. cirq/contrib/acquaintance/bipartite.py +1 -1
  18. cirq/contrib/acquaintance/devices.py +2 -2
  19. cirq/contrib/acquaintance/executor.py +5 -2
  20. cirq/contrib/acquaintance/gates.py +3 -2
  21. cirq/contrib/acquaintance/permutation.py +13 -2
  22. cirq/contrib/acquaintance/testing.py +3 -5
  23. cirq/contrib/paulistring/recombine.py +3 -6
  24. cirq/contrib/qasm_import/_parser.py +17 -21
  25. cirq/contrib/qasm_import/_parser_test.py +30 -45
  26. cirq/contrib/qcircuit/qcircuit_test.py +3 -7
  27. cirq/contrib/quantum_volume/quantum_volume.py +3 -3
  28. cirq/contrib/quimb/mps_simulator.py +1 -1
  29. cirq/contrib/quimb/state_vector.py +2 -0
  30. cirq/contrib/quirk/quirk_gate.py +1 -0
  31. cirq/contrib/svg/svg.py +4 -7
  32. cirq/contrib/svg/svg_test.py +29 -1
  33. cirq/devices/grid_qubit.py +26 -28
  34. cirq/devices/grid_qubit_test.py +21 -5
  35. cirq/devices/line_qubit.py +10 -12
  36. cirq/devices/line_qubit_test.py +9 -2
  37. cirq/devices/named_topologies.py +1 -1
  38. cirq/devices/noise_model.py +4 -1
  39. cirq/devices/superconducting_qubits_noise_properties.py +1 -3
  40. cirq/experiments/n_qubit_tomography.py +1 -1
  41. cirq/experiments/qubit_characterizations.py +2 -2
  42. cirq/experiments/single_qubit_readout_calibration.py +1 -1
  43. cirq/experiments/t2_decay_experiment.py +1 -1
  44. cirq/experiments/xeb_simulation_test.py +2 -2
  45. cirq/interop/quirk/cells/testing.py +1 -1
  46. cirq/json_resolver_cache.py +1 -0
  47. cirq/linalg/__init__.py +2 -0
  48. cirq/linalg/decompositions_test.py +4 -4
  49. cirq/linalg/diagonalize_test.py +5 -6
  50. cirq/linalg/transformations.py +72 -9
  51. cirq/linalg/transformations_test.py +23 -7
  52. cirq/ops/__init__.py +4 -0
  53. cirq/ops/arithmetic_operation.py +4 -6
  54. cirq/ops/classically_controlled_operation.py +10 -3
  55. cirq/ops/clifford_gate.py +1 -7
  56. cirq/ops/common_channels.py +21 -15
  57. cirq/ops/common_gate_families.py +2 -3
  58. cirq/ops/common_gates.py +48 -11
  59. cirq/ops/common_gates_test.py +4 -0
  60. cirq/ops/controlled_gate.py +44 -18
  61. cirq/ops/controlled_operation.py +13 -5
  62. cirq/ops/dense_pauli_string.py +14 -19
  63. cirq/ops/diagonal_gate.py +3 -4
  64. cirq/ops/eigen_gate.py +8 -10
  65. cirq/ops/eigen_gate_test.py +6 -0
  66. cirq/ops/gate_operation.py +11 -6
  67. cirq/ops/gate_operation_test.py +11 -2
  68. cirq/ops/gateset.py +2 -1
  69. cirq/ops/gateset_test.py +38 -5
  70. cirq/ops/global_phase_op.py +28 -2
  71. cirq/ops/global_phase_op_test.py +21 -0
  72. cirq/ops/identity.py +1 -1
  73. cirq/ops/kraus_channel_test.py +2 -2
  74. cirq/ops/linear_combinations.py +7 -6
  75. cirq/ops/linear_combinations_test.py +26 -10
  76. cirq/ops/matrix_gates.py +8 -4
  77. cirq/ops/matrix_gates_test.py +25 -3
  78. cirq/ops/measure_util.py +13 -5
  79. cirq/ops/measure_util_test.py +8 -2
  80. cirq/ops/measurement_gate.py +1 -1
  81. cirq/ops/measurement_gate_test.py +9 -4
  82. cirq/ops/mixed_unitary_channel_test.py +4 -4
  83. cirq/ops/named_qubit.py +2 -4
  84. cirq/ops/parity_gates.py +5 -1
  85. cirq/ops/parity_gates_test.py +6 -0
  86. cirq/ops/pauli_gates.py +9 -9
  87. cirq/ops/pauli_string.py +4 -2
  88. cirq/ops/pauli_string_raw_types.py +4 -11
  89. cirq/ops/pauli_string_test.py +13 -13
  90. cirq/ops/pauli_sum_exponential.py +6 -1
  91. cirq/ops/qubit_manager.py +97 -0
  92. cirq/ops/qubit_manager_test.py +66 -0
  93. cirq/ops/raw_types.py +75 -33
  94. cirq/ops/raw_types_test.py +34 -0
  95. cirq/ops/three_qubit_gates.py +16 -10
  96. cirq/ops/three_qubit_gates_test.py +4 -2
  97. cirq/ops/two_qubit_diagonal_gate.py +3 -3
  98. cirq/ops/wait_gate.py +1 -1
  99. cirq/protocols/__init__.py +1 -0
  100. cirq/protocols/act_on_protocol.py +3 -3
  101. cirq/protocols/act_on_protocol_test.py +5 -5
  102. cirq/protocols/apply_channel_protocol.py +9 -8
  103. cirq/protocols/apply_mixture_protocol.py +8 -8
  104. cirq/protocols/apply_mixture_protocol_test.py +1 -1
  105. cirq/protocols/apply_unitary_protocol.py +66 -19
  106. cirq/protocols/apply_unitary_protocol_test.py +50 -0
  107. cirq/protocols/circuit_diagram_info_protocol.py +7 -9
  108. cirq/protocols/decompose_protocol.py +167 -125
  109. cirq/protocols/decompose_protocol_test.py +132 -2
  110. cirq/protocols/has_stabilizer_effect_protocol.py +2 -1
  111. cirq/protocols/inverse_protocol.py +2 -2
  112. cirq/protocols/json_serialization_test.py +3 -3
  113. cirq/protocols/json_test_data/Linspace.json +20 -7
  114. cirq/protocols/json_test_data/Linspace.repr +4 -1
  115. cirq/protocols/json_test_data/Points.json +19 -8
  116. cirq/protocols/json_test_data/Points.repr +4 -1
  117. cirq/protocols/json_test_data/Result.repr_inward +1 -1
  118. cirq/protocols/json_test_data/ResultDict.repr +1 -1
  119. cirq/protocols/json_test_data/ResultDict.repr_inward +1 -1
  120. cirq/protocols/json_test_data/TrialResult.repr_inward +1 -1
  121. cirq/protocols/json_test_data/XPowGate.json +13 -5
  122. cirq/protocols/json_test_data/XPowGate.repr +1 -1
  123. cirq/protocols/json_test_data/ZPowGate.json +13 -5
  124. cirq/protocols/json_test_data/ZPowGate.repr +1 -1
  125. cirq/protocols/json_test_data/ZipLongest.json +19 -0
  126. cirq/protocols/json_test_data/ZipLongest.repr +1 -0
  127. cirq/protocols/json_test_data/spec.py +1 -0
  128. cirq/protocols/kraus_protocol.py +3 -4
  129. cirq/protocols/measurement_key_protocol.py +3 -1
  130. cirq/protocols/mixture_protocol.py +3 -2
  131. cirq/protocols/phase_protocol.py +3 -3
  132. cirq/protocols/pow_protocol.py +1 -2
  133. cirq/protocols/qasm.py +4 -4
  134. cirq/protocols/qid_shape_protocol.py +8 -8
  135. cirq/protocols/resolve_parameters.py +8 -3
  136. cirq/protocols/resolve_parameters_test.py +3 -3
  137. cirq/protocols/unitary_protocol.py +19 -11
  138. cirq/protocols/unitary_protocol_test.py +37 -0
  139. cirq/qis/channels.py +1 -1
  140. cirq/qis/clifford_tableau.py +4 -5
  141. cirq/qis/quantum_state_representation.py +7 -9
  142. cirq/qis/states.py +21 -13
  143. cirq/qis/states_test.py +7 -0
  144. cirq/sim/clifford/clifford_simulator.py +3 -3
  145. cirq/sim/density_matrix_simulation_state.py +2 -1
  146. cirq/sim/density_matrix_simulator.py +1 -1
  147. cirq/sim/density_matrix_simulator_test.py +9 -5
  148. cirq/sim/density_matrix_utils.py +7 -32
  149. cirq/sim/mux.py +2 -2
  150. cirq/sim/simulation_state.py +58 -18
  151. cirq/sim/simulation_state_base.py +5 -2
  152. cirq/sim/simulation_state_test.py +121 -9
  153. cirq/sim/simulation_utils.py +59 -0
  154. cirq/sim/simulation_utils_test.py +32 -0
  155. cirq/sim/simulator.py +2 -1
  156. cirq/sim/simulator_base_test.py +3 -3
  157. cirq/sim/sparse_simulator.py +1 -1
  158. cirq/sim/sparse_simulator_test.py +5 -5
  159. cirq/sim/state_vector.py +7 -36
  160. cirq/sim/state_vector_simulation_state.py +18 -1
  161. cirq/sim/state_vector_simulator.py +3 -2
  162. cirq/sim/state_vector_simulator_test.py +24 -2
  163. cirq/sim/state_vector_test.py +46 -15
  164. cirq/study/__init__.py +1 -0
  165. cirq/study/flatten_expressions.py +2 -2
  166. cirq/study/resolver.py +2 -0
  167. cirq/study/resolver_test.py +1 -1
  168. cirq/study/result.py +1 -1
  169. cirq/study/sweeps.py +103 -9
  170. cirq/study/sweeps_test.py +64 -0
  171. cirq/testing/__init__.py +4 -0
  172. cirq/testing/circuit_compare.py +15 -18
  173. cirq/testing/consistent_act_on.py +4 -4
  174. cirq/testing/consistent_controlled_gate_op_test.py +1 -1
  175. cirq/testing/consistent_decomposition.py +11 -2
  176. cirq/testing/consistent_decomposition_test.py +8 -1
  177. cirq/testing/consistent_protocols.py +2 -0
  178. cirq/testing/consistent_protocols_test.py +8 -4
  179. cirq/testing/consistent_qasm.py +8 -15
  180. cirq/testing/consistent_specified_has_unitary.py +1 -1
  181. cirq/testing/consistent_unitary.py +85 -0
  182. cirq/testing/consistent_unitary_test.py +96 -0
  183. cirq/testing/equivalent_repr_eval.py +10 -10
  184. cirq/testing/json.py +3 -3
  185. cirq/testing/logs.py +1 -1
  186. cirq/testing/order_tester.py +4 -5
  187. cirq/testing/random_circuit.py +3 -5
  188. cirq/testing/sample_gates.py +79 -0
  189. cirq/testing/sample_gates_test.py +59 -0
  190. cirq/transformers/__init__.py +2 -0
  191. cirq/transformers/analytical_decompositions/__init__.py +8 -0
  192. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +130 -0
  193. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +58 -0
  194. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +230 -0
  195. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +112 -0
  196. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -3
  197. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
  198. cirq/transformers/expand_composite.py +1 -1
  199. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +4 -4
  200. cirq/transformers/measurement_transformers.py +4 -4
  201. cirq/transformers/merge_single_qubit_gates.py +17 -4
  202. cirq/transformers/routing/route_circuit_cqc.py +2 -2
  203. cirq/transformers/stratify.py +125 -62
  204. cirq/transformers/stratify_test.py +20 -16
  205. cirq/transformers/transformer_api.py +1 -1
  206. cirq/transformers/transformer_primitives.py +3 -2
  207. cirq/transformers/transformer_primitives_test.py +11 -0
  208. cirq/value/abc_alt.py +3 -2
  209. cirq/value/abc_alt_test.py +1 -0
  210. cirq/value/classical_data.py +10 -10
  211. cirq/value/digits.py +2 -2
  212. cirq/value/linear_dict.py +18 -19
  213. cirq/value/product_state.py +7 -6
  214. cirq/value/value_equality_attr.py +2 -2
  215. cirq/vis/heatmap.py +1 -1
  216. cirq/vis/heatmap_test.py +2 -2
  217. cirq/work/collector.py +2 -2
  218. cirq/work/observable_measurement_data.py +5 -5
  219. cirq/work/observable_readout_calibration.py +3 -1
  220. cirq/work/observable_settings.py +1 -1
  221. cirq/work/pauli_sum_collector.py +9 -8
  222. cirq/work/sampler.py +2 -0
  223. cirq/work/zeros_sampler.py +2 -2
  224. {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/METADATA +7 -15
  225. {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/RECORD +228 -214
  226. {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/WHEEL +1 -1
  227. {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/LICENSE +0 -0
  228. {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/top_level.txt +0 -0
@@ -33,17 +33,13 @@ def assert_has_qcircuit_diagram(actual: cirq.Circuit, desired: str, **kwargs) ->
33
33
  "Circuit's qcircuit diagram differs from the desired diagram.\n"
34
34
  '\n'
35
35
  'Diagram of actual circuit:\n'
36
- '{}\n'
36
+ f'{actual_diagram}\n'
37
37
  '\n'
38
38
  'Desired qcircuit diagram:\n'
39
- '{}\n'
39
+ f'{desired_diagram}\n'
40
40
  '\n'
41
41
  'Highlighted differences:\n'
42
- '{}\n'.format(
43
- actual_diagram,
44
- desired_diagram,
45
- ct.highlight_text_differences(actual_diagram, desired_diagram),
46
- )
42
+ f'{ct.highlight_text_differences(actual_diagram, desired_diagram)}\n'
47
43
  )
48
44
 
49
45
 
@@ -200,7 +200,7 @@ def compile_circuit(
200
200
  *,
201
201
  device_graph: nx.Graph,
202
202
  routing_attempts: int,
203
- compiler: Callable[[cirq.Circuit], cirq.Circuit] = None,
203
+ compiler: Optional[Callable[[cirq.Circuit], cirq.Circuit]] = None,
204
204
  routing_algo_name: Optional[str] = None,
205
205
  router: Optional[Callable[..., ccr.SwapNetwork]] = None,
206
206
  add_readout_error_correction=False,
@@ -357,7 +357,7 @@ def execute_circuits(
357
357
  samplers: List[cirq.Sampler],
358
358
  circuits: List[Tuple[cirq.Circuit, List[int]]],
359
359
  routing_attempts: int,
360
- compiler: Callable[[cirq.Circuit], cirq.Circuit] = None,
360
+ compiler: Optional[Callable[[cirq.Circuit], cirq.Circuit]] = None,
361
361
  repetitions: int = 10_000,
362
362
  add_readout_error_correction=False,
363
363
  ) -> List[QuantumVolumeResult]:
@@ -429,7 +429,7 @@ def calculate_quantum_volume(
429
429
  device_graph: nx.Graph,
430
430
  samplers: List[cirq.Sampler],
431
431
  random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
432
- compiler: Callable[[cirq.Circuit], cirq.Circuit] = None,
432
+ compiler: Optional[Callable[[cirq.Circuit], cirq.Circuit]] = None,
433
433
  repetitions=10_000,
434
434
  routing_attempts=30,
435
435
  add_readout_error_correction=False,
@@ -569,7 +569,7 @@ class MPSState(SimulationState[_MPSHandler]):
569
569
  simulation_options: MPSOptions = MPSOptions(),
570
570
  grouping: Optional[Dict['cirq.Qid', int]] = None,
571
571
  initial_state: int = 0,
572
- classical_data: 'cirq.ClassicalDataStore' = None,
572
+ classical_data: Optional['cirq.ClassicalDataStore'] = None,
573
573
  ):
574
574
  """Creates and MPSState
575
575
 
@@ -177,6 +177,8 @@ def tensor_expectation_value(
177
177
  if ram_gb > max_ram_gb:
178
178
  raise MemoryError(f"We estimate that this contraction will take too much RAM! {ram_gb} GB")
179
179
  e_val = tn.contract(inplace=True)
180
+ if isinstance(e_val, qtn.TensorNetwork):
181
+ e_val = e_val.item()
180
182
  assert e_val.imag < tol
181
183
  assert cast(complex, pauli_string.coefficient).imag < tol
182
184
  return e_val.real * pauli_string.coefficient
@@ -111,6 +111,7 @@ def single_qubit_matrix_gate(matrix: Optional[np.ndarray]) -> Optional[QuirkOp]:
111
111
  if matrix is None or matrix.shape[0] != 2:
112
112
  return None
113
113
 
114
+ # pylint: disable=consider-using-f-string
114
115
  matrix = matrix.round(6)
115
116
  matrix_repr = '{{%s+%si,%s+%si},{%s+%si,%s+%si}}' % (
116
117
  np.real(matrix[0, 0]),
cirq/contrib/svg/svg.py CHANGED
@@ -16,13 +16,10 @@ def fixup_text(text: str):
16
16
  # https://github.com/quantumlib/Cirq/issues/4499
17
17
  # TODO: Visualize Custom MatrixGate
18
18
  return '?'
19
- if '[<virtual>]' in text:
20
- # https://github.com/quantumlib/Cirq/issues/2905
21
- # TODO: escape angle brackets when you actually want to display tags
22
- return text.replace('[<virtual>]', '') # coverage: ignore
23
- if '[cirq.VirtualTag()]' in text:
24
- # https://github.com/quantumlib/Cirq/issues/2905
25
- return text.replace('[cirq.VirtualTag()]', '')
19
+ # https://github.com/quantumlib/Cirq/issues/2905
20
+ text = text.replace('[<virtual>]', '')
21
+ text = text.replace('[cirq.VirtualTag()]', '')
22
+ text = text.replace('<', '&lt;').replace('>', '&gt;')
26
23
  return text
27
24
 
28
25
 
@@ -1,6 +1,7 @@
1
1
  # pylint: disable=wrong-or-nonexistent-copyright-notice
2
- import pytest
2
+ import IPython.display
3
3
  import numpy as np
4
+ import pytest
4
5
 
5
6
  import cirq
6
7
  from cirq.contrib.svg import circuit_to_svg
@@ -20,6 +21,7 @@ def test_svg():
20
21
  cirq.MatrixGate(np.eye(2)).on(a),
21
22
  )
22
23
  )
24
+ assert '?' in svg_text
23
25
  assert '<svg' in svg_text
24
26
  assert '</svg>' in svg_text
25
27
 
@@ -57,3 +59,29 @@ def test_empty_moments():
57
59
  svg_2 = circuit_to_svg(cirq.Circuit(cirq.Moment()))
58
60
  assert '<svg' in svg_2
59
61
  assert '</svg>' in svg_2
62
+
63
+
64
+ @pytest.mark.parametrize(
65
+ 'symbol,svg_symbol',
66
+ [
67
+ ('<a', '&lt;a'),
68
+ ('<=b', '&lt;=b'),
69
+ ('>c', '&gt;c'),
70
+ ('>=d', '&gt;=d'),
71
+ ('>e<', '&gt;e&lt;'),
72
+ ('A[<virtual>]B[cirq.VirtualTag()]C>D<E', 'ABC&gt;D&lt;E'),
73
+ ],
74
+ )
75
+ def test_gate_with_less_greater_str(symbol, svg_symbol):
76
+ class CustomGate(cirq.Gate):
77
+ def _num_qubits_(self) -> int:
78
+ return 1
79
+
80
+ def _circuit_diagram_info_(self, _) -> cirq.CircuitDiagramInfo:
81
+ return cirq.CircuitDiagramInfo(wire_symbols=[symbol])
82
+
83
+ circuit = cirq.Circuit(CustomGate().on(cirq.LineQubit(0)))
84
+ svg = circuit_to_svg(circuit)
85
+
86
+ _ = IPython.display.SVG(svg)
87
+ assert svg_symbol in svg
@@ -12,10 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import functools
16
- from typing import Any, Dict, Iterable, List, Optional, Tuple, Set, TypeVar, TYPE_CHECKING
17
-
18
15
  import abc
16
+ import functools
17
+ from typing import Any, Dict, Iterable, List, Optional, Tuple, Set, TYPE_CHECKING, Union
18
+ from typing_extensions import Self
19
19
 
20
20
  import numpy as np
21
21
 
@@ -24,10 +24,8 @@ from cirq import _compat, ops, protocols
24
24
  if TYPE_CHECKING:
25
25
  import cirq
26
26
 
27
- TSelf = TypeVar('TSelf', bound='_BaseGridQid')
28
-
29
27
 
30
- @functools.total_ordering # type: ignore
28
+ @functools.total_ordering
31
29
  class _BaseGridQid(ops.Qid):
32
30
  """The Base class for `GridQid` and `GridQubit`."""
33
31
 
@@ -47,13 +45,13 @@ class _BaseGridQid(ops.Qid):
47
45
  return self._col
48
46
 
49
47
  def with_dimension(self, dimension: int) -> 'GridQid':
50
- return GridQid(self.row, self.col, dimension=dimension)
48
+ return GridQid(self._row, self._col, dimension=dimension)
51
49
 
52
50
  def is_adjacent(self, other: 'cirq.Qid') -> bool:
53
51
  """Determines if two qubits are adjacent qubits."""
54
52
  return (
55
53
  isinstance(other, GridQubit)
56
- and abs(self.row - other.row) + abs(self.col - other.col) == 1
54
+ and abs(self._row - other._row) + abs(self._col - other._col) == 1
57
55
  )
58
56
 
59
57
  def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set['_BaseGridQid']:
@@ -69,20 +67,20 @@ class _BaseGridQid(ops.Qid):
69
67
  return neighbors
70
68
 
71
69
  @abc.abstractmethod
72
- def _with_row_col(self: TSelf, row: int, col: int) -> TSelf:
70
+ def _with_row_col(self, row: int, col: int) -> Self:
73
71
  """Returns a qid with the same type but a different coordinate."""
74
72
 
75
73
  def __complex__(self) -> complex:
76
- return self.col + 1j * self.row
74
+ return self._col + 1j * self._row
77
75
 
78
- def __add__(self: TSelf, other: Tuple[int, int]) -> 'TSelf':
76
+ def __add__(self, other: Union[Tuple[int, int], Self]) -> Self:
79
77
  if isinstance(other, _BaseGridQid):
80
78
  if self.dimension != other.dimension:
81
79
  raise TypeError(
82
80
  "Can only add GridQids with identical dimension. "
83
81
  f"Got {self.dimension} and {other.dimension}"
84
82
  )
85
- return self._with_row_col(row=self.row + other.row, col=self.col + other.col)
83
+ return self._with_row_col(row=self._row + other._row, col=self._col + other._col)
86
84
  if not (
87
85
  isinstance(other, (tuple, np.ndarray))
88
86
  and len(other) == 2
@@ -92,16 +90,16 @@ class _BaseGridQid(ops.Qid):
92
90
  'Can only add integer tuples of length 2 to '
93
91
  f'{type(self).__name__}. Instead was {other}'
94
92
  )
95
- return self._with_row_col(row=self.row + other[0], col=self.col + other[1])
93
+ return self._with_row_col(row=self._row + other[0], col=self._col + other[1])
96
94
 
97
- def __sub__(self: TSelf, other: Tuple[int, int]) -> 'TSelf':
95
+ def __sub__(self, other: Union[Tuple[int, int], Self]) -> Self:
98
96
  if isinstance(other, _BaseGridQid):
99
97
  if self.dimension != other.dimension:
100
98
  raise TypeError(
101
99
  "Can only subtract GridQids with identical dimension. "
102
100
  f"Got {self.dimension} and {other.dimension}"
103
101
  )
104
- return self._with_row_col(row=self.row - other.row, col=self.col - other.col)
102
+ return self._with_row_col(row=self._row - other._row, col=self._col - other._col)
105
103
  if not (
106
104
  isinstance(other, (tuple, np.ndarray))
107
105
  and len(other) == 2
@@ -111,16 +109,16 @@ class _BaseGridQid(ops.Qid):
111
109
  "Can only subtract integer tuples of length 2 to "
112
110
  f"{type(self).__name__}. Instead was {other}"
113
111
  )
114
- return self._with_row_col(row=self.row - other[0], col=self.col - other[1])
112
+ return self._with_row_col(row=self._row - other[0], col=self._col - other[1])
115
113
 
116
- def __radd__(self: TSelf, other: Tuple[int, int]) -> 'TSelf':
114
+ def __radd__(self, other: Tuple[int, int]) -> Self:
117
115
  return self + other
118
116
 
119
- def __rsub__(self: TSelf, other: Tuple[int, int]) -> 'TSelf':
117
+ def __rsub__(self, other: Tuple[int, int]) -> Self:
120
118
  return -self + other
121
119
 
122
- def __neg__(self: TSelf) -> 'TSelf':
123
- return self._with_row_col(row=-self.row, col=-self.col)
120
+ def __neg__(self) -> Self:
121
+ return self._with_row_col(row=-self._row, col=-self._col)
124
122
 
125
123
 
126
124
  class GridQid(_BaseGridQid):
@@ -257,16 +255,16 @@ class GridQid(_BaseGridQid):
257
255
  return [GridQid(*c, dimension=dimension) for c in coords]
258
256
 
259
257
  def __repr__(self) -> str:
260
- return f"cirq.GridQid({self.row}, {self.col}, dimension={self.dimension})"
258
+ return f"cirq.GridQid({self._row}, {self._col}, dimension={self.dimension})"
261
259
 
262
260
  def __str__(self) -> str:
263
- return f"q({self.row}, {self.col}) (d={self.dimension})"
261
+ return f"q({self._row}, {self._col}) (d={self.dimension})"
264
262
 
265
263
  def _circuit_diagram_info_(
266
264
  self, args: 'cirq.CircuitDiagramInfoArgs'
267
265
  ) -> 'cirq.CircuitDiagramInfo':
268
266
  return protocols.CircuitDiagramInfo(
269
- wire_symbols=(f"({self.row}, {self.col}) (d={self.dimension})",)
267
+ wire_symbols=(f"({self._row}, {self._col}) (d={self.dimension})",)
270
268
  )
271
269
 
272
270
  def _json_dict_(self) -> Dict[str, Any]:
@@ -307,13 +305,13 @@ class GridQubit(_BaseGridQid):
307
305
  def __eq__(self, other):
308
306
  # Explicitly implemented for performance (vs delegating to Qid).
309
307
  if isinstance(other, GridQubit):
310
- return self.row == other.row and self.col == other.col
308
+ return self._row == other._row and self._col == other._col
311
309
  return NotImplemented
312
310
 
313
311
  def __ne__(self, other):
314
312
  # Explicitly implemented for performance (vs delegating to Qid).
315
313
  if isinstance(other, GridQubit):
316
- return self.row != other.row or self.col != other.col
314
+ return self._row != other._row or self._col != other._col
317
315
  return NotImplemented
318
316
 
319
317
  @property
@@ -414,15 +412,15 @@ class GridQubit(_BaseGridQid):
414
412
  return [GridQubit(*c) for c in coords]
415
413
 
416
414
  def __repr__(self) -> str:
417
- return f"cirq.GridQubit({self.row}, {self.col})"
415
+ return f"cirq.GridQubit({self._row}, {self._col})"
418
416
 
419
417
  def __str__(self) -> str:
420
- return f"q({self.row}, {self.col})"
418
+ return f"q({self._row}, {self._col})"
421
419
 
422
420
  def _circuit_diagram_info_(
423
421
  self, args: 'cirq.CircuitDiagramInfoArgs'
424
422
  ) -> 'cirq.CircuitDiagramInfo':
425
- return protocols.CircuitDiagramInfo(wire_symbols=(f"({self.row}, {self.col})",))
423
+ return protocols.CircuitDiagramInfo(wire_symbols=(f"({self._row}, {self._col})",))
426
424
 
427
425
  def _json_dict_(self) -> Dict[str, Any]:
428
426
  return protocols.obj_to_dict_helper(self, ['row', 'col'])
@@ -335,23 +335,39 @@ def test_to_json():
335
335
 
336
336
 
337
337
  def test_immutable():
338
- with pytest.raises(AttributeError, match="can't set attribute"):
338
+ # Match one of two strings. The second one is message returned since python 3.11.
339
+ with pytest.raises(
340
+ AttributeError,
341
+ match="(can't set attribute)|(property 'col' of 'GridQubit' object has no setter)",
342
+ ):
339
343
  q = cirq.GridQubit(1, 2)
340
344
  q.col = 3
341
345
 
342
- with pytest.raises(AttributeError, match="can't set attribute"):
346
+ with pytest.raises(
347
+ AttributeError,
348
+ match="(can't set attribute)|(property 'row' of 'GridQubit' object has no setter)",
349
+ ):
343
350
  q = cirq.GridQubit(1, 2)
344
351
  q.row = 3
345
352
 
346
- with pytest.raises(AttributeError, match="can't set attribute"):
353
+ with pytest.raises(
354
+ AttributeError,
355
+ match="(can't set attribute)|(property 'col' of 'GridQid' object has no setter)",
356
+ ):
347
357
  q = cirq.GridQid(1, 2, dimension=3)
348
358
  q.col = 3
349
359
 
350
- with pytest.raises(AttributeError, match="can't set attribute"):
360
+ with pytest.raises(
361
+ AttributeError,
362
+ match="(can't set attribute)|(property 'row' of 'GridQid' object has no setter)",
363
+ ):
351
364
  q = cirq.GridQid(1, 2, dimension=3)
352
365
  q.row = 3
353
366
 
354
- with pytest.raises(AttributeError, match="can't set attribute"):
367
+ with pytest.raises(
368
+ AttributeError,
369
+ match="(can't set attribute)|(property 'dimension' of 'GridQid' object has no setter)",
370
+ ):
355
371
  q = cirq.GridQid(1, 2, dimension=3)
356
372
  q.dimension = 3
357
373
 
@@ -12,20 +12,18 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import functools
16
- from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, TypeVar, TYPE_CHECKING
17
-
18
15
  import abc
16
+ import functools
17
+ from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, TYPE_CHECKING, Union
18
+ from typing_extensions import Self
19
19
 
20
20
  from cirq import ops, protocols
21
21
 
22
22
  if TYPE_CHECKING:
23
23
  import cirq
24
24
 
25
- TSelf = TypeVar('TSelf', bound='_BaseLineQid')
26
-
27
25
 
28
- @functools.total_ordering # type: ignore
26
+ @functools.total_ordering
29
27
  class _BaseLineQid(ops.Qid):
30
28
  """The base class for `LineQid` and `LineQubit`."""
31
29
 
@@ -66,10 +64,10 @@ class _BaseLineQid(ops.Qid):
66
64
  return neighbors
67
65
 
68
66
  @abc.abstractmethod
69
- def _with_x(self: TSelf, x: int) -> TSelf:
67
+ def _with_x(self, x: int) -> Self:
70
68
  """Returns a qubit with the same type but a different value of `x`."""
71
69
 
72
- def __add__(self: TSelf, other: int) -> TSelf:
70
+ def __add__(self, other: Union[int, Self]) -> Self:
73
71
  if isinstance(other, _BaseLineQid):
74
72
  if self.dimension != other.dimension:
75
73
  raise TypeError(
@@ -81,7 +79,7 @@ class _BaseLineQid(ops.Qid):
81
79
  raise TypeError(f"Can only add ints and {type(self).__name__}. Instead was {other}")
82
80
  return self._with_x(self.x + other)
83
81
 
84
- def __sub__(self: TSelf, other: int) -> TSelf:
82
+ def __sub__(self, other: Union[int, Self]) -> Self:
85
83
  if isinstance(other, _BaseLineQid):
86
84
  if self.dimension != other.dimension:
87
85
  raise TypeError(
@@ -95,13 +93,13 @@ class _BaseLineQid(ops.Qid):
95
93
  )
96
94
  return self._with_x(self.x - other)
97
95
 
98
- def __radd__(self: TSelf, other: int) -> TSelf:
96
+ def __radd__(self, other: int) -> Self:
99
97
  return self + other
100
98
 
101
- def __rsub__(self: TSelf, other: int) -> TSelf:
99
+ def __rsub__(self, other: int) -> Self:
102
100
  return -self + other
103
101
 
104
- def __neg__(self: TSelf) -> TSelf:
102
+ def __neg__(self) -> Self:
105
103
  return self._with_x(-self.x)
106
104
 
107
105
  def __complex__(self) -> complex:
@@ -242,11 +242,18 @@ def test_for_gate():
242
242
 
243
243
 
244
244
  def test_immutable():
245
- with pytest.raises(AttributeError, match="can't set attribute"):
245
+ # Match one of two strings. The second one is message returned since python 3.11.
246
+ with pytest.raises(
247
+ AttributeError,
248
+ match="(can't set attribute)|(property 'x' of 'LineQubit' object has no setter)",
249
+ ):
246
250
  q = cirq.LineQubit(5)
247
251
  q.x = 6
248
252
 
249
- with pytest.raises(AttributeError, match="can't set attribute"):
253
+ with pytest.raises(
254
+ AttributeError,
255
+ match="(can't set attribute)|(property 'x' of 'LineQid' object has no setter)",
256
+ ):
250
257
  q = cirq.LineQid(5, dimension=4)
251
258
  q.x = 6
252
259
 
@@ -345,7 +345,7 @@ def draw_placements(
345
345
  small_graph: nx.Graph,
346
346
  small_to_big_mappings: Sequence[Dict],
347
347
  max_plots: int = 20,
348
- axes: Sequence[plt.Axes] = None,
348
+ axes: Optional[Sequence[plt.Axes]] = None,
349
349
  tilted: bool = True,
350
350
  bad_placement_callback: Optional[Callable[[plt.Axes, int], None]] = None,
351
351
  ):
@@ -73,7 +73,7 @@ class NoiseModel(metaclass=value.ABCMetaImplementAnyOneOf):
73
73
 
74
74
  raise TypeError(
75
75
  'Expected a NOISE_MODEL_LIKE (None, a cirq.NoiseModel, '
76
- 'or a single qubit gate). Got {!r}'.format(noise)
76
+ f'or a single qubit gate). Got {noise!r}'
77
77
  )
78
78
 
79
79
  def is_virtual_moment(self, moment: 'cirq.Moment') -> bool:
@@ -125,6 +125,7 @@ class NoiseModel(metaclass=value.ABCMetaImplementAnyOneOf):
125
125
  A sequence of OP_TREEs, with the k'th tree corresponding to the
126
126
  noisy operations for the k'th moment.
127
127
  """
128
+ raise NotImplementedError
128
129
 
129
130
  def _noisy_moment_impl_moments(
130
131
  self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']
@@ -150,6 +151,7 @@ class NoiseModel(metaclass=value.ABCMetaImplementAnyOneOf):
150
151
  Returns:
151
152
  An OP_TREE corresponding to the noisy operations for the moment.
152
153
  """
154
+ raise NotImplementedError
153
155
 
154
156
  def _noisy_operation_impl_moments(self, operation: 'cirq.Operation') -> 'cirq.OP_TREE':
155
157
  return self.noisy_moments([moment_module.Moment([operation])], operation.qubits)
@@ -169,6 +171,7 @@ class NoiseModel(metaclass=value.ABCMetaImplementAnyOneOf):
169
171
  An OP_TREE corresponding to the noisy operations implementing the
170
172
  noisy version of the given operation.
171
173
  """
174
+ raise NotImplementedError
172
175
 
173
176
 
174
177
  @value.value_equality
@@ -27,9 +27,7 @@ if TYPE_CHECKING:
27
27
 
28
28
 
29
29
  # TODO: missing per-device defaults
30
- # Type-ignored because mypy cannot handle abstract dataclasses:
31
- # https://github.com/python/mypy/issues/5374
32
- @dataclass # type: ignore
30
+ @dataclass
33
31
  class SuperconductingQubitsNoiseProperties(devices.NoiseProperties, abc.ABC):
34
32
  """Noise-defining properties for a superconducting-qubit-based device.
35
33
 
@@ -134,7 +134,7 @@ def state_tomography(
134
134
  qubits: Sequence['cirq.Qid'],
135
135
  circuit: 'cirq.Circuit',
136
136
  repetitions: int = 1000,
137
- prerotations: Sequence[Tuple[float, float]] = None,
137
+ prerotations: Optional[Sequence[Tuple[float, float]]] = None,
138
138
  ) -> TomographyResult:
139
139
  """This performs n qubit tomography on a cirq circuit
140
140
 
@@ -542,8 +542,8 @@ def _matrix_bar_plot(
542
542
  mat: np.ndarray,
543
543
  z_label: str,
544
544
  ax: plt.Axes,
545
- kets: Sequence[str] = None,
546
- title: str = None,
545
+ kets: Optional[Sequence[str]] = None,
546
+ title: Optional[str] = None,
547
547
  ylim: Tuple[int, int] = (-1, 1),
548
548
  **bar3d_kwargs: Any,
549
549
  ) -> None:
@@ -111,7 +111,7 @@ def estimate_parallel_single_qubit_readout_errors(
111
111
  trials: int = 20,
112
112
  repetitions: int = 1000,
113
113
  trials_per_batch: Optional[int] = None,
114
- bit_strings: np.ndarray = None,
114
+ bit_strings: Optional[np.ndarray] = None,
115
115
  ) -> SingleQubitReadoutCalibrationResult:
116
116
  """Estimate single qubit readout error using parallel operations.
117
117
 
@@ -45,7 +45,7 @@ def t2_decay(
45
45
  min_delay: 'cirq.DURATION_LIKE' = None,
46
46
  repetitions: int = 1000,
47
47
  delay_sweep: Optional[study.Sweep] = None,
48
- num_pulses: List[int] = None,
48
+ num_pulses: Optional[List[int]] = None,
49
49
  ) -> Union['cirq.experiments.T2DecayResult', List['cirq.experiments.T2DecayResult']]:
50
50
  """Runs a t2 transverse relaxation experiment.
51
51
 
@@ -59,7 +59,7 @@ def test_simulate_circuit_length_validation():
59
59
  )
60
60
  for _ in range(2)
61
61
  ]
62
- cycle_depths = np.arange(3, 50, 9)
62
+ cycle_depths = np.arange(3, 50, 9, dtype=np.int64)
63
63
  with pytest.raises(ValueError, match='.*not long enough.*'):
64
64
  _ = simulate_2q_xeb_circuits(circuits=circuits, cycle_depths=cycle_depths)
65
65
 
@@ -127,7 +127,7 @@ def test_incremental_simulate(multiprocess):
127
127
  )
128
128
  for _ in range(20)
129
129
  ]
130
- cycle_depths = np.arange(3, 100, 9)
130
+ cycle_depths = np.arange(3, 100, 9, dtype=np.int64)
131
131
 
132
132
  if multiprocess:
133
133
  pool = multiprocessing.Pool()
@@ -22,7 +22,7 @@ from cirq import quirk_url_to_circuit
22
22
 
23
23
  def assert_url_to_circuit_returns(
24
24
  json_text: str,
25
- circuit: 'cirq.Circuit' = None,
25
+ circuit: Optional['cirq.Circuit'] = None,
26
26
  *,
27
27
  unitary: Optional[np.ndarray] = None,
28
28
  diagram: Optional[str] = None,
@@ -241,6 +241,7 @@ def _class_resolver_dictionary() -> Dict[str, ObjectFactory]:
241
241
  'YYPowGate': cirq.YYPowGate,
242
242
  '_ZEigenState': cirq.value.product_state._ZEigenState,
243
243
  'Zip': cirq.Zip,
244
+ 'ZipLongest': cirq.ZipLongest,
244
245
  'ZPowGate': cirq.ZPowGate,
245
246
  'ZZPowGate': cirq.ZZPowGate,
246
247
  # Old types, only supported for backwards-compatibility
cirq/linalg/__init__.py CHANGED
@@ -81,4 +81,6 @@ from cirq.linalg.transformations import (
81
81
  targeted_conjugate_about,
82
82
  targeted_left_multiply,
83
83
  to_special,
84
+ transpose_flattened_array,
85
+ can_numpy_support_shape,
84
86
  )
@@ -367,12 +367,12 @@ def test_kak_repr():
367
367
  cirq.KakDecomposition(
368
368
  interaction_coefficients=(0.5, 0.25, 0),
369
369
  single_qubit_operations_before=(
370
- np.array([[0j, (1+0j)], [(1+0j), 0j]], dtype=np.complex128),
371
- np.array([[0j, -1j], [1j, 0j]], dtype=np.complex128),
370
+ np.array([[0j, (1+0j)], [(1+0j), 0j]], dtype=np.dtype('complex128')),
371
+ np.array([[0j, -1j], [1j, 0j]], dtype=np.dtype('complex128')),
372
372
  ),
373
373
  single_qubit_operations_after=(
374
- np.array([[1.0, 0.0], [0.0, 1.0]], dtype=np.float64),
375
- np.array([[(1+0j), 0j], [0j, (-1+0j)]], dtype=np.complex128),
374
+ np.array([[1.0, 0.0], [0.0, 1.0]], dtype=np.dtype('float64')),
375
+ np.array([[(1+0j), 0j], [0j, (-1+0j)]], dtype=np.dtype('complex128')),
376
376
  ),
377
377
  global_phase=1)
378
378
  """.strip()
@@ -60,8 +60,9 @@ def random_bi_diagonalizable_pair(
60
60
 
61
61
 
62
62
  def _get_assert_diagonalized_by_str(m, p, d):
63
- return 'm.round(3) : {}, p.round(3) : {}, np.abs(p.T @ m @ p).round(2): {}'.format(
64
- np.round(m, 3), np.round(p, 3), np.abs(d).round(2)
63
+ return (
64
+ f'm.round(3) : {np.round(m, 3)}, p.round(3) : {np.round(p, 3)}, '
65
+ f'np.abs(p.T @ m @ p).round(2): {np.abs(d).round(2)}'
65
66
  )
66
67
 
67
68
 
@@ -75,10 +76,8 @@ def assert_diagonalized_by(m, p, atol: float = 1e-8):
75
76
 
76
77
  def _get_assert_bidiagonalized_by_str(m, p, q, d):
77
78
  return (
78
- 'm.round(3) : {}, p.round(3) : {}, q.round(3): {}, '
79
- 'np.abs(p.T @ m @ p).round(2): {}'.format(
80
- np.round(m, 3), np.round(p, 3), np.round(q, 3), np.abs(d).round(2)
81
- )
79
+ f'm.round(3) : {np.round(m, 3)}, p.round(3) : {np.round(p, 3)}, '
80
+ f'q.round(3): {np.round(q, 3)}, np.abs(p.T @ m @ p).round(2): {np.abs(d).round(2)}'
82
81
  )
83
82
 
84
83