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.Circuit.insert and numpy 2 compat #787

Merged
merged 5 commits into from
Jun 25, 2024
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
10 changes: 6 additions & 4 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@pybind11_bazel//:python_configure.bzl", "python_configure")

http_archive(
name = "pybind11",
build_file = "@pybind11_bazel//:pybind11.BUILD",
sha256 = "d475978da0cdc2d43b73f30910786759d593a9d8ee05b1b6846d1eb16c6d2e0c",
strip_prefix = "pybind11-2.11.1",
urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.11.1.tar.gz"],
sha256 = "bf8f242abd1abcd375d516a7067490fb71abd79519a282d22b6e4d19282185a7",
strip_prefix = "pybind11-2.12.0",
urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.12.0.tar.gz"],
)
load("@pybind11_bazel//:python_configure.bzl", "python_configure")

python_configure(name = "local_config_python")
6 changes: 6 additions & 0 deletions dev/util_gen_stub_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ def __init__(self):


def splay_signature(sig: str) -> List[str]:
# Maintain backwards compatibility with python 3.6
sig = sig.replace('list[', 'List[')
sig = sig.replace('dict[', 'Dict[')
sig = sig.replace('tuple[', 'Tuple[')
sig = sig.replace('set[', 'Set[')

assert sig.startswith('def')
out = []

Expand Down
2 changes: 1 addition & 1 deletion doc/gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -3111,7 +3111,7 @@ Decomposition (into H, S, CX, M, R):
<a name="SPP_DAG"></a>
### The 'SPP_DAG' Instruction

The generalized S gate. Phases the -1 eigenspace of Pauli product observables by i.
The generalized S_DAG gate. Phases the -1 eigenspace of Pauli product observables by -i.

Parens Arguments:

Expand Down
82 changes: 76 additions & 6 deletions doc/python_api_reference_vDev.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.Circuit.get_final_qubit_coordinates`](#stim.Circuit.get_final_qubit_coordinates)
- [`stim.Circuit.has_all_flows`](#stim.Circuit.has_all_flows)
- [`stim.Circuit.has_flow`](#stim.Circuit.has_flow)
- [`stim.Circuit.insert`](#stim.Circuit.insert)
- [`stim.Circuit.inverse`](#stim.Circuit.inverse)
- [`stim.Circuit.likeliest_error_sat_problem`](#stim.Circuit.likeliest_error_sat_problem)
- [`stim.Circuit.num_detectors`](#stim.Circuit.num_detectors)
Expand Down Expand Up @@ -2223,6 +2224,64 @@ def has_flow(
"""
```

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

