Skip to content

Commit

Permalink
Add stim.PauliString.iter_all (#654)
Browse files Browse the repository at this point in the history
- Add `sinter plot --ymax`
- Add `simd_bits::countr_zero`
- Add `simd_bits::operator-=`
- Add `stim.PauliString.iter_all`
- Add `stim.PauliStringIterator`
- Autoformat the code

Fixes #397
  • Loading branch information
Strilanc authored Nov 15, 2023
1 parent c128b57 commit 5784b11
Show file tree
Hide file tree
Showing 44 changed files with 1,510 additions and 320 deletions.
3 changes: 2 additions & 1 deletion dev/util_gen_stub_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ def print_doc(*, full_name: str, parent: object, obj: object, level: int) -> Opt
elif isinstance(obj, (int, str)):
text = f"{term_name}: {type(obj).__name__} = {obj!r}"
doc = ''
elif term_name == term_name.upper():
return None # Skip constants because they lack a doc string.
else:
text = f"class {term_name}"
if inspect.isabstract(obj):
Expand Down Expand Up @@ -296,7 +298,6 @@ def print_doc(*, full_name: str, parent: object, obj: object, level: int) -> Opt


def generate_documentation(*, obj: object, level: int, full_name: str) -> Iterator[DescribedObject]:

if full_name.endswith("__"):
return
if not inspect.ismodule(obj) and not inspect.isclass(obj):
Expand Down
119 changes: 119 additions & 0 deletions doc/python_api_reference_vDev.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,16 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.PauliString.copy`](#stim.PauliString.copy)
- [`stim.PauliString.from_numpy`](#stim.PauliString.from_numpy)
- [`stim.PauliString.from_unitary_matrix`](#stim.PauliString.from_unitary_matrix)
- [`stim.PauliString.iter_all`](#stim.PauliString.iter_all)
- [`stim.PauliString.random`](#stim.PauliString.random)
- [`stim.PauliString.sign`](#stim.PauliString.sign)
- [`stim.PauliString.to_numpy`](#stim.PauliString.to_numpy)
- [`stim.PauliString.to_tableau`](#stim.PauliString.to_tableau)
- [`stim.PauliString.to_unitary_matrix`](#stim.PauliString.to_unitary_matrix)
- [`stim.PauliString.weight`](#stim.PauliString.weight)
- [`stim.PauliStringIterator`](#stim.PauliStringIterator)
- [`stim.PauliStringIterator.__iter__`](#stim.PauliStringIterator.__iter__)
- [`stim.PauliStringIterator.__next__`](#stim.PauliStringIterator.__next__)
- [`stim.Tableau`](#stim.Tableau)
- [`stim.Tableau.__add__`](#stim.Tableau.__add__)
- [`stim.Tableau.__call__`](#stim.Tableau.__call__)
Expand Down Expand Up @@ -8346,6 +8350,68 @@ def from_unitary_matrix(
"""
```

<a name="stim.PauliString.iter_all"></a>
```python
# stim.PauliString.iter_all

# (in class stim.PauliString)
@staticmethod
def iter_all(
num_qubits: int,
*,
min_weight: int = 0,
max_weight: object = None,
allowed_paulis: str = 'XYZ',
) -> stim.PauliStringIterator:
"""Returns an iterator that iterates over all matching pauli strings.
Args:
num_qubits: The desired number of qubits in the pauli strings.
min_weight: Defaults to 0. The minimum number of non-identity terms that
must be present in each yielded pauli string.
max_weight: Defaults to None (unused). The maximum number of non-identity
terms that must be present in each yielded pauli string.
allowed_paulis: Defaults to "XYZ". Set this to a string containing the
non-identity paulis that are allowed to appear in each yielded pauli
string. This argument must be a string made up of only "X", "Y", and
"Z" characters. A non-identity Pauli is allowed if it appears in the
string, and not allowed if it doesn't. Identity Paulis are always
allowed.
Returns:
An Iterable[stim.PauliString] that yields the requested pauli strings.
Examples:
>>> import stim
>>> pauli_string_iterator = stim.PauliString.iter_all(
... num_qubits=3,
... min_weight=1,
... max_weight=2,
... allowed_paulis="XZ",
... )
>>> for p in pauli_string_iterator:
... print(p)
+X__
+Z__
+_X_
+_Z_
+__X
+__Z
+XX_
+XZ_
+ZX_
+ZZ_
+X_X
+X_Z
+Z_X
+Z_Z
+_XX
+_XZ
+_ZX
+_ZZ
"""
```

<a name="stim.PauliString.random"></a>
```python
# stim.PauliString.random
Expand Down Expand Up @@ -8577,6 +8643,59 @@ def weight(
"""
```

<a name="stim.PauliStringIterator"></a>
```python
# stim.PauliStringIterator

# (at top-level in the stim module)
class PauliStringIterator:
"""Iterates over all pauli strings matching specified patterns.
Examples:
>>> import stim
>>> pauli_string_iterator = stim.PauliString.iter_all(
... 2,
... min_weight=1,
... max_weight=1,
... allowed_paulis="XZ",
... )
>>> for p in pauli_string_iterator:
... print(p)
+X_
+Z_
+_X
+_Z
"""
```

<a name="stim.PauliStringIterator.__iter__"></a>
```python
# stim.PauliStringIterator.__iter__

# (in class stim.PauliStringIterator)
def __iter__(
self,
) -> stim.PauliStringIterator:
"""Returns an independent copy of the pauli string iterator.
Since for-loops and loop-comprehensions call `iter` on things they
iterate, this effectively allows the iterator to be iterated
multiple times.
"""
```

<a name="stim.PauliStringIterator.__next__"></a>
```python
# stim.PauliStringIterator.__next__

# (in class stim.PauliStringIterator)
def __next__(
self,
) -> stim.PauliString:
"""Returns the next iterated pauli string.
"""
```

<a name="stim.Tableau"></a>
```python
# stim.Tableau
Expand Down
87 changes: 87 additions & 0 deletions doc/stim.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6403,6 +6403,61 @@ class PauliString:
stim.PauliString("+XZ")
"""
@staticmethod
def iter_all(
num_qubits: int,
*,
min_weight: int = 0,
max_weight: object = None,
allowed_paulis: str = 'XYZ',
) -> stim.PauliStringIterator:
"""Returns an iterator that iterates over all matching pauli strings.
Args:
num_qubits: The desired number of qubits in the pauli strings.
min_weight: Defaults to 0. The minimum number of non-identity terms that
must be present in each yielded pauli string.
max_weight: Defaults to None (unused). The maximum number of non-identity
terms that must be present in each yielded pauli string.
allowed_paulis: Defaults to "XYZ". Set this to a string containing the
non-identity paulis that are allowed to appear in each yielded pauli
string. This argument must be a string made up of only "X", "Y", and
"Z" characters. A non-identity Pauli is allowed if it appears in the
string, and not allowed if it doesn't. Identity Paulis are always
allowed.
Returns:
An Iterable[stim.PauliString] that yields the requested pauli strings.
Examples:
>>> import stim
>>> pauli_string_iterator = stim.PauliString.iter_all(
... num_qubits=3,
... min_weight=1,
... max_weight=2,
... allowed_paulis="XZ",
... )
>>> for p in pauli_string_iterator:
... print(p)
+X__
+Z__
+_X_
+_Z_
+__X
+__Z
+XX_
+XZ_
+ZX_
+ZZ_
+X_X
+X_Z
+Z_X
+Z_Z
+_XX
+_XZ
+_ZX
+_ZZ
"""
@staticmethod
def random(
num_qubits: int,
*,
Expand Down Expand Up @@ -6591,6 +6646,38 @@ class PauliString:
>>> stim.PauliString("-XXX___XXYZ").weight
7
"""
class PauliStringIterator:
"""Iterates over all pauli strings matching specified patterns.
Examples:
>>> import stim
>>> pauli_string_iterator = stim.PauliString.iter_all(
... 2,
... min_weight=1,
... max_weight=1,
... allowed_paulis="XZ",
... )
>>> for p in pauli_string_iterator:
... print(p)
+X_
+Z_
+_X
+_Z
"""
def __iter__(
self,
) -> stim.PauliStringIterator:
"""Returns an independent copy of the pauli string iterator.
Since for-loops and loop-comprehensions call `iter` on things they
iterate, this effectively allows the iterator to be iterated
multiple times.
"""
def __next__(
self,
) -> stim.PauliString:
"""Returns the next iterated pauli string.
"""
class Tableau:
"""A stabilizer tableau.
Expand Down
1 change: 1 addition & 0 deletions file_lists/benchmark_files
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ src/stim/simulators/frame_simulator.perf.cc
src/stim/simulators/tableau_simulator.perf.cc
src/stim/stabilizers/conversions.perf.cc
src/stim/stabilizers/pauli_string.perf.cc
src/stim/stabilizers/pauli_string_iter.perf.cc
src/stim/stabilizers/tableau.perf.cc
src/stim/stabilizers/tableau_iter.perf.cc
1 change: 1 addition & 0 deletions file_lists/python_api_files
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ src/stim/simulators/matched_error.pybind.cc
src/stim/simulators/measurements_to_detection_events.pybind.cc
src/stim/simulators/tableau_simulator.pybind.cc
src/stim/stabilizers/pauli_string.pybind.cc
src/stim/stabilizers/pauli_string_iter.pybind.cc
src/stim/stabilizers/tableau.pybind.cc
src/stim/stabilizers/tableau_iter.pybind.cc
1 change: 1 addition & 0 deletions file_lists/test_files
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ src/stim/simulators/transform_without_feedback.test.cc
src/stim/simulators/vector_simulator.test.cc
src/stim/stabilizers/conversions.test.cc
src/stim/stabilizers/pauli_string.test.cc
src/stim/stabilizers/pauli_string_iter.test.cc
src/stim/stabilizers/tableau.test.cc
src/stim/stabilizers/tableau_iter.test.cc
src/stim/str_util.test.cc
Expand Down
87 changes: 87 additions & 0 deletions glue/python/src/stim/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6403,6 +6403,61 @@ class PauliString:
stim.PauliString("+XZ")
"""
@staticmethod
def iter_all(
num_qubits: int,
*,
min_weight: int = 0,
max_weight: object = None,
allowed_paulis: str = 'XYZ',
) -> stim.PauliStringIterator:
"""Returns an iterator that iterates over all matching pauli strings.
Args:
num_qubits: The desired number of qubits in the pauli strings.
min_weight: Defaults to 0. The minimum number of non-identity terms that
must be present in each yielded pauli string.
max_weight: Defaults to None (unused). The maximum number of non-identity
terms that must be present in each yielded pauli string.
allowed_paulis: Defaults to "XYZ". Set this to a string containing the
non-identity paulis that are allowed to appear in each yielded pauli
string. This argument must be a string made up of only "X", "Y", and
"Z" characters. A non-identity Pauli is allowed if it appears in the
string, and not allowed if it doesn't. Identity Paulis are always
allowed.
Returns:
An Iterable[stim.PauliString] that yields the requested pauli strings.
Examples:
>>> import stim
>>> pauli_string_iterator = stim.PauliString.iter_all(
... num_qubits=3,
... min_weight=1,
... max_weight=2,
... allowed_paulis="XZ",
... )
>>> for p in pauli_string_iterator:
... print(p)
+X__
+Z__
+_X_
+_Z_
+__X
+__Z
+XX_
+XZ_
+ZX_
+ZZ_
+X_X
+X_Z
+Z_X
+Z_Z
+_XX
+_XZ
+_ZX
+_ZZ
"""
@staticmethod
def random(
num_qubits: int,
*,
Expand Down Expand Up @@ -6591,6 +6646,38 @@ class PauliString:
>>> stim.PauliString("-XXX___XXYZ").weight
7
"""
class PauliStringIterator:
"""Iterates over all pauli strings matching specified patterns.
Examples:
>>> import stim
>>> pauli_string_iterator = stim.PauliString.iter_all(
... 2,
... min_weight=1,
... max_weight=1,
... allowed_paulis="XZ",
... )
>>> for p in pauli_string_iterator:
... print(p)
+X_
+Z_
+_X
+_Z
"""
def __iter__(
self,
) -> stim.PauliStringIterator:
"""Returns an independent copy of the pauli string iterator.
Since for-loops and loop-comprehensions call `iter` on things they
iterate, this effectively allows the iterator to be iterated
multiple times.
"""
def __next__(
self,
) -> stim.PauliString:
"""Returns the next iterated pauli string.
"""
class Tableau:
"""A stabilizer tableau.
Expand Down
3 changes: 3 additions & 0 deletions glue/sample/src/sinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
from sinter._csv_out import (
CSV_HEADER,
)
from sinter._decoding_all_built_in_decoders import (
BUILT_IN_DECODERS,
)
from sinter._existing_data import (
read_stats_from_csv_files,
stats_from_csv_files,
Expand Down
Loading

0 comments on commit 5784b11

Please sign in to comment.