diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1456412ae..337d8f01b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -327,7 +327,7 @@ jobs:
- run: diff <(dev/regen_crumble_to_cpp_string_write_to_stdout.sh) src/stim/diagram/crumble_data.cc
- run: pip install -e glue/sample
- run: diff <(python dev/gen_sinter_api_reference.py -dev) doc/sinter_api.md
- - run: diff <(python -c "import stim; stim.main(command_line_args=['help', 'gates'])" | grep " " | sed 's/^ *//g') glue/crumble/test/generated_gate_name_list.txt
+ - run diff <(dev/gen_known_gates_for_js.sh) glue/crumble/test/generated_gate_name_list.test.js
test_generated_file_lists_are_fresh:
runs-on: ubuntu-latest
steps:
diff --git a/dev/gen_known_gates_for_js.sh b/dev/gen_known_gates_for_js.sh
new file mode 100755
index 000000000..90b0b5503
--- /dev/null
+++ b/dev/gen_known_gates_for_js.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+
+#########################################################################
+# Generates javascript exporting a string KNOWN_GATE_NAMES_FROM_STIM.
+#########################################################################
+
+echo "const KNOWN_GATE_NAMES_FROM_STIM = \`"
+python -c "import stim; stim.main(command_line_args=['help', 'gates'])" | grep " " | sed 's/^ *//g'
+echo "\`"
+echo
+echo "export {KNOWN_GATE_NAMES_FROM_STIM};"
diff --git a/dev/regen_docs.sh b/dev/regen_docs.sh
index 8246a5c90..3f2266ead 100755
--- a/dev/regen_docs.sh
+++ b/dev/regen_docs.sh
@@ -16,4 +16,4 @@ python dev/gen_sinter_api_reference.py -dev > doc/sinter_api.md
python -c "import stim; stim.main(command_line_args=['help', 'gates_markdown'])" > doc/gates.md
python -c "import stim; stim.main(command_line_args=['help', 'formats_markdown'])" > doc/result_formats.md
python -c "import stim; stim.main(command_line_args=['help', 'commands_markdown'])" > doc/usage_command_line.md
-python -c "import stim; stim.main(command_line_args=['help', 'gates'])" | grep " " | sed 's/^ *//g' > glue/crumble/test/generated_gate_name_list.txt
+dev/gen_known_gates_for_js.sh > glue/crumble/test/generated_gate_name_list.test.js
diff --git a/doc/python_api_reference_vDev.md b/doc/python_api_reference_vDev.md
index 4a197b909..517845184 100644
--- a/doc/python_api_reference_vDev.md
+++ b/doc/python_api_reference_vDev.md
@@ -35,7 +35,6 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.Circuit.generated`](#stim.Circuit.generated)
- [`stim.Circuit.get_detector_coordinates`](#stim.Circuit.get_detector_coordinates)
- [`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.inverse`](#stim.Circuit.inverse)
- [`stim.Circuit.num_detectors`](#stim.Circuit.num_detectors)
@@ -189,15 +188,6 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.FlippedMeasurement.__init__`](#stim.FlippedMeasurement.__init__)
- [`stim.FlippedMeasurement.observable`](#stim.FlippedMeasurement.observable)
- [`stim.FlippedMeasurement.record_index`](#stim.FlippedMeasurement.record_index)
-- [`stim.Flow`](#stim.Flow)
- - [`stim.Flow.__eq__`](#stim.Flow.__eq__)
- - [`stim.Flow.__init__`](#stim.Flow.__init__)
- - [`stim.Flow.__ne__`](#stim.Flow.__ne__)
- - [`stim.Flow.__repr__`](#stim.Flow.__repr__)
- - [`stim.Flow.__str__`](#stim.Flow.__str__)
- - [`stim.Flow.input_copy`](#stim.Flow.input_copy)
- - [`stim.Flow.measurements_copy`](#stim.Flow.measurements_copy)
- - [`stim.Flow.output_copy`](#stim.Flow.output_copy)
- [`stim.GateData`](#stim.GateData)
- [`stim.GateData.__eq__`](#stim.GateData.__eq__)
- [`stim.GateData.__init__`](#stim.GateData.__init__)
@@ -395,11 +385,9 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.gate_data`](#stim.gate_data)
- [`stim.main`](#stim.main)
- [`stim.read_shot_data_file`](#stim.read_shot_data_file)
-- [`stim.target_combined_paulis`](#stim.target_combined_paulis)
- [`stim.target_combiner`](#stim.target_combiner)
- [`stim.target_inv`](#stim.target_inv)
- [`stim.target_logical_observable_id`](#stim.target_logical_observable_id)
-- [`stim.target_pauli`](#stim.target_pauli)
- [`stim.target_rec`](#stim.target_rec)
- [`stim.target_relative_detector_id`](#stim.target_relative_detector_id)
- [`stim.target_separator`](#stim.target_separator)
@@ -1897,66 +1885,6 @@ def get_final_qubit_coordinates(
"""
```
-
-```python
-# stim.Circuit.has_all_flows
-
-# (in class stim.Circuit)
-def has_all_flows(
- self,
- flows: Iterable[stim.Flow],
- *,
- unsigned: bool = False,
-) -> bool:
- """Determines if the circuit has all the given stabilizer flow or not.
-
- This is a faster version of `all(c.has_flow(f) for f in flows)`. It's faster
- because, behind the scenes, the circuit can be iterated once instead of once
- per flow.
-
- Args:
- flows: An iterable of `stim.Flow` instances representing the flows to check.
- unsigned: Defaults to False. When False, the flows must be correct including
- the sign of the Pauli strings. When True, only the Pauli terms need to
- be correct; the signs are permitted to be inverted. In effect, this
- requires the circuit to be correct up to Pauli gates.
-
- Returns:
- True if the circuit has the given flow; False otherwise.
-
- Examples:
- >>> import stim
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> Y'),
- ... stim.Flow('Z -> X'),
- ... ])
- False
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> -Y'),
- ... stim.Flow('Z -> X'),
- ... ])
- True
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> Y'),
- ... stim.Flow('Z -> X'),
- ... ], unsigned=True)
- True
-
- Caveats:
- Currently, the unsigned=False version of this method is implemented by
- performing 256 randomized tests. Each test has a 50% chance of a false
- positive, and a 0% chance of a false negative. So, when the method returns
- 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.
- """
-```
-
```python
# stim.Circuit.has_flow
@@ -1964,11 +1892,14 @@ def has_all_flows(
# (in class stim.Circuit)
def has_flow(
self,
- flow: stim.Flow,
+ shorthand: Optional[str] = None,
*,
+ start: Union[None, str, stim.PauliString] = None,
+ end: Union[None, str, stim.PauliString] = None,
+ measurements: Optional[Iterable[Union[int, stim.GateTarget]]] = None,
unsigned: bool = False,
) -> bool:
- """Determines if the circuit has the given stabilizer flow or not.
+ """Determines if the circuit has a stabilizer flow or not.
A circuit has a stabilizer flow P -> Q if it maps the instantaneous stabilizer
P at the start of the circuit to the instantaneous stabilizer Q at the end of
@@ -1982,7 +1913,26 @@ def has_flow(
A flow like 1 -> 1 means the circuit contains a check (could be a DETECTOR).
Args:
- flow: The flow to check for.
+ shorthand: Specifies the flow as a short string like "X1 -> -YZ xor rec[1]".
+ The text must contain "->" to separate the input pauli string from the
+ output pauli string. Measurements are included by appending
+ " xor rec[k]" for each measurement index k. Indexing uses the python
+ convention where non-negative indices index from the start and negative
+ indices index from the end. The pauli strings are parsed as if by
+ `stim.PauliString.__init__`.
+ start: The input into the flow at the start of the circuit. Defaults to None
+ (the identity Pauli string). When specified, this should be a
+ `stim.PauliString`, or a `str` (which will be parsed using
+ `stim.PauliString.__init__`).
+ end: The output from the flow at the end of the circuit. Defaults to None
+ (the identity Pauli string). When specified, this should be a
+ `stim.PauliString`, or a `str` (which will be parsed using
+ `stim.PauliString.__init__`).
+ measurements: Defaults to None (empty). The indices of measurements to
+ include in the flow. This should be a collection of integers and/or
+ stim.GateTarget instances. Indexing uses the python convention where
+ non-negative indices index from the start and negative indices index
+ from the end.
unsigned: Defaults to False. When False, the flows must be correct including
the sign of the Pauli strings. When True, only the Pauli terms need to
be correct; the signs are permitted to be inverted. In effect, this
@@ -1991,49 +1941,56 @@ def has_flow(
Returns:
True if the circuit has the given flow; False otherwise.
+ References:
+ Stim's gate documentation includes the stabilizer flows of each gate.
+
+ Appendix A of https://arxiv.org/abs/2302.02192 describes how flows are
+ defined and provides a circuit construction for experimentally verifying
+ their presence.
+
Examples:
>>> import stim
>>> m = stim.Circuit('M 0')
- >>> m.has_flow(stim.Flow('Z -> Z'))
+ >>> m.has_flow('Z -> Z')
True
- >>> m.has_flow(stim.Flow('X -> X'))
+ >>> m.has_flow('X -> X')
False
- >>> m.has_flow(stim.Flow('Z -> I'))
+ >>> m.has_flow('Z -> I')
False
- >>> m.has_flow(stim.Flow('Z -> I xor rec[-1]'))
+ >>> m.has_flow('Z -> I xor rec[-1]')
True
- >>> m.has_flow(stim.Flow('Z -> rec[-1]'))
+ >>> m.has_flow('Z -> rec[-1]')
True
>>> cx58 = stim.Circuit('CX 5 8')
- >>> cx58.has_flow(stim.Flow('X5 -> X5*X8'))
+ >>> cx58.has_flow('X5 -> X5*X8')
True
- >>> cx58.has_flow(stim.Flow('X_ -> XX'))
+ >>> cx58.has_flow('X_ -> XX')
False
- >>> cx58.has_flow(stim.Flow('_____X___ -> _____X__X'))
+ >>> cx58.has_flow('_____X___ -> _____X__X')
True
>>> stim.Circuit('''
... RY 0
- ... ''').has_flow(stim.Flow(
- ... output=stim.PauliString("Y"),
- ... ))
+ ... ''').has_flow(
+ ... end=stim.PauliString("Y"),
+ ... )
True
>>> stim.Circuit('''
... RY 0
- ... ''').has_flow(stim.Flow(
- ... output=stim.PauliString("X"),
- ... ))
+ ... ''').has_flow(
+ ... end=stim.PauliString("X"),
+ ... )
False
>>> stim.Circuit('''
... CX 0 1
- ... ''').has_flow(stim.Flow(
- ... input=stim.PauliString("+X_"),
- ... output=stim.PauliString("+XX"),
- ... ))
+ ... ''').has_flow(
+ ... start=stim.PauliString("+X_"),
+ ... end=stim.PauliString("+XX"),
+ ... )
True
>>> stim.Circuit('''
@@ -2042,29 +1999,22 @@ def has_flow(
... MXX 0 1
... MZZ 1 2
... MX 1
- ... ''').has_flow(stim.Flow(
- ... input=stim.PauliString("+X_X"),
- ... output=stim.PauliString("+__X"),
+ ... ''').has_flow(
+ ... start=stim.PauliString("+X_X"),
+ ... end=stim.PauliString("+__X"),
... measurements=[0, 2],
- ... ))
+ ... )
True
>>> stim.Circuit('''
... H 0
... ''').has_flow(
- ... stim.Flow("Y -> Y"),
+ ... start=stim.PauliString("Y"),
+ ... end=stim.PauliString("Y"),
... unsigned=True,
... )
True
- >>> stim.Circuit('''
- ... H 0
- ... ''').has_flow(
- ... stim.Flow("Y -> Y"),
- ... unsigned=False,
- ... )
- False
-
Caveats:
Currently, the unsigned=False version of this method is implemented by
performing 256 randomized tests. Each test has a 50% chance of a false
@@ -6798,219 +6748,6 @@ def record_index(
"""
```
-
-```python
-# stim.Flow
-
-# (at top-level in the stim module)
-class Flow:
- """A stabilizer flow (e.g. "XI -> XX xor rec[-1]").
-
- Stabilizer circuits implement, and can be defined by, how they turn input
- stabilizers into output stabilizers mediated by measurements. These
- relationships are called stabilizer flows, and `stim.Flow` is a representation
- of such a flow. For example, a `stim.Flow` can be given to
- `stim.Circuit.has_flow` to verify that a circuit implements the flow.
-
- A circuit has a stabilizer flow P -> Q if it maps the instantaneous stabilizer
- P at the start of the circuit to the instantaneous stabilizer Q at the end of
- the circuit. The flow may be mediated by certain measurements. For example,
- a lattice surgery CNOT involves an MXX measurement and an MZZ measurement, and
- the CNOT flows implemented by the circuit involve these measurements.
-
- A flow like P -> Q means the circuit transforms P into Q.
- A flow like 1 -> P means the circuit prepares P.
- A flow like P -> 1 means the circuit measures P.
- A flow like 1 -> 1 means the circuit contains a check (could be a DETECTOR).
-
- References:
- Stim's gate documentation includes the stabilizer flows of each gate.
-
- Appendix A of https://arxiv.org/abs/2302.02192 describes how flows are
- defined and provides a circuit construction for experimentally verifying
- their presence.
-
- Examples:
- >>> import stim
- >>> c = stim.Circuit("CNOT 2 4")
-
- >>> c.has_flow(stim.Flow("__X__ -> __X_X"))
- True
-
- >>> c.has_flow(stim.Flow("X2*X4 -> X2"))
- True
-
- >>> c.has_flow(stim.Flow("Z4 -> Z4"))
- False
- """
-```
-
-
-```python
-# stim.Flow.__eq__
-
-# (in class stim.Flow)
-def __eq__(
- self,
- arg0: stim.Flow,
-) -> bool:
- """Determines if two flows have identical contents.
- """
-```
-
-
-```python
-# stim.Flow.__init__
-
-# (in class stim.Flow)
-def __init__(
- self,
- arg: Union[None, str, stim.Flow] = None,
- /,
- *,
- input: Optional[stim.PauliString] = None,
- output: Optional[stim.PauliString] = None,
- measurements: Optional[Iterable[Union[int, GateTarget]]] = None,
-) -> None:
- """Initializes a stim.Flow.
-
- When given a string, the string is parsed as flow shorthand. For example,
- the string "X_ -> ZZ xor rec[-1]" will result in a flow with input pauli string
- "X_", output pauli string "ZZ", and measurement indices [-1].
-
- Arguments:
- arg [position-only]: Defaults to None. Must be specified by itself if used.
- str: Initializes a flow by parsing the given shorthand text.
- stim.Flow: Initializes a copy of the given flow.
- None (default): Initializes an empty flow.
- input: Defaults to None. Can be set to a stim.PauliString to directly
- specify the flow's input stabilizer.
- output: Defaults to None. Can be set to a stim.PauliString to directly
- specify the flow's output stabilizer.
- measurements: Can be set to a list of integers or gate targets like
- `stim.target_rec(-1)`, to specify the measurements that mediate the
- flow. Negative and positive measurement indices are allowed. Indexes
- follow the python convention where -1 is the last measurement in a
- circuit and 0 is the first measurement in a circuit.
-
- Examples:
- >>> import stim
-
- >>> stim.Flow("X2 -> -Y2*Z4 xor rec[-1]")
- stim.Flow("__X -> -__Y_Z xor rec[-1]")
-
- >>> stim.Flow("Z -> 1 xor rec[-1]")
- stim.Flow("Z -> rec[-1]")
-
- >>> stim.Flow(
- ... input=stim.PauliString("XX"),
- ... output=stim.PauliString("_X"),
- ... measurements=[],
- ... )
- stim.Flow("XX -> _X")
- """
-```
-
-
-```python
-# stim.Flow.__ne__
-
-# (in class stim.Flow)
-def __ne__(
- self,
- arg0: stim.Flow,
-) -> bool:
- """Determines if two flows have non-identical contents.
- """
-```
-
-
-```python
-# stim.Flow.__repr__
-
-# (in class stim.Flow)
-def __repr__(
- self,
-) -> str:
- """Returns valid python code evaluating to an equivalent `stim.Flow`.
- """
-```
-
-
-```python
-# stim.Flow.__str__
-
-# (in class stim.Flow)
-def __str__(
- self,
-) -> str:
- """Returns a shorthand description of the flow.
- """
-```
-
-
-```python
-# stim.Flow.input_copy
-
-# (in class stim.Flow)
-def input_copy(
- self,
-) -> stim.PauliString:
- """Returns a copy of the flow's input stabilizer.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(input=stim.PauliString('XX'))
- >>> f.input_copy()
- stim.PauliString("+XX")
-
- >>> f.input_copy() is f.input_copy()
- False
- """
-```
-
-
-```python
-# stim.Flow.measurements_copy
-
-# (in class stim.Flow)
-def measurements_copy(
- self,
-) -> List[int]:
- """Returns a copy of the flow's measurement indices.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(measurements=[-1, 2])
- >>> f.measurements_copy()
- [-1, 2]
-
- >>> f.measurements_copy() is f.measurements_copy()
- False
- """
-```
-
-
-```python
-# stim.Flow.output_copy
-
-# (in class stim.Flow)
-def output_copy(
- self,
-) -> stim.PauliString:
- """Returns a copy of the flow's output stabilizer.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(output=stim.PauliString('XX'))
- >>> f.output_copy()
- stim.PauliString("+XX")
-
- >>> f.output_copy() is f.output_copy()
- False
- """
-```
-
```python
# stim.GateData
@@ -13709,40 +13446,6 @@ def read_shot_data_file(
"""
```
-
-```python
-# stim.target_combined_paulis
-
-# (at top-level in the stim module)
-def target_combined_paulis(
- paulis: Union[stim.PauliString, List[stim.GateTarget]],
- invert: bool = False,
-) -> stim.GateTarget:
- """Returns a list of targets encoding a pauli product for instructions like MPP.
-
- Args:
- paulis: The paulis to encode into the targets. This can be a
- `stim.PauliString` or a list of pauli targets from `stim.target_x`,
- `stim.target_pauli`, etc.
- invert: Defaults to False. If True, the product is inverted (like "!X2*Y3").
- Note that this is in addition to any inversions specified by the
- `paulis` argument.
-
- Examples:
- >>> import stim
- >>> circuit = stim.Circuit()
- >>> circuit.append("MPP", [
- ... *stim.target_combined_paulis(stim.PauliString("-XYZ")),
- ... *stim.target_combined_paulis([stim.target_x(2), stim.target_y(5)]),
- ... *stim.target_combined_paulis([stim.target_z(9)], invert=True),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP !X0*Y1*Z2 X2*Y5 !Z9
- ''')
- """
-```
-
```python
# stim.target_combiner
@@ -13827,52 +13530,6 @@ def target_logical_observable_id(
"""
```
-
-```python
-# stim.target_pauli
-
-# (at top-level in the stim module)
-def target_pauli(
- qubit_index: int,
- pauli: Union[str, int],
- invert: bool = False,
-) -> stim.GateTarget:
- """Returns a pauli target that can be passed into `stim.Circuit.append`.
-
- Args:
- qubit_index: The qubit that the Pauli applies to.
- pauli: The pauli gate to use. This can either be a string identifying the
- pauli by name ("x", "X", "y", "Y", "z", or "Z") or an integer following
- the convention (1=X, 2=Y, 3=Z). Setting this argument to "I" or to
- 0 will return a qubit target instead of a pauli target.
- invert: Defaults to False. If True, the target is inverted (like "!X10"),
- indicating that, for example, measurement results should be inverted).
-
- Examples:
- >>> import stim
- >>> circuit = stim.Circuit()
- >>> circuit.append("MPP", [
- ... stim.target_pauli(2, "X"),
- ... stim.target_combiner(),
- ... stim.target_pauli(3, "y", invert=True),
- ... stim.target_pauli(5, 3),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP X2*!Y3 Z5
- ''')
-
- >>> circuit.append("M", [
- ... stim.target_pauli(7, "I"),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP X2*!Y3 Z5
- M 7
- ''')
- """
-```
-
```python
# stim.target_rec
diff --git a/doc/stim.pyi b/doc/stim.pyi
index 7e476efcc..f6a6d5105 100644
--- a/doc/stim.pyi
+++ b/doc/stim.pyi
@@ -1311,66 +1311,16 @@ class Circuit:
>>> circuit.get_final_qubit_coordinates()
{1: [1.0, 2.0, 3.0]}
"""
- def has_all_flows(
- self,
- flows: Iterable[stim.Flow],
- *,
- unsigned: bool = False,
- ) -> bool:
- """Determines if the circuit has all the given stabilizer flow or not.
-
- This is a faster version of `all(c.has_flow(f) for f in flows)`. It's faster
- because, behind the scenes, the circuit can be iterated once instead of once
- per flow.
-
- Args:
- flows: An iterable of `stim.Flow` instances representing the flows to check.
- unsigned: Defaults to False. When False, the flows must be correct including
- the sign of the Pauli strings. When True, only the Pauli terms need to
- be correct; the signs are permitted to be inverted. In effect, this
- requires the circuit to be correct up to Pauli gates.
-
- Returns:
- True if the circuit has the given flow; False otherwise.
-
- Examples:
- >>> import stim
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> Y'),
- ... stim.Flow('Z -> X'),
- ... ])
- False
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> -Y'),
- ... stim.Flow('Z -> X'),
- ... ])
- True
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> Y'),
- ... stim.Flow('Z -> X'),
- ... ], unsigned=True)
- True
-
- Caveats:
- Currently, the unsigned=False version of this method is implemented by
- performing 256 randomized tests. Each test has a 50% chance of a false
- positive, and a 0% chance of a false negative. So, when the method returns
- 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 has_flow(
self,
- flow: stim.Flow,
+ shorthand: Optional[str] = None,
*,
+ start: Union[None, str, stim.PauliString] = None,
+ end: Union[None, str, stim.PauliString] = None,
+ measurements: Optional[Iterable[Union[int, stim.GateTarget]]] = None,
unsigned: bool = False,
) -> bool:
- """Determines if the circuit has the given stabilizer flow or not.
+ """Determines if the circuit has a stabilizer flow or not.
A circuit has a stabilizer flow P -> Q if it maps the instantaneous stabilizer
P at the start of the circuit to the instantaneous stabilizer Q at the end of
@@ -1384,7 +1334,26 @@ class Circuit:
A flow like 1 -> 1 means the circuit contains a check (could be a DETECTOR).
Args:
- flow: The flow to check for.
+ shorthand: Specifies the flow as a short string like "X1 -> -YZ xor rec[1]".
+ The text must contain "->" to separate the input pauli string from the
+ output pauli string. Measurements are included by appending
+ " xor rec[k]" for each measurement index k. Indexing uses the python
+ convention where non-negative indices index from the start and negative
+ indices index from the end. The pauli strings are parsed as if by
+ `stim.PauliString.__init__`.
+ start: The input into the flow at the start of the circuit. Defaults to None
+ (the identity Pauli string). When specified, this should be a
+ `stim.PauliString`, or a `str` (which will be parsed using
+ `stim.PauliString.__init__`).
+ end: The output from the flow at the end of the circuit. Defaults to None
+ (the identity Pauli string). When specified, this should be a
+ `stim.PauliString`, or a `str` (which will be parsed using
+ `stim.PauliString.__init__`).
+ measurements: Defaults to None (empty). The indices of measurements to
+ include in the flow. This should be a collection of integers and/or
+ stim.GateTarget instances. Indexing uses the python convention where
+ non-negative indices index from the start and negative indices index
+ from the end.
unsigned: Defaults to False. When False, the flows must be correct including
the sign of the Pauli strings. When True, only the Pauli terms need to
be correct; the signs are permitted to be inverted. In effect, this
@@ -1393,49 +1362,56 @@ class Circuit:
Returns:
True if the circuit has the given flow; False otherwise.
+ References:
+ Stim's gate documentation includes the stabilizer flows of each gate.
+
+ Appendix A of https://arxiv.org/abs/2302.02192 describes how flows are
+ defined and provides a circuit construction for experimentally verifying
+ their presence.
+
Examples:
>>> import stim
>>> m = stim.Circuit('M 0')
- >>> m.has_flow(stim.Flow('Z -> Z'))
+ >>> m.has_flow('Z -> Z')
True
- >>> m.has_flow(stim.Flow('X -> X'))
+ >>> m.has_flow('X -> X')
False
- >>> m.has_flow(stim.Flow('Z -> I'))
+ >>> m.has_flow('Z -> I')
False
- >>> m.has_flow(stim.Flow('Z -> I xor rec[-1]'))
+ >>> m.has_flow('Z -> I xor rec[-1]')
True
- >>> m.has_flow(stim.Flow('Z -> rec[-1]'))
+ >>> m.has_flow('Z -> rec[-1]')
True
>>> cx58 = stim.Circuit('CX 5 8')
- >>> cx58.has_flow(stim.Flow('X5 -> X5*X8'))
+ >>> cx58.has_flow('X5 -> X5*X8')
True
- >>> cx58.has_flow(stim.Flow('X_ -> XX'))
+ >>> cx58.has_flow('X_ -> XX')
False
- >>> cx58.has_flow(stim.Flow('_____X___ -> _____X__X'))
+ >>> cx58.has_flow('_____X___ -> _____X__X')
True
>>> stim.Circuit('''
... RY 0
- ... ''').has_flow(stim.Flow(
- ... output=stim.PauliString("Y"),
- ... ))
+ ... ''').has_flow(
+ ... end=stim.PauliString("Y"),
+ ... )
True
>>> stim.Circuit('''
... RY 0
- ... ''').has_flow(stim.Flow(
- ... output=stim.PauliString("X"),
- ... ))
+ ... ''').has_flow(
+ ... end=stim.PauliString("X"),
+ ... )
False
>>> stim.Circuit('''
... CX 0 1
- ... ''').has_flow(stim.Flow(
- ... input=stim.PauliString("+X_"),
- ... output=stim.PauliString("+XX"),
- ... ))
+ ... ''').has_flow(
+ ... start=stim.PauliString("+X_"),
+ ... end=stim.PauliString("+XX"),
+ ... )
True
>>> stim.Circuit('''
@@ -1444,29 +1420,22 @@ class Circuit:
... MXX 0 1
... MZZ 1 2
... MX 1
- ... ''').has_flow(stim.Flow(
- ... input=stim.PauliString("+X_X"),
- ... output=stim.PauliString("+__X"),
+ ... ''').has_flow(
+ ... start=stim.PauliString("+X_X"),
+ ... end=stim.PauliString("+__X"),
... measurements=[0, 2],
- ... ))
+ ... )
True
>>> stim.Circuit('''
... H 0
... ''').has_flow(
- ... stim.Flow("Y -> Y"),
+ ... start=stim.PauliString("Y"),
+ ... end=stim.PauliString("Y"),
... unsigned=True,
... )
True
- >>> stim.Circuit('''
- ... H 0
- ... ''').has_flow(
- ... stim.Flow("Y -> Y"),
- ... unsigned=False,
- ... )
- False
-
Caveats:
Currently, the unsigned=False version of this method is implemented by
performing 256 randomized tests. Each test has a 50% chance of a false
@@ -5190,156 +5159,6 @@ class FlippedMeasurement:
For example, the fifth measurement in a circuit has a measurement
record index of 4.
"""
-class Flow:
- """A stabilizer flow (e.g. "XI -> XX xor rec[-1]").
-
- Stabilizer circuits implement, and can be defined by, how they turn input
- stabilizers into output stabilizers mediated by measurements. These
- relationships are called stabilizer flows, and `stim.Flow` is a representation
- of such a flow. For example, a `stim.Flow` can be given to
- `stim.Circuit.has_flow` to verify that a circuit implements the flow.
-
- A circuit has a stabilizer flow P -> Q if it maps the instantaneous stabilizer
- P at the start of the circuit to the instantaneous stabilizer Q at the end of
- the circuit. The flow may be mediated by certain measurements. For example,
- a lattice surgery CNOT involves an MXX measurement and an MZZ measurement, and
- the CNOT flows implemented by the circuit involve these measurements.
-
- A flow like P -> Q means the circuit transforms P into Q.
- A flow like 1 -> P means the circuit prepares P.
- A flow like P -> 1 means the circuit measures P.
- A flow like 1 -> 1 means the circuit contains a check (could be a DETECTOR).
-
- References:
- Stim's gate documentation includes the stabilizer flows of each gate.
-
- Appendix A of https://arxiv.org/abs/2302.02192 describes how flows are
- defined and provides a circuit construction for experimentally verifying
- their presence.
-
- Examples:
- >>> import stim
- >>> c = stim.Circuit("CNOT 2 4")
-
- >>> c.has_flow(stim.Flow("__X__ -> __X_X"))
- True
-
- >>> c.has_flow(stim.Flow("X2*X4 -> X2"))
- True
-
- >>> c.has_flow(stim.Flow("Z4 -> Z4"))
- False
- """
- def __eq__(
- self,
- arg0: stim.Flow,
- ) -> bool:
- """Determines if two flows have identical contents.
- """
- def __init__(
- self,
- arg: Union[None, str, stim.Flow] = None,
- /,
- *,
- input: Optional[stim.PauliString] = None,
- output: Optional[stim.PauliString] = None,
- measurements: Optional[Iterable[Union[int, GateTarget]]] = None,
- ) -> None:
- """Initializes a stim.Flow.
-
- When given a string, the string is parsed as flow shorthand. For example,
- the string "X_ -> ZZ xor rec[-1]" will result in a flow with input pauli string
- "X_", output pauli string "ZZ", and measurement indices [-1].
-
- Arguments:
- arg [position-only]: Defaults to None. Must be specified by itself if used.
- str: Initializes a flow by parsing the given shorthand text.
- stim.Flow: Initializes a copy of the given flow.
- None (default): Initializes an empty flow.
- input: Defaults to None. Can be set to a stim.PauliString to directly
- specify the flow's input stabilizer.
- output: Defaults to None. Can be set to a stim.PauliString to directly
- specify the flow's output stabilizer.
- measurements: Can be set to a list of integers or gate targets like
- `stim.target_rec(-1)`, to specify the measurements that mediate the
- flow. Negative and positive measurement indices are allowed. Indexes
- follow the python convention where -1 is the last measurement in a
- circuit and 0 is the first measurement in a circuit.
-
- Examples:
- >>> import stim
-
- >>> stim.Flow("X2 -> -Y2*Z4 xor rec[-1]")
- stim.Flow("__X -> -__Y_Z xor rec[-1]")
-
- >>> stim.Flow("Z -> 1 xor rec[-1]")
- stim.Flow("Z -> rec[-1]")
-
- >>> stim.Flow(
- ... input=stim.PauliString("XX"),
- ... output=stim.PauliString("_X"),
- ... measurements=[],
- ... )
- stim.Flow("XX -> _X")
- """
- def __ne__(
- self,
- arg0: stim.Flow,
- ) -> bool:
- """Determines if two flows have non-identical contents.
- """
- def __repr__(
- self,
- ) -> str:
- """Returns valid python code evaluating to an equivalent `stim.Flow`.
- """
- def __str__(
- self,
- ) -> str:
- """Returns a shorthand description of the flow.
- """
- def input_copy(
- self,
- ) -> stim.PauliString:
- """Returns a copy of the flow's input stabilizer.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(input=stim.PauliString('XX'))
- >>> f.input_copy()
- stim.PauliString("+XX")
-
- >>> f.input_copy() is f.input_copy()
- False
- """
- def measurements_copy(
- self,
- ) -> List[int]:
- """Returns a copy of the flow's measurement indices.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(measurements=[-1, 2])
- >>> f.measurements_copy()
- [-1, 2]
-
- >>> f.measurements_copy() is f.measurements_copy()
- False
- """
- def output_copy(
- self,
- ) -> stim.PauliString:
- """Returns a copy of the flow's output stabilizer.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(output=stim.PauliString('XX'))
- >>> f.output_copy()
- stim.PauliString("+XX")
-
- >>> f.output_copy() is f.output_copy()
- False
- """
class GateData:
"""Details about a gate supported by stim.
@@ -5416,22 +5235,22 @@ class GateData:
>>> for e in stim.gate_data('H').__unstable_flows:
... print(e)
- X -> Z
- Z -> X
+ +X -> +Z
+ +Z -> +X
>>> for e in stim.gate_data('ISWAP').__unstable_flows:
... print(e)
- X_ -> ZY
- Z_ -> _Z
- _X -> YZ
- _Z -> Z_
+ +X_ -> +ZY
+ +Z_ -> +_Z
+ +_X -> +YZ
+ +_Z -> +Z_
>>> for e in stim.gate_data('MXX').__unstable_flows:
... print(e)
- X_ -> X_
- _X -> _X
- ZZ -> ZZ
- XX -> rec[-1]
+ +X_ -> +X_
+ +_X -> +_X
+ +ZZ -> +ZZ
+ +XX -> rec[-1]
"""
@property
def aliases(
@@ -10706,33 +10525,6 @@ def read_shot_data_file(
array([[False, False, False, False],
[False, True, False, True]])
"""
-def target_combined_paulis(
- paulis: Union[stim.PauliString, List[stim.GateTarget]],
- invert: bool = False,
-) -> stim.GateTarget:
- """Returns a list of targets encoding a pauli product for instructions like MPP.
-
- Args:
- paulis: The paulis to encode into the targets. This can be a
- `stim.PauliString` or a list of pauli targets from `stim.target_x`,
- `stim.target_pauli`, etc.
- invert: Defaults to False. If True, the product is inverted (like "!X2*Y3").
- Note that this is in addition to any inversions specified by the
- `paulis` argument.
-
- Examples:
- >>> import stim
- >>> circuit = stim.Circuit()
- >>> circuit.append("MPP", [
- ... *stim.target_combined_paulis(stim.PauliString("-XYZ")),
- ... *stim.target_combined_paulis([stim.target_x(2), stim.target_y(5)]),
- ... *stim.target_combined_paulis([stim.target_z(9)], invert=True),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP !X0*Y1*Z2 X2*Y5 !Z9
- ''')
- """
def target_combiner(
) -> stim.GateTarget:
"""Returns a target combiner that can be used to build Pauli products.
@@ -10796,45 +10588,6 @@ def target_logical_observable_id(
error(0.25) L13
''')
"""
-def target_pauli(
- qubit_index: int,
- pauli: Union[str, int],
- invert: bool = False,
-) -> stim.GateTarget:
- """Returns a pauli target that can be passed into `stim.Circuit.append`.
-
- Args:
- qubit_index: The qubit that the Pauli applies to.
- pauli: The pauli gate to use. This can either be a string identifying the
- pauli by name ("x", "X", "y", "Y", "z", or "Z") or an integer following
- the convention (1=X, 2=Y, 3=Z). Setting this argument to "I" or to
- 0 will return a qubit target instead of a pauli target.
- invert: Defaults to False. If True, the target is inverted (like "!X10"),
- indicating that, for example, measurement results should be inverted).
-
- Examples:
- >>> import stim
- >>> circuit = stim.Circuit()
- >>> circuit.append("MPP", [
- ... stim.target_pauli(2, "X"),
- ... stim.target_combiner(),
- ... stim.target_pauli(3, "y", invert=True),
- ... stim.target_pauli(5, 3),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP X2*!Y3 Z5
- ''')
-
- >>> circuit.append("M", [
- ... stim.target_pauli(7, "I"),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP X2*!Y3 Z5
- M 7
- ''')
- """
def target_rec(
lookback_index: int,
) -> stim.GateTarget:
diff --git a/glue/crumble/gates/gateset.test.js b/glue/crumble/gates/gateset.test.js
index 70b5d2958..b38f10adc 100644
--- a/glue/crumble/gates/gateset.test.js
+++ b/glue/crumble/gates/gateset.test.js
@@ -1,14 +1,11 @@
import {GATE_MAP, GATE_ALIAS_MAP} from "./gateset.js"
import {test, assertThat, skipRestOfTestIfHeadless} from "../test/test_util.js";
import {Operation} from '../circuit/operation.js';
+import {KNOWN_GATE_NAMES_FROM_STIM} from '../test/generated_gate_name_list.test.js';
-test("gateset.expected_gates", async () => {
- let gateNamesFile = await fetch("generated_gate_name_list.txt");
- assertThat(gateNamesFile.ok).withInfo(gateNamesFile.url).isEqualTo(true);
- let gateNamesText = await gateNamesFile.text();
-
+test("gateset.expected_gates", () => {
let expectedGates = new Set();
- for (let e of gateNamesText.split("\n")) {
+ for (let e of KNOWN_GATE_NAMES_FROM_STIM.split("\n")) {
if (e.length > 0) {
expectedGates.add(e);
}
diff --git a/glue/crumble/test/generated_gate_name_list.txt b/glue/crumble/test/generated_gate_name_list.test.js
similarity index 87%
rename from glue/crumble/test/generated_gate_name_list.txt
rename to glue/crumble/test/generated_gate_name_list.test.js
index 9e5db2612..014f45523 100644
--- a/glue/crumble/test/generated_gate_name_list.txt
+++ b/glue/crumble/test/generated_gate_name_list.test.js
@@ -1,3 +1,4 @@
+const KNOWN_GATE_NAMES_FROM_STIM = `
I
X
Y
@@ -77,3 +78,6 @@ OBSERVABLE_INCLUDE
QUBIT_COORDS
SHIFT_COORDS
TICK
+`
+
+export {KNOWN_GATE_NAMES_FROM_STIM};
diff --git a/glue/python/src/stim/__init__.pyi b/glue/python/src/stim/__init__.pyi
index 7e476efcc..f6a6d5105 100644
--- a/glue/python/src/stim/__init__.pyi
+++ b/glue/python/src/stim/__init__.pyi
@@ -1311,66 +1311,16 @@ class Circuit:
>>> circuit.get_final_qubit_coordinates()
{1: [1.0, 2.0, 3.0]}
"""
- def has_all_flows(
- self,
- flows: Iterable[stim.Flow],
- *,
- unsigned: bool = False,
- ) -> bool:
- """Determines if the circuit has all the given stabilizer flow or not.
-
- This is a faster version of `all(c.has_flow(f) for f in flows)`. It's faster
- because, behind the scenes, the circuit can be iterated once instead of once
- per flow.
-
- Args:
- flows: An iterable of `stim.Flow` instances representing the flows to check.
- unsigned: Defaults to False. When False, the flows must be correct including
- the sign of the Pauli strings. When True, only the Pauli terms need to
- be correct; the signs are permitted to be inverted. In effect, this
- requires the circuit to be correct up to Pauli gates.
-
- Returns:
- True if the circuit has the given flow; False otherwise.
-
- Examples:
- >>> import stim
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> Y'),
- ... stim.Flow('Z -> X'),
- ... ])
- False
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> -Y'),
- ... stim.Flow('Z -> X'),
- ... ])
- True
-
- >>> stim.Circuit('H 0').has_all_flows([
- ... stim.Flow('X -> Z'),
- ... stim.Flow('Y -> Y'),
- ... stim.Flow('Z -> X'),
- ... ], unsigned=True)
- True
-
- Caveats:
- Currently, the unsigned=False version of this method is implemented by
- performing 256 randomized tests. Each test has a 50% chance of a false
- positive, and a 0% chance of a false negative. So, when the method returns
- 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 has_flow(
self,
- flow: stim.Flow,
+ shorthand: Optional[str] = None,
*,
+ start: Union[None, str, stim.PauliString] = None,
+ end: Union[None, str, stim.PauliString] = None,
+ measurements: Optional[Iterable[Union[int, stim.GateTarget]]] = None,
unsigned: bool = False,
) -> bool:
- """Determines if the circuit has the given stabilizer flow or not.
+ """Determines if the circuit has a stabilizer flow or not.
A circuit has a stabilizer flow P -> Q if it maps the instantaneous stabilizer
P at the start of the circuit to the instantaneous stabilizer Q at the end of
@@ -1384,7 +1334,26 @@ class Circuit:
A flow like 1 -> 1 means the circuit contains a check (could be a DETECTOR).
Args:
- flow: The flow to check for.
+ shorthand: Specifies the flow as a short string like "X1 -> -YZ xor rec[1]".
+ The text must contain "->" to separate the input pauli string from the
+ output pauli string. Measurements are included by appending
+ " xor rec[k]" for each measurement index k. Indexing uses the python
+ convention where non-negative indices index from the start and negative
+ indices index from the end. The pauli strings are parsed as if by
+ `stim.PauliString.__init__`.
+ start: The input into the flow at the start of the circuit. Defaults to None
+ (the identity Pauli string). When specified, this should be a
+ `stim.PauliString`, or a `str` (which will be parsed using
+ `stim.PauliString.__init__`).
+ end: The output from the flow at the end of the circuit. Defaults to None
+ (the identity Pauli string). When specified, this should be a
+ `stim.PauliString`, or a `str` (which will be parsed using
+ `stim.PauliString.__init__`).
+ measurements: Defaults to None (empty). The indices of measurements to
+ include in the flow. This should be a collection of integers and/or
+ stim.GateTarget instances. Indexing uses the python convention where
+ non-negative indices index from the start and negative indices index
+ from the end.
unsigned: Defaults to False. When False, the flows must be correct including
the sign of the Pauli strings. When True, only the Pauli terms need to
be correct; the signs are permitted to be inverted. In effect, this
@@ -1393,49 +1362,56 @@ class Circuit:
Returns:
True if the circuit has the given flow; False otherwise.
+ References:
+ Stim's gate documentation includes the stabilizer flows of each gate.
+
+ Appendix A of https://arxiv.org/abs/2302.02192 describes how flows are
+ defined and provides a circuit construction for experimentally verifying
+ their presence.
+
Examples:
>>> import stim
>>> m = stim.Circuit('M 0')
- >>> m.has_flow(stim.Flow('Z -> Z'))
+ >>> m.has_flow('Z -> Z')
True
- >>> m.has_flow(stim.Flow('X -> X'))
+ >>> m.has_flow('X -> X')
False
- >>> m.has_flow(stim.Flow('Z -> I'))
+ >>> m.has_flow('Z -> I')
False
- >>> m.has_flow(stim.Flow('Z -> I xor rec[-1]'))
+ >>> m.has_flow('Z -> I xor rec[-1]')
True
- >>> m.has_flow(stim.Flow('Z -> rec[-1]'))
+ >>> m.has_flow('Z -> rec[-1]')
True
>>> cx58 = stim.Circuit('CX 5 8')
- >>> cx58.has_flow(stim.Flow('X5 -> X5*X8'))
+ >>> cx58.has_flow('X5 -> X5*X8')
True
- >>> cx58.has_flow(stim.Flow('X_ -> XX'))
+ >>> cx58.has_flow('X_ -> XX')
False
- >>> cx58.has_flow(stim.Flow('_____X___ -> _____X__X'))
+ >>> cx58.has_flow('_____X___ -> _____X__X')
True
>>> stim.Circuit('''
... RY 0
- ... ''').has_flow(stim.Flow(
- ... output=stim.PauliString("Y"),
- ... ))
+ ... ''').has_flow(
+ ... end=stim.PauliString("Y"),
+ ... )
True
>>> stim.Circuit('''
... RY 0
- ... ''').has_flow(stim.Flow(
- ... output=stim.PauliString("X"),
- ... ))
+ ... ''').has_flow(
+ ... end=stim.PauliString("X"),
+ ... )
False
>>> stim.Circuit('''
... CX 0 1
- ... ''').has_flow(stim.Flow(
- ... input=stim.PauliString("+X_"),
- ... output=stim.PauliString("+XX"),
- ... ))
+ ... ''').has_flow(
+ ... start=stim.PauliString("+X_"),
+ ... end=stim.PauliString("+XX"),
+ ... )
True
>>> stim.Circuit('''
@@ -1444,29 +1420,22 @@ class Circuit:
... MXX 0 1
... MZZ 1 2
... MX 1
- ... ''').has_flow(stim.Flow(
- ... input=stim.PauliString("+X_X"),
- ... output=stim.PauliString("+__X"),
+ ... ''').has_flow(
+ ... start=stim.PauliString("+X_X"),
+ ... end=stim.PauliString("+__X"),
... measurements=[0, 2],
- ... ))
+ ... )
True
>>> stim.Circuit('''
... H 0
... ''').has_flow(
- ... stim.Flow("Y -> Y"),
+ ... start=stim.PauliString("Y"),
+ ... end=stim.PauliString("Y"),
... unsigned=True,
... )
True
- >>> stim.Circuit('''
- ... H 0
- ... ''').has_flow(
- ... stim.Flow("Y -> Y"),
- ... unsigned=False,
- ... )
- False
-
Caveats:
Currently, the unsigned=False version of this method is implemented by
performing 256 randomized tests. Each test has a 50% chance of a false
@@ -5190,156 +5159,6 @@ class FlippedMeasurement:
For example, the fifth measurement in a circuit has a measurement
record index of 4.
"""
-class Flow:
- """A stabilizer flow (e.g. "XI -> XX xor rec[-1]").
-
- Stabilizer circuits implement, and can be defined by, how they turn input
- stabilizers into output stabilizers mediated by measurements. These
- relationships are called stabilizer flows, and `stim.Flow` is a representation
- of such a flow. For example, a `stim.Flow` can be given to
- `stim.Circuit.has_flow` to verify that a circuit implements the flow.
-
- A circuit has a stabilizer flow P -> Q if it maps the instantaneous stabilizer
- P at the start of the circuit to the instantaneous stabilizer Q at the end of
- the circuit. The flow may be mediated by certain measurements. For example,
- a lattice surgery CNOT involves an MXX measurement and an MZZ measurement, and
- the CNOT flows implemented by the circuit involve these measurements.
-
- A flow like P -> Q means the circuit transforms P into Q.
- A flow like 1 -> P means the circuit prepares P.
- A flow like P -> 1 means the circuit measures P.
- A flow like 1 -> 1 means the circuit contains a check (could be a DETECTOR).
-
- References:
- Stim's gate documentation includes the stabilizer flows of each gate.
-
- Appendix A of https://arxiv.org/abs/2302.02192 describes how flows are
- defined and provides a circuit construction for experimentally verifying
- their presence.
-
- Examples:
- >>> import stim
- >>> c = stim.Circuit("CNOT 2 4")
-
- >>> c.has_flow(stim.Flow("__X__ -> __X_X"))
- True
-
- >>> c.has_flow(stim.Flow("X2*X4 -> X2"))
- True
-
- >>> c.has_flow(stim.Flow("Z4 -> Z4"))
- False
- """
- def __eq__(
- self,
- arg0: stim.Flow,
- ) -> bool:
- """Determines if two flows have identical contents.
- """
- def __init__(
- self,
- arg: Union[None, str, stim.Flow] = None,
- /,
- *,
- input: Optional[stim.PauliString] = None,
- output: Optional[stim.PauliString] = None,
- measurements: Optional[Iterable[Union[int, GateTarget]]] = None,
- ) -> None:
- """Initializes a stim.Flow.
-
- When given a string, the string is parsed as flow shorthand. For example,
- the string "X_ -> ZZ xor rec[-1]" will result in a flow with input pauli string
- "X_", output pauli string "ZZ", and measurement indices [-1].
-
- Arguments:
- arg [position-only]: Defaults to None. Must be specified by itself if used.
- str: Initializes a flow by parsing the given shorthand text.
- stim.Flow: Initializes a copy of the given flow.
- None (default): Initializes an empty flow.
- input: Defaults to None. Can be set to a stim.PauliString to directly
- specify the flow's input stabilizer.
- output: Defaults to None. Can be set to a stim.PauliString to directly
- specify the flow's output stabilizer.
- measurements: Can be set to a list of integers or gate targets like
- `stim.target_rec(-1)`, to specify the measurements that mediate the
- flow. Negative and positive measurement indices are allowed. Indexes
- follow the python convention where -1 is the last measurement in a
- circuit and 0 is the first measurement in a circuit.
-
- Examples:
- >>> import stim
-
- >>> stim.Flow("X2 -> -Y2*Z4 xor rec[-1]")
- stim.Flow("__X -> -__Y_Z xor rec[-1]")
-
- >>> stim.Flow("Z -> 1 xor rec[-1]")
- stim.Flow("Z -> rec[-1]")
-
- >>> stim.Flow(
- ... input=stim.PauliString("XX"),
- ... output=stim.PauliString("_X"),
- ... measurements=[],
- ... )
- stim.Flow("XX -> _X")
- """
- def __ne__(
- self,
- arg0: stim.Flow,
- ) -> bool:
- """Determines if two flows have non-identical contents.
- """
- def __repr__(
- self,
- ) -> str:
- """Returns valid python code evaluating to an equivalent `stim.Flow`.
- """
- def __str__(
- self,
- ) -> str:
- """Returns a shorthand description of the flow.
- """
- def input_copy(
- self,
- ) -> stim.PauliString:
- """Returns a copy of the flow's input stabilizer.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(input=stim.PauliString('XX'))
- >>> f.input_copy()
- stim.PauliString("+XX")
-
- >>> f.input_copy() is f.input_copy()
- False
- """
- def measurements_copy(
- self,
- ) -> List[int]:
- """Returns a copy of the flow's measurement indices.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(measurements=[-1, 2])
- >>> f.measurements_copy()
- [-1, 2]
-
- >>> f.measurements_copy() is f.measurements_copy()
- False
- """
- def output_copy(
- self,
- ) -> stim.PauliString:
- """Returns a copy of the flow's output stabilizer.
-
- Examples:
- >>> import stim
- >>> f = stim.Flow(output=stim.PauliString('XX'))
- >>> f.output_copy()
- stim.PauliString("+XX")
-
- >>> f.output_copy() is f.output_copy()
- False
- """
class GateData:
"""Details about a gate supported by stim.
@@ -5416,22 +5235,22 @@ class GateData:
>>> for e in stim.gate_data('H').__unstable_flows:
... print(e)
- X -> Z
- Z -> X
+ +X -> +Z
+ +Z -> +X
>>> for e in stim.gate_data('ISWAP').__unstable_flows:
... print(e)
- X_ -> ZY
- Z_ -> _Z
- _X -> YZ
- _Z -> Z_
+ +X_ -> +ZY
+ +Z_ -> +_Z
+ +_X -> +YZ
+ +_Z -> +Z_
>>> for e in stim.gate_data('MXX').__unstable_flows:
... print(e)
- X_ -> X_
- _X -> _X
- ZZ -> ZZ
- XX -> rec[-1]
+ +X_ -> +X_
+ +_X -> +_X
+ +ZZ -> +ZZ
+ +XX -> rec[-1]
"""
@property
def aliases(
@@ -10706,33 +10525,6 @@ def read_shot_data_file(
array([[False, False, False, False],
[False, True, False, True]])
"""
-def target_combined_paulis(
- paulis: Union[stim.PauliString, List[stim.GateTarget]],
- invert: bool = False,
-) -> stim.GateTarget:
- """Returns a list of targets encoding a pauli product for instructions like MPP.
-
- Args:
- paulis: The paulis to encode into the targets. This can be a
- `stim.PauliString` or a list of pauli targets from `stim.target_x`,
- `stim.target_pauli`, etc.
- invert: Defaults to False. If True, the product is inverted (like "!X2*Y3").
- Note that this is in addition to any inversions specified by the
- `paulis` argument.
-
- Examples:
- >>> import stim
- >>> circuit = stim.Circuit()
- >>> circuit.append("MPP", [
- ... *stim.target_combined_paulis(stim.PauliString("-XYZ")),
- ... *stim.target_combined_paulis([stim.target_x(2), stim.target_y(5)]),
- ... *stim.target_combined_paulis([stim.target_z(9)], invert=True),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP !X0*Y1*Z2 X2*Y5 !Z9
- ''')
- """
def target_combiner(
) -> stim.GateTarget:
"""Returns a target combiner that can be used to build Pauli products.
@@ -10796,45 +10588,6 @@ def target_logical_observable_id(
error(0.25) L13
''')
"""
-def target_pauli(
- qubit_index: int,
- pauli: Union[str, int],
- invert: bool = False,
-) -> stim.GateTarget:
- """Returns a pauli target that can be passed into `stim.Circuit.append`.
-
- Args:
- qubit_index: The qubit that the Pauli applies to.
- pauli: The pauli gate to use. This can either be a string identifying the
- pauli by name ("x", "X", "y", "Y", "z", or "Z") or an integer following
- the convention (1=X, 2=Y, 3=Z). Setting this argument to "I" or to
- 0 will return a qubit target instead of a pauli target.
- invert: Defaults to False. If True, the target is inverted (like "!X10"),
- indicating that, for example, measurement results should be inverted).
-
- Examples:
- >>> import stim
- >>> circuit = stim.Circuit()
- >>> circuit.append("MPP", [
- ... stim.target_pauli(2, "X"),
- ... stim.target_combiner(),
- ... stim.target_pauli(3, "y", invert=True),
- ... stim.target_pauli(5, 3),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP X2*!Y3 Z5
- ''')
-
- >>> circuit.append("M", [
- ... stim.target_pauli(7, "I"),
- ... ])
- >>> circuit
- stim.Circuit('''
- MPP X2*!Y3 Z5
- M 7
- ''')
- """
def target_rec(
lookback_index: int,
) -> stim.GateTarget: