cirq-core 1.5.0.dev20250404235631__py3-none-any.whl → 1.5.0.dev20250405050852__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 CHANGED
@@ -28,4 +28,4 @@ if sys.version_info < (3, 10, 0): # pragma: no cover
28
28
  'of cirq (e.g. "python -m pip install cirq==1.1.*")'
29
29
  )
30
30
 
31
- __version__ = "1.5.0.dev20250404235631"
31
+ __version__ = "1.5.0.dev20250405050852"
cirq/_version_test.py CHANGED
@@ -3,4 +3,4 @@ import cirq
3
3
 
4
4
 
5
5
  def test_version():
6
- assert cirq.__version__ == "1.5.0.dev20250404235631"
6
+ assert cirq.__version__ == "1.5.0.dev20250405050852"
@@ -1089,15 +1089,12 @@ class BitFlipChannel(raw_types.Gate):
1089
1089
  ValueError: if p is not a valid probability.
1090
1090
  """
1091
1091
  self._p = value.validate_probability(p, 'p')
1092
- self._delegate = AsymmetricDepolarizingChannel(p, 0.0, 0.0)
1093
1092
 
1094
1093
  def _num_qubits_(self) -> int:
1095
1094
  return 1
1096
1095
 
1097
- def _mixture_(self) -> Sequence[Tuple[float, np.ndarray]]:
1098
- mixture = self._delegate._mixture_()
1099
- # just return identity and x term
1100
- return (mixture[0], mixture[1])
1096
+ def _mixture_(self) -> Sequence[Tuple[float, Any]]:
1097
+ return ((1 - self._p, identity.I), (self._p, pauli_gates.X))
1101
1098
 
1102
1099
  def _has_mixture_(self) -> bool:
1103
1100
  return True
cirq/ops/common_gates.py CHANGED
@@ -326,12 +326,6 @@ class XPowGate(eigen_gate.EigenGate):
326
326
  d['dimension'] = self.dimension
327
327
  return d
328
328
 
329
- def _value_equality_values_(self):
330
- return (*super()._value_equality_values_(), self._dimension)
331
-
332
- def _value_equality_approximate_values_(self):
333
- return (*super()._value_equality_approximate_values_(), self._dimension)
334
-
335
329
 
336
330
  class Rx(XPowGate):
337
331
  r"""A gate with matrix $e^{-i X t/2}$ that rotates around the X axis of the Bloch sphere by $t$.
@@ -862,12 +856,6 @@ class ZPowGate(eigen_gate.EigenGate):
862
856
  d['dimension'] = self.dimension
863
857
  return d
864
858
 
865
- def _value_equality_values_(self):
866
- return (*super()._value_equality_values_(), self._dimension)
867
-
868
- def _value_equality_approximate_values_(self):
869
- return (*super()._value_equality_approximate_values_(), self._dimension)
870
-
871
859
 
872
860
  class Rz(ZPowGate):
873
861
  r"""A gate with matrix $e^{-i Z t/2}$ that rotates around the Z axis of the Bloch sphere by $t$.
@@ -245,11 +245,12 @@ def test_rot_gates_eq():
245
245
  eq.add_equality_group(cirq.YPowGate(), cirq.YPowGate(exponent=1), cirq.Y)
246
246
  eq.add_equality_group(cirq.ZPowGate(), cirq.ZPowGate(exponent=1), cirq.Z)
247
247
  eq.add_equality_group(
248
- cirq.ZPowGate(exponent=1, global_shift=-0.5), cirq.ZPowGate(exponent=5, global_shift=-0.5)
248
+ cirq.ZPowGate(exponent=1, global_shift=-0.5),
249
+ cirq.ZPowGate(exponent=5, global_shift=-0.5),
250
+ cirq.ZPowGate(exponent=5, global_shift=-0.1),
249
251
  )
250
252
  eq.add_equality_group(cirq.ZPowGate(exponent=3, global_shift=-0.5))
251
253
  eq.add_equality_group(cirq.ZPowGate(exponent=1, global_shift=-0.1))
252
- eq.add_equality_group(cirq.ZPowGate(exponent=5, global_shift=-0.1))
253
254
  eq.add_equality_group(
254
255
  cirq.CNotPowGate(), cirq.CXPowGate(), cirq.CNotPowGate(exponent=1), cirq.CNOT
255
256
  )
cirq/ops/eigen_gate.py CHANGED
@@ -34,7 +34,6 @@ import numpy as np
34
34
  import sympy
35
35
 
36
36
  from cirq import protocols, value
37
- from cirq.linalg import tolerance
38
37
  from cirq.ops import raw_types
39
38
 
40
39
  if TYPE_CHECKING:
@@ -122,7 +121,6 @@ class EigenGate(raw_types.Gate):
122
121
  exponent = exponent.real
123
122
  self._exponent = exponent
124
123
  self._global_shift = global_shift
125
- self._canonical_exponent_cached = None
126
124
 
127
125
  @property
128
126
  def exponent(self) -> value.TParamVal:
@@ -305,30 +303,19 @@ class EigenGate(raw_types.Gate):
305
303
  return NotImplemented # pragma: no cover
306
304
  return self._with_exponent(exponent=new_exponent)
307
305
 
308
- @property
309
- def _canonical_exponent(self):
310
- if self._canonical_exponent_cached is None:
311
- period = self._period()
312
- if not period:
313
- self._canonical_exponent_cached = self._exponent
314
- elif protocols.is_parameterized(self._exponent):
315
- self._canonical_exponent_cached = self._exponent
316
- if isinstance(self._exponent, sympy.Number):
317
- self._canonical_exponent_cached = float(self._exponent)
318
- else:
319
- self._canonical_exponent_cached = self._exponent % period
320
- return self._canonical_exponent_cached
321
-
322
306
  def _value_equality_values_(self):
323
- return self._canonical_exponent, self._global_shift
307
+ """The phases by which we multiply the eigenspaces.
324
308
 
325
- def _value_equality_approximate_values_(self):
326
- period = self._period()
327
- if not period or protocols.is_parameterized(self._exponent):
328
- exponent = self._exponent
329
- else:
330
- exponent = value.PeriodicValue(self._exponent, period)
331
- return exponent, self._global_shift
309
+ The default implementation assumes that the eigenspaces are constant
310
+ for the class, and the eigenphases are the only distinguishing
311
+ characteristics. For gates whose eigenspaces can change, such as
312
+ `PhasedISwapPowGate`, this must be overridden to provide the additional
313
+ fields that affect the eigenspaces.
314
+ """
315
+ symbolic = lambda x: isinstance(x, sympy.Expr) and x.free_symbols
316
+ f = lambda x: x if symbolic(x) else float(x)
317
+ shifts = (f(self._exponent) * f(self._global_shift + e) for e in self._eigen_shifts())
318
+ return tuple(s if symbolic(s) else value.PeriodicValue(f(s), 2) for s in shifts)
332
319
 
333
320
  def _trace_distance_bound_(self) -> Optional[float]:
334
321
  if protocols.is_parameterized(self._exponent):
@@ -378,20 +365,9 @@ class EigenGate(raw_types.Gate):
378
365
  return False
379
366
  self_without_phase = self._with_exponent(self.exponent)
380
367
  self_without_phase._global_shift = 0
381
- self_without_exp_or_phase = self_without_phase._with_exponent(0)
382
- self_without_exp_or_phase._global_shift = 0
383
368
  other_without_phase = other._with_exponent(other.exponent)
384
369
  other_without_phase._global_shift = 0
385
- other_without_exp_or_phase = other_without_phase._with_exponent(0)
386
- other_without_exp_or_phase._global_shift = 0
387
- if not protocols.approx_eq(
388
- self_without_exp_or_phase, other_without_exp_or_phase, atol=atol
389
- ):
390
- return False
391
-
392
- period = self_without_phase._period()
393
- exponents_diff = exponents[0] - exponents[1]
394
- return tolerance.near_zero_mod(exponents_diff, period, atol=atol)
370
+ return protocols.approx_eq(self_without_phase, other_without_phase, atol=atol)
395
371
 
396
372
  def _json_dict_(self) -> Dict[str, Any]:
397
373
  return protocols.obj_to_dict_helper(self, ['exponent', 'global_shift'])
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import re
16
15
  from typing import List, Tuple
17
16
 
18
17
  import numpy as np
@@ -50,7 +49,7 @@ class CExpZinGate(cirq.EigenGate, cirq.testing.TwoQubitGate):
50
49
  ]
51
50
 
52
51
 
53
- class ZGateDef(cirq.EigenGate, cirq.testing.TwoQubitGate):
52
+ class ZGateDef(cirq.EigenGate, cirq.testing.SingleQubitGate):
54
53
  @property
55
54
  def exponent(self):
56
55
  return self._exponent
@@ -97,7 +96,6 @@ def test_eq():
97
96
  eq.make_equality_group(lambda: CExpZinGate(quarter_turns=0.1))
98
97
  eq.add_equality_group(CExpZinGate(0), CExpZinGate(4), CExpZinGate(-4))
99
98
 
100
- # Equates by canonicalized period.
101
99
  eq.add_equality_group(CExpZinGate(1.5), CExpZinGate(41.5))
102
100
  eq.add_equality_group(CExpZinGate(3.5), CExpZinGate(-0.5))
103
101
 
@@ -109,6 +107,64 @@ def test_eq():
109
107
  eq.add_equality_group(ZGateDef(exponent=0.5, global_shift=0.5))
110
108
  eq.add_equality_group(ZGateDef(exponent=1.0, global_shift=0.5))
111
109
 
110
+ # All variants of (0,0) == (0*a,0*a) == (0, 2) == (2, 2)
111
+ a, b = sympy.symbols('a, b')
112
+ eq.add_equality_group(
113
+ WeightedZPowGate(0),
114
+ WeightedZPowGate(0) ** 1.1,
115
+ WeightedZPowGate(0) ** a,
116
+ (WeightedZPowGate(0) ** a) ** 1.2,
117
+ WeightedZPowGate(0) ** (a + 1.3),
118
+ WeightedZPowGate(0) ** b,
119
+ WeightedZPowGate(1) ** 2,
120
+ WeightedZPowGate(0, global_shift=1) ** 2,
121
+ WeightedZPowGate(1, global_shift=1) ** 2,
122
+ WeightedZPowGate(2),
123
+ WeightedZPowGate(0, global_shift=2),
124
+ WeightedZPowGate(2, global_shift=2),
125
+ )
126
+ # WeightedZPowGate(2) is identity, but non-integer exponent would make it different, similar to
127
+ # how we treat (X**2)**0.5==X. So these are in their own equality group. (0, 2*a)
128
+ eq.add_equality_group(
129
+ WeightedZPowGate(2) ** a,
130
+ (WeightedZPowGate(1) ** 2) ** a,
131
+ (WeightedZPowGate(1) ** a) ** 2,
132
+ WeightedZPowGate(1) ** (a * 2),
133
+ WeightedZPowGate(1) ** (a + a),
134
+ )
135
+ # Similarly, these are identity without the exponent, but global_shift affects both phases
136
+ # instead of just the one, so will have a different effect from the above depending on the
137
+ # exponent. (2*a, 0)
138
+ eq.add_equality_group(
139
+ WeightedZPowGate(0, global_shift=2) ** a,
140
+ (WeightedZPowGate(0, global_shift=1) ** 2) ** a,
141
+ (WeightedZPowGate(0, global_shift=1) ** a) ** 2,
142
+ WeightedZPowGate(0, global_shift=1) ** (a * 2),
143
+ WeightedZPowGate(0, global_shift=1) ** (a + a),
144
+ )
145
+ # Symbolic exponents that cancel (0, 1) == (0, a/a)
146
+ eq.add_equality_group(
147
+ WeightedZPowGate(1),
148
+ WeightedZPowGate(a) ** (1 / a),
149
+ WeightedZPowGate(b) ** (1 / b),
150
+ WeightedZPowGate(1 / a) ** a,
151
+ WeightedZPowGate(1 / b) ** b,
152
+ )
153
+ # Symbol in one phase and constant off by period in another (0, a) == (2, a)
154
+ eq.add_equality_group(
155
+ WeightedZPowGate(a),
156
+ WeightedZPowGate(a - 2, global_shift=2),
157
+ WeightedZPowGate(1 - 2 / a, global_shift=2 / a) ** a,
158
+ )
159
+ # Different symbol, different equality group (0, b)
160
+ eq.add_equality_group(WeightedZPowGate(b))
161
+ # Various number types
162
+ eq.add_equality_group(
163
+ WeightedZPowGate(np.int64(3), global_shift=sympy.Number(5)) ** 7.0,
164
+ WeightedZPowGate(sympy.Number(3), global_shift=5.0) ** np.int64(7),
165
+ WeightedZPowGate(3.0, global_shift=np.int64(5)) ** sympy.Number(7),
166
+ )
167
+
112
168
 
113
169
  def test_approx_eq():
114
170
  assert cirq.approx_eq(CExpZinGate(1.5), CExpZinGate(1.5), atol=0.1)
@@ -118,8 +174,7 @@ def test_approx_eq():
118
174
  assert cirq.approx_eq(ZGateDef(exponent=1.5), ZGateDef(exponent=1.5), atol=0.1)
119
175
  assert not cirq.approx_eq(CExpZinGate(1.5), ZGateDef(exponent=1.5), atol=0.1)
120
176
  with pytest.raises(
121
- TypeError,
122
- match=re.escape("unsupported operand type(s) for -: 'Symbol' and 'PeriodicValue'"),
177
+ TypeError, match="unsupported operand type\\(s\\) for -: '.*' and 'PeriodicValue'"
123
178
  ):
124
179
  cirq.approx_eq(ZGateDef(exponent=1.5), ZGateDef(exponent=sympy.Symbol('a')), atol=0.1)
125
180
  assert cirq.approx_eq(CExpZinGate(sympy.Symbol('a')), CExpZinGate(sympy.Symbol('a')), atol=0.1)
@@ -333,11 +388,6 @@ class WeightedZPowGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
333
388
  self.weight = weight
334
389
  super().__init__(**kwargs)
335
390
 
336
- def _value_equality_values_(self):
337
- return self.weight, self._canonical_exponent, self._global_shift
338
-
339
- _value_equality_approximate_values_ = _value_equality_values_
340
-
341
391
  def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
342
392
  return [(0, np.diag([1, 0])), (self.weight, np.diag([0, 1]))]
343
393
 
@@ -39,6 +39,7 @@ def test_xx_eq():
39
39
  cirq.XXPowGate(),
40
40
  cirq.XXPowGate(exponent=1, global_shift=0),
41
41
  cirq.XXPowGate(exponent=3, global_shift=0),
42
+ cirq.XXPowGate(global_shift=100000),
42
43
  )
43
44
  eq.add_equality_group(cirq.XX**0.5, cirq.XX**2.5, cirq.XX**4.5)
44
45
  eq.add_equality_group(cirq.XX**0.25, cirq.XX**2.25, cirq.XX**-1.75)
cirq/ops/pauli_gates.py CHANGED
@@ -103,11 +103,6 @@ class Pauli(raw_types.Gate, metaclass=abc.ABCMeta):
103
103
 
104
104
  return pauli_string.SingleQubitPauliStringGateOperation(self, qubits[0])
105
105
 
106
- @property
107
- def _canonical_exponent(self):
108
- """Overrides EigenGate._canonical_exponent in subclasses."""
109
- return 1
110
-
111
106
 
112
107
  class _PauliX(Pauli, common_gates.XPowGate):
113
108
  def __init__(self):
@@ -85,7 +85,13 @@ class PauliInteractionGate(gate_features.InterchangeableQubitsGate, eigen_gate.E
85
85
  return 2
86
86
 
87
87
  def _value_equality_values_(self):
88
- return (self.pauli0, self.invert0, self.pauli1, self.invert1, self._canonical_exponent)
88
+ return (
89
+ self.pauli0,
90
+ self.invert0,
91
+ self.pauli1,
92
+ self.invert1,
93
+ value.PeriodicValue(self.exponent, 2),
94
+ )
89
95
 
90
96
  def qubit_index_to_equivalence_group_key(self, index: int) -> int:
91
97
  if self.pauli0 == self.pauli1 and self.invert0 == self.invert1:
@@ -24,7 +24,6 @@ from cirq import linalg
24
24
  from cirq._doc import doc_private
25
25
  from cirq.protocols import qid_shape_protocol
26
26
  from cirq.protocols.apply_unitary_protocol import apply_unitary, ApplyUnitaryArgs
27
- from cirq.protocols.mixture_protocol import mixture
28
27
 
29
28
  # This is a special indicator value used by the apply_mixture method
30
29
  # to determine whether or not the caller provided a 'default' argument. It must
@@ -260,9 +259,9 @@ def apply_mixture(
260
259
  return result
261
260
 
262
261
  # Fallback to using the object's `_mixture_` matrices. (STEP C)
263
- prob_mix = mixture(val, None)
264
- if prob_mix is not None:
265
- return _mixture_strat(prob_mix, args, is_density_matrix)
262
+ result = _apply_mixture_from_mixture_strat(val, args, is_density_matrix)
263
+ if result is not None:
264
+ return result
266
265
 
267
266
  # Don't know how to apply mixture. Fallback to specified default behavior.
268
267
  # (STEP D)
@@ -359,11 +358,19 @@ def _apply_unitary_from_matrix_strat(
359
358
  return args.target_tensor
360
359
 
361
360
 
362
- def _mixture_strat(val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool) -> np.ndarray:
361
+ def _apply_mixture_from_mixture_strat(
362
+ val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool
363
+ ) -> Optional[np.ndarray]:
363
364
  """Attempt to use unitary matrices in _mixture_ and return the result."""
365
+ method = getattr(val, '_mixture_', None)
366
+ if method is None:
367
+ return None
368
+ prob_mix = method()
369
+ if prob_mix is NotImplemented or prob_mix is None:
370
+ return None
364
371
  args.out_buffer[:] = 0
365
372
  np.copyto(dst=args.auxiliary_buffer1, src=args.target_tensor)
366
- for prob, op in val:
373
+ for prob, op in prob_mix:
367
374
  np.copyto(dst=args.target_tensor, src=args.auxiliary_buffer1)
368
375
  right_result = _apply_unitary_strat(op, args, is_density_matrix)
369
376
  if right_result is None:
@@ -237,6 +237,17 @@ def test_apply_mixture_no_protocols_implemented():
237
237
  assert_apply_mixture_returns(NoProtocols(), rho, left_axes=[1], right_axes=[1])
238
238
 
239
239
 
240
+ def test_apply_mixture_mixture_returns_not_implemented():
241
+ class NoMixture:
242
+ def _mixture_(self):
243
+ return NotImplemented
244
+
245
+ rho = np.ones((2, 2, 2, 2), dtype=np.complex128)
246
+
247
+ with pytest.raises(TypeError, match='has no'):
248
+ assert_apply_mixture_returns(NoMixture(), rho, left_axes=[1], right_axes=[1])
249
+
250
+
240
251
  def test_apply_mixture_no_protocols_implemented_default():
241
252
  class NoProtocols:
242
253
  pass
@@ -24,6 +24,7 @@ from typing_extensions import Protocol
24
24
  from cirq._doc import doc_private
25
25
  from cirq.protocols.decompose_protocol import _try_decompose_into_operations_and_qubits
26
26
  from cirq.protocols.mixture_protocol import has_mixture
27
+ from cirq.protocols.unitary_protocol import unitary
27
28
 
28
29
  # This is a special indicator value used by the channel method to determine
29
30
  # whether or not the caller provided a 'default' argument. It must be of type
@@ -145,7 +146,9 @@ def kraus(
145
146
  mixture_getter = getattr(val, '_mixture_', None)
146
147
  mixture_result = NotImplemented if mixture_getter is None else mixture_getter()
147
148
  if mixture_result is not NotImplemented and mixture_result is not None:
148
- return tuple(np.sqrt(p) * u for p, u in mixture_result)
149
+ return tuple(
150
+ np.sqrt(p) * (u if isinstance(u, np.ndarray) else unitary(u)) for p, u in mixture_result
151
+ )
149
152
 
150
153
  unitary_getter = getattr(val, '_unitary_', None)
151
154
  unitary_result = NotImplemented if unitary_getter is None else unitary_getter()
@@ -23,6 +23,7 @@ from typing_extensions import Protocol
23
23
  from cirq._doc import doc_private
24
24
  from cirq.protocols.decompose_protocol import _try_decompose_into_operations_and_qubits
25
25
  from cirq.protocols.has_unitary_protocol import has_unitary
26
+ from cirq.protocols.unitary_protocol import unitary
26
27
 
27
28
  # This is a special indicator value used by the inverse method to determine
28
29
  # whether or not the caller provided a 'default' argument.
@@ -84,14 +85,14 @@ def mixture(
84
85
  with that probability in the mixture. The probabilities will sum to 1.0.
85
86
 
86
87
  Raises:
87
- TypeError: If `val` has no `_mixture_` or `_unitary_` mehod, or if it
88
+ TypeError: If `val` has no `_mixture_` or `_unitary_` method, or if it
88
89
  does and this method returned `NotImplemented`.
89
90
  """
90
91
 
91
92
  mixture_getter = getattr(val, '_mixture_', None)
92
93
  result = NotImplemented if mixture_getter is None else mixture_getter()
93
- if result is not NotImplemented:
94
- return result
94
+ if result is not NotImplemented and result is not None:
95
+ return tuple((p, u if isinstance(u, np.ndarray) else unitary(u)) for p, u in result)
95
96
 
96
97
  unitary_getter = getattr(val, '_unitary_', None)
97
98
  result = NotImplemented if unitary_getter is None else unitary_getter()
@@ -17,6 +17,9 @@ import pytest
17
17
 
18
18
  import cirq
19
19
 
20
+ a = np.array([1])
21
+ b = np.array([1j])
22
+
20
23
 
21
24
  class NoMethod:
22
25
  pass
@@ -32,7 +35,7 @@ class ReturnsNotImplemented:
32
35
 
33
36
  class ReturnsValidTuple(cirq.SupportsMixture):
34
37
  def _mixture_(self):
35
- return ((0.4, 'a'), (0.6, 'b'))
38
+ return ((0.4, a), (0.6, b))
36
39
 
37
40
  def _has_mixture_(self):
38
41
  return True
@@ -40,27 +43,27 @@ class ReturnsValidTuple(cirq.SupportsMixture):
40
43
 
41
44
  class ReturnsNonnormalizedTuple:
42
45
  def _mixture_(self):
43
- return ((0.4, 'a'), (0.4, 'b'))
46
+ return ((0.4, a), (0.4, b))
44
47
 
45
48
 
46
49
  class ReturnsNegativeProbability:
47
50
  def _mixture_(self):
48
- return ((0.4, 'a'), (-0.4, 'b'))
51
+ return ((0.4, a), (-0.4, b))
49
52
 
50
53
 
51
54
  class ReturnsGreaterThanUnityProbability:
52
55
  def _mixture_(self):
53
- return ((1.2, 'a'), (0.4, 'b'))
56
+ return ((1.2, a), (0.4, b))
54
57
 
55
58
 
56
59
  class ReturnsMixtureButNoHasMixture:
57
60
  def _mixture_(self):
58
- return ((0.4, 'a'), (0.6, 'b'))
61
+ return ((0.4, a), (0.6, b))
59
62
 
60
63
 
61
64
  class ReturnsUnitary:
62
65
  def _unitary_(self):
63
- return np.ones((2, 2))
66
+ return np.eye(2)
64
67
 
65
68
  def _has_unitary_(self):
66
69
  return True
@@ -74,12 +77,18 @@ class ReturnsNotImplementedUnitary:
74
77
  return NotImplemented
