A fast quantum stabilizer circuit simulator.
Project description
Stim
Stim is a fast simulator for non-adaptive quantum stabilizer circuits.
Stim can be installed into a python 3 environment using pip:
pip install stim
Once stim is installed, you can import stim
and use it.
There are two supported use cases: interactive usage and high speed sampling.
You can use the Tableau simulator in an interactive fashion:
import stim
s = stim.TableauSimulator()
# Create a GHZ state.
s.h(0)
s.cnot(0, 1)
s.cnot(0, 2)
# Measure the GHZ state.
print(s.measure_many(0, 1, 2)) # [False, False, False] or [True, True, True]
Alternatively, you can compile a circuit and then begin generating samples from it:
import stim
# Create a circuit that measures a large GHZ state.
c = stim.Circuit()
c.append_operation("H", [0])
for k in range(1, 30):
c.append_operation("CNOT", [0, k])
c.append_operation("M", range(30))
# Compile the circuit into a high performance sampler.
sampler = c.compile_sampler()
# Collect a batch of samples.
# Note: the ideal batch size, in terms of speed per sample, is roughly 1024.
# Smaller batches are slower because they are not sufficiently vectorized.
# Bigger batches are slower because they use more memory.
batch = sampler.sample(1024)
print(type(batch)) # numpy.ndarray
print(batch.dtype) # numpy.uint8
print(batch.shape) # (1024, 30)
print(batch)
# Prints something like:
# [[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
# ...
# [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
# [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]]
The circuit can also include noise:
import stim
import numpy as np
c = stim.Circuit()
c.append_from_stim_program_text("""
X_ERROR(0.1) 0
Y_ERROR(0.2) 1
Z_ERROR(0.3) 2
DEPOLARIZE1(0.4) 3
DEPOLARIZE2(0.5) 4 5
M 0 1 2 3 4 5
""")
batch = c.compile_sampler().sample(2**20)
print(np.mean(batch, axis=0).round(3))
# Prints something like:
# [0.1 0.2 0. 0.267 0.267 0.266]
You can also sample annotated detection events using stim.Circuit.compile_detector_sampler
.
Supported Gates
General facts about all gates.
-
Qubit Targets: Qubits are referred to by non-negative integers. There is a qubit
0
, a qubit1
, and so forth (up to an implemented-defined maximum of16777215
). For example, the lineX 2
says to apply anX
gate to qubit2
. Beware that touching qubit999999
implicitly tells simulators to resize their internal state to accommodate a million qubits. -
Measurement Record Targets: Measurement results are referred to by
rec[-#]
arguments, where the index within the square brackets uses python-style negative indices to refer to the end of the growing measurement record. For example,CNOT rec[-1] 3
says "toggle qubit3
if the most recent measurement returnedTrue
andCZ 1 rec[-2]
means "phase flip qubit1
if the second most recent measurement returnedTrue
. There is implementation-defined maximum lookback of-16777215
when accessing the measurement record. Non-negative indices are not permitted. -
Broadcasting: Most gates support broadcasting over multiple targets. For example,
H 0 1 2
will broadcast a Hadamard gate over qubits0
,1
, and2
. Two qubit gates can also broadcast, and do so over aligned pair of targets. For example,CNOT 0 1 2 3
will applyCNOT 0 1
and thenCNOT 2 3
. Broadcasting is always evaluated in left-to-right order.
Single qubit gates
Z
: Pauli Z gate. Phase flip.Y
: Pauli Y gate.X
: Pauli X gate. Bit flip.H
(alternate nameH_XZ
): Hadamard gate. Swaps the X and Z axes. Unitary equals (X + Z) / sqrt(2).H_XY
: Variant of the Hadamard gate that swaps the X and Y axes (instead of X and Z). Unitary equals (X + Y) / sqrt(2).H_YZ
: Variant of the Hadamard gate that swaps the Y and Z axes (instead of X and Z). Unitary equals (Y + Z) / sqrt(2).S
(alternate nameSQRT_Z
): Principle square root of Z gate. Equal todiag(1, i)
.S_DAG
(alternate nameSQRT_Z_DAG
): Adjoint square root of Z gate. Equal todiag(1, -i)
.SQRT_Y
: Principle square root of Y gate. Equal toH_YZ*S*H_YZ
.SQRT_Y_DAG
: Adjoint square root of Y gate. Equal toH_YZ*S_DAG*H_YZ
.SQRT_X
: Principle square root of X gate. Equal toH*S*H
.SQRT_X_DAG
: Adjoint square root of X gate. Equal toH*S_DAG*H
.I
: Identity gate. Does nothing. Why is this even here? Probably out of a misguided desire for closure.
Two qubit gates
SWAP
: Swaps two qubits.ISWAP
: Swaps two qubits while phasing the ZZ observable by i. Equal toSWAP * CZ * (S tensor S)
.ISWAP_DAG
: Swaps two qubits while phasing the ZZ observable by -i. Equal toSWAP * CZ * (S_DAG tensor S_DAG)
.CNOT
(alternate namesCX
,ZCX
): Controlled NOT operation. Qubit pairs are in name order (first qubit is the control, second is the target). This gate can be controlled by on the measurement record. Examples: unitaryCNOT 1 2
, feedbackCNOT rec[-1] 4
.CY
(alternate nameZCY
): Controlled Y operation. Qubit pairs are in name order (first qubit is the control, second is the target). This gate can be controlled by on the measurement record. Examples: unitaryCY 1 2
, feedbackCY rec[-1] 4
.CZ
(alternate nameZCZ
): Controlled Z operation. This gate can be controlled by on the measurement record. Examples: unitaryCZ 1 2
, feedbackCZ rec[-1] 4
orCZ 4 rec[-1]
.YCZ
: Y-basis-controlled Z operation (i.e. the reversed-argument-order controlled-Y). Qubit pairs are in name order. This gate can be controlled by on the measurement record. Examples: unitaryYCZ 1 2
, feedbackYCZ 4 rec[-1]
.YCY
: Y-basis-controlled Y operation.YCX
: Y-basis-controlled X operation. Qubit pairs are in name order.XCZ
: X-basis-controlled Z operation (i.e. the reversed-argument-order controlled-not). Qubit pairs are in name order. This gate can be controlled by on the measurement record. Examples: unitaryXCZ 1 2
, feedbackXCZ 4 rec[-1]
.XCY
: X-basis-controlled Y operation. Qubit pairs are in name order.XCX
: X-basis-controlled X operation.
Collapsing gates
M
: Z-basis measurement. Examples:M 0
,M 2 1
,M 0 !3 1 2
. Collapses the target qubits and reports their values (optionally flipped). Prefixing a target with a!
indicates that the measurement result should be inverted when reported. In the tableau simulator, this operation may require a transpose and so is more efficient when grouped (e.g. preferM 0 1 \n H 0
overM 0 \n H 0 \n M 1
).R
: Reset to |0>. Examples:R 0
,R 2 1
,R 0 3 1 2
. Silently measures the target qubits and bit flips them if they're in the |1> state. Equivalently, discards the target qubits for zero'd qubits. In the tableau simulator, this operation may require a transpose and so is more efficient when grouped (e.g. preferR 0 1 \n X 0
overR 0 \n X 0 \ nR 1
).MR
: Z-basis measurement and reset. Examples:MR 0
,MR 2 1
,MR 0 !3 1 2
. Collapses the target qubits, reports their values (optionally flipped), then resets them to the |0> state. Prefixing a target with a!
indicates that the measurement result should be inverted when reported. (The ! does not change that the qubit is reset to |0>.) In the tableau simulator, this operation may require a transpose and so is more efficient when grouped (e.g. preferMR 0 1 \n H 0
overMR 0 \n H 0 \n MR 1
).
Noise Gates
-
DEPOLARIZE1(p)
: Single qubit depolarizing error. Examples:DEPOLARIZE1(0.001) 1
,DEPOLARIZE1(0.0003) 0 2 4 6
. With probabilityp
, applies independent single-qubit depolarizing kicks to the given qubits. A single-qubit depolarizing kick isX
,Y
, orZ
chosen uniformly at random. -
DEPOLARIZE2(p)
: Two qubit depolarizing error. Examples:DEPOLARIZE2(0.001) 0 1
,DEPOLARIZE2(0.0003) 0 2 4 6
. With probabilityp
, applies independent two-qubit depolarizing kicks to the given qubit pairs. A two-qubit depolarizing kick isIX
,IY
,IZ
,XI
,XX
,XY
,XZ
,YI
,YX
,YY
,YZ
,ZI
,ZX
,ZY
,ZZ
chosen uniformly at random. -
X_ERROR(p)
: Single-qubit probabilistic X error. Examples:X_ERROR(0.001) 0 1
. For each target qubit, independently applies an X gate With probabilityp
. -
Y_ERROR(p)
: Single-qubit probabilistic Y error. Examples:Y_ERROR(0.001) 0 1
. For each target qubit, independently applies a Y gate With probabilityp
. -
Z_ERROR(p)
: Single-qubit probabilistic Z error. Examples:Z_ERROR(0.001) 0 1
. For each target qubit, independently applies a Z gate With probabilityp
. -
CORRELATED_ERROR(p)
(alternate nameE
) andELSE_CORRELATED_ERROR(p)
: Pauli product error cases. Probabilistically applies a Pauli product error with probabilityp
, unless the "correlated error occurred" flag is already set.CORRELATED_ERROR
is equivalent toELSE_CORRELATED_ERROR
except thatCORRELATED_ERROR
starts by clearing the "correlated error occurred" flag. Both operations set the "correlated error occurred" flag if they apply their error. Example:# With 40% probability, uniformly pick X1*Y2 or Z2*Z3 or X1*Y2*Z3. CORRELATED_ERROR(0.2) X1 Y2 ELSE_CORRELATED_ERROR(0.25) Z2 Z3 ELSE_CORRELATED_ERROR(0.33333333333) X1 Y2 Z3
Annotations
DETECTOR
: Asserts that a set of measurements have a deterministic result, and that this result changing can be used to detect errors. Ignored in measurement sampling mode. In detection sampling mode, a detector produces a sample indicating if it was inverted by noise or not. Example:DETECTOR rec[-1] rec[-2]
.OBSERVABLE_INCLUDE(k)
: Adds physical measurement locations to a specified logical observable. The logical measurement result is the parity of all physical measurements added to it. Behaves similarly to a Detector, except observables can be built up globally over the entire circuit instead of being defined locally. Ignored in measurement sampling mode. In detection sampling mode, a logical observable can produce a sample indicating if it was inverted by noise or not. These samples are dropped or put before or after detector samples, depending on command line flags. Examples:OBSERVABLE_INCLUDE(0) rec[-1] rec[-2]
,OBSERVABLE_INCLUDE(3) rec[-7]
.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file stim-1.0.tar.gz
.
File metadata
- Download URL: stim-1.0.tar.gz
- Upload date:
- Size: 67.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.8.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5ad1cfabac9a2372a8475b8b09a5fc230f76e9f11be2c96dcfd0e5b232224143 |
|
MD5 | 7a1d2ad713a9745200e50227f5540d60 |
|
BLAKE2b-256 | cf0dbf873dad9f119567a73934eaba713ec20d5b000a2932434817dc10d5d5a0 |