cirq-core 1.6.0.dev20250722041606__py3-none-any.whl → 1.6.0.dev20250722170817__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/matrix_gates.py +3 -3
- cirq/ops/matrix_gates_test.py +13 -0
- cirq/protocols/kraus_protocol.py +40 -0
- cirq/protocols/kraus_protocol_test.py +72 -0
- cirq/testing/circuit_compare.py +1 -0
- {cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.dist-info}/RECORD +12 -12
- {cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.dist-info}/top_level.txt +0 -0
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
cirq/ops/matrix_gates.py
CHANGED
|
@@ -22,7 +22,7 @@ import numpy as np
|
|
|
22
22
|
|
|
23
23
|
from cirq import _import, linalg, protocols
|
|
24
24
|
from cirq._compat import proper_repr
|
|
25
|
-
from cirq.ops import global_phase_op,
|
|
25
|
+
from cirq.ops import global_phase_op, phased_x_z_gate, raw_types
|
|
26
26
|
|
|
27
27
|
if TYPE_CHECKING:
|
|
28
28
|
import cirq
|
|
@@ -170,8 +170,8 @@ class MatrixGate(raw_types.Gate):
|
|
|
170
170
|
return NotImplemented
|
|
171
171
|
# The above algorithms ignore phase, but phase is important to maintain if the gate is
|
|
172
172
|
# controlled. Here, we add it back in with a global phase op.
|
|
173
|
-
|
|
174
|
-
u =
|
|
173
|
+
circuit = Circuit(*decomposed)
|
|
174
|
+
u = circuit.unitary(qubit_order=qubits, qubits_that_should_be_present=qubits)
|
|
175
175
|
phase_delta = linalg.phase_delta(u, self._matrix)
|
|
176
176
|
# Phase delta is on the complex unit circle, so if real(phase_delta) >= 1, that means
|
|
177
177
|
# no phase delta. (>1 is rounding error).
|
cirq/ops/matrix_gates_test.py
CHANGED
|
@@ -413,3 +413,16 @@ def test_matrixgate_name_serialization():
|
|
|
413
413
|
gate_after_serialization3 = cirq.read_json(json_text=cirq.to_json(gate3))
|
|
414
414
|
assert gate3._name == ''
|
|
415
415
|
assert gate_after_serialization3._name == ''
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def test_decompose_when_qubits_not_in_ascending_order():
|
|
419
|
+
# Previous code for preserving global phase would misorder qubits
|
|
420
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
421
|
+
circuit1 = cirq.Circuit()
|
|
422
|
+
matrix = cirq.testing.random_unitary(4, random_state=0)
|
|
423
|
+
circuit1.append(cirq.MatrixGate(matrix).on(q1, q0))
|
|
424
|
+
u1 = cirq.unitary(circuit1)
|
|
425
|
+
decomposed = cirq.decompose(circuit1)
|
|
426
|
+
circuit2 = cirq.Circuit(decomposed)
|
|
427
|
+
u2 = cirq.unitary(circuit2)
|
|
428
|
+
np.testing.assert_allclose(u1, u2, atol=1e-14)
|
cirq/protocols/kraus_protocol.py
CHANGED
|
@@ -23,6 +23,7 @@ from typing import Any, Sequence, TypeVar
|
|
|
23
23
|
import numpy as np
|
|
24
24
|
from typing_extensions import Protocol
|
|
25
25
|
|
|
26
|
+
from cirq import protocols, qis
|
|
26
27
|
from cirq._doc import doc_private
|
|
27
28
|
from cirq.protocols.decompose_protocol import _try_decompose_into_operations_and_qubits
|
|
28
29
|
from cirq.protocols.mixture_protocol import has_mixture
|
|
@@ -94,6 +95,37 @@ class SupportsKraus(Protocol):
|
|
|
94
95
|
"""
|
|
95
96
|
|
|
96
97
|
|
|
98
|
+
def _strat_kraus_from_apply_channel(val: Any) -> tuple[np.ndarray, ...] | None:
|
|
99
|
+
"""Attempts to compute a value's Kraus operators via its _apply_channel_ method.
|
|
100
|
+
This is very expensive (O(16^N)), so only do this as a last resort."""
|
|
101
|
+
method = getattr(val, '_apply_channel_', None)
|
|
102
|
+
if method is None:
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
qid_shape = protocols.qid_shape(val)
|
|
106
|
+
|
|
107
|
+
eye = qis.eye_tensor(qid_shape * 2, dtype=np.complex128)
|
|
108
|
+
buffer = np.empty_like(eye)
|
|
109
|
+
buffer.fill(float('nan'))
|
|
110
|
+
superop = protocols.apply_channel(
|
|
111
|
+
val=val,
|
|
112
|
+
args=protocols.ApplyChannelArgs(
|
|
113
|
+
target_tensor=eye,
|
|
114
|
+
out_buffer=buffer,
|
|
115
|
+
auxiliary_buffer0=buffer.copy(),
|
|
116
|
+
auxiliary_buffer1=buffer.copy(),
|
|
117
|
+
left_axes=list(range(len(qid_shape))),
|
|
118
|
+
right_axes=list(range(len(qid_shape), len(qid_shape) * 2)),
|
|
119
|
+
),
|
|
120
|
+
default=None,
|
|
121
|
+
)
|
|
122
|
+
if superop is None or superop is NotImplemented:
|
|
123
|
+
return None
|
|
124
|
+
n = np.prod(qid_shape) ** 2
|
|
125
|
+
kraus_ops = qis.superoperator_to_kraus(superop.reshape((n, n)))
|
|
126
|
+
return tuple(kraus_ops)
|
|
127
|
+
|
|
128
|
+
|
|
97
129
|
def kraus(
|
|
98
130
|
val: Any, default: Any = RaiseTypeErrorIfNotProvided
|
|
99
131
|
) -> tuple[np.ndarray, ...] | TDefault:
|
|
@@ -159,6 +191,14 @@ def kraus(
|
|
|
159
191
|
if channel_result is not NotImplemented:
|
|
160
192
|
return tuple(channel_result) # pragma: no cover
|
|
161
193
|
|
|
194
|
+
# Last-resort fallback: try to derive Kraus from _apply_channel_.
|
|
195
|
+
# Note: _apply_channel can lead to kraus being called again, so if default
|
|
196
|
+
# is None, this can trigger an infinite loop.
|
|
197
|
+
if default is not None:
|
|
198
|
+
result = _strat_kraus_from_apply_channel(val)
|
|
199
|
+
if result is not None:
|
|
200
|
+
return result
|
|
201
|
+
|
|
162
202
|
if default is not RaiseTypeErrorIfNotProvided:
|
|
163
203
|
return default
|
|
164
204
|
|
|
@@ -22,6 +22,7 @@ import numpy as np
|
|
|
22
22
|
import pytest
|
|
23
23
|
|
|
24
24
|
import cirq
|
|
25
|
+
from cirq.protocols.apply_channel_protocol import _apply_kraus
|
|
25
26
|
|
|
26
27
|
LOCAL_DEFAULT: list[np.ndarray] = [np.array([])]
|
|
27
28
|
|
|
@@ -171,3 +172,74 @@ def test_has_kraus_when_decomposed(decomposed_cls) -> None:
|
|
|
171
172
|
op = HasKrausWhenDecomposed(decomposed_cls).on(cirq.NamedQubit('test'))
|
|
172
173
|
assert cirq.has_kraus(op)
|
|
173
174
|
assert not cirq.has_kraus(op, allow_decompose=False)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def test_strat_kraus_from_apply_channel_returns_none():
|
|
178
|
+
# Remove _kraus_ and _apply_channel_ methods
|
|
179
|
+
class NoApplyChannelReset(cirq.ResetChannel):
|
|
180
|
+
def _kraus_(self):
|
|
181
|
+
return NotImplemented
|
|
182
|
+
|
|
183
|
+
def _apply_channel_(self, args):
|
|
184
|
+
return NotImplemented
|
|
185
|
+
|
|
186
|
+
gate_no_apply = NoApplyChannelReset()
|
|
187
|
+
with pytest.raises(
|
|
188
|
+
TypeError,
|
|
189
|
+
match="does have a _kraus_, _mixture_ or _unitary_ method, but it returned NotImplemented",
|
|
190
|
+
):
|
|
191
|
+
cirq.kraus(gate_no_apply)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@pytest.mark.parametrize(
|
|
195
|
+
'channel_cls,params',
|
|
196
|
+
[
|
|
197
|
+
(cirq.BitFlipChannel, (0.5,)),
|
|
198
|
+
(cirq.PhaseFlipChannel, (0.3,)),
|
|
199
|
+
(cirq.DepolarizingChannel, (0.2,)),
|
|
200
|
+
(cirq.AmplitudeDampingChannel, (0.4,)),
|
|
201
|
+
(cirq.PhaseDampingChannel, (0.25,)),
|
|
202
|
+
],
|
|
203
|
+
)
|
|
204
|
+
def test_kraus_fallback_to_apply_channel(channel_cls, params) -> None:
|
|
205
|
+
"""Kraus protocol falls back to _apply_channel_ when no _kraus_, _mixture_, or _unitary_."""
|
|
206
|
+
# Create the expected channel and get its Kraus operators
|
|
207
|
+
expected_channel = channel_cls(*params)
|
|
208
|
+
expected_kraus = cirq.kraus(expected_channel)
|
|
209
|
+
|
|
210
|
+
class TestChannel:
|
|
211
|
+
def __init__(self, channel_cls, params):
|
|
212
|
+
self.channel_cls = channel_cls
|
|
213
|
+
self.params = params
|
|
214
|
+
self.expected_kraus = cirq.kraus(channel_cls(*params))
|
|
215
|
+
|
|
216
|
+
def _num_qubits_(self):
|
|
217
|
+
return 1
|
|
218
|
+
|
|
219
|
+
def _apply_channel_(self, args: cirq.ApplyChannelArgs):
|
|
220
|
+
return _apply_kraus(self.expected_kraus, args)
|
|
221
|
+
|
|
222
|
+
chan = TestChannel(channel_cls, params)
|
|
223
|
+
kraus_ops = cirq.kraus(chan)
|
|
224
|
+
|
|
225
|
+
# Compare the superoperator matrices for equivalence
|
|
226
|
+
expected_super = sum(np.kron(k, k.conj()) for k in expected_kraus)
|
|
227
|
+
actual_super = sum(np.kron(k, k.conj()) for k in kraus_ops)
|
|
228
|
+
np.testing.assert_allclose(actual_super, expected_super, atol=1e-8)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def test_reset_channel_kraus_apply_channel_consistency():
|
|
232
|
+
Reset = cirq.ResetChannel
|
|
233
|
+
# Original gate
|
|
234
|
+
gate = Reset()
|
|
235
|
+
cirq.testing.assert_has_consistent_apply_channel(gate)
|
|
236
|
+
cirq.testing.assert_consistent_channel(gate)
|
|
237
|
+
|
|
238
|
+
# Remove _kraus_ method
|
|
239
|
+
class NoKrausReset(Reset):
|
|
240
|
+
def _kraus_(self):
|
|
241
|
+
return NotImplemented
|
|
242
|
+
|
|
243
|
+
gate_no_kraus = NoKrausReset()
|
|
244
|
+
# Should still match the original superoperator
|
|
245
|
+
np.testing.assert_allclose(cirq.kraus(gate), cirq.kraus(gate_no_kraus), atol=1e-8)
|
cirq/testing/circuit_compare.py
CHANGED
|
@@ -336,6 +336,7 @@ def assert_has_consistent_apply_channel(val: Any, *, atol: float = 1e-8) -> None
|
|
|
336
336
|
atol: Absolute error tolerance.
|
|
337
337
|
"""
|
|
338
338
|
__tracebackhide__ = True
|
|
339
|
+
assert hasattr(val, '_apply_channel_')
|
|
339
340
|
|
|
340
341
|
kraus = protocols.kraus(val, default=None)
|
|
341
342
|
expected = qis.kraus_to_superoperator(kraus) if kraus is not None else None
|
{cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.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.dev20250722170817
|
|
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.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.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=_kMl3JRDUx0uWereGzzxnl55QCVAISV1PjAdpb9UIdc,1206
|
|
8
|
+
cirq/_version_test.py,sha256=YPglnCVZk8K6xjmYv-Tp-eC0-Es2CnNotUVN2i0kXAE,155
|
|
9
9
|
cirq/conftest.py,sha256=wSDKNdIQRDfLnXvOCWD3erheOw8JHRhdfQ53EyTUIXg,1239
|
|
10
10
|
cirq/json_resolver_cache.py,sha256=A5DIgFAY1hUNt9vai_C3-gGBv24116CJMzQxMcXOax4,13726
|
|
11
11
|
cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
|
|
@@ -319,8 +319,8 @@ cirq/ops/kraus_channel.py,sha256=uSLq2AG72zbwzcbiEETFOAZ35KNR9U9KIFO31HYzLKA,507
|
|
|
319
319
|
cirq/ops/kraus_channel_test.py,sha256=FhgCyCKa4bIgGc4yAQbqDKB80910TEVVWRknyyGbILg,4955
|
|
320
320
|
cirq/ops/linear_combinations.py,sha256=AQA0aFDuHXks44fFtevrc2Zl1chleSlf1A0LkmrZrW8,39883
|
|
321
321
|
cirq/ops/linear_combinations_test.py,sha256=EYqrWlFFThv8dl5B_9yIckEn_z3-Nfzh7rdVzGpIVWM,67351
|
|
322
|
-
cirq/ops/matrix_gates.py,sha256=
|
|
323
|
-
cirq/ops/matrix_gates_test.py,sha256=
|
|
322
|
+
cirq/ops/matrix_gates.py,sha256=or8Kc3kP1NFjLbAHemmrZIqYFgEeeteMogNVEzYjosk,10238
|
|
323
|
+
cirq/ops/matrix_gates_test.py,sha256=MEK1VsaAv2Li_aYhFIfD53gytCNo854l5-BXL9yZBFs,14770
|
|
324
324
|
cirq/ops/measure_util.py,sha256=iT7vrYLTo6L4z4_Zdm-8e8iiiKyQgF2v9Ui74Tg52aw,7261
|
|
325
325
|
cirq/ops/measure_util_test.py,sha256=WrbR2jr_bFXxpQe8n3ANLAKYo1hcf-SlgsFOi-ULRXU,5343
|
|
326
326
|
cirq/ops/measurement_gate.py,sha256=i7ThYTd1xdzOG274jzFnzqEz5Qmv6wggcubWa-3FDZE,11874
|
|
@@ -414,8 +414,8 @@ cirq/protocols/inverse_protocol.py,sha256=tHaY8-dfd0SD59v3DZ_zpwz7lwFrraPExEnIgn
|
|
|
414
414
|
cirq/protocols/inverse_protocol_test.py,sha256=5RoZfSRzBvpGpLdg1XKYdB6qy-GkDvZsATUvxdFrLJ0,2067
|
|
415
415
|
cirq/protocols/json_serialization.py,sha256=z7Yu2vsNabRkdeYyIuNCoXATHkrOGreTRShNyN0Fjuc,24520
|
|
416
416
|
cirq/protocols/json_serialization_test.py,sha256=An57W8eBWaUF4kKOCos2UlHzNiILnUJvqmZLmwZ_6MA,27872
|
|
417
|
-
cirq/protocols/kraus_protocol.py,sha256=
|
|
418
|
-
cirq/protocols/kraus_protocol_test.py,sha256=
|
|
417
|
+
cirq/protocols/kraus_protocol.py,sha256=xNcjUBjxLOcsWRDkv7wdJ51iUvDhtHpxy_vXhhc2Gyw,10735
|
|
418
|
+
cirq/protocols/kraus_protocol_test.py,sha256=yw0WEXYNEOgA7xJB9UMIGbHRn2HJwPa88LKOoOuvRWc,7959
|
|
419
419
|
cirq/protocols/measurement_key_protocol.py,sha256=JU7XbZfR7o6Wcv5qRJisp3ZAWwW9Fx7OHtxNMrWtZoQ,13351
|
|
420
420
|
cirq/protocols/measurement_key_protocol_test.py,sha256=PqSU9uB4t2yvPz9hZBLby2mZnZo-DOLlx3HIicyPeLo,8768
|
|
421
421
|
cirq/protocols/mixture_protocol.py,sha256=A8J-kkwUqiQphw6d3DK3QZ-lP31DTWv475ZzdeqYA0w,6428
|
|
@@ -976,7 +976,7 @@ cirq/study/sweepable_test.py,sha256=gMKkCoy8JxaCDeMTiDLdmcbBrioWs-teYOnqrri_2rI,
|
|
|
976
976
|
cirq/study/sweeps.py,sha256=VhGc1Q4qJHF9QQlCpGh-X5rF3tKp0esUvWCy1y22S9M,21403
|
|
977
977
|
cirq/study/sweeps_test.py,sha256=fiOKKnDyD-Ju7xeQM7A9pKkfR58VHXKdc0qw9d0MwRA,17231
|
|
978
978
|
cirq/testing/__init__.py,sha256=QNkOC_QdYkiNrIxYuNjPsB_iWmTW8zUrUwOSiz_8LPg,6171
|
|
979
|
-
cirq/testing/circuit_compare.py,sha256=
|
|
979
|
+
cirq/testing/circuit_compare.py,sha256=vWgMVa-TVwTRUMyEvNV6Ah3CMRlZYVo1xn41MsCTHzo,18766
|
|
980
980
|
cirq/testing/circuit_compare_test.py,sha256=4ov58dOiez9HSQUJDP5hW1Li2tL75Gkevts2PiyyfSU,19738
|
|
981
981
|
cirq/testing/consistent_act_on.py,sha256=hE_6fRPcmlvgRf2bHkB0XS4jnh_cR2PVS-g9YyNIijo,7670
|
|
982
982
|
cirq/testing/consistent_act_on_test.py,sha256=UR-1RMhF88wlG3cFnbR0i8khrWFEuWg75WF5lnoXWWM,3571
|
|
@@ -1224,8 +1224,8 @@ cirq/work/sampler.py,sha256=rxbMWvrhu3gfNSBjZKozw28lLKVvBAS_1EGyPdYe8Xg,19041
|
|
|
1224
1224
|
cirq/work/sampler_test.py,sha256=SsMrRvLDYELyOAWLKISjkdEfrBwLYWRsT6D8WrsLM3Q,13533
|
|
1225
1225
|
cirq/work/zeros_sampler.py,sha256=Fs2JWwq0n9zv7_G5Rm-9vPeHUag7uctcMOHg0JTkZpc,2371
|
|
1226
1226
|
cirq/work/zeros_sampler_test.py,sha256=lQLgQDGBLtfImryys2HzQ2jOSGxHgc7-koVBUhv8qYk,3345
|
|
1227
|
-
cirq_core-1.6.0.
|
|
1228
|
-
cirq_core-1.6.0.
|
|
1229
|
-
cirq_core-1.6.0.
|
|
1230
|
-
cirq_core-1.6.0.
|
|
1231
|
-
cirq_core-1.6.0.
|
|
1227
|
+
cirq_core-1.6.0.dev20250722170817.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
1228
|
+
cirq_core-1.6.0.dev20250722170817.dist-info/METADATA,sha256=YO4I5RwXxcwxk32N6ggIh0zSFCIzfT7DAN-NQdSDyC0,4857
|
|
1229
|
+
cirq_core-1.6.0.dev20250722170817.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1230
|
+
cirq_core-1.6.0.dev20250722170817.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
|
|
1231
|
+
cirq_core-1.6.0.dev20250722170817.dist-info/RECORD,,
|
{cirq_core-1.6.0.dev20250722041606.dist-info → cirq_core-1.6.0.dev20250722170817.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|