cirq-core 1.3.0.dev20231201164435__py3-none-any.whl → 1.4.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.

Potentially problematic release.


This version of cirq-core might be problematic. Click here for more details.

Files changed (157) hide show
  1. cirq/__init__.py +4 -0
  2. cirq/_compat.py +9 -11
  3. cirq/_compat_test.py +45 -56
  4. cirq/_version.py +31 -1
  5. cirq/_version_test.py +1 -1
  6. cirq/circuits/circuit.py +13 -8
  7. cirq/circuits/circuit_operation.py +2 -1
  8. cirq/circuits/circuit_test.py +2 -2
  9. cirq/circuits/frozen_circuit.py +3 -2
  10. cirq/circuits/moment.py +12 -10
  11. cirq/circuits/qasm_output.py +5 -1
  12. cirq/circuits/qasm_output_test.py +25 -10
  13. cirq/contrib/qcircuit/qcircuit_diagram_info.py +9 -7
  14. cirq/contrib/quimb/mps_simulator_test.py +1 -1
  15. cirq/contrib/quimb/state_vector.py +9 -2
  16. cirq/contrib/svg/svg.py +2 -1
  17. cirq/contrib/svg/svg_test.py +1 -0
  18. cirq/devices/grid_qubit.py +85 -32
  19. cirq/devices/grid_qubit_test.py +22 -4
  20. cirq/devices/line_qubit.py +74 -26
  21. cirq/devices/line_qubit_test.py +19 -0
  22. cirq/devices/noise_utils.py +33 -31
  23. cirq/devices/noise_utils_test.py +1 -84
  24. cirq/devices/superconducting_qubits_noise_properties.py +7 -6
  25. cirq/experiments/__init__.py +8 -0
  26. cirq/experiments/qubit_characterizations.py +288 -44
  27. cirq/experiments/qubit_characterizations_test.py +61 -7
  28. cirq/experiments/random_quantum_circuit_generation.py +1 -1
  29. cirq/experiments/single_qubit_readout_calibration.py +132 -6
  30. cirq/experiments/single_qubit_readout_calibration_test.py +3 -1
  31. cirq/experiments/t1_decay_experiment.py +14 -7
  32. cirq/experiments/t1_decay_experiment_test.py +14 -26
  33. cirq/experiments/two_qubit_xeb.py +483 -0
  34. cirq/experiments/two_qubit_xeb_test.py +304 -0
  35. cirq/json_resolver_cache.py +2 -0
  36. cirq/linalg/decompositions.py +11 -13
  37. cirq/linalg/decompositions_test.py +1 -3
  38. cirq/linalg/diagonalize.py +5 -4
  39. cirq/linalg/predicates.py +8 -6
  40. cirq/linalg/transformations.py +2 -1
  41. cirq/linalg/transformations_test.py +1 -1
  42. cirq/ops/__init__.py +2 -0
  43. cirq/ops/clifford_gate.py +59 -16
  44. cirq/ops/common_gates_test.py +1 -2
  45. cirq/ops/control_values.py +4 -3
  46. cirq/ops/controlled_gate_test.py +1 -3
  47. cirq/ops/gate_operation.py +10 -1
  48. cirq/ops/named_qubit.py +74 -28
  49. cirq/ops/named_qubit_test.py +19 -0
  50. cirq/ops/parity_gates.py +5 -0
  51. cirq/ops/parity_gates_test.py +2 -10
  52. cirq/ops/pauli_gates.py +5 -2
  53. cirq/ops/pauli_string.py +2 -2
  54. cirq/ops/permutation_gate.py +16 -18
  55. cirq/ops/phased_iswap_gate_test.py +1 -3
  56. cirq/ops/phased_x_gate.py +1 -1
  57. cirq/ops/phased_x_z_gate.py +17 -1
  58. cirq/ops/phased_x_z_gate_test.py +24 -0
  59. cirq/ops/qid_util.py +4 -8
  60. cirq/ops/qubit_manager.py +7 -4
  61. cirq/ops/qubit_manager_test.py +20 -0
  62. cirq/ops/raw_types.py +5 -2
  63. cirq/ops/raw_types_test.py +14 -15
  64. cirq/ops/uniform_superposition_gate.py +123 -0
  65. cirq/ops/uniform_superposition_gate_test.py +94 -0
  66. cirq/protocols/approximate_equality_protocol_test.py +2 -2
  67. cirq/protocols/circuit_diagram_info_protocol.py +6 -4
  68. cirq/protocols/commutes_protocol.py +2 -4
  69. cirq/protocols/decompose_protocol.py +7 -12
  70. cirq/protocols/decompose_protocol_test.py +7 -3
  71. cirq/protocols/has_stabilizer_effect_protocol.py +1 -5
  72. cirq/protocols/has_stabilizer_effect_protocol_test.py +13 -4
  73. cirq/protocols/json_serialization.py +51 -181
  74. cirq/protocols/json_serialization_test.py +13 -47
  75. cirq/protocols/json_test_data/CircuitOperation.json +131 -148
  76. cirq/protocols/json_test_data/CircuitOperation.json_inward +55 -0
  77. cirq/protocols/json_test_data/CircuitOperation.repr_inward +6 -0
  78. cirq/protocols/json_test_data/FrozenCircuit.json +196 -210
  79. cirq/protocols/json_test_data/FrozenCircuit.json_inward +35 -0
  80. cirq/protocols/json_test_data/FrozenCircuit.repr_inward +4 -0
  81. cirq/protocols/json_test_data/UniformSuperpositionGate.json +5 -0
  82. cirq/protocols/json_test_data/UniformSuperpositionGate.repr +1 -0
  83. cirq/protocols/json_test_data/cirq.MSGate.json +4 -0
  84. cirq/protocols/json_test_data/cirq.MSGate.repr +1 -0
  85. cirq/protocols/json_test_data/spec.py +2 -0
  86. cirq/protocols/pow_protocol_test.py +1 -3
  87. cirq/protocols/resolve_parameters.py +4 -2
  88. cirq/qis/__init__.py +10 -0
  89. cirq/qis/clifford_tableau.py +8 -2
  90. cirq/qis/noise_utils.py +123 -0
  91. cirq/qis/noise_utils_test.py +97 -0
  92. cirq/sim/classical_simulator.py +227 -87
  93. cirq/sim/classical_simulator_test.py +135 -0
  94. cirq/sim/clifford/clifford_simulator_test.py +4 -2
  95. cirq/sim/mux.py +5 -3
  96. cirq/sim/simulation_product_state.py +15 -10
  97. cirq/sim/simulation_state.py +1 -1
  98. cirq/sim/simulation_state_test.py +2 -2
  99. cirq/sim/simulator_base.py +3 -3
  100. cirq/sim/state_vector_simulation_state.py +4 -4
  101. cirq/sim/state_vector_simulator.py +17 -2
  102. cirq/study/__init__.py +1 -0
  103. cirq/study/result.py +14 -0
  104. cirq/study/result_test.py +6 -0
  105. cirq/study/sweeps.py +4 -2
  106. cirq/study/sweeps_test.py +8 -0
  107. cirq/testing/__init__.py +6 -1
  108. cirq/testing/_compat_test_data/__init__.py +3 -3
  109. cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
  110. cirq/testing/circuit_compare.py +1 -1
  111. cirq/testing/consistent_qasm.py +6 -0
  112. cirq/testing/gate_features.py +10 -0
  113. cirq/testing/lin_alg_utils.py +5 -3
  114. cirq/transformers/__init__.py +15 -0
  115. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +3 -1
  116. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +24 -0
  117. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +17 -0
  118. cirq/transformers/dynamical_decoupling.py +122 -0
  119. cirq/transformers/dynamical_decoupling_test.py +123 -0
  120. cirq/transformers/gauge_compiling/__init__.py +26 -0
  121. cirq/transformers/gauge_compiling/cz_gauge.py +46 -0
  122. cirq/transformers/gauge_compiling/cz_gauge_test.py +23 -0
  123. cirq/transformers/gauge_compiling/gauge_compiling.py +214 -0
  124. cirq/transformers/gauge_compiling/gauge_compiling_test.py +41 -0
  125. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +83 -0
  126. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +52 -0
  127. cirq/transformers/gauge_compiling/iswap_gauge.py +105 -0
  128. cirq/transformers/gauge_compiling/iswap_gauge_test.py +23 -0
  129. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +33 -0
  130. cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +37 -0
  131. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +64 -0
  132. cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +27 -0
  133. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +94 -0
  134. cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +22 -0
  135. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +1 -0
  136. cirq/transformers/merge_k_qubit_gates_test.py +23 -23
  137. cirq/transformers/merge_single_qubit_gates_test.py +14 -14
  138. cirq/transformers/optimize_for_target_gateset.py +39 -17
  139. cirq/transformers/optimize_for_target_gateset_test.py +189 -39
  140. cirq/transformers/qubit_management_transformers.py +1 -1
  141. cirq/transformers/routing/visualize_routed_circuit_test.py +17 -17
  142. cirq/transformers/stratify_test.py +13 -13
  143. cirq/transformers/target_gatesets/compilation_target_gateset.py +26 -2
  144. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +16 -16
  145. cirq/transformers/target_gatesets/cz_gateset.py +4 -0
  146. cirq/transformers/transformer_api.py +1 -2
  147. cirq/transformers/transformer_primitives.py +15 -14
  148. cirq/transformers/transformer_primitives_test.py +99 -72
  149. cirq/value/classical_data.py +6 -6
  150. cirq/value/value_equality_attr.py +4 -0
  151. cirq/work/sampler.py +3 -4
  152. cirq/work/sampler_test.py +25 -0
  153. {cirq_core-1.3.0.dev20231201164435.dist-info → cirq_core-1.4.0.dist-info}/METADATA +10 -19
  154. {cirq_core-1.3.0.dev20231201164435.dist-info → cirq_core-1.4.0.dist-info}/RECORD +157 -130
  155. {cirq_core-1.3.0.dev20231201164435.dist-info → cirq_core-1.4.0.dist-info}/WHEEL +1 -1
  156. {cirq_core-1.3.0.dev20231201164435.dist-info → cirq_core-1.4.0.dist-info}/LICENSE +0 -0
  157. {cirq_core-1.3.0.dev20231201164435.dist-info → cirq_core-1.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,52 @@
1
+ # Copyright 2024 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
+ import numpy as np
17
+ import cirq
18
+ from cirq.transformers.gauge_compiling.gauge_compiling_test_utils import GaugeTester
19
+ from cirq.transformers import GaugeTransformer, GaugeSelector, ConstantGauge
20
+
21
+
22
+ class ExampleGate(cirq.testing.TwoQubitGate):
23
+ unitary = cirq.unitary(cirq.CZ**0.123)
24
+
25
+ def _unitary_(self) -> np.ndarray:
26
+ return self.unitary
27
+
28
+
29
+ _EXAMPLE_TARGET = ExampleGate()
30
+
31
+ _GOOD_TRANSFORMER = GaugeTransformer(
32
+ target=_EXAMPLE_TARGET,
33
+ gauge_selector=GaugeSelector(gauges=[ConstantGauge(two_qubit_gate=_EXAMPLE_TARGET)]),
34
+ )
35
+
36
+ _BAD_TRANSFORMER = GaugeTransformer(
37
+ target=_EXAMPLE_TARGET,
38
+ gauge_selector=GaugeSelector(
39
+ gauges=[ConstantGauge(two_qubit_gate=_EXAMPLE_TARGET, pre_q0=cirq.X)]
40
+ ),
41
+ )
42
+
43
+
44
+ class TestValidTransformer(GaugeTester):
45
+ two_qubit_gate = _EXAMPLE_TARGET
46
+ gauge_transformer = _GOOD_TRANSFORMER
47
+
48
+
49
+ class TestInvalidTransformer(GaugeTester):
50
+ two_qubit_gate = _EXAMPLE_TARGET
51
+ gauge_transformer = _BAD_TRANSFORMER
52
+ must_fail = True
@@ -0,0 +1,105 @@
1
+ # Copyright 2024 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
+ """A Gauge transformer for ISWAP gate."""
16
+
17
+ import numpy as np
18
+
19
+ from cirq.transformers.gauge_compiling.gauge_compiling import (
20
+ ConstantGauge,
21
+ Gauge,
22
+ GaugeTransformer,
23
+ GaugeSelector,
24
+ )
25
+ from cirq import ops
26
+
27
+
28
+ class RZRotation(Gauge):
29
+ """Represents an ISWAP Gauge composed of Rz rotations.
30
+
31
+ The gauge replaces an ISWAP gate with either
32
+ 0: ───Rz(t)──────iSwap───Rz(sgn*t)───
33
+
34
+ 1: ───Rz(-sgn*t)───iSwap───Rz(-t)───
35
+
36
+ where t is uniformly sampled from [0, 2π) and sgn is uniformly sampled from {-1, 1}.
37
+ """
38
+
39
+ def weight(self) -> float:
40
+ return 2.0
41
+
42
+ def _rz(self, theta, sgn: int) -> ConstantGauge:
43
+ """Returns an ISWAP Gauge composed of Rz rotations.
44
+
45
+ 0: ───Rz(theta)──────iSwap───Rz(sgn*theta)───
46
+
47
+ 1: ───Rz(-sgn*theta)───iSwap───Rz(-theta)───
48
+
49
+ """
50
+ flip_diangonal = sgn == -1
51
+ rz = ops.rz(theta)
52
+ n_rz = ops.rz(-theta)
53
+ return ConstantGauge(
54
+ two_qubit_gate=ops.ISWAP,
55
+ pre_q0=rz,
56
+ pre_q1=n_rz if flip_diangonal else rz,
57
+ post_q0=rz if flip_diangonal else n_rz,
58
+ post_q1=n_rz,
59
+ )
60
+
61
+ def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
62
+ theta = prng.random() * 2 * np.pi
63
+ return self._rz(theta, prng.choice([-1, 1]))
64
+
65
+
66
+ class XYRotation(Gauge):
67
+ """Represents an ISWAP Gauge composed of XY rotations.
68
+
69
+ The gauge replaces an ISWAP gate with either
70
+ 0: ───XY(a)───iSwap───XY(b)───
71
+
72
+ 1: ───XY(b)───iSwap───XY(a)───
73
+
74
+ where a and b are uniformly sampled from [0, 2π) and XY is a single-qubit rotation defined as
75
+ XY(theta) = cos(theta) X + sin(theta) Y
76
+ """
77
+
78
+ def weight(self) -> float:
79
+ return 2.0
80
+
81
+ def _xy(self, theta: float) -> ops.PhasedXZGate:
82
+ unitary = np.cos(theta) * np.array([[0, 1], [1, 0]]) + np.sin(theta) * np.array(
83
+ [[0, -1j], [1j, 0]]
84
+ )
85
+ return ops.PhasedXZGate.from_matrix(unitary)
86
+
87
+ def _xy_gauge(self, a: float, b: float) -> ConstantGauge:
88
+ xy_a = self._xy(a)
89
+ xy_b = self._xy(b)
90
+ return ConstantGauge(
91
+ two_qubit_gate=ops.ISWAP, pre_q0=xy_a, pre_q1=xy_b, post_q0=xy_b, post_q1=xy_a
92
+ )
93
+
94
+ def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
95
+ a = prng.random() * 2 * np.pi
96
+ if prng.choice([0, 1]):
97
+ return self._xy_gauge(a, a)
98
+ else:
99
+ b = prng.random() * 2 * np.pi
100
+ return self._xy_gauge(a, b)
101
+
102
+
103
+ ISWAPGaugeTransformer = GaugeTransformer(
104
+ target=ops.ISWAP, gauge_selector=GaugeSelector(gauges=[RZRotation(), XYRotation()])
105
+ )
@@ -0,0 +1,23 @@
1
+ # Copyright 2024 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
+ import cirq
17
+ from cirq.transformers.gauge_compiling import ISWAPGaugeTransformer
18
+ from cirq.transformers.gauge_compiling.gauge_compiling_test_utils import GaugeTester
19
+
20
+
21
+ class TestISWAPGauge(GaugeTester):
22
+ two_qubit_gate = cirq.ISWAP
23
+ gauge_transformer = ISWAPGaugeTransformer
@@ -0,0 +1,33 @@
1
+ # Copyright 2024 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
+ """The spin inversion gauge transformer."""
16
+
17
+ from cirq.transformers.gauge_compiling.gauge_compiling import (
18
+ GaugeTransformer,
19
+ GaugeSelector,
20
+ SameGateGauge,
21
+ )
22
+ from cirq import ops
23
+
24
+ SpinInversionGaugeSelector = GaugeSelector(
25
+ gauges=[
26
+ SameGateGauge(pre_q0=ops.X, post_q0=ops.X, pre_q1=ops.X, post_q1=ops.X),
27
+ SameGateGauge(),
28
+ ]
29
+ )
30
+
31
+ SpinInversionGaugeTransformer = GaugeTransformer(
32
+ target=ops.GateFamily(ops.ZZPowGate), gauge_selector=SpinInversionGaugeSelector
33
+ )
@@ -0,0 +1,37 @@
1
+ # Copyright 2024 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
+ from cirq.transformers.gauge_compiling import SpinInversionGaugeTransformer
17
+ from cirq.transformers.gauge_compiling.gauge_compiling_test_utils import GaugeTester
18
+
19
+
20
+ class TestSpinInversionGauge_0(GaugeTester):
21
+ two_qubit_gate = cirq.ZZ
22
+ gauge_transformer = SpinInversionGaugeTransformer
23
+
24
+
25
+ class TestSpinInversionGauge_1(GaugeTester):
26
+ two_qubit_gate = cirq.ZZ**0.1
27
+ gauge_transformer = SpinInversionGaugeTransformer
28
+
29
+
30
+ class TestSpinInversionGauge_2(GaugeTester):
31
+ two_qubit_gate = cirq.ZZ**-1
32
+ gauge_transformer = SpinInversionGaugeTransformer
33
+
34
+
35
+ class TestSpinInversionGauge_3(GaugeTester):
36
+ two_qubit_gate = cirq.ZZ**0.3
37
+ gauge_transformer = SpinInversionGaugeTransformer
@@ -0,0 +1,64 @@
1
+ # Copyright 2024 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
+ """A Gauge transformer for CZ**0.5 and CZ**-0.5 gates."""
16
+
17
+
18
+ from typing import TYPE_CHECKING
19
+ import numpy as np
20
+
21
+ from cirq.transformers.gauge_compiling.gauge_compiling import (
22
+ GaugeTransformer,
23
+ GaugeSelector,
24
+ ConstantGauge,
25
+ Gauge,
26
+ )
27
+ from cirq.ops import CZ, S, X, Gateset
28
+
29
+ if TYPE_CHECKING:
30
+ import cirq
31
+
32
+ _SQRT_CZ = CZ**0.5
33
+ _ADJ_S = S**-1
34
+
35
+
36
+ class SqrtCZGauge(Gauge):
37
+
38
+ def weight(self) -> float:
39
+ return 3.0
40
+
41
+ def sample(self, gate: 'cirq.Gate', prng: np.random.Generator) -> ConstantGauge:
42
+ if prng.choice([True, False]):
43
+ return ConstantGauge(two_qubit_gate=gate)
44
+ swap_qubits = prng.choice([True, False])
45
+ if swap_qubits:
46
+ return ConstantGauge(
47
+ pre_q1=X,
48
+ post_q1=X,
49
+ post_q0=S if gate == _SQRT_CZ else _ADJ_S,
50
+ two_qubit_gate=gate**-1,
51
+ swap_qubits=True,
52
+ )
53
+ else:
54
+ return ConstantGauge(
55
+ pre_q0=X,
56
+ post_q0=X,
57
+ post_q1=S if gate == _SQRT_CZ else _ADJ_S,
58
+ two_qubit_gate=gate**-1,
59
+ )
60
+
61
+
62
+ SqrtCZGaugeTransformer = GaugeTransformer(
63
+ target=Gateset(_SQRT_CZ, _SQRT_CZ**-1), gauge_selector=GaugeSelector(gauges=[SqrtCZGauge()])
64
+ )
@@ -0,0 +1,27 @@
1
+ # Copyright 2024 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
+ from cirq.transformers.gauge_compiling import SqrtCZGaugeTransformer
17
+ from cirq.transformers.gauge_compiling.gauge_compiling_test_utils import GaugeTester
18
+
19
+
20
+ class TestSqrtCZGauge(GaugeTester):
21
+ two_qubit_gate = cirq.CZ**0.5
22
+ gauge_transformer = SqrtCZGaugeTransformer
23
+
24
+
25
+ class TestAdjointSqrtCZGauge(GaugeTester):
26
+ two_qubit_gate = cirq.CZ**-0.5
27
+ gauge_transformer = SqrtCZGaugeTransformer
@@ -0,0 +1,94 @@
1
+ # Copyright 2024 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
+ """A Gauge transformer for SQRT_ISWAP gate."""
16
+
17
+ import numpy as np
18
+ from cirq.transformers.gauge_compiling.gauge_compiling import (
19
+ ConstantGauge,
20
+ Gauge,
21
+ GaugeTransformer,
22
+ GaugeSelector,
23
+ )
24
+ from cirq import ops
25
+
26
+
27
+ class RZRotation(Gauge):
28
+ """Represents a SQRT_ISWAP Gauge composed of Rz rotations.
29
+
30
+ The gauge replaces an SQRT_ISWAP gate with either
31
+ 0: ───Rz(t)───iSwap───────Rz(-t)───
32
+
33
+ 1: ───Rz(t)───iSwap^0.5───Rz(-t)───
34
+
35
+ where t is uniformly sampled from [0, 2π).
36
+ """
37
+
38
+ def weight(self) -> float:
39
+ return 1.0
40
+
41
+ def _rz(self, theta: float) -> ConstantGauge:
42
+ """Returns a SQRT_ISWAP Gauge composed of Rz rotations.
43
+
44
+ 0: ───Rz(theta)────iSwap───Rz(theta)───
45
+
46
+ 1: ───Rz(theta)───iSwap^0.5───Rz(theta)───
47
+
48
+ """
49
+ rz = ops.rz(theta)
50
+ n_rz = ops.rz(-theta)
51
+ return ConstantGauge(
52
+ two_qubit_gate=ops.SQRT_ISWAP, pre_q0=rz, pre_q1=rz, post_q0=n_rz, post_q1=n_rz
53
+ )
54
+
55
+ def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
56
+ return self._rz(prng.random() * 2 * np.pi)
57
+
58
+
59
+ class XYRotation(Gauge):
60
+ """Represents a SQRT_ISWAP Gauge composed of XY rotations.
61
+
62
+ The gauge replaces an SQRT_ISWAP gate with either
63
+ 0: ───XY(t)───iSwap───────XY(t)───
64
+
65
+ 1: ───XY(t)───iSwap^0.5───XY(t)───
66
+
67
+ where t is uniformly sampled from [0, 2π) and
68
+ XY(theta) = cos(theta) X + sin(theta) Y
69
+ """
70
+
71
+ def weight(self) -> float:
72
+ return 1.0
73
+
74
+ def _xy(self, theta: float) -> ops.PhasedXZGate:
75
+ unitary = np.cos(theta) * np.array([[0, 1], [1, 0]]) + np.sin(theta) * np.array(
76
+ [[0, -1j], [1j, 0]]
77
+ )
78
+ return ops.PhasedXZGate.from_matrix(unitary)
79
+
80
+ def _xy_gauge(self, theta: float) -> ConstantGauge:
81
+ xy = self._xy(theta)
82
+ return ConstantGauge(
83
+ two_qubit_gate=ops.SQRT_ISWAP, pre_q0=xy, pre_q1=xy, post_q0=xy, post_q1=xy
84
+ )
85
+
86
+ def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
87
+ return self._xy_gauge(prng.random() * 2 * np.pi)
88
+
89
+
90
+ SqrtISWAPGaugeSelector = GaugeSelector(gauges=[RZRotation(), XYRotation()])
91
+
92
+ SqrtISWAPGaugeTransformer = GaugeTransformer(
93
+ target=ops.SQRT_ISWAP, gauge_selector=SqrtISWAPGaugeSelector
94
+ )
@@ -0,0 +1,22 @@
1
+ # Copyright 2024 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
+ from cirq.transformers.gauge_compiling import SqrtISWAPGaugeTransformer
17
+ from cirq.transformers.gauge_compiling.gauge_compiling_test_utils import GaugeTester
18
+
19
+
20
+ class TestSqrtISWAPGauge(GaugeTester):
21
+ two_qubit_gate = cirq.SQRT_ISWAP
22
+ gauge_transformer = SqrtISWAPGaugeTransformer
@@ -55,6 +55,7 @@ class TwoQubitGateTabulationResult(NamedTuple):
55
55
  equal to U_target.
56
56
  success: Whether actual_gate is expected to be close to U_target.
57
57
  """
58
+
58
59
  base_gate_unitary: np.ndarray
59
60
  target_gate: np.ndarray
60
61
  local_unitaries: Tuple[_SingleQubitGatePair, ...]
@@ -122,13 +122,13 @@ def test_merge_complex_circuit_preserving_moment_structure():
122
122
  cirq.testing.assert_has_diagram(
123
123
  c_orig,
124
124
  '''
125
- 0: ───H───@───@───H───@───X───────@─────────────────X───X['ignore']───@───X───
126
- │ │ │ │ │ ║
127
- 1: ───H───┼───X───────@───────Y───X───@['ignore']───────Y─────────────X───╫───
128
- │ │
129
- 2: ───H───X───────────────────────────X─────────────────Z─────────────M───╫───
130
- ║ ║
131
- a: ═══════════════════════════════════════════════════════════════════@═══^═══
125
+ 0: ───H───@───@───H───@───X───────@───────────────X───X[ignore]───@───X───
126
+ │ │ │ │ │ ║
127
+ 1: ───H───┼───X───────@───────Y───X───@[ignore]───────Y───────────X───╫───
128
+ │ │
129
+ 2: ───H───X───────────────────────────X───────────────Z───────────M───╫───
130
+ ║ ║
131
+ a: ═══════════════════════════════════════════════════════════════@═══^═══
132
132
  ''',
133
133
  )
134
134
  component_id = 0
@@ -147,15 +147,15 @@ a: ═════════════════════════
147
147
  cirq.testing.assert_has_diagram(
148
148
  cirq.drop_empty_moments(c_new),
149
149
  '''
150
- [ 0: ───H───@─── ] [ 0: ───────@───H───@───X───@───X─── ] [ 0: ───────@─── ]
151
- 0: ───[ │ ]────────[ │ │ │ ]──────────────────────X['ignore']───────────[ │ ]────────X───
152
- [ 2: ───H───X─── ]['1'] [ 1: ───H───X───────@───Y───X─────── ]['2'] [ 1: ───Y───X─── ]['4'] ║
153
-
154
- 1: ───┼─────────────────────────#2────────────────────────────────────────────@['ignore']─────────────────────────#2────────────────────────╫───
155
-
156
- 2: ───#2──────────────────────────────────────────────────────────────────────X─────────────[ 2: ───Z─── ]['3']───M─────────────────────────╫───
157
-
158
- a: ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════@═════════════════════════^═══''',
150
+ [ 0: ───H───@─── ] [ 0: ───────@───H───@───X───@───X─── ] [ 0: ───────@─── ]
151
+ 0: ───[ │ ]──────[ │ │ │ ]──────────────────X[ignore]───────────[ │ ]──────X───
152
+ [ 2: ───H───X─── ][1] [ 1: ───H───X───────@───Y───X─────── ][2] [ 1: ───Y───X─── ][4] ║
153
+
154
+ 1: ───┼───────────────────────#2──────────────────────────────────────────@[ignore]───────────────────────#2──────────────────────╫───
155
+
156
+ 2: ───#2──────────────────────────────────────────────────────────────────X───────────[ 2: ───Z─── ][3]───M───────────────────────╫───
157
+
158
+ a: ═══════════════════════════════════════════════════════════════════════════════════════════════════════@═══════════════════════^═══''',
159
159
  )
160
160
 
161
161
  component_id = 0
@@ -179,13 +179,13 @@ a: ═════════════════════════
179
179
  cirq.testing.assert_has_diagram(
180
180
  cirq.drop_empty_moments(c_new),
181
181
  '''
182
- 0: ───T['1']───iSwap['1']───T['1']───T['2']───iSwap['2']───T['2']─────────────────X['ignore']───T['4']───iSwap['4']───T['4']───X───
183
-
184
- 1: ────────────┼─────────────────────T['2']───iSwap^0.5────T['2']───@['ignore']─────────────────T['4']───iSwap^0.5────T['4']───╫───
185
-
186
- 2: ───T['1']───iSwap^0.5────T['1']──────────────────────────────────X─────────────T['3']────────M──────────────────────────────╫───
187
-
188
- a: ═════════════════════════════════════════════════════════════════════════════════════════════@══════════════════════════════^═══''',
182
+ 0: ───T[1]───iSwap[1]────T[1]───T[2]───iSwap[2]────T[2]───────────────X[ignore]───T[4]───iSwap[4]────T[4]───X───
183
+
184
+ 1: ──────────┼──────────────────T[2]───iSwap^0.5───T[2]───@[ignore]───────────────T[4]───iSwap^0.5───T[4]───╫───
185
+
186
+ 2: ───T[1]───iSwap^0.5───T[1]─────────────────────────────X───────────T[3]────────M─────────────────────────╫───
187
+
188
+ a: ═══════════════════════════════════════════════════════════════════════════════@═════════════════════════^═══''',
189
189
  )
190
190
 
191
191
 
@@ -153,13 +153,13 @@ def test_merge_single_qubit_moments_to_phxz():
153
153
  cirq.testing.assert_has_diagram(
154
154
  c_orig,
155
155
  '''
156
- 0: ───X───────Y───@───X───────Y───Y['nocompile']───X───M───────────
157
-
158
- 1: ───X───T───Y───@───X───T───Y───Z────────────────────╫───X───X───
159
- ║ ║
160
- 2: ───────T───────Y───────T───────Z────────────────────╫───╫───────
161
- ║ ║
162
- a: ════════════════════════════════════════════════════@═══^═══════
156
+ 0: ───X───────Y───@───X───────Y───Y[nocompile]───X───M───────────
157
+
158
+ 1: ───X───T───Y───@───X───T───Y───Z──────────────────╫───X───X───
159
+ ║ ║
160
+ 2: ───────T───────Y───────T───────Z──────────────────╫───╫───────
161
+ ║ ║
162
+ a: ══════════════════════════════════════════════════@═══^═══════
163
163
  ''',
164
164
  )
165
165
  context = cirq.TransformerContext(tags_to_ignore=("nocompile",))
@@ -167,13 +167,13 @@ a: ═════════════════════════
167
167
  cirq.testing.assert_has_diagram(
168
168
  c_new,
169
169
  '''
170
- 0: ───PhXZ(a=-0.5,x=0,z=-1)──────@───PhXZ(a=-0.5,x=0,z=-1)──────Y['nocompile']───X───M───────────
171
-
172
- 1: ───PhXZ(a=-0.25,x=0,z=0.75)───@───PhXZ(a=-0.25,x=0,z=0.75)───Z────────────────────╫───X───X───
173
- ║ ║
174
- 2: ───PhXZ(a=0.25,x=0,z=0.25)────Y───PhXZ(a=0.25,x=0,z=0.25)────Z────────────────────╫───╫───────
175
- ║ ║
176
- a: ══════════════════════════════════════════════════════════════════════════════════@═══^═══════
170
+ 0: ───PhXZ(a=-0.5,x=0,z=-1)──────@───PhXZ(a=-0.5,x=0,z=-1)──────Y[nocompile]───X───M───────────
171
+
172
+ 1: ───PhXZ(a=-0.25,x=0,z=0.75)───@───PhXZ(a=-0.25,x=0,z=0.75)───Z──────────────────╫───X───X───
173
+ ║ ║
174
+ 2: ───PhXZ(a=0.25,x=0,z=0.25)────Y───PhXZ(a=0.25,x=0,z=0.25)────Z──────────────────╫───╫───────
175
+ ║ ║
176
+ a: ════════════════════════════════════════════════════════════════════════════════@═══^═══════
177
177
  ''',
178
178
  )
179
179