cirq-core 1.6.0.dev20250625011740__py3-none-any.whl → 1.6.0.dev20250625151218__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/ops/common_gates.py +50 -1
- cirq/ops/common_gates_test.py +34 -0
- cirq/ops/controlled_gate.py +23 -53
- cirq/ops/controlled_gate_test.py +28 -0
- cirq/ops/global_phase_op.py +27 -0
- cirq/ops/global_phase_op_test.py +20 -0
- cirq/ops/three_qubit_gates.py +4 -12
- cirq/protocols/decompose_protocol.py +7 -0
- cirq/protocols/decompose_protocol_test.py +9 -0
- {cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/RECORD +16 -16
- {cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/top_level.txt +0 -0
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
cirq/ops/common_gates.py
CHANGED
|
@@ -37,7 +37,14 @@ import cirq
|
|
|
37
37
|
from cirq import protocols, value
|
|
38
38
|
from cirq._compat import proper_repr
|
|
39
39
|
from cirq._doc import document
|
|
40
|
-
from cirq.ops import
|
|
40
|
+
from cirq.ops import (
|
|
41
|
+
control_values as cv,
|
|
42
|
+
controlled_gate,
|
|
43
|
+
eigen_gate,
|
|
44
|
+
gate_features,
|
|
45
|
+
global_phase_op,
|
|
46
|
+
raw_types,
|
|
47
|
+
)
|
|
41
48
|
from cirq.ops.measurement_gate import MeasurementGate
|
|
42
49
|
from cirq.ops.swap_gates import ISWAP, ISwapPowGate, SWAP, SwapPowGate
|
|
43
50
|
|
|
@@ -235,6 +242,11 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
235
242
|
return cirq.CCXPowGate(exponent=self._exponent)
|
|
236
243
|
return result
|
|
237
244
|
|
|
245
|
+
def _decompose_with_context_(
|
|
246
|
+
self, qubits: tuple[cirq.Qid, ...], context: cirq.DecompositionContext
|
|
247
|
+
) -> list[cirq.Operation] | NotImplementedType:
|
|
248
|
+
return _extract_phase(self, XPowGate, qubits, context)
|
|
249
|
+
|
|
238
250
|
def _pauli_expansion_(self) -> value.LinearDict[str]:
|
|
239
251
|
if self._dimension != 2:
|
|
240
252
|
return NotImplemented # pragma: no cover
|
|
@@ -487,6 +499,11 @@ class YPowGate(eigen_gate.EigenGate):
|
|
|
487
499
|
f'global_shift={self._global_shift!r})'
|
|
488
500
|
)
|
|
489
501
|
|
|
502
|
+
def _decompose_with_context_(
|
|
503
|
+
self, qubits: tuple[cirq.Qid, ...], context: cirq.DecompositionContext
|
|
504
|
+
) -> list[cirq.Operation] | NotImplementedType:
|
|
505
|
+
return _extract_phase(self, YPowGate, qubits, context)
|
|
506
|
+
|
|
490
507
|
|
|
491
508
|
class Ry(YPowGate):
|
|
492
509
|
r"""A gate with matrix $e^{-i Y t/2}$ that rotates around the Y axis of the Bloch sphere by $t$.
|
|
@@ -699,6 +716,11 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
699
716
|
return cirq.CCZPowGate(exponent=self._exponent)
|
|
700
717
|
return result
|
|
701
718
|
|
|
719
|
+
def _decompose_with_context_(
|
|
720
|
+
self, qubits: tuple[cirq.Qid, ...], context: cirq.DecompositionContext
|
|
721
|
+
) -> list[cirq.Operation] | NotImplementedType:
|
|
722
|
+
return _extract_phase(self, ZPowGate, qubits, context)
|
|
723
|
+
|
|
702
724
|
def _qid_shape_(self) -> tuple[int, ...]:
|
|
703
725
|
return (self._dimension,)
|
|
704
726
|
|
|
@@ -1131,6 +1153,11 @@ class CZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
1131
1153
|
control_qid_shape=result.control_qid_shape + (2,),
|
|
1132
1154
|
)
|
|
1133
1155
|
|
|
1156
|
+
def _decompose_with_context_(
|
|
1157
|
+
self, qubits: tuple[cirq.Qid, ...], context: cirq.DecompositionContext
|
|
1158
|
+
) -> list[cirq.Operation] | NotImplementedType:
|
|
1159
|
+
return _extract_phase(self, CZPowGate, qubits, context)
|
|
1160
|
+
|
|
1134
1161
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
1135
1162
|
return protocols.CircuitDiagramInfo(
|
|
1136
1163
|
wire_symbols=('@', '@'), exponent=self._diagram_exponent(args)
|
|
@@ -1486,3 +1513,25 @@ def _phased_x_or_pauli_gate(
|
|
|
1486
1513
|
case 0.5:
|
|
1487
1514
|
return YPowGate(exponent=exponent)
|
|
1488
1515
|
return cirq.ops.PhasedXPowGate(exponent=exponent, phase_exponent=phase_exponent)
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
def _extract_phase(
|
|
1519
|
+
gate: cirq.EigenGate,
|
|
1520
|
+
gate_class: type,
|
|
1521
|
+
qubits: tuple[cirq.Qid, ...],
|
|
1522
|
+
context: cirq.DecompositionContext,
|
|
1523
|
+
) -> list[cirq.Operation] | NotImplementedType:
|
|
1524
|
+
"""Extracts the global phase field to its own gate, or absorbs it if it has no effect.
|
|
1525
|
+
|
|
1526
|
+
This is for use within the decompose handlers, and will return `NotImplemented` if there is no
|
|
1527
|
+
global phase, implying it is already in its simplest form. It will return a list, with the
|
|
1528
|
+
original op minus any global phase first, and the global phase op second. If the resulting
|
|
1529
|
+
global phase is empty (can happen for example in `XPowGate(global_phase=2/3)**3`), then it is
|
|
1530
|
+
excluded from the return value."""
|
|
1531
|
+
if not context.extract_global_phases or gate.global_shift == 0:
|
|
1532
|
+
return NotImplemented
|
|
1533
|
+
result = [gate_class(exponent=gate.exponent).on(*qubits)]
|
|
1534
|
+
phase_gate = global_phase_op.from_phase_and_exponent(gate.global_shift, gate.exponent)
|
|
1535
|
+
if not phase_gate.is_identity():
|
|
1536
|
+
result.append(phase_gate())
|
|
1537
|
+
return result
|
cirq/ops/common_gates_test.py
CHANGED
|
@@ -1322,3 +1322,37 @@ def test_parameterized_pauli_expansion(gate_type, exponent) -> None:
|
|
|
1322
1322
|
gate_resolved = cirq.resolve_parameters(gate, {'s': 0.5})
|
|
1323
1323
|
pauli_resolved = cirq.resolve_parameters(pauli, {'s': 0.5})
|
|
1324
1324
|
assert cirq.approx_eq(pauli_resolved, cirq.pauli_expansion(gate_resolved))
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
@pytest.mark.parametrize('gate_type', [cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZPowGate])
|
|
1328
|
+
@pytest.mark.parametrize('exponent', [0, 0.5, 2, 3, -0.5, -2, -3, sympy.Symbol('s')])
|
|
1329
|
+
def test_decompose_with_extracted_phases(gate_type: type, exponent: cirq.TParamVal) -> None:
|
|
1330
|
+
context = cirq.DecompositionContext(cirq.SimpleQubitManager(), extract_global_phases=True)
|
|
1331
|
+
test_shift = 2 / 3 # Interesting because e.g. X(shift=2/3) ** 3 == X with no phase
|
|
1332
|
+
gate = gate_type(exponent=exponent, global_shift=test_shift)
|
|
1333
|
+
op = gate.on(*cirq.LineQubit.range(cirq.num_qubits(gate)))
|
|
1334
|
+
decomposed = cirq.decompose(op, context=context)
|
|
1335
|
+
|
|
1336
|
+
# The first gate should be the original gate, but with shift removed.
|
|
1337
|
+
gate0 = decomposed[0].gate
|
|
1338
|
+
assert isinstance(gate0, gate_type)
|
|
1339
|
+
assert isinstance(gate0, cirq.EigenGate)
|
|
1340
|
+
assert gate0.global_shift == 0
|
|
1341
|
+
assert gate0.exponent == exponent
|
|
1342
|
+
if exponent % 3 == 0:
|
|
1343
|
+
# Since test_shift == 2/3, gate**3 nullifies the phase, leaving only the unphased gate.
|
|
1344
|
+
assert len(decomposed) == 1
|
|
1345
|
+
else:
|
|
1346
|
+
# Other exponents emit a global phase gate to compensate.
|
|
1347
|
+
assert len(decomposed) == 2
|
|
1348
|
+
gate1 = decomposed[1].gate
|
|
1349
|
+
assert isinstance(gate1, cirq.GlobalPhaseGate)
|
|
1350
|
+
assert gate1.coefficient == 1j ** (2 * exponent * test_shift)
|
|
1351
|
+
|
|
1352
|
+
# Sanity check that the decomposition is equivalent to the original.
|
|
1353
|
+
decomposed_circuit = cirq.Circuit(decomposed)
|
|
1354
|
+
if cirq.is_parameterized(exponent):
|
|
1355
|
+
resolver = {'s': -1.234} # arbitrary
|
|
1356
|
+
op = cirq.resolve_parameters(op, resolver)
|
|
1357
|
+
decomposed_circuit = cirq.resolve_parameters(decomposed_circuit, resolver)
|
|
1358
|
+
np.testing.assert_allclose(cirq.unitary(op), cirq.unitary(decomposed_circuit), atol=1e-10)
|
cirq/ops/controlled_gate.py
CHANGED
|
@@ -24,7 +24,6 @@ from cirq.ops import (
|
|
|
24
24
|
control_values as cv,
|
|
25
25
|
controlled_operation as cop,
|
|
26
26
|
diagonal_gate as dg,
|
|
27
|
-
global_phase_op as gp,
|
|
28
27
|
op_tree,
|
|
29
28
|
raw_types,
|
|
30
29
|
)
|
|
@@ -139,12 +138,9 @@ class ControlledGate(raw_types.Gate):
|
|
|
139
138
|
def _qid_shape_(self) -> tuple[int, ...]:
|
|
140
139
|
return self.control_qid_shape + protocols.qid_shape(self.sub_gate)
|
|
141
140
|
|
|
142
|
-
def _decompose_(self, qubits: tuple[cirq.Qid, ...]) -> None | NotImplementedType | cirq.OP_TREE:
|
|
143
|
-
return self._decompose_with_context_(qubits)
|
|
144
|
-
|
|
145
141
|
def _decompose_with_context_(
|
|
146
|
-
self, qubits: tuple[cirq.Qid, ...], context: cirq.DecompositionContext
|
|
147
|
-
) ->
|
|
142
|
+
self, qubits: tuple[cirq.Qid, ...], context: cirq.DecompositionContext
|
|
143
|
+
) -> NotImplementedType | cirq.OP_TREE:
|
|
148
144
|
control_qubits = list(qubits[: self.num_controls()])
|
|
149
145
|
controlled_sub_gate = self.sub_gate.controlled(
|
|
150
146
|
self.num_controls(), self.control_values, self.control_qid_shape
|
|
@@ -152,6 +148,25 @@ class ControlledGate(raw_types.Gate):
|
|
|
152
148
|
# Prefer the subgate controlled version if available
|
|
153
149
|
if self != controlled_sub_gate:
|
|
154
150
|
return controlled_sub_gate.on(*qubits)
|
|
151
|
+
|
|
152
|
+
# Try decomposing the subgate next.
|
|
153
|
+
result = protocols.decompose_once_with_qubits(
|
|
154
|
+
self.sub_gate,
|
|
155
|
+
qubits[self.num_controls() :],
|
|
156
|
+
NotImplemented,
|
|
157
|
+
flatten=False,
|
|
158
|
+
# Extract global phases from decomposition, as controlled phases decompose easily.
|
|
159
|
+
context=context.extracting_global_phases(),
|
|
160
|
+
)
|
|
161
|
+
if result is not NotImplemented:
|
|
162
|
+
return op_tree.transform_op_tree(
|
|
163
|
+
result,
|
|
164
|
+
lambda op: op.controlled_by(
|
|
165
|
+
*qubits[: self.num_controls()], control_values=self.control_values
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Finally try brute-force on the unitary.
|
|
155
170
|
if protocols.has_unitary(self.sub_gate) and all(q.dimension == 2 for q in qubits):
|
|
156
171
|
n_qubits = protocols.num_qubits(self.sub_gate)
|
|
157
172
|
# Case 1: Global Phase (1x1 Matrix)
|
|
@@ -173,54 +188,9 @@ class ControlledGate(raw_types.Gate):
|
|
|
173
188
|
protocols.unitary(self.sub_gate), control_qubits, qubits[-1]
|
|
174
189
|
)
|
|
175
190
|
return invert_ops + decomposed_ops + invert_ops
|
|
176
|
-
if isinstance(self.sub_gate, common_gates.CZPowGate):
|
|
177
|
-
z_sub_gate = common_gates.ZPowGate(exponent=self.sub_gate.exponent)
|
|
178
|
-
num_controls = self.num_controls() + 1
|
|
179
|
-
control_values = self.control_values & cv.ProductOfSums(((1,),))
|
|
180
|
-
control_qid_shape = self.control_qid_shape + (2,)
|
|
181
|
-
controlled_z = (
|
|
182
|
-
z_sub_gate.controlled(
|
|
183
|
-
num_controls=num_controls,
|
|
184
|
-
control_values=control_values,
|
|
185
|
-
control_qid_shape=control_qid_shape,
|
|
186
|
-
)
|
|
187
|
-
if protocols.is_parameterized(self)
|
|
188
|
-
else ControlledGate(
|
|
189
|
-
z_sub_gate,
|
|
190
|
-
num_controls=num_controls,
|
|
191
|
-
control_values=control_values,
|
|
192
|
-
control_qid_shape=control_qid_shape,
|
|
193
|
-
)
|
|
194
|
-
)
|
|
195
|
-
if self != controlled_z:
|
|
196
|
-
result = controlled_z.on(*qubits)
|
|
197
|
-
if self.sub_gate.global_shift == 0:
|
|
198
|
-
return result
|
|
199
|
-
# Reconstruct the controlled global shift of the subgate.
|
|
200
|
-
total_shift = self.sub_gate.exponent * self.sub_gate.global_shift
|
|
201
|
-
phase_gate = gp.GlobalPhaseGate(1j ** (2 * total_shift))
|
|
202
|
-
controlled_phase_op = phase_gate.controlled(
|
|
203
|
-
num_controls=self.num_controls(),
|
|
204
|
-
control_values=self.control_values,
|
|
205
|
-
control_qid_shape=self.control_qid_shape,
|
|
206
|
-
).on(*control_qubits)
|
|
207
|
-
return [result, controlled_phase_op]
|
|
208
|
-
result = protocols.decompose_once_with_qubits(
|
|
209
|
-
self.sub_gate,
|
|
210
|
-
qubits[self.num_controls() :],
|
|
211
|
-
NotImplemented,
|
|
212
|
-
flatten=False,
|
|
213
|
-
context=context,
|
|
214
|
-
)
|
|
215
|
-
if result is NotImplemented:
|
|
216
|
-
return NotImplemented
|
|
217
191
|
|
|
218
|
-
return
|
|
219
|
-
|
|
220
|
-
lambda op: op.controlled_by(
|
|
221
|
-
*qubits[: self.num_controls()], control_values=self.control_values
|
|
222
|
-
),
|
|
223
|
-
)
|
|
192
|
+
# If nothing works, return `NotImplemented`.
|
|
193
|
+
return NotImplemented
|
|
224
194
|
|
|
225
195
|
def on(self, *qubits: cirq.Qid) -> cop.ControlledOperation:
|
|
226
196
|
if len(qubits) == 0:
|
cirq/ops/controlled_gate_test.py
CHANGED
|
@@ -804,3 +804,31 @@ def test_controlled_global_phase_matrix_gate_decomposes(
|
|
|
804
804
|
decomposed = cirq.decompose(cg_matrix(*all_qubits))
|
|
805
805
|
assert not any(isinstance(op.gate, cirq.MatrixGate) for op in decomposed)
|
|
806
806
|
np.testing.assert_allclose(cirq.unitary(cirq.Circuit(decomposed)), cirq.unitary(cg_matrix))
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
@pytest.mark.parametrize('gate_type', [cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZPowGate])
|
|
810
|
+
@pytest.mark.parametrize('test_shift', np.pi * (np.random.default_rng(324).random(10) * 2 - 1))
|
|
811
|
+
def test_controlled_phase_extracted_before_decomposition(gate_type, test_shift) -> None:
|
|
812
|
+
test_shift = 0.123 # arbitrary
|
|
813
|
+
|
|
814
|
+
shifted_gate = gate_type(global_shift=test_shift).controlled()
|
|
815
|
+
unshifted_gate = gate_type().controlled()
|
|
816
|
+
qs = cirq.LineQubit.range(cirq.num_qubits(shifted_gate))
|
|
817
|
+
shifted_op = shifted_gate.on(*qs)
|
|
818
|
+
unshifted_op = unshifted_gate.on(*qs)
|
|
819
|
+
shifted_decomposition = cirq.decompose(shifted_op)
|
|
820
|
+
unshifted_decomposition = cirq.decompose(unshifted_op)
|
|
821
|
+
|
|
822
|
+
# No brute-force calculation. It's the standard decomposition plus Z for the controlled shift.
|
|
823
|
+
assert shifted_decomposition[:-1] == unshifted_decomposition
|
|
824
|
+
z_op = shifted_decomposition[-1]
|
|
825
|
+
assert z_op.qubits == (qs[0],)
|
|
826
|
+
z = z_op.gate
|
|
827
|
+
assert isinstance(z, cirq.ZPowGate)
|
|
828
|
+
np.testing.assert_approx_equal(z.exponent, test_shift)
|
|
829
|
+
assert z.global_shift == 0
|
|
830
|
+
|
|
831
|
+
# Sanity check that the decomposition is equivalent
|
|
832
|
+
np.testing.assert_allclose(
|
|
833
|
+
cirq.unitary(cirq.Circuit(shifted_decomposition)), cirq.unitary(shifted_op), atol=1e-10
|
|
834
|
+
)
|
cirq/ops/global_phase_op.py
CHANGED
|
@@ -92,6 +92,13 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
92
92
|
coefficient = protocols.resolve_parameters(self.coefficient, resolver, recursive)
|
|
93
93
|
return GlobalPhaseGate(coefficient=coefficient)
|
|
94
94
|
|
|
95
|
+
def is_identity(self) -> bool:
|
|
96
|
+
"""Checks if gate is equivalent to an identity.
|
|
97
|
+
|
|
98
|
+
Returns: True if the coefficient is within rounding error of 1.
|
|
99
|
+
"""
|
|
100
|
+
return not protocols.is_parameterized(self._coefficient) and np.isclose(self.coefficient, 1)
|
|
101
|
+
|
|
95
102
|
def controlled(
|
|
96
103
|
self,
|
|
97
104
|
num_controls: int | None = None,
|
|
@@ -122,3 +129,23 @@ def global_phase_operation(
|
|
|
122
129
|
) -> cirq.GateOperation:
|
|
123
130
|
"""Creates an operation that represents a global phase on the state."""
|
|
124
131
|
return GlobalPhaseGate(coefficient, atol)()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def from_phase_and_exponent(
|
|
135
|
+
half_turns: cirq.TParamVal, exponent: cirq.TParamVal
|
|
136
|
+
) -> cirq.GlobalPhaseGate:
|
|
137
|
+
"""Creates a GlobalPhaseGate from the global phase and exponent.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
half_turns: The number of half turns to rotate by.
|
|
141
|
+
exponent: The power to raise the phase to.
|
|
142
|
+
|
|
143
|
+
Returns: A `GlobalPhaseGate` with the corresponding coefficient.
|
|
144
|
+
"""
|
|
145
|
+
coefficient = 1j ** (2 * half_turns * exponent)
|
|
146
|
+
coefficient = (
|
|
147
|
+
complex(coefficient)
|
|
148
|
+
if isinstance(coefficient, sympy.Expr) and coefficient.is_complex
|
|
149
|
+
else coefficient
|
|
150
|
+
)
|
|
151
|
+
return GlobalPhaseGate(coefficient)
|
cirq/ops/global_phase_op_test.py
CHANGED
|
@@ -19,6 +19,7 @@ import pytest
|
|
|
19
19
|
import sympy
|
|
20
20
|
|
|
21
21
|
import cirq
|
|
22
|
+
from cirq.ops import global_phase_op
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def test_init() -> None:
|
|
@@ -304,3 +305,22 @@ def test_global_phase_gate_controlled(coeff, exp) -> None:
|
|
|
304
305
|
assert g.controlled(control_values=xor_control_values) == cirq.ControlledGate(
|
|
305
306
|
g, control_values=xor_control_values
|
|
306
307
|
)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def test_is_identity() -> None:
|
|
311
|
+
g = cirq.GlobalPhaseGate(1)
|
|
312
|
+
assert g.is_identity()
|
|
313
|
+
g = cirq.GlobalPhaseGate(1j)
|
|
314
|
+
assert not g.is_identity()
|
|
315
|
+
g = cirq.GlobalPhaseGate(-1)
|
|
316
|
+
assert not g.is_identity()
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def test_from_phase_and_exponent() -> None:
|
|
320
|
+
g = global_phase_op.from_phase_and_exponent(2.5, 0.5)
|
|
321
|
+
assert g.coefficient == np.exp(1.25j * np.pi)
|
|
322
|
+
a, b = sympy.symbols('a, b')
|
|
323
|
+
g = global_phase_op.from_phase_and_exponent(a, b)
|
|
324
|
+
assert g.coefficient == 1j ** (2 * a * b)
|
|
325
|
+
g = global_phase_op.from_phase_and_exponent(1 / a, a)
|
|
326
|
+
assert g.coefficient == -1
|
cirq/ops/three_qubit_gates.py
CHANGED
|
@@ -106,19 +106,11 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
106
106
|
elif not b.is_adjacent(c):
|
|
107
107
|
a, b = b, a
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
exp = self._exponent
|
|
110
|
+
p = common_gates.T**exp
|
|
110
111
|
sweep_abc = [common_gates.CNOT(a, b), common_gates.CNOT(b, c)]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
complex(global_phase)
|
|
114
|
-
if protocols.is_parameterized(global_phase) and global_phase.is_complex
|
|
115
|
-
else global_phase
|
|
116
|
-
)
|
|
117
|
-
global_phase_operation = (
|
|
118
|
-
[global_phase_op.global_phase_operation(global_phase)]
|
|
119
|
-
if protocols.is_parameterized(global_phase) or abs(global_phase - 1.0) > 0
|
|
120
|
-
else []
|
|
121
|
-
)
|
|
112
|
+
global_phase_gate = global_phase_op.from_phase_and_exponent(self.global_shift, exp)
|
|
113
|
+
global_phase_operation = [] if global_phase_gate.is_identity() else [global_phase_gate()]
|
|
122
114
|
return global_phase_operation + [
|
|
123
115
|
p(a),
|
|
124
116
|
p(b),
|
|
@@ -81,9 +81,16 @@ class DecompositionContext:
|
|
|
81
81
|
Args:
|
|
82
82
|
qubit_manager: A `cirq.QubitManager` instance to allocate clean / dirty ancilla qubits as
|
|
83
83
|
part of the decompose protocol.
|
|
84
|
+
extract_global_phases: If set, will extract the global phases from
|
|
85
|
+
`DECOMPOSE_TARGET_GATESET` into independent global phase operations.
|
|
84
86
|
"""
|
|
85
87
|
|
|
86
88
|
qubit_manager: cirq.QubitManager
|
|
89
|
+
extract_global_phases: bool = False
|
|
90
|
+
|
|
91
|
+
def extracting_global_phases(self) -> DecompositionContext:
|
|
92
|
+
"""Returns a copy with the `extract_global_phases` field set."""
|
|
93
|
+
return dataclasses.replace(self, extract_global_phases=True)
|
|
87
94
|
|
|
88
95
|
|
|
89
96
|
class SupportsDecompose(Protocol):
|
|
@@ -445,3 +445,12 @@ def test_decompose_without_context_succeed() -> None:
|
|
|
445
445
|
cirq.ops.CleanQubit(1, prefix='_decompose_protocol'),
|
|
446
446
|
)
|
|
447
447
|
]
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def test_extracting_global_phases() -> None:
|
|
451
|
+
qm = cirq.SimpleQubitManager()
|
|
452
|
+
context = cirq.DecompositionContext(qm)
|
|
453
|
+
new_context = context.extracting_global_phases()
|
|
454
|
+
assert not context.extract_global_phases
|
|
455
|
+
assert new_context.extract_global_phases
|
|
456
|
+
assert new_context.qubit_manager is qm
|
{cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cirq-core
|
|
3
|
-
Version: 1.6.0.
|
|
3
|
+
Version: 1.6.0.dev20250625151218
|
|
4
4
|
Summary: A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
|
|
5
5
|
Home-page: http://github.com/quantumlib/cirq
|
|
6
6
|
Author: The Cirq Developers
|
{cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/RECORD
RENAMED
|
@@ -4,8 +4,8 @@ cirq/_compat_test.py,sha256=emXpdD5ZvwLRlFAoQB8YatmZyU3b4e9jg6FppMTUhkU,33900
|
|
|
4
4
|
cirq/_doc.py,sha256=BrnoABo1hk5RgB3Cgww4zLHUfiyFny0F1V-tOMCbdaU,2909
|
|
5
5
|
cirq/_import.py,sha256=ixBu4EyGl46Ram2cP3p5eZVEFDW5L2DS-VyTjz4N9iw,8429
|
|
6
6
|
cirq/_import_test.py,sha256=oF4izzOVZLc7NZ0aZHFcGv-r01eiFFt_JORx_x7_D4s,1089
|
|
7
|
-
cirq/_version.py,sha256=
|
|
8
|
-
cirq/_version_test.py,sha256=
|
|
7
|
+
cirq/_version.py,sha256=JFjFH7nhtoKUCtDTOqc6JVjGQTTrG0dSwORtZIWSIQE,1206
|
|
8
|
+
cirq/_version_test.py,sha256=4nJELIk_dACmHUTIXaCc33fN-FvAxaaqujvxtqOU_co,155
|
|
9
9
|
cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
|
|
10
10
|
cirq/json_resolver_cache.py,sha256=hYyG53VJeV61X0oukK5ndZYega8lkL2FyaL1m0j6h5M,13556
|
|
11
11
|
cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
|
|
@@ -283,12 +283,12 @@ cirq/ops/common_channels.py,sha256=BD8-qJDGITOSP0bJVcWGgjbI5dj2dwFkSzzWb-qgfcc,3
|
|
|
283
283
|
cirq/ops/common_channels_test.py,sha256=Qzw7nDrWgO1GDB7qkN2YUZi3NDswvvBJ9TEnSNakJX4,30755
|
|
284
284
|
cirq/ops/common_gate_families.py,sha256=trK4ZXCKqYahZkyuwaAn-TcjUu7gmI9n9geO8PYiRGE,8606
|
|
285
285
|
cirq/ops/common_gate_families_test.py,sha256=SfIKolQhVIof0uOHljY1QKT9Tu_4WzUsoeCNR2jIOPg,5441
|
|
286
|
-
cirq/ops/common_gates.py,sha256=
|
|
287
|
-
cirq/ops/common_gates_test.py,sha256=
|
|
286
|
+
cirq/ops/common_gates.py,sha256=pnyLK2FurjE6idejtAzgRaawiW-AqiM22w7xMkEpxVs,58221
|
|
287
|
+
cirq/ops/common_gates_test.py,sha256=IcUWxDTTTbis0efXz2Kn0zAdclp9R31fZAfCx3E-BOo,49758
|
|
288
288
|
cirq/ops/control_values.py,sha256=GrNi8YJZSZDCl8Su6Ocimvd1R1SejFJjVu2thcJ8VLI,13346
|
|
289
289
|
cirq/ops/control_values_test.py,sha256=Wyn0nwtcpnJvcPVRHmFGb3PtYxvsbpluA5UbPrG7tIo,13067
|
|
290
|
-
cirq/ops/controlled_gate.py,sha256=
|
|
291
|
-
cirq/ops/controlled_gate_test.py,sha256=
|
|
290
|
+
cirq/ops/controlled_gate.py,sha256=3Hex9AdY6c_DedKoCqqpS4gx9rAgm9KZITbwUBXsoYg,13562
|
|
291
|
+
cirq/ops/controlled_gate_test.py,sha256=jmIOlCx8dC3VId4NynX1ZYy7s7tkLav_d-fjiIZyVh0,29308
|
|
292
292
|
cirq/ops/controlled_operation.py,sha256=l0pjUfru39HBuAbBkRCqJmrJDxah0JOFxXXILcUt0v8,13978
|
|
293
293
|
cirq/ops/controlled_operation_test.py,sha256=qXpnUoeWmOQaTMZPAuuICtX9Idf-JWtdARTsTENv54g,16546
|
|
294
294
|
cirq/ops/dense_pauli_string.py,sha256=1TijNu1D2HIbbnwLbT_f546R2L4OCQtm1bKjqhno1Kg,24234
|
|
@@ -307,8 +307,8 @@ cirq/ops/gate_operation.py,sha256=MF8JIYEM6bQu6ft9Eb19hSOillzu8MmaIoXSlmwbm5U,13
|
|
|
307
307
|
cirq/ops/gate_operation_test.py,sha256=4QwWxCjGXNM__6QGw1kYSbBMh_4783jBZVBJD1ERGPk,18020
|
|
308
308
|
cirq/ops/gateset.py,sha256=9HFW5Sg_jPpao8SEd7XgLdc_6xgUwZfvb6f7pfVPIF8,21492
|
|
309
309
|
cirq/ops/gateset_test.py,sha256=_dpKTEwXuOY-jpev9rBPEcMy4KZ7zd6GmJ5JkvZAeog,16580
|
|
310
|
-
cirq/ops/global_phase_op.py,sha256=
|
|
311
|
-
cirq/ops/global_phase_op_test.py,sha256=
|
|
310
|
+
cirq/ops/global_phase_op.py,sha256=GcERs4X5h5_at6tvJc8-AcM0cVsLCRPlpPkAWMINm54,5711
|
|
311
|
+
cirq/ops/global_phase_op_test.py,sha256=9BBnPZLLmBzHsMoRPMFTAShx87TJnhTLvvgLpHJF4wc,10721
|
|
312
312
|
cirq/ops/greedy_qubit_manager.py,sha256=UTd9cTRbl4GQmf6ai6zqVBn5TR3-Vg84jJu4AN-0cxc,4050
|
|
313
313
|
cirq/ops/greedy_qubit_manager_test.py,sha256=5vSKWsO0q8LwaKJSnOqr0bVQooKt0cwcO7zmPArHRRs,3464
|
|
314
314
|
cirq/ops/identity.py,sha256=jWPE3jWLduXF5JgA0qol2blHXRvFUndClukG6nwGvUE,5862
|
|
@@ -374,7 +374,7 @@ cirq/ops/swap_gates.py,sha256=mEDVB4pdBsbenaOahrNtAcE2B1ZPW-4vGq079rECxf4,11743
|
|
|
374
374
|
cirq/ops/swap_gates_test.py,sha256=8Yee6RgkQahsnB92ZD-rTb9dNqMLXdBKlgWC8qWd2uo,7624
|
|
375
375
|
cirq/ops/tags.py,sha256=nBKqDnPHunxABIOqSAHsVb2hByRAJSfGCJjTC6-AbTY,2307
|
|
376
376
|
cirq/ops/tags_test.py,sha256=EUCAjFYsQ98r6eo8XUNJoQCKMRCc4KvcqXUZAzfPqiE,1210
|
|
377
|
-
cirq/ops/three_qubit_gates.py,sha256=
|
|
377
|
+
cirq/ops/three_qubit_gates.py,sha256=yPzu3xYz9_bKQCzuRyH3YnB8KHEI1qtdH8whBgHhMkU,27911
|
|
378
378
|
cirq/ops/three_qubit_gates_test.py,sha256=r9bO7noLCUIGhSprE-KUTlnrf16IEoAhy93Obi6oL18,11951
|
|
379
379
|
cirq/ops/two_qubit_diagonal_gate.py,sha256=m2wnFpi0sHA9cxMa2cqwRYGQIlbyTGohMTLdVVQZ2-U,5377
|
|
380
380
|
cirq/ops/two_qubit_diagonal_gate_test.py,sha256=pv24VMf2yQ-2gaHg_EUwWx5tAFvXo47_sKzdbdCPhRY,4100
|
|
@@ -399,8 +399,8 @@ cirq/protocols/commutes_protocol.py,sha256=6cJNba3aEsCh_XHIeNTHb0LRzws6ZbxOrKL_r
|
|
|
399
399
|
cirq/protocols/commutes_protocol_test.py,sha256=9YhBFYAwc-XpU7HrQp-GarKwmwmbgyadUYqlkiG10A8,5885
|
|
400
400
|
cirq/protocols/control_key_protocol.py,sha256=uGgfahCHzsFpUGq6flgTMuqPh20zUSB2AOkSrhyoqwQ,2621
|
|
401
401
|
cirq/protocols/control_key_protocol_test.py,sha256=fNDDkf4mQpA_tKuhX1e2BJN72v9HdGftgd79sOqREJE,1014
|
|
402
|
-
cirq/protocols/decompose_protocol.py,sha256=
|
|
403
|
-
cirq/protocols/decompose_protocol_test.py,sha256=
|
|
402
|
+
cirq/protocols/decompose_protocol.py,sha256=zwmrlFmBggInx1u1xZEeBDxaLGRWMGHCp87F7RRQPH4,19129
|
|
403
|
+
cirq/protocols/decompose_protocol_test.py,sha256=s5ELgra5UKExKCjDHUtMOwTZrGmYwxAphCRryRLMM_Q,16456
|
|
404
404
|
cirq/protocols/equal_up_to_global_phase_protocol.py,sha256=y-GPOImHgdjVqXF-qE3SUmlekF6-zI0tgi0E2nTdW1M,4106
|
|
405
405
|
cirq/protocols/equal_up_to_global_phase_protocol_test.py,sha256=EDfWnCuYAVfcvBXHYoZ0lDukNEGG2c53vzP7s8jHLKA,6050
|
|
406
406
|
cirq/protocols/has_stabilizer_effect_protocol.py,sha256=T_CVVpvckp3ZTsWi089mPqbmwOPLlF6GalEKrVK7Hvs,4309
|
|
@@ -1220,8 +1220,8 @@ cirq/work/sampler.py,sha256=rxbMWvrhu3gfNSBjZKozw28lLKVvBAS_1EGyPdYe8Xg,19041
|
|
|
1220
1220
|
cirq/work/sampler_test.py,sha256=SsMrRvLDYELyOAWLKISjkdEfrBwLYWRsT6D8WrsLM3Q,13533
|
|
1221
1221
|
cirq/work/zeros_sampler.py,sha256=Fs2JWwq0n9zv7_G5Rm-9vPeHUag7uctcMOHg0JTkZpc,2371
|
|
1222
1222
|
cirq/work/zeros_sampler_test.py,sha256=lQLgQDGBLtfImryys2HzQ2jOSGxHgc7-koVBUhv8qYk,3345
|
|
1223
|
-
cirq_core-1.6.0.
|
|
1224
|
-
cirq_core-1.6.0.
|
|
1225
|
-
cirq_core-1.6.0.
|
|
1226
|
-
cirq_core-1.6.0.
|
|
1227
|
-
cirq_core-1.6.0.
|
|
1223
|
+
cirq_core-1.6.0.dev20250625151218.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
1224
|
+
cirq_core-1.6.0.dev20250625151218.dist-info/METADATA,sha256=VQ-hW8jm5hWk7VDRsEm_Nf3h2rQyRc_JYD1pNOyhyMY,4857
|
|
1225
|
+
cirq_core-1.6.0.dev20250625151218.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1226
|
+
cirq_core-1.6.0.dev20250625151218.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
|
|
1227
|
+
cirq_core-1.6.0.dev20250625151218.dist-info/RECORD,,
|
{cirq_core-1.6.0.dev20250625011740.dist-info → cirq_core-1.6.0.dev20250625151218.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|