Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stim.PauliString.iter_all #654

Merged
merged 3 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading