Skip to content

Commit 4040fd8

Browse files
authored
Add stim.Circuit.decomposed (#712)
- And allow `MPAD` to take a noise argument
1 parent dc59667 commit 4040fd8

25 files changed

+1351
-298
lines changed

doc/gates.md

+6
Original file line numberDiff line numberDiff line change
@@ -3143,6 +3143,12 @@ This can be useful for ensuring measurements are aligned to word boundaries, or
31433143
number of measurement bits produced per circuit layer is always the same even if the number
31443144
of measured qubits varies.
31453145

3146+
Parens Arguments:
3147+
3148+
If no parens argument is given, the padding bits are recorded perfectly.
3149+
If one parens argument is given, the padding bits are recorded noisily.
3150+
The argument is the probability of recording the wrong result.
3151+
31463152
Targets:
31473153

31483154
Each target is a measurement result to add.

doc/python_api_reference_vDev.md

+73
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ API references for stable versions are kept on the [stim github wiki](https://gi
2727
- [`stim.Circuit.compile_sampler`](#stim.Circuit.compile_sampler)
2828
- [`stim.Circuit.copy`](#stim.Circuit.copy)
2929
- [`stim.Circuit.count_determined_measurements`](#stim.Circuit.count_determined_measurements)
30+
- [`stim.Circuit.decomposed`](#stim.Circuit.decomposed)
3031
- [`stim.Circuit.detecting_regions`](#stim.Circuit.detecting_regions)
3132
- [`stim.Circuit.detector_error_model`](#stim.Circuit.detector_error_model)
3233
- [`stim.Circuit.diagram`](#stim.Circuit.diagram)
@@ -1273,6 +1274,78 @@ def count_determined_measurements(
12731274
"""
12741275
```
12751276

1277+
<a name="stim.Circuit.decomposed"></a>
1278+
```python
1279+
# stim.Circuit.decomposed
1280+
1281+
# (in class stim.Circuit)
1282+
def decomposed(
1283+
self,
1284+
) -> stim.Circuit:
1285+
"""Recreates the circuit using (mostly) the {H,S,CX,M,R} gate set.
1286+
1287+
The intent of this method is to simplify the circuit to use fewer gate types,
1288+
so it's easier for other tools to consume. Currently, this method performs the
1289+
following simplifications:
1290+
1291+
- Single qubit cliffords are decomposed into {H,S}.
1292+
- Multi-qubit cliffords are decomposed into {H,S,CX}.
1293+
- Single qubit dissipative gates are decomposed into {H,S,M,R}.
1294+
- Multi-qubit dissipative gates are decomposed into {H,S,CX,M,R}.
1295+
1296+
Currently, the following types of gate *aren't* simplified, but they may be
1297+
in the future:
1298+
1299+
- Noise instructions (like X_ERROR, DEPOLARIZE2, and E).
1300+
- Annotations (like TICK, DETECTOR, and SHIFT_COORDS).
1301+
- The MPAD instruction.
1302+
- Repeat blocks are not flattened.
1303+
1304+
Returns:
1305+
A `stim.Circuit` whose function is equivalent to the original circuit,
1306+
but with most gates decomposed into the {H,S,CX,M,R} gate set.
1307+
1308+
Examples:
1309+
>>> import stim
1310+
1311+
>>> stim.Circuit('''
1312+
... SWAP 0 1
1313+
... ''').decomposed()
1314+
stim.Circuit('''
1315+
CX 0 1 1 0 0 1
1316+
''')
1317+
1318+
>>> stim.Circuit('''
1319+
... ISWAP 0 1 2 1
1320+
... TICK
1321+
... MPP !X1*Y2*Z3
1322+
... ''').decomposed()
1323+
stim.Circuit('''
1324+
H 0
1325+
CX 0 1 1 0
1326+
H 1
1327+
S 1 0
1328+
H 2
1329+
CX 2 1 1 2
1330+
H 1
1331+
S 1 2
1332+
TICK
1333+
H 1 2
1334+
S 2
1335+
H 2
1336+
S 2 2
1337+
CX 2 1 3 1
1338+
M !1
1339+
CX 2 1 3 1
1340+
H 2
1341+
S 2
1342+
H 2
1343+
S 2 2
1344+
H 1
1345+
''')
1346+
"""
1347+
```
1348+
12761349
<a name="stim.Circuit.detecting_regions"></a>
12771350
```python
12781351
# stim.Circuit.detecting_regions

doc/stim.pyi

+65
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,71 @@ class Circuit:
716716
>>> circuit.num_detectors + circuit.num_observables
717717
217
718718
"""
719+
def decomposed(
720+
self,
721+
) -> stim.Circuit:
722+
"""Recreates the circuit using (mostly) the {H,S,CX,M,R} gate set.
723+
724+
The intent of this method is to simplify the circuit to use fewer gate types,
725+
so it's easier for other tools to consume. Currently, this method performs the
726+
following simplifications:
727+
728+
- Single qubit cliffords are decomposed into {H,S}.
729+
- Multi-qubit cliffords are decomposed into {H,S,CX}.
730+
- Single qubit dissipative gates are decomposed into {H,S,M,R}.
731+
- Multi-qubit dissipative gates are decomposed into {H,S,CX,M,R}.
732+
733+
Currently, the following types of gate *aren't* simplified, but they may be
734+
in the future:
735+
736+
- Noise instructions (like X_ERROR, DEPOLARIZE2, and E).
737+
- Annotations (like TICK, DETECTOR, and SHIFT_COORDS).
738+
- The MPAD instruction.
739+
- Repeat blocks are not flattened.
740+
741+
Returns:
742+
A `stim.Circuit` whose function is equivalent to the original circuit,
743+
but with most gates decomposed into the {H,S,CX,M,R} gate set.
744+
745+
Examples:
746+
>>> import stim
747+
748+
>>> stim.Circuit('''
749+
... SWAP 0 1
750+
... ''').decomposed()
751+
stim.Circuit('''
752+
CX 0 1 1 0 0 1
753+
''')
754+
755+
>>> stim.Circuit('''
756+
... ISWAP 0 1 2 1
757+
... TICK
758+
... MPP !X1*Y2*Z3
759+
... ''').decomposed()
760+
stim.Circuit('''
761+
H 0
762+
CX 0 1 1 0
763+
H 1
764+
S 1 0
765+
H 2
766+
CX 2 1 1 2
767+
H 1
768+
S 1 2
769+
TICK
770+
H 1 2
771+
S 2
772+
H 2
773+
S 2 2
774+
CX 2 1 3 1
775+
M !1
776+
CX 2 1 3 1
777+
H 2
778+
S 2
779+
H 2
780+
S 2 2
781+
H 1
782+
''')
783+
"""
719784
def detecting_regions(
720785
self,
721786
*,

glue/python/src/stim/__init__.pyi

+65
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,71 @@ class Circuit:
716716
>>> circuit.num_detectors + circuit.num_observables
717717
217
718718
"""
719+
def decomposed(
720+
self,
721+
) -> stim.Circuit:
722+
"""Recreates the circuit using (mostly) the {H,S,CX,M,R} gate set.
723+
724+
The intent of this method is to simplify the circuit to use fewer gate types,
725+
so it's easier for other tools to consume. Currently, this method performs the
726+
following simplifications:
727+
728+
- Single qubit cliffords are decomposed into {H,S}.
729+
- Multi-qubit cliffords are decomposed into {H,S,CX}.
730+
- Single qubit dissipative gates are decomposed into {H,S,M,R}.
731+
- Multi-qubit dissipative gates are decomposed into {H,S,CX,M,R}.
732+
733+
Currently, the following types of gate *aren't* simplified, but they may be
734+
in the future:
735+
736+
- Noise instructions (like X_ERROR, DEPOLARIZE2, and E).
737+
- Annotations (like TICK, DETECTOR, and SHIFT_COORDS).
738+
- The MPAD instruction.
739+
- Repeat blocks are not flattened.
740+
741+
Returns:
742+
A `stim.Circuit` whose function is equivalent to the original circuit,
743+
but with most gates decomposed into the {H,S,CX,M,R} gate set.
744+
745+
Examples:
746+
>>> import stim
747+
748+
>>> stim.Circuit('''
749+
... SWAP 0 1
750+
... ''').decomposed()
751+
stim.Circuit('''
752+
CX 0 1 1 0 0 1
753+
''')
754+
755+
>>> stim.Circuit('''
756+
... ISWAP 0 1 2 1
757+
... TICK
758+
... MPP !X1*Y2*Z3
759+
... ''').decomposed()
760+
stim.Circuit('''
761+
H 0
762+
CX 0 1 1 0
763+
H 1
764+
S 1 0
765+
H 2
766+
CX 2 1 1 2
767+
H 1
768+
S 1 2
769+
TICK
770+
H 1 2
771+
S 2
772+
H 2
773+
S 2 2
774+
CX 2 1 3 1
775+
M !1
776+
CX 2 1 3 1
777+
H 2
778+
S 2
779+
H 2
780+
S 2 2
781+
H 1
782+
''')
783+
"""
719784
def detecting_regions(
720785
self,
721786
*,

src/stim/circuit/circuit.pybind.cc

+68
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,74 @@ void stim_pybind::pybind_circuit_methods(pybind11::module &, pybind11::class_<Ci
23452345
)DOC")
23462346
.data());
23472347

2348+
c.def(
2349+
"decomposed",
2350+
&simplified_circuit,
2351+
clean_doc_string(R"DOC(
2352+
Recreates the circuit using (mostly) the {H,S,CX,M,R} gate set.
2353+
2354+
The intent of this method is to simplify the circuit to use fewer gate types,
2355+
so it's easier for other tools to consume. Currently, this method performs the
2356+
following simplifications:
2357+
2358+
- Single qubit cliffords are decomposed into {H,S}.
2359+
- Multi-qubit cliffords are decomposed into {H,S,CX}.
2360+
- Single qubit dissipative gates are decomposed into {H,S,M,R}.
2361+
- Multi-qubit dissipative gates are decomposed into {H,S,CX,M,R}.
2362+
2363+
Currently, the following types of gate *aren't* simplified, but they may be
2364+
in the future:
2365+
2366+
- Noise instructions (like X_ERROR, DEPOLARIZE2, and E).
2367+
- Annotations (like TICK, DETECTOR, and SHIFT_COORDS).
2368+
- The MPAD instruction.
2369+
- Repeat blocks are not flattened.
2370+
2371+
Returns:
2372+
A `stim.Circuit` whose function is equivalent to the original circuit,
2373+
but with most gates decomposed into the {H,S,CX,M,R} gate set.
2374+
2375+
Examples:
2376+
>>> import stim
2377+
2378+
>>> stim.Circuit('''
2379+
... SWAP 0 1
2380+
... ''').decomposed()
2381+
stim.Circuit('''
2382+
CX 0 1 1 0 0 1
2383+
''')
2384+
2385+
>>> stim.Circuit('''
2386+
... ISWAP 0 1 2 1
2387+
... TICK
2388+
... MPP !X1*Y2*Z3
2389+
... ''').decomposed()
2390+
stim.Circuit('''
2391+
H 0
2392+
CX 0 1 1 0
2393+
H 1
2394+
S 1 0
2395+
H 2
2396+
CX 2 1 1 2
2397+
H 1
2398+
S 1 2
2399+
TICK
2400+
H 1 2
2401+
S 2
2402+
H 2
2403+
S 2 2
2404+
CX 2 1 3 1
2405+
M !1
2406+
CX 2 1 3 1
2407+
H 2
2408+
S 2
2409+
H 2
2410+
S 2 2
2411+
H 1
2412+
''')
2413+
)DOC")
2414+
.data());
2415+
23482416
c.def(
23492417
"with_inlined_feedback",
23502418
&circuit_with_inlined_feedback,

src/stim/circuit/circuit_pybind_test.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
1415
import pathlib
15-
import re
1616
import tempfile
1717
from typing import cast
1818

@@ -1695,10 +1695,40 @@ def test_has_flow_shorthands():
16951695
assert c.has_flow(stim.Flow("iX_ -> iXX xor rec[1] xor rec[3]"))
16961696
assert not c.has_flow(stim.Flow("-iX_ -> iXX xor rec[1] xor rec[3]"))
16971697
assert c.has_flow(stim.Flow("-iX_ -> -iXX xor rec[1] xor rec[3]"))
1698-
with pytest.raises(ValueError):
1698+
with pytest.raises(ValueError, match="Anti-Hermitian"):
16991699
stim.Flow("iX_ -> XX")
17001700

17011701

1702+
def test_decomposed():
1703+
assert stim.Circuit("""
1704+
ISWAP 0 1 2 1
1705+
TICK
1706+
MPP X1*Z2*Y3
1707+
""").decomposed() == stim.Circuit("""
1708+
H 0
1709+
CX 0 1 1 0
1710+
H 1
1711+
S 1 0
1712+
H 2
1713+
CX 2 1 1 2
1714+
H 1
1715+
S 1 2
1716+
TICK
1717+
H 1 3
1718+
S 3
1719+
H 3
1720+
S 3 3
1721+
CX 2 1 3 1
1722+
M 1
1723+
CX 2 1 3 1
1724+
H 3
1725+
S 3
1726+
H 3
1727+
S 3 3
1728+
H 1
1729+
""")
1730+
1731+
17021732
def test_detecting_regions():
17031733
assert stim.Circuit('''
17041734
R 0

0 commit comments

Comments
 (0)