# (in class stim.Circuit)
def insert(
self,
index: int,
operation: Union[stim.CircuitInstruction, stim.Circuit],
) -> None:
"""Inserts an operation at the given index, pushing existing operations forward.

Note that, unlike when appending operations or parsing stim circuit files,
inserted operations aren't automatically fused into the preceding operation.
This is to avoid creating complicated situations where it's difficult to reason
about how the indices of operations change in response to insertions.

Args:
index: The index to insert at.

Must satisfy -len(circuit) <= index < len(circuit). Negative indices
are made non-negative by adding len(circuit) to them, so they refer to
indices relative to the end of the circuit instead of the start.

Instructions before the index are not shifted. Instructions that
were at or after the index are shifted forwards.
operation: The object to insert. This can be a single
stim.CircuitInstruction or an entire stim.Circuit.

Examples:
>>> import stim
>>> c = stim.Circuit('''
... H 0
... S 1
... X 2
... ''')
>>> c.insert(1, stim.CircuitInstruction("Y", [3, 4, 5]))
>>> c
stim.Circuit('''
H 0
Y 3 4 5
S 1
X 2
''')
>>> c.insert(-1, stim.Circuit("S 999\nCX 0 1\nCZ 2 3"))
>>> c
stim.Circuit('''
H 0
Y 3 4 5
S 1
S 999
CX 0 1
CZ 2 3
X 2
''')
"""
```

<a name="stim.Circuit.inverse"></a>
```python
# stim.Circuit.inverse
Expand Down Expand Up @@ -2569,6 +2628,14 @@ def reference_sample(

Returns:
reference_sample: reference sample sampled from the given circuit.

Examples:
>>> import stim
>>> stim.Circuit('''
... X 1
... M 0 1
... ''').reference_sample()
array([False, True])
"""
```

Expand Down Expand Up @@ -13832,15 +13899,18 @@ def state_vector(
>>> import numpy as np
>>> s = stim.TableauSimulator()
>>> s.x(2)
>>> list(s.state_vector(endian='little'))
[0j, 0j, 0j, 0j, (1+0j), 0j, 0j, 0j]
>>> s.state_vector(endian='little')
array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dtype=complex64)

>>> list(s.state_vector(endian='big'))
[0j, (1+0j), 0j, 0j, 0j, 0j, 0j, 0j]
>>> s.state_vector(endian='big')
array([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dtype=complex64)

>>> s.sqrt_x(1, 2)
>>> list(s.state_vector())
[(0.5+0j), 0j, -0.5j, 0j, 0.5j, 0j, (0.5+0j), 0j]
>>> s.state_vector()
array([0.5+0.j , 0. +0.j , 0. -0.5j, 0. +0.j , 0. +0.5j, 0. +0.j ,
0.5+0.j , 0. +0.j ], dtype=complex64)
"""
```

Expand Down
74 changes: 68 additions & 6 deletions doc/stim.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,57 @@ class Circuit:
True, there is technically still a 2^-256 chance the circuit doesn't have
the flow. This is lower than the chance of a cosmic ray flipping the result.
"""
def insert(
self,
index: int,
operation: Union[stim.CircuitInstruction, stim.Circuit],
) -> None:
"""Inserts an operation at the given index, pushing existing operations forward.

Note that, unlike when appending operations or parsing stim circuit files,
inserted operations aren't automatically fused into the preceding operation.
This is to avoid creating complicated situations where it's difficult to reason
about how the indices of operations change in response to insertions.

Args:
index: The index to insert at.

Must satisfy -len(circuit) <= index < len(circuit). Negative indices
are made non-negative by adding len(circuit) to them, so they refer to
indices relative to the end of the circuit instead of the start.

Instructions before the index are not shifted. Instructions that
were at or after the index are shifted forwards.
operation: The object to insert. This can be a single
stim.CircuitInstruction or an entire stim.Circuit.

Examples:
>>> import stim
>>> c = stim.Circuit('''
... H 0
... S 1
... X 2
... ''')
>>> c.insert(1, stim.CircuitInstruction("Y", [3, 4, 5]))
>>> c
stim.Circuit('''
H 0
Y 3 4 5
S 1
X 2
''')
>>> c.insert(-1, stim.Circuit("S 999\nCX 0 1\nCZ 2 3"))
>>> c
stim.Circuit('''
H 0
Y 3 4 5
S 1
S 999
CX 0 1
CZ 2 3
X 2
''')
"""
def inverse(
self,
) -> stim.Circuit:
Expand Down Expand Up @@ -1885,6 +1936,14 @@ class Circuit:

Returns:
reference_sample: reference sample sampled from the given circuit.

Examples:
>>> import stim
>>> stim.Circuit('''
... X 1
... M 0 1
... ''').reference_sample()
array([False, True])
"""
def search_for_undetectable_logical_errors(
self,
Expand Down Expand Up @@ -10851,15 +10910,18 @@ class TableauSimulator:
>>> import numpy as np
>>> s = stim.TableauSimulator()
>>> s.x(2)
>>> list(s.state_vector(endian='little'))
[0j, 0j, 0j, 0j, (1+0j), 0j, 0j, 0j]
>>> s.state_vector(endian='little')
array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dtype=complex64)

>>> list(s.state_vector(endian='big'))
[0j, (1+0j), 0j, 0j, 0j, 0j, 0j, 0j]
>>> s.state_vector(endian='big')
array([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dtype=complex64)

>>> s.sqrt_x(1, 2)
>>> list(s.state_vector())
[(0.5+0j), 0j, -0.5j, 0j, 0.5j, 0j, (0.5+0j), 0j]
>>> s.state_vector()
array([0.5+0.j , 0. +0.j , 0. -0.5j, 0. +0.j , 0. +0.5j, 0. +0.j ,
0.5+0.j , 0. +0.j ], dtype=complex64)
"""
def swap(
self,
Expand Down
74 changes: 68 additions & 6 deletions glue/python/src/stim/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,57 @@ class Circuit:
True, there is technically still a 2^-256 chance the circuit doesn't have
the flow. This is lower than the chance of a cosmic ray flipping the result.
"""
def insert(
self,
index: int,
operation: Union[stim.CircuitInstruction, stim.Circuit],
) -> None:
"""Inserts an operation at the given index, pushing existing operations forward.

Note that, unlike when appending operations or parsing stim circuit files,
inserted operations aren't automatically fused into the preceding operation.
This is to avoid creating complicated situations where it's difficult to reason
about how the indices of operations change in response to insertions.

Args:
index: The index to insert at.

Must satisfy -len(circuit) <= index < len(circuit). Negative indices
are made non-negative by adding len(circuit) to them, so they refer to
indices relative to the end of the circuit instead of the start.

Instructions before the index are not shifted. Instructions that
were at or after the index are shifted forwards.
operation: The object to insert. This can be a single
stim.CircuitInstruction or an entire stim.Circuit.

Examples:
>>> import stim
>>> c = stim.Circuit('''
... H 0
... S 1
... X 2
... ''')
>>> c.insert(1, stim.CircuitInstruction("Y", [3, 4, 5]))
>>> c
stim.Circuit('''
H 0
Y 3 4 5
S 1
X 2
''')
>>> c.insert(-1, stim.Circuit("S 999\nCX 0 1\nCZ 2 3"))
>>> c
stim.Circuit('''
H 0
Y 3 4 5
S 1
S 999
CX 0 1
CZ 2 3
X 2
''')
"""
def inverse(
self,
) -> stim.Circuit:
Expand Down Expand Up @@ -1885,6 +1936,14 @@ class Circuit:

Returns:
reference_sample: reference sample sampled from the given circuit.

Examples:
>>> import stim
>>> stim.Circuit('''
... X 1
... M 0 1
... ''').reference_sample()
array([False, True])
"""
def search_for_undetectable_logical_errors(
self,
Expand Down Expand Up @@ -10851,15 +10910,18 @@ class TableauSimulator:
>>> import numpy as np
>>> s = stim.TableauSimulator()
>>> s.x(2)
>>> list(s.state_vector(endian='little'))
[0j, 0j, 0j, 0j, (1+0j), 0j, 0j, 0j]
>>> s.state_vector(endian='little')
array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dtype=complex64)

>>> list(s.state_vector(endian='big'))
[0j, (1+0j), 0j, 0j, 0j, 0j, 0j, 0j]
>>> s.state_vector(endian='big')
array([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dtype=complex64)

>>> s.sqrt_x(1, 2)
>>> list(s.state_vector())
[(0.5+0j), 0j, -0.5j, 0j, 0.5j, 0j, (0.5+0j), 0j]
>>> s.state_vector()
array([0.5+0.j , 0. +0.j , 0. -0.5j, 0. +0.j , 0. +0.5j, 0. +0.j ,
0.5+0.j , 0. +0.j ], dtype=complex64)
"""
def swap(
self,
Expand Down
Loading
Loading