75
78
 
76
79
 
80
+ class ReturnsMixtureOfReturnsUnitary:
81
+ def _mixture_(self):
82
+ return ((0.4, ReturnsUnitary()), (0.6, ReturnsUnitary()))
83
+
84
+
77
85
  @pytest.mark.parametrize(
78
86
  'val,mixture',
79
87
  (
80
- (ReturnsValidTuple(), ((0.4, 'a'), (0.6, 'b'))),
81
- (ReturnsNonnormalizedTuple(), ((0.4, 'a'), (0.4, 'b'))),
82
- (ReturnsUnitary(), ((1.0, np.ones((2, 2))),)),
88
+ (ReturnsValidTuple(), ((0.4, a), (0.6, b))),
89
+ (ReturnsNonnormalizedTuple(), ((0.4, a), (0.4, b))),
90
+ (ReturnsUnitary(), ((1.0, np.eye(2)),)),
91
+ (ReturnsMixtureOfReturnsUnitary(), ((0.4, np.eye(2)), (0.6, np.eye(2)))),
83
92
  ),
84
93
  )
85
94
  def test_objects_with_mixture(val, mixture):
@@ -88,7 +97,7 @@ def test_objects_with_mixture(val, mixture):
88
97
  np.testing.assert_almost_equal(keys, expected_keys)
89
98
  np.testing.assert_equal(values, expected_values)
90
99
 
91
- keys, values = zip(*cirq.mixture(val, ((0.3, 'a'), (0.7, 'b'))))
100
+ keys, values = zip(*cirq.mixture(val, ((0.3, a), (0.7, b))))
92
101
  np.testing.assert_almost_equal(keys, expected_keys)
93
102
  np.testing.assert_equal(values, expected_values)
94
103
 
@@ -101,7 +110,7 @@ def test_objects_with_no_mixture(val):
101
110
  _ = cirq.mixture(val)
102
111
  assert cirq.mixture(val, None) is None
