cirq-core 1.7.0.dev20250911070206__py3-none-any.whl → 1.7.0.dev20250911180440__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, 11, 0): # pragma: no cover
28
28
  'of Cirq (e.g. "python -m pip install cirq==1.5.0")'
29
29
  )
30
30
 
31
- __version__ = "1.7.0.dev20250911070206"
31
+ __version__ = "1.7.0.dev20250911180440"
cirq/_version_test.py CHANGED
@@ -3,4 +3,4 @@ import cirq
3
3
 
4
4
 
5
5
  def test_version() -> None:
6
- assert cirq.__version__ == "1.7.0.dev20250911070206"
6
+ assert cirq.__version__ == "1.7.0.dev20250911180440"
@@ -247,35 +247,25 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
247
247
 
248
248
  def __mul__(self, other):
249
249
  concrete_class = type(self)
250
- if isinstance(other, BaseDensePauliString):
251
- if isinstance(other, MutableDensePauliString):
252
- concrete_class = MutableDensePauliString
253
- max_len = max(len(self.pauli_mask), len(other.pauli_mask))
254
- min_len = min(len(self.pauli_mask), len(other.pauli_mask))
255
- new_mask = np.zeros(max_len, dtype=np.uint8)
256
- new_mask[: len(self.pauli_mask)] ^= self.pauli_mask
257
- new_mask[: len(other.pauli_mask)] ^= other.pauli_mask
258
- tweak = _vectorized_pauli_mul_phase(
259
- self.pauli_mask[:min_len], other.pauli_mask[:min_len]
260
- )
261
- return concrete_class(
262
- pauli_mask=new_mask, coefficient=self.coefficient * other.coefficient * tweak
263
- )
264
-
265
250
  if isinstance(other, (sympy.Basic, numbers.Number)):
266
251
  new_coef = protocols.mul(self.coefficient, other, default=None)
267
252
  if new_coef is None:
268
253
  return NotImplemented
269
254
  return concrete_class(pauli_mask=self.pauli_mask, coefficient=new_coef)
270
255
 
271
- split = _attempt_value_to_pauli_index(other)
272
- if split is not None:
273
- p, i = split
274
- mask = np.copy(self.pauli_mask)
275
- mask[i] ^= p
256
+ if (other_dps := _try_interpret_as_dps(other)) is not None:
257
+ if isinstance(other_dps, MutableDensePauliString):
258
+ concrete_class = MutableDensePauliString
259
+ max_len = max(len(self.pauli_mask), len(other_dps.pauli_mask))
260
+ min_len = min(len(self.pauli_mask), len(other_dps.pauli_mask))
261
+ new_mask = np.zeros(max_len, dtype=np.uint8)
262
+ new_mask[: len(self.pauli_mask)] ^= self.pauli_mask
263
+ new_mask[: len(other_dps.pauli_mask)] ^= other_dps.pauli_mask
264
+ tweak = _vectorized_pauli_mul_phase(
265
+ self.pauli_mask[:min_len], other_dps.pauli_mask[:min_len]
266
+ )
276
267
  return concrete_class(
277
- pauli_mask=mask,
278
- coefficient=self.coefficient * _vectorized_pauli_mul_phase(self.pauli_mask[i], p),
268
+ pauli_mask=new_mask, coefficient=self.coefficient * other_dps.coefficient * tweak
279
269
  )
280
270
 
281
271
  return NotImplemented
@@ -284,15 +274,8 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
284
274
  if isinstance(other, (sympy.Basic, numbers.Number)):
285
275
  return self.__mul__(other)
286
276
 
287
- split = _attempt_value_to_pauli_index(other)
288
- if split is not None:
289
- p, i = split
290
- mask = np.copy(self.pauli_mask)
291
- mask[i] ^= p
292
- return type(self)(
293
- pauli_mask=mask,
294
- coefficient=self.coefficient * _vectorized_pauli_mul_phase(p, self.pauli_mask[i]),
295
- )
277
+ if other := _try_interpret_as_dps(other):
278
+ return other.__mul__(self)
296
279
 
297
280
  return NotImplemented
298
281
 
@@ -369,18 +352,11 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
369
352
  )
370
353
 
371
354
  def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType | None:
372
- if isinstance(other, BaseDensePauliString):
373
- n = min(len(self.pauli_mask), len(other.pauli_mask))
374
- phase = _vectorized_pauli_mul_phase(self.pauli_mask[:n], other.pauli_mask[:n])
355
+ if (other_dps := _try_interpret_as_dps(other)) is not None:
356
+ n = min(len(self.pauli_mask), len(other_dps.pauli_mask))
357
+ phase = _vectorized_pauli_mul_phase(self.pauli_mask[:n], other_dps.pauli_mask[:n])
375
358
  return phase == 1 or phase == -1
