stimcirq 1.15.dev1743880617__tar.gz → 1.15.dev1743894906__tar.gz

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.
Files changed (38) hide show
  1. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/PKG-INFO +1 -1
  2. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/setup.py +1 -1
  3. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/__init__.py +7 -1
  4. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_cirq_to_stim.py +2 -0
  5. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_cirq_to_stim_test.py +7 -4
  6. stimcirq-1.15.dev1743894906/stimcirq/_i_error_gate.py +41 -0
  7. stimcirq-1.15.dev1743894906/stimcirq/_i_error_gate_test.py +24 -0
  8. stimcirq-1.15.dev1743894906/stimcirq/_ii_error_gate.py +41 -0
  9. stimcirq-1.15.dev1743894906/stimcirq/_ii_error_gate_test.py +24 -0
  10. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_ii_gate.py +0 -1
  11. stimcirq-1.15.dev1743894906/stimcirq/_ii_gate_test.py +22 -0
  12. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_stim_to_cirq.py +16 -2
  13. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_stim_to_cirq_test.py +18 -6
  14. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq.egg-info/PKG-INFO +1 -1
  15. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq.egg-info/SOURCES.txt +5 -0
  16. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/README.md +0 -0
  17. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/setup.cfg +0 -0
  18. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_cx_swap_gate.py +0 -0
  19. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_cx_swap_test.py +0 -0
  20. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_cz_swap_gate.py +0 -0
  21. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_cz_swap_test.py +0 -0
  22. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_det_annotation.py +0 -0
  23. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_det_annotation_test.py +0 -0
  24. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_measure_and_or_reset_gate.py +0 -0
  25. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_measure_and_or_reset_gate_test.py +0 -0
  26. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_obs_annotation.py +0 -0
  27. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_obs_annotation_test.py +0 -0
  28. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_shift_coords_annotation.py +0 -0
  29. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_shift_coords_annotation_test.py +0 -0
  30. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_stim_sampler.py +0 -0
  31. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_stim_sampler_test.py +0 -0
  32. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_sweep_pauli.py +0 -0
  33. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_sweep_pauli_test.py +0 -0
  34. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_two_qubit_asymmetric_depolarize.py +0 -0
  35. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq/_two_qubit_asymmetric_depolarize_test.py +0 -0
  36. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq.egg-info/dependency_links.txt +0 -0
  37. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq.egg-info/requires.txt +0 -0
  38. {stimcirq-1.15.dev1743880617 → stimcirq-1.15.dev1743894906}/stimcirq.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stimcirq
3
- Version: 1.15.dev1743880617
3
+ Version: 1.15.dev1743894906
4
4
  Summary: Implements a cirq.Sampler backed by stim.
5
5
  Home-page: https://github.com/quantumlib/stim
6
6
  Author: Craig Gidney
@@ -17,7 +17,7 @@ from setuptools import setup
17
17
  with open('README.md', encoding='UTF-8') as f:
18
18
  long_description = f.read()
19
19
 
20
- __version__ = '1.15.dev1743880617'
20
+ __version__ = '1.15.dev1743894906'
21
21
 
