Skip to content

Commit edee3be

Browse files
authored
Improve handling of disjoint errors in circuit-to-dem conversion (#617)
- Analytically solve the bulk of the PAULI_CHANNEL_1 disjoint-to-independent problem, with a fallback to Newton-Rhapson approximation, with a fallback to just leaving it disjoint - Merge undistinguished cases of a disjoint error channel using addition instead of Bernoulli addition - Add `HERALDED_PAULI_CHANNEL_1` gate - Pull `dev/regen_crumble_html.sh` script out of cpp string generation script Fixes #602
1 parent 422a1d0 commit edee3be

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1284
-364
lines changed

dev/canvas_with_texture_for_3d_diagrams.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,25 @@
9797
let {x, y} = pickRect(i);
9898
ctx.fillStyle = 'black';
9999
ctx.fillRect(x * 32, y * 32, 32, 32);
100-
ctx.fillStyle = 'white';
100+
ctx.fillStyle = 'yellow';
101101
ctx.font = '6pt serif';
102102
ctx.fillText('HERALD', x * 32 + 16 - ctx.measureText('HERALD').width / 2, y * 32 + 11);
103103
ctx.font = '7pt serif';
104104
ctx.fillText('ERASE', x * 32 + 16 - ctx.measureText('ERASE').width / 2, y * 32 + 18);
105105
}
106106

107+
function drawHeraldPauliError1(ctx, i) {
108+
let {x, y} = pickRect(i);
109+
ctx.fillStyle = 'black';
110+
ctx.fillRect(x * 32, y * 32, 32, 32);
111+
ctx.fillStyle = 'yellow';
112+
ctx.font = '6pt serif';
113+
ctx.fillText('HERALD', x * 32 + 16 - ctx.measureText('HERALD').width / 2, y * 32 + 3);
114+
ctx.font = '9pt serif';
115+
ctx.fillText('Pauli', x * 32 + 16 - ctx.measureText('Pauli').width / 2, y * 32 + 11);
116+
ctx.fillText('Err1', x * 32 + 16 - ctx.measureText('Err1').width / 2, y * 32 + 21);
117+
}
118+
107119
/**
108120
* @param {!CanvasRenderingContext2D} ctx
109121
*/
@@ -190,6 +202,7 @@
190202
drawRect(ctx, "M_ZZ", "#44F", "#000", n++);
191203
drawRect(ctx, "M_PAD", "#888", "#000", n++);
192204
drawHeraldErase(ctx, n++);
205+
drawHeraldPauliError1(ctx, n++);
193206
}
194207

195208
draw(document.getElementById('cv').getContext('2d'))

dev/regen_crumble_html.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
set -e
3+
4+
cd "$( dirname "${BASH_SOURCE[0]}" )"
5+
cd "$(git rev-parse --show-toplevel)"
6+
7+
cat glue/crumble/crumble.html | grep -v "^<script";
8+
echo "<script>";
9+
# HACK: this temp file is to work around https://github.com/rollup/rollup/issues/5097
10+
rollup glue/crumble/main.js > tmp_crumble.tmp
11+
uglifyjs -c -m --mangle-props --toplevel < tmp_crumble.tmp;
12+
rm tmp_crumble.tmp
13+
echo "</script>";

dev/regen_crumble_to_cpp_string_write_to_stdout.sh

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,15 @@ set -e
55
cd "$( dirname "${BASH_SOURCE[0]}" )"
66
cd "$(git rev-parse --show-toplevel)"
77

8-
{
9-
echo '#include "stim/diagram/crumble_data.h"';
10-
echo '';
11-
echo 'std::string stim_draw_internal::make_crumble_html() {';
12-
echo ' std::string result;'
13-
{
14-
cat glue/crumble/crumble.html | grep -v "^<script";
15-
echo "<script>";
16-
# HACK: this temp file is to work around https://github.com/rollup/rollup/issues/5097
17-
rollup glue/crumble/main.js > tmp_crumble.tmp
18-
uglifyjs -c -m --mangle-props --toplevel < tmp_crumble.tmp;
19-
rm tmp_crumble.tmp
20-
echo "</script>";
21-
} | python -c '
8+
echo '#include "stim/diagram/crumble_data.h"'
9+
echo '';
10+
echo 'std::string stim_draw_internal::make_crumble_html() {'
11+
echo ' std::string result;'
12+
dev/regen_crumble_html.sh | python -c '
2213
import sys
2314
for line in sys.stdin:
2415
for k in range(0, len(line), 1024):
2516
part = line[k:k+1024]
2617
print(f""" result.append(R"CRUMBLE_PART({part})CRUMBLE_PART");""")';
27-
echo ' return result;'
28-
echo '}';
29-
}
18+
echo ' return result;'
19+
echo '}'