376
359
 
377
- # Single qubit Pauli operation.
378
- split = _attempt_value_to_pauli_index(other)
379
- if split is not None:
380
- p1, i = split
381
- p2 = self.pauli_mask[i]
382
- return (p1 or p2) == (p2 or p1)
383
-
384
360
  return NotImplemented
385
361
 
386
362
  def frozen(self) -> DensePauliString:
@@ -518,20 +494,6 @@ class MutableDensePauliString(BaseDensePauliString):
518
494
  return NotImplemented
519
495
 
520
496
  def __imul__(self, other):
521
- if isinstance(other, BaseDensePauliString):
522
- if len(other) > len(self):
523
- raise ValueError(
524
- "The receiving dense pauli string is smaller than "
525
- "the dense pauli string being multiplied into it.\n"
526
- f"self={repr(self)}\n"
527
- f"other={repr(other)}"
528
- )
529
- self_mask = self.pauli_mask[: len(other.pauli_mask)]
530
- self._coefficient *= _vectorized_pauli_mul_phase(self_mask, other.pauli_mask)
531
- self._coefficient *= other.coefficient
532
- self_mask ^= other.pauli_mask
533
- return self
534
-
535
497
  if isinstance(other, (sympy.Basic, numbers.Number)):
536
498
  new_coef = protocols.mul(self.coefficient, other, default=None)
537
499
  if new_coef is None:
@@ -539,11 +501,18 @@ class MutableDensePauliString(BaseDensePauliString):
539
501
  self._coefficient = new_coef if isinstance(new_coef, sympy.Basic) else complex(new_coef)
540
502
  return self
541
503
 
542
- split = _attempt_value_to_pauli_index(other)
543
- if split is not None:
544
- p, i = split
545
- self._coefficient *= _vectorized_pauli_mul_phase(self.pauli_mask[i], p)
546
- self.pauli_mask[i] ^= p
504
+ if (other_dps := _try_interpret_as_dps(other)) is not None:
505
+ if len(other_dps) > len(self):
506
+ raise ValueError(
507
+ "The receiving dense pauli string is smaller than "
508
+ "the dense pauli string being multiplied into it.\n"
509
+ f"self={repr(self)}\n"
510
+ f"other={repr(other)}"
511
+ )
512
+ self_mask = self.pauli_mask[: len(other_dps.pauli_mask)]
513
+ self._coefficient *= _vectorized_pauli_mul_phase(self_mask, other_dps.pauli_mask)
514
+ self._coefficient *= other_dps.coefficient
515
+ self_mask ^= other_dps.pauli_mask
547
516
  return self
548
517
 
549
518
  return NotImplemented
@@ -613,23 +582,27 @@ def _as_pauli_mask(val: Iterable[cirq.PAULI_GATE_LIKE] | np.ndarray) -> np.ndarr
613
582
  return np.array([_pauli_index(v) for v in val], dtype=np.uint8)
614
583
 
615
584
 
616
- def _attempt_value_to_pauli_index(v: cirq.Operation) -> tuple[int, int] | None:
585
+ def _try_interpret_as_dps(v: cirq.Operation) -> BaseDensePauliString | None:
586
+ if isinstance(v, BaseDensePauliString):
587
+ return v
588
+
617
589
  if (ps := pauli_string._try_interpret_as_pauli_string(v)) is None:
618
590
  return None
619
591
 
620
- if len(ps.qubits) != 1:
621
- return None # pragma: no cover
622
-
623
- q = ps.qubits[0]
624
592
  from cirq import devices
625
593
 
626
- if not isinstance(q, devices.LineQubit):
594
+ if not all(isinstance(q, devices.LineQubit) for q in ps.qubits):
627
595
  raise ValueError(
628
596
  'Got a Pauli operation, but it was applied to a qubit type '
629
597
  'other than `cirq.LineQubit` so its dense index is ambiguous.\n'
630
598
  f'v={repr(v)}.'
631
599
  )
632
- return pauli_string.PAULI_GATE_LIKE_TO_INDEX_MAP[ps[q]], q.x
600
+
601
+ pauli_mask = np.zeros(max((q.x + 1 for q in ps.qubits), default=0), dtype=np.uint8)
602
+ for q in ps.qubits:
603
+ pauli_mask[q.x] = pauli_string.PAULI_GATE_LIKE_TO_INDEX_MAP[ps[q]]
604
+
605
+ return DensePauliString(pauli_mask)
633
606
 
634
607
 
635
608
  def _vectorized_pauli_mul_phase(lhs: int | np.ndarray, rhs: int | np.ndarray) -> complex:
@@ -173,6 +173,10 @@ def test_mul() -> None:
173
173
  with pytest.raises(ValueError, match='other than `cirq.LineQubit'):
