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
@@ -29,6 +29,8 @@ from cirq.linalg import predicates
29
29
  # user provides a different np.array([]) value.
30
30
  RaiseValueErrorIfNotProvided: np.ndarray = np.array([])
31
31
 
32
+ _NPY_MAXDIMS = 32 # Should be changed once numpy/numpy#5744 is resolved.
33
+
32
34
 
33
35
  def reflection_matrix_pow(reflection_matrix: np.ndarray, exponent: float):
34
36
  """Raises a matrix with two opposing eigenvalues to a power.
@@ -249,7 +251,7 @@ def targeted_conjugate_about(
249
251
  tensor: np.ndarray,
250
252
  target: np.ndarray,
251
253
  indices: Sequence[int],
252
- conj_indices: Sequence[int] = None,
254
+ conj_indices: Optional[Sequence[int]] = None,
253
255
  buffer: Optional[np.ndarray] = None,
254
256
  out: Optional[np.ndarray] = None,
255
257
  ) -> np.ndarray:
@@ -399,13 +401,13 @@ def partial_trace(tensor: np.ndarray, keep_indices: Sequence[int]) -> np.ndarray
399
401
  ndim = tensor.ndim // 2
400
402
  if not all(tensor.shape[i] == tensor.shape[i + ndim] for i in range(ndim)):
401
403
  raise ValueError(
402
- 'Tensors must have shape (d_0,...,d_{{k-1}},d_0,...,'
403
- 'd_{{k-1}}) but had shape ({}).'.format(tensor.shape)
404
+ f'Tensors must have shape (d_0,...,d_{{k-1}},d_0,...,'
405
+ f'd_{{k-1}}) but had shape ({tensor.shape}).'
404
406
  )
405
407
  if not all(i < ndim for i in keep_indices):
406
408
  raise ValueError(
407
- 'keep_indices were {} but must be in first half, '
408
- 'i.e. have index less that {}.'.format(keep_indices, ndim)
409
+ f'keep_indices were {keep_indices} but must be in first half, '
410
+ f'i.e. have index less that {ndim}.'
409
411
  )
410
412
  keep_set = set(keep_indices)
411
413
  keep_map = dict(zip(keep_indices, sorted(keep_indices)))
@@ -530,8 +532,8 @@ def sub_state_vector(
530
532
 
531
533
  if not np.log2(state_vector.size).is_integer():
532
534
  raise ValueError(
533
- "Input state_vector of size {} does not represent a "
534
- "state over qubits.".format(state_vector.size)
535
+ f"Input state_vector of size {state_vector.size} does not represent a "
536
+ "state over qubits."
535
537
  )
536
538
 
537
539
  n_qubits = int(np.log2(state_vector.size))
@@ -572,8 +574,7 @@ def sub_state_vector(
572
574
  return default
573
575
 
574
576
  raise EntangledStateError(
575
- "Input state vector could not be factored into pure state over "
576
- "indices {}".format(keep_indices)
577
+ f"Input state vector could not be factored into pure state over indices {keep_indices}"
577
578
  )
578
579
 
579
580
 
@@ -746,3 +747,65 @@ def transpose_density_matrix_to_axis_order(t: np.ndarray, axes: Sequence[int]):
746
747
  """
747
748
  axes = list(axes) + [i + len(axes) for i in axes]
748
749
  return transpose_state_vector_to_axis_order(t, axes)