doc/gates.md

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
- [E](#E)
5353
- [ELSE_CORRELATED_ERROR](#ELSE_CORRELATED_ERROR)
5454
- [HERALDED_ERASE](#HERALDED_ERASE)
55+
- [HERALDED_PAULI_CHANNEL_1](#HERALDED_PAULI_CHANNEL_1)
5556
- [PAULI_CHANNEL_1](#PAULI_CHANNEL_1)
5657
- [PAULI_CHANNEL_2](#PAULI_CHANNEL_2)
5758
- [X_ERROR](#X_ERROR)
@@ -1911,6 +1912,21 @@ record. When it doesn't fire, nothing happens to the target qubit and a
19111912
is erased to the maximally mixed state by applying X_ERROR(0.5) and
19121913
Z_ERROR(0.5).
19131914

1915+
CAUTION: when converting a circuit with this error into a detector
1916+
error model, this channel is split into multiple potential effects.
1917+
In the context of a DEM, these effects are considered independent.
1918+
This is an approximation, because independent effects can be combined.
1919+
The effect of this approximation, assuming a detector is declared
1920+
on the herald, is that it appears this detector can be cancelled out
1921+
by two of the (originally disjoint) heralded effects firing together.
1922+
Sampling from the DEM instead of the circuit can thus produce unheralded
1923+
errors, even if the circuit noise model only contains heralded errors.
1924+
These issues occur with probability p^2, where p is the probability of a
1925+
heralded error, since two effects that came from the same heralded error
1926+
must occur together to cancel out the herald detector. This also means
1927+
a decoder configured using the DEM will think there's a chance of unheralded
1928+
errors even if the circuit the DEM came from only uses heralded errors.
1929+
19141930
Parens Arguments:
19151931

19161932
A single float (p) specifying the chance of the noise firing.
@@ -1954,6 +1970,75 @@ Examples:
19541970
DETECTOR rec[-4]
19551971
DETECTOR rec[-5]
19561972

1973+
<a name="HERALDED_PAULI_CHANNEL_1"></a>
1974+
### The 'HERALDED_PAULI_CHANNEL_1' Instruction
1975+
1976+
A heralded error channel that applies biased noise.
1977+
1978+
This error records a bit into the measurement record, indicating whether
1979+
or not the herald fired. How likely it is that the herald fires, and the
1980+
corresponding chance of each possible error effect (I, X, Y, or Z) are
1981+
configured by the parens arguments of the instruction.
1982+
1983+
CAUTION: when converting a circuit with this error into a detector
1984+
error model, this channel is split into multiple potential effects.
1985+
In the context of a DEM, these effects are considered independent.
1986+
This is an approximation, because independent effects can be combined.
1987+
The effect of this approximation, assuming a detector is declared
1988+
on the herald, is that it appears this detector can be cancelled out
1989+
by two of the (originally disjoint) heralded effects firing together.
1990+
Sampling from the DEM instead of the circuit can thus produce unheralded
1991+
errors, even if the circuit noise model only contains heralded errors.
1992+
These issues occur with probability p^2, where p is the probability of a
1993+
heralded error, since two effects that came from the same heralded error
1994+
must occur together to cancel out the herald detector. This also means
1995+
a decoder configured using the DEM will think there's a chance of unheralded
1996+
errors even if the circuit the DEM came from only uses heralded errors.
1997+
1998+
Parens Arguments:
1999+
2000+
This instruction takes four arguments (pi, px, py, pz). The
2001+
arguments are disjoint probabilities, specifying the chances
2002+
of heralding with various effects.
2003+
2004+
pi is the chance of heralding with no effect (a false positive).
2005+
px is the chance of heralding with an X error.
2006+
py is the chance of heralding with a Y error.
2007+
pz is the chance of heralding with a Z error.
2008+
2009+
Targets:
2010+
2011+
Qubits to apply heralded biased noise to.
2012+
2013+
Pauli Mixture:
2014+
2015+
1-pi-px-py-pz: record 0, apply I
2016+
pi: record 1, apply I
2017+
px: record 1, apply X
2018+
py: record 1, apply Y
2019+
pz: record 1, apply Z
2020+
2021+
Examples:
2022+
2023+
# With 10% probability perform a phase flip of qubit 0.
2024+
HERALDED_PAULI_CHANNEL_1(0, 0, 0, 0.1) 0
2025+
DETECTOR rec[-1] # Include the herald in detectors available to the decoder
2026+
2027+
# With 20% probability perform a heralded dephasing of qubit 0.
2028+
HERALDED_PAULI_CHANNEL_1(0.1, 0, 0, 0.1) 0
2029+
DETECTOR rec[-1]
2030+
2031+
# Subject a Bell Pair to heralded noise.
2032+
MXX 0 1
2033+
MZZ 0 1
2034+
HERALDED_PAULI_CHANNEL_1(0.01, 0.02, 0.03, 0.04) 0 1
2035+
MXX 0 1
2036+
MZZ 0 1
2037+
DETECTOR rec[-1] rec[-5] # Did ZZ stabilizer change?
2038+
DETECTOR rec[-2] rec[-6] # Did XX stabilizer change?
2039+
DETECTOR rec[-3] # Did the herald on qubit 1 fire?
2040+
DETECTOR rec[-4] # Did the herald on qubit 0 fire?
2041+
19572042
<a name="PAULI_CHANNEL_1"></a>
19582043
### The 'PAULI_CHANNEL_1' Instruction
19592044

@@ -1962,9 +2047,9 @@ A single qubit Pauli error channel with explicitly specified probabilities for e
19622047
Parens Arguments:
19632048

19642049
Three floats specifying disjoint Pauli case probabilities.
1965-
px: Probability of applying an X operation.
1966-
py: Probability of applying a Y operation.
1967-
pz: Probability of applying a Z operation.
2050+
px: Disjoint probability of applying an X error.
2051+
py: Disjoint probability of applying a Y error.
2052+
pz: Disjoint probability of applying a Z error.
19682053

19692054
Targets:
19702055

doc/python_api_reference_vDev.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12510,8 +12510,8 @@ def gate_data(
1251012510
>>> stim.gate_data('cnot').is_two_qubit_gate
1251112511
True
1251212512
>>> gate_dict = stim.gate_data()
12513-
>>> len(gate_dict)
12514-
65
12513+
>>> len(gate_dict) > 50
12514+
True
1251512515
>>> gate_dict['MX'].produces_measurements
1251612516
True
1251712517
"""

doc/stim.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9741,8 +9741,8 @@ def gate_data(
97419741
>>> stim.gate_data('cnot').is_two_qubit_gate
97429742
True
97439743
>>> gate_dict = stim.gate_data()
9744-
>>> len(gate_dict)
9745-
65
9744+
>>> len(gate_dict) > 50
9745+
True
97469746
>>> gate_dict['MX'].produces_measurements
97479747
True
97489748
"""

file_lists/benchmark_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ src/stim/simulators/dem_sampler.perf.cc
1414
src/stim/simulators/error_analyzer.perf.cc
1515
src/stim/simulators/frame_simulator.perf.cc
1616
src/stim/simulators/tableau_simulator.perf.cc
17+
src/stim/stabilizers/conversions.perf.cc
1718
src/stim/stabilizers/pauli_string.perf.cc
1819
src/stim/stabilizers/tableau.perf.cc
1920
src/stim/stabilizers/tableau_iter.perf.cc

file_lists/source_files_no_main

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,4 @@ src/stim/simulators/matched_error.cc
8282
src/stim/simulators/sparse_rev_frame_tracker.cc
8383
src/stim/simulators/transform_without_feedback.cc
8484
src/stim/simulators/vector_simulator.cc
85+
src/stim/stabilizers/conversions.cc

file_lists/test_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ src/stim/cmd/command_sample_dem.test.cc
1717
src/stim/dem/detector_error_model.test.cc
1818
src/stim/diagram/ascii_diagram.test.cc
1919
src/stim/diagram/base64.test.cc
20+
src/stim/diagram/coord.test.cc
2021
src/stim/diagram/detector_slice/detector_slice_set.test.cc
2122
src/stim/diagram/graph/match_graph_3d_drawer.test.cc
2223
src/stim/diagram/graph/match_graph_svg_drawer.test.cc

glue/cirq/stimcirq/_stim_to_cirq.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ def handler(
485485
"HERALDED_ERASE": not_impl(
486486
"Converting HERALDED_ERASE to cirq is not supported."
487487
),
488+
"HERALDED_PAULI_CHANNEL_1": not_impl(
489+
"Converting HERALDED_PAULI_CHANNEL_1 to cirq is not supported."
490+
),
488491
}
489492

490493

0 commit comments

Comments
 (0)