174
174
  _ = f('III') * cirq.X(cirq.NamedQubit('tmp'))
175
175
 
176
+ # Parity operations.
177
+ assert f('IXYZ') * cirq.XX(*cirq.LineQubit.range(1, 3)) == -1j * f('IIZZ')
178
+ assert cirq.XX(*cirq.LineQubit.range(1, 3)) * f('IXYZ') == 1j * f('IIZZ')
179
+
176
180
  # Mixed types.
177
181
  m = cirq.MutableDensePauliString
178
182
  assert m('X') * m('Z') == -1j * m('Y')
@@ -187,6 +191,10 @@ def test_mul() -> None:
187
191
  assert f('I') * f('III') == f('III')
188
192
  assert f('X') * f('XXX') == f('IXX')
189
193
  assert f('XXX') * f('X') == f('IXX')
194
+ assert f('X') * cirq.Y(cirq.LineQubit(2)) == f('XIY')
195
+ assert f('XY') * cirq.YY(*cirq.LineQubit.range(1, 3)) == f('XIY')
196
+ assert cirq.X(cirq.LineQubit(2)) * f('Y') == f('YIX')
197
+ assert cirq.XX(*cirq.LineQubit.range(1, 3)) * f('YX') == f('YIX')
190
198
 
191
199
  with pytest.raises(TypeError):
192
200
  _ = f('I') * object()
@@ -235,8 +243,15 @@ def test_imul() -> None:
235
243
  p *= cirq.X(cirq.LineQubit(1))
236
244
  assert p == m('IZI')
237
245
 
246
+ p *= cirq.ZZ(*cirq.LineQubit.range(1, 3))
247
+ assert p == m('IIZ')
248
+
238
249
  with pytest.raises(ValueError, match='smaller than'):
239
250
  p *= f('XXXXXXXXXXXX')
251
+ with pytest.raises(ValueError, match='smaller than'):
252
+ p *= cirq.X(cirq.LineQubit(3))
253
+ with pytest.raises(ValueError, match='smaller than'):
254
+ p *= cirq.XX(*cirq.LineQubit.range(2, 4))
240
255
  with pytest.raises(TypeError):
241
256
  p *= object()
242
257
 
@@ -511,6 +526,8 @@ def test_commutes() -> None:
511
526
  assert cirq.commutes(f('IIIXII'), cirq.X(cirq.LineQubit(2)) ** 3)
512
527
  assert not cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(3)) ** 3)
513
528
  assert cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(2)) ** 3)
529
+ assert cirq.commutes(f('X'), cirq.Z(cirq.LineQubit(10)))
530
+ assert cirq.commutes(cirq.Z(cirq.LineQubit(10)), f('X'))
514
531
 
515
532
  assert cirq.commutes(f('XX'), "test", default=NotImplemented) is NotImplemented
516
533
 
@@ -323,6 +323,7 @@ def test_constructor_flexibility() -> None:
323
323
  @pytest.mark.parametrize('qubit_pauli_map', _sample_qubit_pauli_maps())
324
324
  def test_getitem(qubit_pauli_map) -> None:
325
325
  other = cirq.NamedQubit('other')
326
+ pauli_string: cirq.PauliString[cirq.NamedQubit]
326
327
  pauli_string = cirq.PauliString(qubit_pauli_map=qubit_pauli_map)
327
328
  for key in qubit_pauli_map:
328
329
  assert qubit_pauli_map[key] == pauli_string[key]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cirq-core
3
- Version: 1.7.0.dev20250911070206
3
+ Version: 1.7.0.dev20250911180440
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=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=JVq3XyWok9yeOK1H682f3S7y9xBiwyyX--njnMgHF9I,1206
8
- cirq/_version_test.py,sha256=dzDdyWPBZoNP7e52Fif6y9yqcw-THoOa79zkaT0CzP4,155
7
+ cirq/_version.py,sha256=WZf8DKe02pUwbJxvCArRinKukjW5-YPt2iLOZy20qgw,1206
8
+ cirq/_version_test.py,sha256=V1B9c05GreflNKusZ1yTqJ-pAgBTGz1_txhU4P_dvno,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
@@ -303,8 +303,8 @@ cirq/ops/controlled_gate.py,sha256=3Hex9AdY6c_DedKoCqqpS4gx9rAgm9KZITbwUBXsoYg,1
303
303
  cirq/ops/controlled_gate_test.py,sha256=jmIOlCx8dC3VId4NynX1ZYy7s7tkLav_d-fjiIZyVh0,29308
304
304
  cirq/ops/controlled_operation.py,sha256=KAbQGf6-AXm-DV9nk05S3sqJumOgvG9P6jO4Zx1gxec,13561
305
305
  cirq/ops/controlled_operation_test.py,sha256=hTqK6R0so-ZmZLcqS9xQl39ekNZ82UVYPbhmfbbh6vg,16699