22
22
  setup(
23
23
  name='stimcirq',
@@ -1,4 +1,4 @@
1
- __version__ = '1.15.dev1743880617'
1
+ __version__ = '1.15.dev1743894906'
2
2
  from ._cirq_to_stim import cirq_circuit_to_stim_circuit
3
3
  from ._cx_swap_gate import CXSwapGate
4
4
  from ._cz_swap_gate import CZSwapGate
@@ -12,6 +12,9 @@ from ._stim_to_cirq import (
12
12
  )
13
13
  from ._sweep_pauli import SweepPauli
14
14
  from ._two_qubit_asymmetric_depolarize import TwoQubitAsymmetricDepolarizingChannel
15
+ from ._i_error_gate import IErrorGate
16
+ from ._ii_error_gate import IIErrorGate
17
+ from ._ii_gate import IIGate
15
18
 
16
19
  JSON_RESOLVERS_DICT = {
17
20
  "CumulativeObservableAnnotation": CumulativeObservableAnnotation,
@@ -22,5 +25,8 @@ JSON_RESOLVERS_DICT = {
22
25
  "TwoQubitAsymmetricDepolarizingChannel": TwoQubitAsymmetricDepolarizingChannel,
23
26
  "CXSwapGate": CXSwapGate,
24
27
  "CZSwapGate": CZSwapGate,
28
+ "IIGate": IIGate,
29
+ "IIErrorGate": IIErrorGate,
30
+ "IErrorGate": IErrorGate,
25
31
  }
26
32
  JSON_RESOLVER = JSON_RESOLVERS_DICT.get
@@ -6,6 +6,8 @@ from typing import Callable, cast, Dict, Iterable, List, Optional, Sequence, Tup
6
6
  import cirq
7
7
  import stim
8
8
 
9
+ from ._i_error_gate import IErrorGate
10
+ from ._ii_error_gate import IIErrorGate
9
11
  from ._ii_gate import IIGate
10
12
 
11
13
 
@@ -183,7 +183,7 @@ def test_frame_simulator_sampling_noisy_gates_agrees_with_cirq_data(gate: cirq.G
183
183
  allowed_variation = 5 * (expected_rate * (1 - expected_rate) / sample_count) ** 0.5
184
184
  if not 0 <= expected_rate - allowed_variation <= 1:
185
185
  raise ValueError("Not enough samples to bound results away from extremes.")
186
- assert abs(expected_rate - actual_rate) < allowed_variation, (
186
+ assert abs(expected_rate - actual_rate) <= allowed_variation, (
187
187
  f"Sample rate {actual_rate} is over 5 standard deviations away from {expected_rate}.\n"
188
188
  f"Gate: {gate}\n"
189
189
  f"Test circuit:\n{circuit}\n"
@@ -230,7 +230,7 @@ def test_tableau_simulator_sampling_noisy_gates_agrees_with_cirq_data(gate: cirq
230
230
  allowed_variation = 5 * (expected_rate * (1 - expected_rate) / sample_count) ** 0.5
231
231
  if not 0 <= expected_rate - allowed_variation <= 1:
232
232
  raise ValueError("Not enough samples to bound results away from extremes.")
233
- assert abs(expected_rate - actual_rate) < allowed_variation, (
233
+ assert abs(expected_rate - actual_rate) <= allowed_variation, (
234
234
  f"Sample rate {actual_rate} is over 5 standard deviations away from {expected_rate}.\n"
235
235
  f"Gate: {gate}\n"
236
236
  f"Test circuit:\n{circuit}\n"
@@ -336,8 +336,11 @@ def test_on_loop():
336
336
  repetitions=3,
337
337
  )
338
338
  )
339
- result = stimcirq.StimSampler().run(c)
340
- assert result.measurements.keys() == {'0:a', '0:b', '1:a', '1:b', '2:a', '2:b'}
339
+ result_normal = cirq.Simulator().run(c)
340
+ result_stim = stimcirq.StimSampler().run(c)
341
+ assert result_normal.records.keys() == result_stim.records.keys()
342
+ for k in result_normal.records.keys():
343
+ assert result_stim.records[k].shape == result_normal.records[k].shape
341
344
 
342
345
 
343
346
  def test_multi_moment_circuit_operation():
@@ -0,0 +1,41 @@
1
+ from typing import Any, Dict, List, Iterable
2
+
3
+ import cirq
4
+ import stim
5
+
6
+
7
+
8
+ @cirq.value_equality
9
+ class IErrorGate(cirq.Gate):
10
+ """Handles explaining stim's I_ERROR gate to cirq."""
11
+
12
+ def __init__(self, gate_args: Iterable[float]):
13
+ self.gate_args = tuple(gate_args)
14
+
15
+ def _num_qubits_(self) -> int:
16
+ return 1
17
+
18
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> List[str]:
19
+ return [f'I_ERROR({self.gate_args})']
20
+
21
+ def _value_equality_values_(self):
22
+ return self.gate_args
23
+
24
+ def _decompose_(self, qubits):
25
+ pass
26
+
27
+ def _stim_conversion_(self, edit_circuit: stim.Circuit, targets: List[int], tag: str, **kwargs):
28
+ edit_circuit.append('I_ERROR', targets, arg=self.gate_args, tag=tag)
29
+
30
+ def __str__(self) -> str:
31
+ return 'I_ERROR(' + ",".join(str(e) for e in self.gate_args) + ')'
32
+
33
+ def __repr__(self):
34
+ return f'stimcirq.IErrorGate({self.gate_args!r})'
35
+
36
+ @staticmethod
37
+ def _json_namespace_() -> str:
38
+ return ''
39
+
40
+ def _json_dict_(self) -> Dict[str, Any]:
41
+ return {'gate_args': self.gate_args}
@@ -0,0 +1,24 @@
1
+ import cirq
2
+ import stimcirq
3
+
4
+
5
+ def test_repr():
6
+ r = stimcirq.IErrorGate([0.25, 0.125])
7
+ assert eval(repr(r), {'stimcirq': stimcirq}) == r
8
+ r = stimcirq.IErrorGate([])
9
+ assert eval(repr(r), {'stimcirq': stimcirq}) == r
10
+
11
+
12
+ def test_json_serialization():
13
+ r = stimcirq.IErrorGate([0.25, 0.125])
14
+ c = cirq.Circuit(r(cirq.LineQubit(1)))
15
+ json = cirq.to_json(c)
16
+ c2 = cirq.read_json(json_text=json, resolvers=[*cirq.DEFAULT_RESOLVERS, stimcirq.JSON_RESOLVER])
17
+ assert c == c2
18
+
19
+
20
+ def test_json_backwards_compat_exact():
21
+ raw = stimcirq.IErrorGate([0.25, 0.125])
22
+ packed = '{\n "cirq_type": "IErrorGate",\n "gate_args": [\n 0.25,\n 0.125\n ]\n}'
23
+ assert cirq.read_json(json_text=packed, resolvers=[*cirq.DEFAULT_RESOLVERS, stimcirq.JSON_RESOLVER]) == raw
24
+ assert cirq.to_json(raw) == packed
@@ -0,0 +1,41 @@
1
+ from typing import Any, Dict, List, Iterable
2
+
3
+ import cirq
4
+ import stim
5
+
6
+
7
+
8
+ @cirq.value_equality
9
+ class IIErrorGate(cirq.Gate):
10
+ """Handles explaining stim's II_ERROR gate to cirq."""
11
+
12
+ def __init__(self, gate_args: Iterable[float]):
13
+ self.gate_args = tuple(gate_args)
14
+
15
+ def _num_qubits_(self) -> int:
16
+ return 2
17
+
18
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> List[str]:
19
+ return [f'II_ERROR({self.gate_args})', f'II_ERROR({self.gate_args})']
20
+
21
+ def _value_equality_values_(self):
22
+ return self.gate_args
23
+
24
+ def _decompose_(self, qubits):
25
+ pass
26
+
27
+ def _stim_conversion_(self, edit_circuit: stim.Circuit, targets: List[int], tag: str, **kwargs):
28
+ edit_circuit.append('II_ERROR', targets, arg=self.gate_args, tag=tag)
29
+
30
+ def __str__(self) -> str:
31
+ return 'II_ERROR(' + ",".join(str(e) for e in self.gate_args) + ')'
32
+
33
+ def __repr__(self):
34
+ return f'stimcirq.IIErrorGate({self.gate_args!r})'
35
+
36
+ @staticmethod
37
+ def _json_namespace_() -> str:
38
+ return ''
39
+
40
+ def _json_dict_(self) -> Dict[str, Any]:
41
+ return {'gate_args': self.gate_args}
@@ -0,0 +1,24 @@
1
+ import cirq
2
+ import stimcirq
3
+
4
+
5
+ def test_repr():
6
+ r = stimcirq.IIErrorGate([0.25, 0.125])
7
+ assert eval(repr(r), {'stimcirq': stimcirq}) == r
8
+ r = stimcirq.IIErrorGate([])
9
+ assert eval(repr(r), {'stimcirq': stimcirq}) == r
10
+
11
+
12
+ def test_json_serialization():
13
+ r = stimcirq.IIErrorGate([0.25, 0.125])
14
+ c = cirq.Circuit(r(cirq.LineQubit(1), cirq.LineQubit(3)))
15
+ json = cirq.to_json(c)
16
+ c2 = cirq.read_json(json_text=json, resolvers=[*cirq.DEFAULT_RESOLVERS, stimcirq.JSON_RESOLVER])
17
+ assert c == c2
18
+
19
+
20
+ def test_json_backwards_compat_exact():
21
+ raw = stimcirq.IIErrorGate([0.25, 0.125])
22
+ packed = '{\n "cirq_type": "IIErrorGate",\n "gate_args": [\n 0.25,\n 0.125\n ]\n}'
23
+ assert cirq.read_json(json_text=packed, resolvers=[*cirq.DEFAULT_RESOLVERS, stimcirq.JSON_RESOLVER]) == raw
24
+ assert cirq.to_json(raw) == packed
@@ -3,7 +3,6 @@ from typing import Any, Dict, List
3
3
  import cirq
4
4
  import stim
5
5
 
6
-
7
6
  @cirq.value_equality
8
7
  class IIGate(cirq.Gate):
9
8
  """Handles explaining stim's II gate to cirq."""
@@ -0,0 +1,22 @@
1
+ import cirq
2
+ import stimcirq
3
+
4
+
5
+ def test_repr():
6
+ r = stimcirq.IIGate()
7
+ assert eval(repr(r), {'stimcirq': stimcirq}) == r
8
+
9
+
10
+ def test_json_serialization():
11
+ r = stimcirq.IIGate()
12
+ c = cirq.Circuit(r(cirq.LineQubit(1), cirq.LineQubit(3)))
13
+ json = cirq.to_json(c)
14
+ c2 = cirq.read_json(json_text=json, resolvers=[*cirq.DEFAULT_RESOLVERS, stimcirq.JSON_RESOLVER])
15
+ assert c == c2
16
+
17
+
18
+ def test_json_backwards_compat_exact():
19
+ raw = stimcirq.IIGate()
20
+ packed = '{\n "cirq_type": "IIGate"\n}'
21
+ assert cirq.read_json(json_text=packed, resolvers=[*cirq.DEFAULT_RESOLVERS, stimcirq.JSON_RESOLVER]) == raw
22
+ assert cirq.to_json(raw) == packed
@@ -18,6 +18,8 @@ import stim
18
18
  from ._cx_swap_gate import CXSwapGate
19
19
  from ._cz_swap_gate import CZSwapGate
20
20
  from ._det_annotation import DetAnnotation
21
+ from ._ii_error_gate import IIErrorGate
22
+ from ._i_error_gate import IErrorGate
21
23
  from ._ii_gate import IIGate
22
24
  from ._measure_and_or_reset_gate import MeasureAndOrResetGate
23
25
  from ._obs_annotation import CumulativeObservableAnnotation
@@ -457,6 +459,17 @@ class CircuitTranslationTracker:
457
459
  self.prob_to_gate(instruction.gate_args_copy()[0]), instruction
458
460
  )
459
461
 
462
+ class MultiArgumentGateHandler:
463
+ def __init__(self, args_to_gate: Callable[[List[float]], cirq.Gate]):
464
+ self.args_to_gate = args_to_gate
465
+
466
+ def __call__(
467
+ self, tracker: 'CircuitTranslationTracker', instruction: stim.CircuitInstruction
468
+ ) -> None:
469
+ tracker.process_gate_instruction(
470
+ self.args_to_gate(instruction.gate_args_copy()), instruction
471
+ )
472
+
460
473
  @staticmethod
461
474
  @functools.lru_cache(maxsize=1)
462
475
  def get_handler_table() -> Dict[
@@ -465,6 +478,7 @@ class CircuitTranslationTracker:
465
478
  gate = CircuitTranslationTracker.OneToOneGateHandler
466
479
  measure_gate = CircuitTranslationTracker.OneToOneMeasurementHandler
467
480
  noise = CircuitTranslationTracker.OneToOneNoisyGateHandler
481
+ multi_arg = CircuitTranslationTracker.MultiArgumentGateHandler
468
482
  sweep_gate = CircuitTranslationTracker.SweepableGateHandler
469
483
 
470
484
  def not_impl(message) -> Callable[[Any, Any], None]:
@@ -580,8 +594,8 @@ class CircuitTranslationTracker:
580
594
  "X_ERROR": noise(cirq.X.with_probability),
581
595
  "Y_ERROR": noise(cirq.Y.with_probability),
582
596
  "Z_ERROR": noise(cirq.Z.with_probability),
583
- "I_ERROR": noise(cirq.I.with_probability),
584
- "II_ERROR": noise(IIGate().with_probability),
597
+ "I_ERROR": multi_arg(IErrorGate),
598
+ "II_ERROR": multi_arg(IIErrorGate),
585
599
  "PAULI_CHANNEL_1": CircuitTranslationTracker.process_pauli_channel_1,
586
600
  "PAULI_CHANNEL_2": CircuitTranslationTracker.process_pauli_channel_2,
587
601
  "ELSE_CORRELATED_ERROR": not_impl(
@@ -1,12 +1,11 @@
1
- import inspect
2
1
  import itertools
3
- from typing import Any, Callable, cast, Tuple, Union
2
+ from typing import cast
4
3
 
5
4
  import cirq
6
5
  import pytest
7
6
  import stim
8
- import stimcirq
9
7
 
8
+ import stimcirq
10
9
  from ._stim_to_cirq import CircuitTranslationTracker
11
10
 
12
11
 
@@ -619,7 +618,7 @@ def test_stim_circuit_to_cirq_circuit_mpad():
619
618
  cirq_circuit = stimcirq.stim_circuit_to_cirq_circuit(stim_circuit)
620
619
  assert cirq_circuit == cirq.Circuit(
621
620
  cirq.PauliMeasurementGate(cirq.DensePauliString(""), key="0").on(),
622
- cirq.PauliMeasurementGate(-cirq.DensePauliString(""), key="1").on(),
621
+ cirq.PauliMeasurementGate(cirq.DensePauliString("", coefficient=-1), key="1").on(),
623
622
  )
624
623
 
625
624
 
@@ -633,8 +632,8 @@ def test_stim_circuit_to_cirq_circuit_mxx_myy_mzz():
633
632
  a, b = cirq.LineQubit.range(2)
634
633
  assert cirq_circuit == cirq.Circuit(
635
634
  cirq.PauliMeasurementGate(cirq.DensePauliString("XX"), key='0').on(a, b),
636
- cirq.PauliMeasurementGate(-cirq.DensePauliString("YY"), key='1').on(a, b),
637
- cirq.PauliMeasurementGate(-cirq.DensePauliString("ZZ"), key='2').on(a, b),
635
+ cirq.PauliMeasurementGate(cirq.DensePauliString("YY", coefficient=-1), key='1').on(a, b),
636
+ cirq.PauliMeasurementGate(cirq.DensePauliString("ZZ", coefficient=-1), key='2').on(a, b),
638
637
  )
639
638
  assert stimcirq.cirq_circuit_to_stim_circuit(cirq_circuit) == stim.Circuit("""
640
639
  MPP X0*X1
@@ -751,3 +750,16 @@ def test_loop_tagging():
751
750
  )
752
751
  restored_circuit = stimcirq.cirq_circuit_to_stim_circuit(cirq_circuit)
753
752
  assert restored_circuit == stim_circuit
753
+
754
+
755
+ def test_id_error_round_trip():
756
+ stim_circuit = stim.Circuit("""
757
+ I_ERROR 0
758
+ I_ERROR(0.125, 0.25) 1
759
+ II_ERROR(0.25, 0.125) 2 3
760
+ II_ERROR 4 5
761
+ TICK
762
+ """)
763
+ cirq_circuit = stimcirq.stim_circuit_to_cirq_circuit(stim_circuit)
764
+ restored_circuit = stimcirq.cirq_circuit_to_stim_circuit(cirq_circuit)
765
+ assert restored_circuit == stim_circuit
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stimcirq
3
- Version: 1.15.dev1743880617
3
+ Version: 1.15.dev1743894906
4
4
  Summary: Implements a cirq.Sampler backed by stim.
5
5
  Home-page: https://github.com/quantumlib/stim
6
6
  Author: Craig Gidney
@@ -9,7 +9,12 @@ stimcirq/_cz_swap_gate.py
9
9
  stimcirq/_cz_swap_test.py
10
10
  stimcirq/_det_annotation.py
11
11
  stimcirq/_det_annotation_test.py
12
+ stimcirq/_i_error_gate.py
13
+ stimcirq/_i_error_gate_test.py
14
+ stimcirq/_ii_error_gate.py
15
+ stimcirq/_ii_error_gate_test.py
12
16
  stimcirq/_ii_gate.py
17
+ stimcirq/_ii_gate_test.py
13
18
  stimcirq/_measure_and_or_reset_gate.py
14
19
  stimcirq/_measure_and_or_reset_gate_test.py
15
20
  stimcirq/_obs_annotation.py