103
112
  assert cirq.mixture(val, NotImplemented) is NotImplemented
104
- default = ((0.4, 'a'), (0.6, 'b'))
113
+ default = ((0.4, a), (0.6, b))
105
114
  assert cirq.mixture(val, default) == default
106
115
 
107
116
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cirq-core
3
- Version: 1.5.0.dev20250404235631
3
+ Version: 1.5.0.dev20250405050852
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
@@ -4,8 +4,8 @@ cirq/_compat_test.py,sha256=0m3sYIyxRNv9jvAo6rzJ-cnbpny3KGnAByrbU7bApgQ,34720
4
4
  cirq/_doc.py,sha256=yDyWUD_2JDS0gShfGRb-rdqRt9-WeL7DhkqX7np0Nko,2879
5
5
  cirq/_import.py,sha256=cfocxtT1BJ4HkfZ-VO8YyIhPP-xfqHDkLrzz6eeO5U0,8421
6
6
  cirq/_import_test.py,sha256=6K_v0riZJXOXUphHNkGA8MY-JcmGlezFaGmvrNhm3OQ,1015
7
- cirq/_version.py,sha256=KinPtb06uZbX8CW--RiF5vnOluHAD1sq7bzElrrToKI,1206
8
- cirq/_version_test.py,sha256=PwTQFs7hoDk7E-ZsPnJZ1KoVIt3qxLszOF88pLVLN_o,147
7
+ cirq/_version.py,sha256=rrHncQSD1uha8V-ZVfxjGi97KobvlRJIdilCH7DsjIw,1206
8
+ cirq/_version_test.py,sha256=ZAHy9pdX7FT9NoLH9SJy53S2EU42iikkMzR--NkmMMg,147
9
9
  cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
10
10
  cirq/json_resolver_cache.py,sha256=YVamU72nCUT5dG0bhAvRKVX5lXcZMNTwP3H36v-cYag,13615
11
11
  cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
@@ -276,12 +276,12 @@ cirq/ops/classically_controlled_operation.py,sha256=ePhBPrHymodrsztJFk_g2IGI3QSb
276
276
  cirq/ops/classically_controlled_operation_test.py,sha256=nIYyXfNH4E2IibZSLk6QDVHpfJQbuI_iWwirCH8rhi8,50209
277
277
  cirq/ops/clifford_gate.py,sha256=5mE97WQG6kW9ntRcn20hoFip71TFofnNKMx01RHETO4,39488
278
278
  cirq/ops/clifford_gate_test.py,sha256=dqghYb7_afYxCLceBarX56Tn9y_dSWCKF75W-Qrzvcw,40341
279
- cirq/ops/common_channels.py,sha256=LfIjy4WBRF_K81kc12Y4nLjdVZnJUhIKHL7sxiNNINU,37259
279
+ cirq/ops/common_channels.py,sha256=lGDOSdstoK57DingL-lo2n49-a51MshhJOl4LOcpQfg,37126
280
280
  cirq/ops/common_channels_test.py,sha256=nQsSSxu7vtedb3ZUuw4hNKIX7MYI4x8lxvLyWMZNt10,30079
281
281
  cirq/ops/common_gate_families.py,sha256=2E31Qr_Yv1zI-r_MNWmr1xJYrEHHU45274iDrt_oKPE,8611
282
282
  cirq/ops/common_gate_families_test.py,sha256=bEF6Q6GtEOTc9kHM5WC1UIULPGnMPXdtm8gzLT_aNBI,5276
283
- cirq/ops/common_gates.py,sha256=nTW9PAOdkbDei01ZUx6N-D2V1zslRJnk8WS_-NJSdlg,58330
284
- cirq/ops/common_gates_test.py,sha256=6y6uPS29Lnby3YesV4YG8fmI1FWqj7BfPQEGbvJl928,46882
283
+ cirq/ops/common_gates.py,sha256=nZ5gOd4JPnq7k6jrnNILacMnG-43OzdQQj5W1Vw5JKI,57846
284
+ cirq/ops/common_gates_test.py,sha256=bASPqAkuN92Ij3CCAVwOftL0heIu3J5VPcCtmm6nVU0,46873
285
285
  cirq/ops/control_values.py,sha256=Loi_voLNOzPJpjD6AnQz8JrqJLOAUe0jvV3XB_0tTGE,13430
286
286
  cirq/ops/control_values_test.py,sha256=K8tbKM6b6PqMEL_lHLFzdrnWF1SkLN0Scft6YMT7FlE,12907
287
287
  cirq/ops/controlled_gate.py,sha256=uzQL7scPsKmnu3Kdiw-zF7b4FxdyqvaD6oPkczs1skQ,15234
@@ -292,8 +292,8 @@ cirq/ops/dense_pauli_string.py,sha256=nQs4lfm9zSGPGE9p9KAJbEhkldpg9krqTwvIkLePs9
292
292
  cirq/ops/dense_pauli_string_test.py,sha256=duvgzhgTV9wuem4kDSwtL62SEUCThkz1tdP984-C4_s,21504
293
293
  cirq/ops/diagonal_gate.py,sha256=NpCGuZpdqMGoM6ya8Q8Jp7UTut2WglMB7DK5oqBRXiE,9021