306
- cirq/ops/dense_pauli_string.py,sha256=lfnSfRhwgNLBknXDm11FTpAULGOvw7jd4-r9IuB8v04,24211
307
- cirq/ops/dense_pauli_string_test.py,sha256=XlGZuLw_O10hJPhg1EMuvgZd2lAFNF-QbYWl_qxUIAU,22321
306
+ cirq/ops/dense_pauli_string.py,sha256=sRf2O62YXSedbOYyKSfS5qQbTaunC6BH6AobmX72nPc,23365
307
+ cirq/ops/dense_pauli_string_test.py,sha256=t4kl_8QdXnAbM3Bs-RpO-_fjtGZ1LSRl1UbXWJMX8Kc,23159
308
308
  cirq/ops/diagonal_gate.py,sha256=HNMxcgKgfZ2ZcXGaPhcBp6yOwu_stpSN3_GtNeWnR5s,8909
309
309
  cirq/ops/diagonal_gate_test.py,sha256=JRQWrL4cEYzVjwal-EewyIPgThUwLdrE6f9i7ifd6Rk,6319
310
310
  cirq/ops/eigen_gate.py,sha256=OoUpOwHw6VZ2CpH0Qb-eQLD4c-cjj8wFwBr8NEc7C0g,17788
@@ -356,7 +356,7 @@ cirq/ops/pauli_string_phasor.py,sha256=5Tm_OoR_v44Kb3AQAw5XIxpcmKtompdbq5ZefYGEU
356
356
  cirq/ops/pauli_string_phasor_test.py,sha256=ZIoraHH3kOFjtEfThXDS-sxUvSU8MYZ2avtdiPcyN6w,28309
357
357
  cirq/ops/pauli_string_raw_types.py,sha256=mBOAwfBT_y7yiSyC6Hr-ofLyIkjyOH5urmK-gitD3-Y,2226
358
358
  cirq/ops/pauli_string_raw_types_test.py,sha256=ZcOZ31KSVIc7ReZoO8WZEX8MOyPOhUWaYLppvGTE4-8,2761
359
- cirq/ops/pauli_string_test.py,sha256=miI50nAuQ4fM7jKNR7JRNgvSlYmiOZKTbz4EIMqNdlA,79568
359
+ cirq/ops/pauli_string_test.py,sha256=YoYcJxJZCDJjRx1ULxy_8_PkMsj8wGgpLs71iAVfLmg,79620
360
360
  cirq/ops/pauli_sum_exponential.py,sha256=Zq8YBMZ7sLLEPQuoX4uR95I9VY4C38Ma8FtOEjQGr3k,4861
361
361
  cirq/ops/pauli_sum_exponential_test.py,sha256=u9fVBUMuiIb6xOPC2GRTR3zFUeO6N3vanejUk5_u9_8,5485
362
362
  cirq/ops/permutation_gate.py,sha256=mTCKrLSNP3nm2hPebfBJNR5mHO6qb1ZqDT3pFA0zM_M,4218
@@ -1234,8 +1234,8 @@ cirq/work/sampler.py,sha256=rxbMWvrhu3gfNSBjZKozw28lLKVvBAS_1EGyPdYe8Xg,19041
1234
1234
  cirq/work/sampler_test.py,sha256=SsMrRvLDYELyOAWLKISjkdEfrBwLYWRsT6D8WrsLM3Q,13533
1235
1235
  cirq/work/zeros_sampler.py,sha256=Fs2JWwq0n9zv7_G5Rm-9vPeHUag7uctcMOHg0JTkZpc,2371
1236
1236
  cirq/work/zeros_sampler_test.py,sha256=lQLgQDGBLtfImryys2HzQ2jOSGxHgc7-koVBUhv8qYk,3345
1237
- cirq_core-1.7.0.dev20250911070206.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1238
- cirq_core-1.7.0.dev20250911070206.dist-info/METADATA,sha256=UOrxXFQdQJv-z8m05_YpZdWsIRjGTYykdJcH-LO76XE,4758
1239
- cirq_core-1.7.0.dev20250911070206.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1240
- cirq_core-1.7.0.dev20250911070206.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1241
- cirq_core-1.7.0.dev20250911070206.dist-info/RECORD,,
1237
+ cirq_core-1.7.0.dev20250911180440.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1238
+ cirq_core-1.7.0.dev20250911180440.dist-info/METADATA,sha256=47ShaMjH8g5w_ELAQqyjkNknU_TI-brYDFD5ffq9Yyw,4758
1239
+ cirq_core-1.7.0.dev20250911180440.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1240
+ cirq_core-1.7.0.dev20250911180440.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1241
+ cirq_core-1.7.0.dev20250911180440.dist-info/RECORD,,