750
+
751
+
752
+ def _volumes(shape: Sequence[int]) -> List[int]:
753
+ r"""Returns a list of the volume spanned by each dimension.
754
+
755
+ Given a shape=[d_0, d_1, .., d_n] the volume spanned by each dimension is
756
+ volume[i] = `\prod_{j=i+1}^n d_j`
757
+
758
+ Args:
759
+ shape: Sequence of the size of each dimension.
760
+
761
+ Returns:
762
+ Sequence of the volume spanned of each dimension.
763
+ """
764
+ volume = [0] * len(shape)
765
+ v = 1
766
+ for i in reversed(range(len(shape))):
767
+ volume[i] = v
768
+ v *= shape[i]
769
+ return volume
770
+
771
+
772
+ def _coordinates_from_index(idx: int, volume: Sequence[int]) -> Sequence[int]:
773
+ ret = []
774
+ for v in volume:
775
+ ret.append(idx // v)
776
+ idx %= v
777
+ return tuple(ret)
778
+
779
+
780
+ def _index_from_coordinates(s: Sequence[int], volume: Sequence[int]) -> int:
781
+ return np.dot(s, volume)
782
+
783
+
784
+ def transpose_flattened_array(t: np.ndarray, shape: Sequence[int], axes: Sequence[int]):
785
+ """Transposes a flattened array.
786
+
787
+ Equivalent to np.transpose(t.reshape(shape), axes).reshape((-1,)).
788
+
789
+ Args:
790
+ t: flat array.
791
+ shape: the shape of `t` before flattening.
792
+ axes: permutation of range(len(shape)).
793
+
794
+ Returns:
795
+ Flattened transpose of `t`.
796
+ """
797
+ if len(t.shape) != 1:
798
+ t = t.reshape((-1,))
799
+ cur_volume = _volumes(shape)
800
+ new_volume = _volumes([shape[i] for i in axes])
801
+ ret = np.zeros_like(t)
802
+ for idx in range(t.shape[0]):
803
+ cell = _coordinates_from_index(idx, cur_volume)
804
+ new_cell = [cell[i] for i in axes]
805
+ ret[_index_from_coordinates(new_cell, new_volume)] = t[idx]
806
+ return ret
807
+
808
+
809
+ def can_numpy_support_shape(shape: Sequence[int]) -> bool:
810
+ """Returns whether numpy supports the given shape or not numpy/numpy#5744."""
811
+ return len(shape) <= _NPY_MAXDIMS
@@ -17,6 +17,7 @@ import pytest
17
17
 
18
18
  import cirq
19
19
  import cirq.testing
20
+ from cirq import linalg
20
21
 
21
22
 
22
23
  def test_reflection_matrix_pow_consistent_results():
@@ -352,20 +353,20 @@ def test_sub_state_vector():
352
353
  a = np.arange(4) / np.linalg.norm(np.arange(4))
353
354
  b = (np.arange(8) + 3) / np.linalg.norm(np.arange(8) + 3)
354
355
  c = (np.arange(16) + 1) / np.linalg.norm(np.arange(16) + 1)
355
- state = np.kron(np.kron(a, b), c).reshape(2, 2, 2, 2, 2, 2, 2, 2, 2)
356
+ state = np.kron(np.kron(a, b), c).reshape((2, 2, 2, 2, 2, 2, 2, 2, 2))
356
357
 
357
358
  assert cirq.equal_up_to_global_phase(cirq.sub_state_vector(a, [0, 1], atol=1e-8), a)
358
359
  assert cirq.equal_up_to_global_phase(cirq.sub_state_vector(b, [0, 1, 2], atol=1e-8), b)
359
360
  assert cirq.equal_up_to_global_phase(cirq.sub_state_vector(c, [0, 1, 2, 3], atol=1e-8), c)
360
361
 
361
362
  assert cirq.equal_up_to_global_phase(
362
- cirq.sub_state_vector(state, [0, 1], atol=1e-15), a.reshape(2, 2)
363
+ cirq.sub_state_vector(state, [0, 1], atol=1e-15), a.reshape((2, 2))
363
364
  )
364
365
  assert cirq.equal_up_to_global_phase(
365
- cirq.sub_state_vector(state, [2, 3, 4], atol=1e-15), b.reshape(2, 2, 2)
366
+ cirq.sub_state_vector(state, [2, 3, 4], atol=1e-15), b.reshape((2, 2, 2))
366
367
  )
367
368
  assert cirq.equal_up_to_global_phase(
368
- cirq.sub_state_vector(state, [5, 6, 7, 8], atol=1e-15), c.reshape(2, 2, 2, 2)
369
+ cirq.sub_state_vector(state, [5, 6, 7, 8], atol=1e-15), c.reshape((2, 2, 2, 2))
369
370
  )
370
371
 
371
372
  # Output state vector conforms to the shape of the input state vector.
@@ -485,15 +486,15 @@ def test_partial_trace_of_state_vector_as_mixture_pure_result():
485
486
 
486
487
  assert mixtures_equal(
487
488
  cirq.partial_trace_of_state_vector_as_mixture(state, [0, 1], atol=1e-8),
488
- ((1.0, a.reshape(2, 2)),),
489
+ ((1.0, a.reshape((2, 2))),),
489
490
  )
490
491
  assert mixtures_equal(
491
492
  cirq.partial_trace_of_state_vector_as_mixture(state, [2, 3, 4], atol=1e-8),
492
- ((1.0, b.reshape(2, 2, 2)),),
493
+ ((1.0, b.reshape((2, 2, 2))),),
493
494
  )
494
495
  assert mixtures_equal(
495
496
  cirq.partial_trace_of_state_vector_as_mixture(state, [5, 6, 7, 8], atol=1e-8),
496
- ((1.0, c.reshape(2, 2, 2, 2)),),
497
+ ((1.0, c.reshape((2, 2, 2, 2))),),
497
498
  )
498
499
  assert mixtures_equal(
499
500
  cirq.partial_trace_of_state_vector_as_mixture(state, [0, 1, 2, 3, 4], atol=1e-8),
@@ -632,3 +633,18 @@ def test_factor_state_vector(state_1: int, state_2: int):
632
633
  # All phase goes into a1, and b1 is just the dephased state vector
633
634
  assert np.allclose(a1, a * phase)
634
635
  assert np.allclose(b1, b)
636
+
637
+
638
+ @pytest.mark.parametrize('num_dimensions', [*range(1, 7)])
639
+ def test_transpose_flattened_array(num_dimensions):
640
+ np.random.seed(0)
641
+ for _ in range(10):
642
+ shape = np.random.randint(1, 5, (num_dimensions,)).tolist()
643
+ axes = np.random.permutation(num_dimensions).tolist()
644
+ volume = np.prod(shape)
645
+ A = np.random.permutation(volume)
646
+ want = np.transpose(A.reshape(shape), axes)
647
+ got = linalg.transpose_flattened_array(A, shape, axes).reshape(want.shape)
648
+ assert np.array_equal(want, got)
649
+ got = linalg.transpose_flattened_array(A.reshape(shape), shape, axes).reshape(want.shape)
650
+ assert np.array_equal(want, got)
cirq/ops/__init__.py CHANGED
@@ -41,6 +41,7 @@ from cirq.ops.common_channels import (
41
41
  phase_flip,
42
42
  PhaseDampingChannel,
43
43
  PhaseFlipChannel,
44
+ R,
44
45
  reset,
45
46
  reset_each,
46
47
  ResetChannel,
@@ -119,6 +120,8 @@ from cirq.ops.projector import ProjectorString
119
120
 
120
121
  from cirq.ops.controlled_operation import ControlledOperation
121
122
 
123
+ from cirq.ops.qubit_manager import BorrowableQubit, CleanQubit, QubitManager, SimpleQubitManager
124
+
122
125
  from cirq.ops.qubit_order import QubitOrder
123
126
 
124
127
  from cirq.ops.qubit_order_or_list import QubitOrderOrList
@@ -126,6 +129,7 @@ from cirq.ops.qubit_order_or_list import QubitOrderOrList
126
129
  from cirq.ops.matrix_gates import MatrixGate
127
130
 
128
131
  from cirq.ops.measure_util import (
132
+ M,
129
133
  measure,
130
134
  measure_each,
131
135
  measure_paulistring_terms,
@@ -15,7 +15,8 @@
15
15
 
16
16
  import abc
17
17
  import itertools
18
- from typing import Union, Iterable, List, Sequence, cast, Tuple, TypeVar, TYPE_CHECKING
18
+ from typing import Union, Iterable, List, Sequence, cast, Tuple, TYPE_CHECKING
19
+ from typing_extensions import Self
19
20
 
20
21
  import numpy as np
21
22
 
@@ -25,9 +26,6 @@ if TYPE_CHECKING:
25
26
  import cirq
26
27
 
27
28
 
28
- TSelfGate = TypeVar('TSelfGate', bound='ArithmeticGate')
29
-
30
-
31
29
  class ArithmeticGate(Gate, metaclass=abc.ABCMeta):
32
30
  r"""A helper gate for implementing reversible classical arithmetic.
33
31
 
@@ -55,7 +53,7 @@ class ArithmeticGate(Gate, metaclass=abc.ABCMeta):
55
53
  ...
56
54
  ... def with_registers(
57
55
  ... self, *new_registers: 'Union[int, Sequence[int]]'
58
- ... ) -> 'TSelfGate':
56
+ ... ) -> 'Add':
59
57
  ... return Add(*new_registers)
60
58
  ...
61
59
  ... def apply(self, *register_values: int) -> 'Union[int, Iterable[int]]':
@@ -105,7 +103,7 @@ class ArithmeticGate(Gate, metaclass=abc.ABCMeta):
105
103
  raise NotImplementedError()
106
104
 
107
105
  @abc.abstractmethod
108
- def with_registers(self: TSelfGate, *new_registers: Union[int, Sequence[int]]) -> TSelfGate:
106
+ def with_registers(self, *new_registers: Union[int, Sequence[int]]) -> Self:
109
107
  """Returns the same fate targeting different registers.
110
108
 
111
109
  Args:
@@ -28,7 +28,7 @@ from typing import (
28
28
  import sympy
29
29
 
30
30
  from cirq import protocols, value
31
- from cirq.ops import raw_types
31
+ from cirq.ops import op_tree, raw_types
32
32
 
33
33
  if TYPE_CHECKING:
34
34
  import cirq
@@ -105,11 +105,18 @@ class ClassicallyControlledOperation(raw_types.Operation):
105
105
  )
106
106
 
107
107
  def _decompose_(self):
108
- result = protocols.decompose_once(self._sub_operation, NotImplemented)
108
+ return self._decompose_with_context_()
109
+
110
+ def _decompose_with_context_(self, context: Optional['cirq.DecompositionContext'] = None):
111
+ result = protocols.decompose_once(
112
+ self._sub_operation, NotImplemented, flatten=False, context=context
113
+ )
109
114
  if result is NotImplemented:
110
115
  return NotImplemented
111
116
 
112
- return [ClassicallyControlledOperation(op, self._conditions) for op in result]
117
+ return op_tree.transform_op_tree(
118
+ result, lambda op: ClassicallyControlledOperation(op, self._conditions)
119
+ )
113
120
 
114
121
  def _value_equality_values_(self):
115
122
  return (frozenset(self._conditions), self._sub_operation)
cirq/ops/clifford_gate.py CHANGED
@@ -75,12 +75,6 @@ def _to_clifford_tableau(
75
75
  return clifford_tableau
76
76
 
77
77
 
78
- def _pretend_initialized() -> 'SingleQubitCliffordGate':
79
- # HACK: This is a workaround to fool mypy and pylint into correctly handling
80
- # class fields that can't be initialized until after the class is defined.
81
- pass
82
-
83
-
84
78
  def _validate_map_input(
85
79
  required_transform_count: int,
86
80
  pauli_map_to: Optional[Dict[Pauli, Tuple[Pauli, bool]]],
@@ -97,6 +91,7 @@ def _validate_map_input(
97
91
  ' of x_to, y_to, and z_to but both were given'
98
92
  )
99
93
  if len(pauli_map_to) != required_transform_count:
94
+ # pylint: disable=consider-using-f-string
100
95
  raise ValueError(
101
96
  'Method takes {} transform{} but {} {} given'.format(
102
97
  required_transform_count,
@@ -440,7 +435,6 @@ class CliffordGate(raw_types.Gate, CommonCliffordGates):
440
435
  def _act_on_(
441
436
  self, sim_state: 'cirq.SimulationStateBase', qubits: Sequence['cirq.Qid']
442
437
  ) -> Union[NotImplementedType, bool]:
443
-
444
438
  # Note the computation complexity difference between _decompose_ and _act_on_.
445
439
  # Suppose this Gate has `m` qubits, args has `n` qubits, and the decomposition of
446
440
  # this operation into `k` operations:
@@ -775,10 +775,16 @@ class ResetChannel(raw_types.Gate):
775
775
 
776
776
 
777
777
  def reset(qubit: 'cirq.Qid') -> raw_types.Operation:
778
- """Returns a `cirq.ResetChannel` on the given qubit."""
778
+ """Returns a `cirq.ResetChannel` on the given qubit.
779
+
780
+ This can also be used with the alias `cirq.R`.
781
+ """
779
782
  return ResetChannel(qubit.dimension).on(qubit)
780
783
 
781
784
 
785
+ R = reset
786
+
787
+
782
788
  def reset_each(*qubits: 'cirq.Qid') -> List[raw_types.Operation]:
783
789
  """Returns a list of `cirq.ResetChannel` instances on the given qubits."""
784
790
  return [ResetChannel(q.dimension).on(q) for q in qubits]
@@ -1010,15 +1016,15 @@ def _phase_flip(p: float) -> PhaseFlipChannel:
1010
1016
 
1011
1017
  $$
1012
1018
  \begin{aligned}
1013
- M_0 =& \sqrt{p} \begin{bmatrix}
1019
+ M_0 =& \sqrt{1 - p} \begin{bmatrix}
1014
1020
  1 & 0 \\
1015
1021
  0 & 1
1016
- \end{bmatrix}
1022
+ \end{bmatrix}
1017
1023
  \\
1018
- M_1 =& \sqrt{1-p} \begin{bmatrix}
1024
+ M_1 =& \sqrt{p} \begin{bmatrix}
1019
1025
  1 & 0 \\
1020
1026
  0 & -1
1021
- \end{bmatrix}
1027
+ \end{bmatrix}
1022
1028
  \end{aligned}
1023
1029
  $$
1024
1030
 
@@ -1046,15 +1052,15 @@ def phase_flip(p: Optional[float] = None) -> Union[common_gates.ZPowGate, PhaseF
1046
1052
 
1047
1053
  $$
1048
1054
  \begin{aligned}
1049
- M_0 =& \sqrt{p} \begin{bmatrix}
1055
+ M_0 =& \sqrt{1 - p} \begin{bmatrix}
1050
1056
  1 & 0 \\
1051
1057
  0 & 1
1052
- \end{bmatrix}
1058
+ \end{bmatrix}
1053
1059
  \\
1054
- M_1 =& \sqrt{1-p} \begin{bmatrix}
1060
+ M_1 =& \sqrt{p} \begin{bmatrix}
1055
1061
  1 & 0 \\
1056
1062
  0 & -1
1057
- \end{bmatrix}
1063
+ \end{bmatrix}
1058
1064
  \end{aligned}
1059
1065
  $$
1060
1066
 
@@ -1162,14 +1168,14 @@ def _bit_flip(p: float) -> BitFlipChannel:
1162
1168
 
1163
1169
  $$
1164
1170
  \begin{aligned}
1165
- M_0 =& \sqrt{p} \begin{bmatrix}
1171
+ M_0 =& \sqrt{1-p} \begin{bmatrix}
1166
1172
  1 & 0 \\
1167
1173
  0 & 1
1168
1174
  \end{bmatrix}
1169
1175
  \\
1170
- M_1 =& \sqrt{1-p} \begin{bmatrix}
1176
+ M_1 =& \sqrt{p} \begin{bmatrix}
1171
1177
  0 & 1 \\
1172
- 1 & -0
1178
+ 1 & 0
1173
1179
  \end{bmatrix}
1174
1180
  \end{aligned}
1175
1181
  $$
@@ -1198,14 +1204,14 @@ def bit_flip(p: Optional[float] = None) -> Union[common_gates.XPowGate, BitFlipC
1198
1204
 
1199
1205
  $$
1200
1206
  \begin{aligned}
1201
- M_0 =& \sqrt{p} \begin{bmatrix}
1207
+ M_0 =& \sqrt{1-p} \begin{bmatrix}
1202
1208
  1 & 0 \\
1203
1209
  0 & 1
1204
1210
  \end{bmatrix}
1205
1211
  \\
1206
- M_1 =& \sqrt{1-p} \begin{bmatrix}
1212
+ M_1 =& \sqrt{p} \begin{bmatrix}
1207
1213
  0 & 1 \\
1208
- 1 & -0
1214
+ 1 & 0
1209
1215
  \end{bmatrix}
1210
1216
  \end{aligned}
1211
1217
  $$
@@ -37,9 +37,8 @@ class AnyUnitaryGateFamily(gateset.GateFamily):
37
37
 
38
38
  self._num_qubits = num_qubits
39
39
  name = f'{str(num_qubits) if num_qubits else "Any"}-Qubit UnitaryGateFamily'
40
- description = 'Accepts any {}unitary gate'.format(
41
- f'{num_qubits}-qubit ' if num_qubits else ''
42
- )
40
+ kind = f'{num_qubits}-qubit ' if num_qubits else ''
41
+ description = f'Accepts any {kind}unitary gate'
43
42
  super().__init__(raw_types.Gate, name=name, description=description)
44
43
 
45
44
  def _predicate(self, g: raw_types.Gate) -> bool:
cirq/ops/common_gates.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
  """Quantum gates that are commonly used in the literature.
15
16
 
16
17
  This module creates Gate instances for the following gates:
@@ -120,6 +121,10 @@ class XPowGate(eigen_gate.EigenGate):
120
121
  super().__init__(exponent=exponent, global_shift=global_shift)
121
122
  self._dimension = dimension
122
123
 
124
+ @property
125
+ def dimension(self) -> value.TParamVal:
126
+ return self._dimension
127
+
123
128
  def _num_qubits_(self) -> int:
124
129
  return 1
125
130
 
@@ -183,7 +188,7 @@ class XPowGate(eigen_gate.EigenGate):
183
188
 
184
189
  def controlled(
185
190
  self,
186
- num_controls: int = None,
191
+ num_controls: Optional[int] = None,
187
192
  control_values: Optional[
188
193
  Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
189
194
  ] = None,
@@ -316,6 +321,18 @@ class XPowGate(eigen_gate.EigenGate):
316
321
  all_args = ', '.join(args)
317
322
  return f'cirq.XPowGate({all_args})'
318
323
 
324
+ def _json_dict_(self) -> Dict[str, Any]:
325
+ d = protocols.obj_to_dict_helper(self, ['exponent', 'global_shift'])
326
+ if self.dimension != 2:
327
+ d['dimension'] = self.dimension
328
+ return d
329
+
330
+ def _value_equality_values_(self):
331
+ return (*super()._value_equality_values_(), self._dimension)
332
+
333
+ def _value_equality_approximate_values_(self):
334
+ return (*super()._value_equality_approximate_values_(), self._dimension)
335
+
319
336
 
320
337
  class Rx(XPowGate):
321
338
  r"""A gate with matrix $e^{-i X t/2}$ that rotates around the X axis of the Bloch sphere by $t$.
@@ -341,7 +358,7 @@ class Rx(XPowGate):
341
358
  self._rads = rads
342
359
  super().__init__(exponent=rads / _pi(rads), global_shift=-0.5)
343
360
 
344
- def _with_exponent(self: 'Rx', exponent: value.TParamVal) -> 'Rx':
361
+ def _with_exponent(self, exponent: value.TParamVal) -> 'Rx':
345
362
  return Rx(rads=exponent * _pi(exponent))
346
363
 
347
364
  def _circuit_diagram_info_(
@@ -496,8 +513,10 @@ class YPowGate(eigen_gate.EigenGate):
496
513
  if self._exponent == 1:
497
514
  return 'cirq.Y'
498
515
  return f'(cirq.Y**{proper_repr(self._exponent)})'
499
- return 'cirq.YPowGate(exponent={}, global_shift={!r})'.format(
500
- proper_repr(self._exponent), self._global_shift
516
+ return (
517
+ 'cirq.YPowGate('
518
+ f'exponent={proper_repr(self._exponent)}, '
519
+ f'global_shift={self._global_shift!r})'
501
520
  )
502
521
 
503
522
 
@@ -525,7 +544,7 @@ class Ry(YPowGate):
525
544
  self._rads = rads
526
545
  super().__init__(exponent=rads / _pi(rads), global_shift=-0.5)
527
546
 
528
- def _with_exponent(self: 'Ry', exponent: value.TParamVal) -> 'Ry':
547
+ def _with_exponent(self, exponent: value.TParamVal) -> 'Ry':
529
548
  return Ry(rads=exponent * _pi(exponent))
530
549
 
531
550
  def _circuit_diagram_info_(
@@ -608,6 +627,10 @@ class ZPowGate(eigen_gate.EigenGate):
608
627
  super().__init__(exponent=exponent, global_shift=global_shift)
609
628
  self._dimension = dimension
610
629
 
630
+ @property
631
+ def dimension(self) -> value.TParamVal:
632
+ return self._dimension
633
+
611
634
  def _num_qubits_(self) -> int:
612
635
  return 1
613
636
 
@@ -647,7 +670,7 @@ class ZPowGate(eigen_gate.EigenGate):
647
670
 
648
671
  def controlled(
649
672
  self,
650
- num_controls: int = None,
673
+ num_controls: Optional[int] = None,
651
674
  control_values: Optional[
652
675
  Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
653
676
  ] = None,
@@ -834,6 +857,18 @@ class ZPowGate(eigen_gate.EigenGate):
834
857
  return NotImplemented
835
858
  return True
836
859
 
860
+ def _json_dict_(self) -> Dict[str, Any]:
861
+ d = protocols.obj_to_dict_helper(self, ['exponent', 'global_shift'])
862
+ if self.dimension != 2:
863
+ d['dimension'] = self.dimension
864
+ return d
865
+
866
+ def _value_equality_values_(self):
867
+ return (*super()._value_equality_values_(), self._dimension)
868
+
869
+ def _value_equality_approximate_values_(self):
870
+ return (*super()._value_equality_approximate_values_(), self._dimension)
871
+
837
872
 
838
873
  class Rz(ZPowGate):
839
874
  r"""A gate with matrix $e^{-i Z t/2}$ that rotates around the Z axis of the Bloch sphere by $t$.
@@ -859,7 +894,7 @@ class Rz(ZPowGate):
859
894
  self._rads = rads
860
895
  super().__init__(exponent=rads / _pi(rads), global_shift=-0.5)
861
896
 
862
- def _with_exponent(self: 'Rz', exponent: value.TParamVal) -> 'Rz':
897
+ def _with_exponent(self, exponent: value.TParamVal) -> 'Rz':
863
898
  return Rz(rads=exponent * _pi(exponent))
864
899
 
865
900
  def _circuit_diagram_info_(
@@ -1090,7 +1125,7 @@ class CZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
1090
1125
 
1091
1126
  def controlled(
1092
1127
  self,
1093
- num_controls: int = None,
1128
+ num_controls: Optional[int] = None,
1094
1129
  control_values: Optional[
1095
1130
  Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
1096
1131
  ] = None,
@@ -1189,8 +1224,10 @@ class CZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
1189
1224
  if self._exponent == 1:
1190
1225
  return 'cirq.CZ'
1191
1226
  return f'(cirq.CZ**{proper_repr(self._exponent)})'
1192
- return 'cirq.CZPowGate(exponent={}, global_shift={!r})'.format(
1193
- proper_repr(self._exponent), self._global_shift
1227
+ return (
1228
+ 'cirq.CZPowGate('
1229
+ f'exponent={proper_repr(self._exponent)}, '
1230
+ f'global_shift={self._global_shift!r})'
1194
1231
  )
1195
1232
 
1196
1233
 
@@ -1296,7 +1333,7 @@ class CXPowGate(eigen_gate.EigenGate):
1296
1333
 
1297
1334
  def controlled(
1298
1335
  self,
1299
- num_controls: int = None,
1336
+ num_controls: Optional[int] = None,
1300
1337
  control_values: Optional[
1301
1338
  Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
1302
1339
  ] = None,
@@ -1100,6 +1100,7 @@ def test_approx_eq():
1100
1100
 
1101
1101
  def test_xpow_dim_3():
1102
1102
  x = cirq.XPowGate(dimension=3)
1103
+ assert cirq.X != x
1103
1104
  # fmt: off
1104
1105
  expected = [
1105
1106
  [0, 0, 1],
@@ -1127,6 +1128,7 @@ def test_xpow_dim_3():
1127
1128
 
1128
1129
  def test_xpow_dim_4():
1129
1130
  x = cirq.XPowGate(dimension=4)
1131
+ assert cirq.X != x
1130
1132
  # fmt: off
1131
1133
  expected = [
1132
1134
  [0, 0, 0, 1],
@@ -1159,6 +1161,7 @@ def test_zpow_dim_3():
1159
1161
  L = np.exp(2 * np.pi * 1j / 3)
1160
1162
  L2 = L**2
1161
1163
  z = cirq.ZPowGate(dimension=3)
1164
+ assert cirq.Z != z
1162
1165
  # fmt: off
1163
1166
  expected = [
1164
1167
  [1, 0, 0],
@@ -1209,6 +1212,7 @@ def test_zpow_dim_3():
1209
1212
 
1210
1213
  def test_zpow_dim_4():
1211
1214
  z = cirq.ZPowGate(dimension=4)
1215
+ assert cirq.Z != z
1212
1216
  # fmt: off
1213
1217
  expected = [
1214
1218
  [1, 0, 0, 0],