294
294
  cirq/ops/diagonal_gate_test.py,sha256=wsPZWhImVGNrEg1mYnXsO4nJ6VziDBfvEilAFtJJ8b4,6224
295
- cirq/ops/eigen_gate.py,sha256=ci_5rhFZxiSIKa7e1-jTPrVX3AsIFsEF7lkGbww57eE,18343
296
- cirq/ops/eigen_gate_test.py,sha256=vWYAMKN9EwDRxXelkOXu0-c3TGz2l6A2atf-zqr7hfA,13928
295
+ cirq/ops/eigen_gate.py,sha256=GRtLML2LbTBvVMNlar5SIzdDVK6UHL3lRwAPR6JOPOQ,17494
296
+ cirq/ops/eigen_gate_test.py,sha256=D9ETnoJ4NRcz9EvzQOFra84bonph8optp7zhW57rgWA,16139
297
297
  cirq/ops/fourier_transform.py,sha256=_YWqBq7zqRv7rH5oQPPg7zdUSiTp2px8kaaWZZmakZA,7513
298
298
  cirq/ops/fourier_transform_test.py,sha256=mtWhiC_Tg60uNh7mhhMb02cckGfNC_Tjte-Q4gRcF8c,6226
299
299
  cirq/ops/fsim_gate.py,sha256=Avzlcb_O201K0_tBmNR5m9fWkpBM7Nby0MfJjNJ9g_8,20136
@@ -329,10 +329,10 @@ cirq/ops/op_tree_test.py,sha256=FzDaDjooimUEYvCvXrTCXbR2Je8QjRTZ0VXoeI7AGyo,5700
329
329
  cirq/ops/parallel_gate.py,sha256=lkwaatEWd0roRbRKq_fkBz7nmZoMB4hdwFT6LUNxmJ4,6318
330
330
  cirq/ops/parallel_gate_test.py,sha256=lWCLnlEhs_LDNgewp7e3uN-23Q513i4G0JMva96_GiE,6299
331
331
  cirq/ops/parity_gates.py,sha256=WjuWb69Deym_g22ZJIurrMGY0AWdLQjxNkOFnnrbzAg,14383
332
- cirq/ops/parity_gates_test.py,sha256=7C0BmJl1HuoyVzfA8-lVCTiE1qNYQhMtyQlVx2uvFKA,11244
333
- cirq/ops/pauli_gates.py,sha256=WcjbuCjO3IjeEihvN5hb3-dXl8lnuG76EKKzihpvCAI,6967
332
+ cirq/ops/parity_gates_test.py,sha256=43k4Q6YIm2wOVxaAgp02ki0zpAQ271_lcG2GbWR4TJc,11289
333
+ cirq/ops/pauli_gates.py,sha256=NTt6Jd1WrlkqyvEDNKTLvzSR5pE4Imr-SDTZUs3gPgA,6831
334
334
  cirq/ops/pauli_gates_test.py,sha256=3AX2hzr-xeXrZUeSr-yBFYhbLeHK1qEh7_Bq9vGUAgo,7753
335
- cirq/ops/pauli_interaction_gate.py,sha256=MmFg4U_y0uomIwb03FaDPGiGzBCVRk7Kuo_eNXpLdXQ,5519
335
+ cirq/ops/pauli_interaction_gate.py,sha256=2e0VaCO0IE0rdwPb5F50S3rujqOuSWz54r2lNWUDrBA,5603
336
336
  cirq/ops/pauli_interaction_gate_test.py,sha256=adnIIgCvFzO-inNaN77HER-WJ0hg6L63_HfiT60oV3M,4543
337
337
  cirq/ops/pauli_measurement_gate.py,sha256=ODHQJgy7oEuDb7qOJ2ja_i0w4jvbV202FaO4O_deo6Y,7239
338
338
  cirq/ops/pauli_measurement_gate_test.py,sha256=acKmYvwSQniIX2FtOCVrIPRPmyUBeV4uNUFmyShJixE,6778
@@ -384,8 +384,8 @@ cirq/protocols/act_on_protocol.py,sha256=pRjl2lHqxuYWlJopkWCSPiwrHPggHOdRMb0nu-k
384
384
  cirq/protocols/act_on_protocol_test.py,sha256=q4vOBfG9-O8CIzmwU8HaB2HZR_U1fk2Vm-q1QhyeEpY,3147
385
385
  cirq/protocols/apply_channel_protocol.py,sha256=s5gkjAcAMe_qdPJGPuZnt4r6zZhszpddnK8Ed-wEO90,15678
386
386
  cirq/protocols/apply_channel_protocol_test.py,sha256=ETAWrBTVkPuUPUgHsLZo1HUsJnZsO0hD2fQeXlXtvjE,10582
387
- cirq/protocols/apply_mixture_protocol.py,sha256=t_nSa5nISHqDM-wUzMRRz50RhxZ2d1nHq2a4RL2NTqU,16306
388
- cirq/protocols/apply_mixture_protocol_test.py,sha256=6sNZhauFDec2MvHmUsvmkVF-qjH1WLDnZO35RT0OtRY,10793
387
+ cirq/protocols/apply_mixture_protocol.py,sha256=pYxlpOXxPjMIddyYtEw82_18ioNNvEEcmsImaQ1YiBc,16479
388
+ cirq/protocols/apply_mixture_protocol_test.py,sha256=aWyzK9h9QNmpZJBu0ASaQ8BGYJt5T5KugN4OPMO5pCU,11129
389
389
  cirq/protocols/apply_unitary_protocol.py,sha256=giJwec5XCEt5s0_uyNEuhGBlcDeJymPvuoIVx08hszY,29772
390
390
  cirq/protocols/apply_unitary_protocol_test.py,sha256=ajjHvcBBv5n8Qh_hMPZkdsOvy1xJ774q4kuC25DJnKM,26136
391
391
  cirq/protocols/approximate_equality_protocol.py,sha256=ZqnkoltD8vS1eQjV7Lw3RS49cdjZjGTF0LbdRUlBOCw,6257
@@ -409,12 +409,12 @@ cirq/protocols/inverse_protocol.py,sha256=aicyqdJVDbd-ZO-wKHA8S_5CcPl3HDhRklSSdo
409
409
  cirq/protocols/inverse_protocol_test.py,sha256=pqqIU4_G4Npc9Z-SeoM9eCB2T5JRTeI02NCXhP0UtaI,2017
410
410
  cirq/protocols/json_serialization.py,sha256=VJCEXB9fkIZh3_d6dkh_QDxwjC3iJAlELGHsCmAMvE4,24779
411
411
  cirq/protocols/json_serialization_test.py,sha256=qrh6XTy6k-FCVAd3QvSV_ENHVf9UUgHOt_pzsniI6UM,28144
412
- cirq/protocols/kraus_protocol.py,sha256=Icazcmk9J1GSC0FL_dYLkrnpE_FH7G7xtawYuYbx3_g,9179
412
+ cirq/protocols/kraus_protocol.py,sha256=NVzMsIyqxytGAui-avLdq3K0C7UqjckrTDvr0ENmDtQ,9300
413
413
  cirq/protocols/kraus_protocol_test.py,sha256=NYVayiCaEpfvelsoR7bP57lUKn2pjFKYOiVOFHeZn9Q,5400
414
414
  cirq/protocols/measurement_key_protocol.py,sha256=vqoxjmthtmQ1nWbi7Xd4fdxFNe5y3WL7DZkQ3M_VPnc,13409
415
415
  cirq/protocols/measurement_key_protocol_test.py,sha256=W7yWKFVo6fMr7JjTECe8bMh1-NMDOpGMh3S-vmNl_3s,8654
416
- cirq/protocols/mixture_protocol.py,sha256=Hva80ZD09ZEfGa_jCGVNYygk_yyI02zzOEDykHejxPo,6301
417
- cirq/protocols/mixture_protocol_test.py,sha256=N09cs9WoXj3CBvs1p95yDpLK-h6WTManz3-xvHcFGO4,3615
416
+ cirq/protocols/mixture_protocol.py,sha256=L6FDIJmYqirVGsNwoUz5sulEDFoRUbhwz4yFL0ML2Po,6448
417
+ cirq/protocols/mixture_protocol_test.py,sha256=5mCh6JjlumMiSwDM818Nvo72AGxttuIYuawyESIQFtY,3818
418
418
  cirq/protocols/mul_protocol.py,sha256=ZhkowiHCulggWanjoz6HpMGf0ODqDNIjM32knFKPuJ0,2770
419
419
  cirq/protocols/mul_protocol_test.py,sha256=Qv7y17r-HjLXC7e-6t_Y6ht8lD_iiXE6CRyRFb7noGE,2136
420
420
  cirq/protocols/pauli_expansion_protocol.py,sha256=vtpVoBlU1pXm4RQf3DDGervXwcW8jqNxs6ETHPSsp1I,3750
@@ -1209,8 +1209,8 @@ cirq/work/sampler.py,sha256=sW0RhIelGABAKbqTM58shwyyCPgf86JIv9IGdJe__js,19186
1209
1209
  cirq/work/sampler_test.py,sha256=mdk1J-WrvbPUYhY41VhWf9_te4DnXr_XMPcugWwc4-I,13281
1210
1210
  cirq/work/zeros_sampler.py,sha256=8_Ne6dBkDANtTZuql7Eb0Qg_E_P3-_gu-ybFzxTbKAQ,2356
1211
1211
  cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
1212
- cirq_core-1.5.0.dev20250404235631.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1213
- cirq_core-1.5.0.dev20250404235631.dist-info/METADATA,sha256=h1oY0Qt8QuSr4lKNpxi8bG2GYLU8amhYZz7moJH89_U,4584
1214
- cirq_core-1.5.0.dev20250404235631.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1215
- cirq_core-1.5.0.dev20250404235631.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1216
- cirq_core-1.5.0.dev20250404235631.dist-info/RECORD,,
1212
+ cirq_core-1.5.0.dev20250405050852.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1213
+ cirq_core-1.5.0.dev20250405050852.dist-info/METADATA,sha256=JbcLAzlUu5jxiad1Wd8Gb9vhve4q05YQnFhfyMBMgLI,4584
1214
+ cirq_core-1.5.0.dev20250405050852.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1215
+ cirq_core-1.5.0.dev20250405050852.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1216
+ cirq_core-1.5.0.dev20250405050852.dist-info/RECORD,,