> ## Documentation Index
> Fetch the complete documentation index at: https://tsim.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

Tsim is a quantum circuit sampler that can efficiently sample from Clifford+T circuits with Pauli noise. It is based on ZX-calculus stabilizer rank decomposition and parametrized ZX diagrams, following work of [arXiv:2403.06777](https://arxiv.org/abs/2403.06777).

## Supported Gates

Tsim supports a universal gate set, together with measurement and reset instructions, and Pauli noise channels.

### Clifford Instructions

Tsim supports all instructions [supported by Stim](https://github.com/quantumlib/Stim/wiki/Stim-v1.13-Gate-Reference). Below, we show the standard generating set of Clifford gates:

```python theme={null}
from tsim import Circuit

c = Circuit("H 0")
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 0.70710678+0.j  0.70710678+0.j]
 [ 0.70710678+0.j -0.70710678+0.j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-001&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>H</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-001&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 1"
  loading="lazy"
/>

```python theme={null}
c = Circuit("S 0")
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 1.+0.j  0.-0.j]
 [-0.+0.j  0.+1.j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-002&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>S</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-002&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 2"
  loading="lazy"
/>

```python theme={null}
c = Circuit("CNOT 0 1")
print(c.to_matrix())
c.diagram("timeline-svg", height=160)
```

```text title="Output" theme={null}
[[ 1.+0.j  0.+0.j -0.+0.j  0.+0.j]
 [ 0.+0.j  1.+0.j  0.+0.j -0.+0.j]
 [ 0.+0.j -0.+0.j  0.+0.j  1.+0.j]
 [-0.+0.j  0.+0.j  1.+0.j  0.+0.j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-003&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:114.28571428571429px; height:160.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:224.0px; transform:scale(0.7142857142857143);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L128,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<path d=&#x22;M96,64 L96,128 &#x22; stroke=&#x22;black&#x22;/>
<circle cx=&#x22;96&#x22; cy=&#x22;64&#x22; r=&#x22;12&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle cx=&#x22;96&#x22; cy=&#x22;128&#x22; r=&#x22;12&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<path d=&#x22;M84,128 L108,128 M96,116 L96,140 &#x22; stroke=&#x22;black&#x22;/>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-003&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 224.0;
var scale = 0.7142857142857143;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="164"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 3"
  loading="lazy"
/>

### Non-Clifford Instructions

In addition to Clifford gates, Tsim supports the following non-Clifford gates. Note that all rotation parameters are defined in units of $\pi$.

Computation time and memory requirement scales exponentially with the number of non-Clifford gates.

```python theme={null}
c = Circuit("T 0")
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 1.        +0.j          0.        +0.j        ]
 [-0.        +0.j          0.70710678+0.70710678j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-004&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>T</text></svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-004&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 4"
  loading="lazy"
/>

```python theme={null}
c = Circuit("R_X(0.1) 0")  # rotation around X-axis by 0.1π
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 0.98768834-0.j          0.        -0.15643447j]
 [-0.        -0.15643447j  0.98768834-0.j        ]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-005&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;14&#x22;>X</tspan></text><text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;black&#x22; x=&#x22;96&#x22; y=&#x22;84&#x22;>0.1π</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-005&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 5"
  loading="lazy"
/>

$$
R_X(\alpha) =
\left(
\begin{array}{cc}
\cos(\alpha\pi/2) & -i \sin(\alpha\pi/2) \\
-i \sin(\alpha\pi/2) & \cos(\alpha\pi/2)
\end{array}
\right)
$$

```python theme={null}
c = Circuit("R_Y(0.1) 0")  # rotation around Y-axis by 0.1π
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 0.98768834-0.j -0.15643447+0.j]
 [ 0.15643447-0.j  0.98768834-0.j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-006&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;14&#x22;>Y</tspan></text><text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;black&#x22; x=&#x22;96&#x22; y=&#x22;84&#x22;>0.1π</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-006&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 6"
  loading="lazy"
/>

$$
R_Y(\alpha) =
\left(
\begin{array}{cc}
\cos(\alpha\pi/2) & -\sin(\alpha\pi/2) \\
\sin(\alpha\pi/2) & \cos(\alpha\pi/2)
\end{array}
\right)
$$

```python theme={null}
c = Circuit("R_Z(0.1) 0")  # rotation around Z-axis by 0.1π
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 0.98768834-0.15643447j  0.        +0.j        ]
 [-0.        +0.j          0.98768834+0.15643447j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-007&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;14&#x22;>Z</tspan></text><text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;black&#x22; x=&#x22;96&#x22; y=&#x22;84&#x22;>0.1π</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-007&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 7"
  loading="lazy"
/>

$$
R_Z(\alpha) =
\left(
\begin{array}{cc}
e^{-i\alpha\pi/2} & 0 \\
0 & e^{i\alpha\pi/2}
\end{array}
\right)
$$

```python theme={null}
c = Circuit("U3(0.1, 0.2, 0.3) 0")
print(c.to_matrix())
c.diagram("timeline-svg", height=120)
```

```text title="Output" theme={null}
[[ 0.98768834-0.j         -0.09194987-0.12655814j]
 [ 0.12655814+0.09194987j  0.        +0.98768834j]]
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-008&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>U<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;14&#x22;>3</tspan></text></svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-008&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 8"
  loading="lazy"
/>

$$
U_3(\theta, \phi, \lambda) =
\left(
\begin{array}{cc}
\cos(\theta\pi/2) & -e^{i\lambda\pi}\sin(\theta\pi/2) \\
e^{i\phi\pi}\sin(\theta\pi/2) & e^{i(\phi+\lambda)\pi}\cos(\theta\pi/2)
\end{array}
\right)
$$

### Measurement and Reset instructions

Tsim supports all collapsing gates [supported by Stim](https://github.com/quantumlib/Stim/wiki/Stim-v1.9-Gate-Reference#collapsing-gates).

```python theme={null}
c = Circuit("M 0")
c.diagram("timeline-svg", height=120)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-009&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-009&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 9"
  loading="lazy"
/>

Measurements (`M`, `MX`, `MY`, `MZ`) project the state into the measurement basis and write the resulting bit into the measurement record.

The measurement record can be used to conditionally apply Pauli gates:

```python theme={null}
c = Circuit("""
M 0
CY rec[-1] 1
""")
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-010&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:170.0px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:224.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;224.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 224 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L192,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L192,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;96&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;128&#x22; y=&#x22;128&#x22;>Y<tspan baseline-shift=&#x22;super&#x22; font-size=&#x22;10&#x22;>rec[0]</tspan></text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-010&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 224.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 10"
  loading="lazy"
/>

The `!` operator can be used to invert the classical measurement bit that is written into the measurement record:

```python theme={null}
c = Circuit("M !0")
c.diagram("timeline-svg", height=120)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-011&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-011&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 11"
  loading="lazy"
/>

The `MPP` instruction measures Pauli strings. The MPP can also be used in conjunction with the `!` operator to flip the classical measurement bit before writing it into the measurement record.

```python theme={null}
c = Circuit("MPP !Z0*X2*Y3")
c.diagram("timeline-svg", height=260)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-012&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:118.18181818181819px; height:260.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:352.0px; transform:scale(0.7386363636363636);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;352.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 352&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L128,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
<path id=&#x22;qubit_line:2&#x22; d=&#x22;M64,192 L128,192 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;192&#x22;>q2</text>
<path id=&#x22;qubit_line:3&#x22; d=&#x22;M64,256 L128,256 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;256&#x22;>q3</text>
</g>
<path d=&#x22;M96,64 L96,256 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>MPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;80&#x22; y=&#x22;176&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;192&#x22; fill=&#x22;white&#x22;>MPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>X</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;240&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;256&#x22; fill=&#x22;white&#x22;>MPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Y</tspan></text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-012&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 352.0;
var scale = 0.7386363636363636;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="264"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 12"
  loading="lazy"
/>

The `MXX`, `MYY`, and `MZZ` instructions measure two-qubit Pauli parity. For example, `MZZ` measures whether pairs of qubits are in the same-parity subspace ($\{|00\rangle, |11\rangle\}$) or opposite-parity subspace ($\{|01\rangle, |10\rangle\}$).

```python theme={null}
c = Circuit("MZZ 0 1")
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-013&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:121.42857142857142px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L128,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<path d=&#x22;M96,64 L96,128 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;18&#x22; x=&#x22;96&#x22; y=&#x22;58&#x22; fill=&#x22;white&#x22;>M<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;18&#x22;>ZZ</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;18&#x22; x=&#x22;96&#x22; y=&#x22;122&#x22; fill=&#x22;white&#x22;>M<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;18&#x22;>ZZ</tspan></text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-013&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 13"
  loading="lazy"
/>

The `MPAD` instruction pads the measurement record with fixed bit values (0 or 1), without performing any actual measurement.

```python theme={null}
c = Circuit("MPAD 0 1 1 0")
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-014&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:170.0px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:224.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;224.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 224 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L192,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L192,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;gray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;18&#x22; x=&#x22;96&#x22; y=&#x22;58&#x22; fill=&#x22;white&#x22;>M<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;12&#x22;>PAD</tspan></text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;gray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;18&#x22; x=&#x22;96&#x22; y=&#x22;122&#x22; fill=&#x22;white&#x22;>M<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;12&#x22;>PAD</tspan></text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;108&#x22;>rec[1]</text>
<rect x=&#x22;144&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;gray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;18&#x22; x=&#x22;160&#x22; y=&#x22;122&#x22; fill=&#x22;white&#x22;>M<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;12&#x22;>PAD</tspan></text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;160&#x22; y=&#x22;108&#x22;>rec[2]</text>
<rect x=&#x22;144&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;gray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;18&#x22; x=&#x22;160&#x22; y=&#x22;58&#x22; fill=&#x22;white&#x22;>M<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;12&#x22;>PAD</tspan></text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;160&#x22; y=&#x22;44&#x22;>rec[3]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-014&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 224.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 14"
  loading="lazy"
/>

The `SPP` instruction applies $e^{-i \pi/4 \cdot P}$ (up to global phase) for a Pauli product $P$, which is equivalent to phasing the $-1$ eigenspace of $P$ by $i$. For example, `SPP Z0` is equivalent to the `S` gate, and `SPP X0*X1` is equivalent to `SQRT_XX`. The `SPP_DAG` instruction applies $e^{+i \pi/4 \cdot P}$ (phases by $-i$) instead. The `!` operator inverts the product, swapping `SPP` and `SPP_DAG` behavior.

```python theme={null}
c = Circuit("SPP X0*Y1*Z2")
c.diagram("timeline-svg", height=220)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-015&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:122.22222222222221px; height:220.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:288.0px; transform:scale(0.7638888888888888);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;288.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 288&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L128,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
<path id=&#x22;qubit_line:2&#x22; d=&#x22;M64,192 L128,192 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;192&#x22;>q2</text>
</g>
<path d=&#x22;M96,64 L96,192 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>SPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>X</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>SPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Y</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;176&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;192&#x22; fill=&#x22;white&#x22;>SPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-015&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 288.0;
var scale = 0.7638888888888888;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="224"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 15"
  loading="lazy"
/>

Similarly, `TPP` applies $e^{-i \pi/8 \cdot P}$ (up to global phase), phasing the $-1$ eigenspace by $e^{i\pi/4}$. `TPP_DAG` applies $e^{+i \pi/8 \cdot P}$ (phases by $e^{-i\pi/4}$).

```python theme={null}
c = Circuit("""
    SPP Z0 * Z3 * Y4
    # TPP X0*Y1
    TPP Z0
    SPP Z0*Z0*Z1*Z1
    TPP_DAG X0*Y1*Z2
""")
c.diagram("timeline-svg", height=420)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-016&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:355.38461538461536px; height:420.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:352.0px; height:416.0px; transform:scale(1.0096153846153846);&#x22;>
<svg width=&#x22;352.0&#x22; height=&#x22;416.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 352 416&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L320,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L320,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
<path id=&#x22;qubit_line:2&#x22; d=&#x22;M64,192 L320,192 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;192&#x22;>q2</text>
<path id=&#x22;qubit_line:3&#x22; d=&#x22;M64,256 L320,256 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;256&#x22;>q3</text>
<path id=&#x22;qubit_line:4&#x22; d=&#x22;M64,320 L320,320 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;320&#x22;>q4</text>
</g>
<path d=&#x22;M96,64 L96,320 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>SPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;240&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;256&#x22; fill=&#x22;white&#x22;>SPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;304&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;320&#x22; fill=&#x22;white&#x22;>SPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Y</tspan></text>
<rect x=&#x22;144&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;160&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>TPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<path d=&#x22;M224,64 L224,128 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;208&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;224&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>TPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<rect x=&#x22;208&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;224&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>TPP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<path d=&#x22;M288,64 L288,192 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;272&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;288&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>TPP†<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>X</tspan></text>
<rect x=&#x22;272&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;288&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>TPP†<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Y</tspan></text>
<rect x=&#x22;272&#x22; y=&#x22;176&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;288&#x22; y=&#x22;192&#x22; fill=&#x22;white&#x22;>TPP†<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-016&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 352.0;
var natH = 416.0;
var scale = 1.0096153846153846;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="424"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 16"
  loading="lazy"
/>

### Noise Channels

Tsim supports all noise channels [supported by Stim](https://github.com/quantumlib/Stim/wiki/Stim-v1.9-Gate-Reference#noise-channels).

The `X_ERROR(p)` instruction is a `X` instruction that is applied with probability `p`.

```python theme={null}
c = Circuit("X_ERROR(0.1) 0")
c.diagram("timeline-svg", height=120)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-017&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>ERR<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>X</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;96&#x22; y=&#x22;84&#x22;>0.1</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-017&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 17"
  loading="lazy"
/>

The `PAULI_CHANNEL_1(p_x, p_y, p_z)` instruction is a `X`, `Y`, and `Z` instruction that is applied with probabilities `p_x`, `p_y`, and `p_z` respectively.

```python theme={null}
c = Circuit("PAULI_CHANNEL_1(0.1, 0.2, 0.3) 0")
c.diagram("timeline-svg", height=120)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-018&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:264.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:352.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;352.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 352 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L320,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;192&#x22; y=&#x22;64&#x22;>PAULI_CHANNEL_1</text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;192&#x22; y=&#x22;84&#x22;>0.1,0.2,0.3</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-018&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 352.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 18"
  loading="lazy"
/>

The `PAULI_CHANNEL_2` instruction takes fifteen floats specifying the disjoint probabilities of each possible Pauli pair
that can occur (except for the non-error double identity case).
The disjoint probability arguments are (in order):

p\_ix,
p\_iy,
p\_iz,
p\_xi,
p\_xx,
p\_xy,
p\_xz,
p\_yi,
p\_yx,
p\_yy,
p\_yz,
p\_zi,
p\_zx,
p\_zy,
p\_zz

```python theme={null}
c = Circuit(
    "PAULI_CHANNEL_2(0.01, 0.01, 0.03, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01) 0 1"
)
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-019&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:850.0px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:1120.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;1120.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 1120 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L1088,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L1088,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<path d=&#x22;M96,64 L96,128 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;992&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;576&#x22; y=&#x22;64&#x22;>PAULI_CHANNEL_2<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>0</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;992&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;576&#x22; y=&#x22;128&#x22;>PAULI_CHANNEL_2<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>1</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;576&#x22; y=&#x22;148&#x22;>0.01,0.01,0.03,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-019&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 1120.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 19"
  loading="lazy"
/>

The `DEPOLARIZE1(p)` instruction applies a randomly chosen Pauli with probability `p`.

```python theme={null}
c = Circuit("DEPOLARIZE1(0.01) 0")
c.diagram("timeline-svg", height=120)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-020&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:120.0px; height:120.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:160.0px; transform:scale(0.75);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>1</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;96&#x22; y=&#x22;84&#x22;>0.01</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-020&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 160.0;
var scale = 0.75;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="124"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 20"
  loading="lazy"
/>

The `DEPOLARIZE2(p)` instruction applies a randomly chosen two-qubit Pauli with probability `p`.

```python theme={null}
c = Circuit("DEPOLARIZE2(0.01) 0 1")
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-021&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:121.42857142857142px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:160.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;160.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 160 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L128,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L128,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<path d=&#x22;M96,64 L96,128 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>2</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;96&#x22; y=&#x22;128&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>2</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;96&#x22; y=&#x22;148&#x22;>0.01</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-021&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 160.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 21"
  loading="lazy"
/>

The `CORRELATED_ERROR(p)` instruction applies a specified Pauli product with probability `p`. If no error occurred, then a following `ELSE_CORRELATED_ERROR(p2)` instruction may apply a Pauli product with probabiliy `p2`. If no error occurs again, further `ELSE_CORRELATED_ERROR(pi)` instructions in the chain may apply a Pauli products.

```python theme={null}
c = Circuit("""
CORRELATED_ERROR(0.1) X0  # Apply X with probability 0.1
ELSE_CORRELATED_ERROR(0.2) Z0 Y1  # If no error occurred, apply Z0*Y1 with probability 0.2
ELSE_CORRELATED_ERROR(0.3) X1 # If still no error, apply X1 with probability 0.3
""")
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-022&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:218.57142857142856px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:288.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;288.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 288 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L256,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L256,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22;>E<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>X</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;96&#x22; y=&#x22;84&#x22;>0.1</text>
<path d=&#x22;M160,64 L160,128 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;144&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;160&#x22; y=&#x22;64&#x22;>EE<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Z</tspan></text>
<rect x=&#x22;144&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;160&#x22; y=&#x22;128&#x22;>EE<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>Y</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;160&#x22; y=&#x22;148&#x22;>0.2</text>
<rect x=&#x22;208&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;224&#x22; y=&#x22;128&#x22;>EE<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>X</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;224&#x22; y=&#x22;148&#x22;>0.3</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-022&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 288.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 22"
  loading="lazy"
/>

### Annotations

Tsim supports detector and observable annotations.

The `DETECTOR` instruction is only used in detector sampling mode and ignored otherwise. It instructs the detector sampler to record the XOR of classical outcomes of specified measurement bits.

```python theme={null}
c = Circuit("""
    M 0 0
    DETECTOR rec[-1] rec[-2]
""")
c.diagram("timeline-svg", height=150)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-023&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:450.0px; height:150.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:480.0px; height:160.0px; transform:scale(0.9375);&#x22;>
<svg width=&#x22;480.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 480 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L448,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;144&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;160&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;160&#x22; y=&#x22;44&#x22;>rec[1]</text>
<rect x=&#x22;208&#x22; y=&#x22;48&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;320&#x22; y=&#x22;64&#x22;>DETECTOR</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;320&#x22; y=&#x22;44&#x22;>D0 = rec[1]*rec[0]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-023&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 480.0;
var natH = 160.0;
var scale = 0.9375;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="154"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 23"
  loading="lazy"
/>

The `OBSERVABLE_INCLUDE` instruction is only used in observable sampling mode and ignored otherwise. It instructs the detector sampler to record the XOR of the specified measurement bits.

```python theme={null}
c = Circuit("""
    M 0 0
    OBSERVABLE_INCLUDE(0) rec[-1] rec[-2]
""")
c.diagram("timeline-svg", height=150)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-024&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:450.0px; height:150.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:480.0px; height:160.0px; transform:scale(0.9375);&#x22;>
<svg width=&#x22;480.0&#x22; height=&#x22;160.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 480 160&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L448,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;96&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;144&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;160&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;160&#x22; y=&#x22;44&#x22;>rec[1]</text>
<rect x=&#x22;208&#x22; y=&#x22;48&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;320&#x22; y=&#x22;64&#x22;>OBS_INCLUDE(0)</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;320&#x22; y=&#x22;44&#x22;>L0 *= rec[1]*rec[0]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-024&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 480.0;
var natH = 160.0;
var scale = 0.9375;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="154"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 24"
  loading="lazy"
/>

## Sampling

Tsim supports multiple samplers. The first is a measurement sampler. This will simply sample bits for each measurement instruction in the circuit. Detector and observable annotations will simply be ignored by this sampler.

```python theme={null}
c = Circuit("""
    RX 0
    R 1
    CNOT 0 1
    M 0 1
""")
sampler = c.compile_sampler()
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-025&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:218.57142857142856px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:288.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;288.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 288 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L256,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L256,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;26&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;16&#x22;>X</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>R</text>
<path d=&#x22;M160,64 L160,128 &#x22; stroke=&#x22;black&#x22;/>
<circle cx=&#x22;160&#x22; cy=&#x22;64&#x22; r=&#x22;12&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle cx=&#x22;160&#x22; cy=&#x22;128&#x22; r=&#x22;12&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<path d=&#x22;M148,128 L172,128 M160,116 L160,140 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;208&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;224&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;224&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;208&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;224&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;224&#x22; y=&#x22;108&#x22;>rec[1]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-025&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 288.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 25"
  loading="lazy"
/>

```python theme={null}
sampler.sample(shots=5)
```

```text title="Output" theme={null}
array([[False, False],
       [ True,  True],
       [False, False],
       [False, False],
       [ True,  True]])
```

The second sampling mode is detector sampling. This will sample detector events and observable values. Detector and observable bits can always be obtained by linear transformations of the measurement bits as return by the measurement sampler.
In practice, however, it can be much more efficient to sample detector events directly.

```python theme={null}
c = Circuit("""
    RX 0
    R 1
    CNOT 0 1
    M 0 1
    DETECTOR rec[-1] rec[-2]
    OBSERVABLE_INCLUDE(0) rec[-1]
""")
sampler = c.compile_detector_sampler()
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-026&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:412.85714285714283px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:544.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;544.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 544 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L512,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L512,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;26&#x22; x=&#x22;96&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;16&#x22;>X</tspan></text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;96&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>R</text>
<path d=&#x22;M160,64 L160,128 &#x22; stroke=&#x22;black&#x22;/>
<circle cx=&#x22;160&#x22; cy=&#x22;64&#x22; r=&#x22;12&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle cx=&#x22;160&#x22; cy=&#x22;128&#x22; r=&#x22;12&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<path d=&#x22;M148,128 L172,128 M160,116 L160,140 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;208&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;224&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;224&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;208&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;224&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;224&#x22; y=&#x22;108&#x22;>rec[1]</text>
<rect x=&#x22;272&#x22; y=&#x22;48&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;384&#x22; y=&#x22;64&#x22;>DETECTOR</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;384&#x22; y=&#x22;44&#x22;>D0 = rec[1]*rec[0]</text>
<rect x=&#x22;272&#x22; y=&#x22;112&#x22; width=&#x22;160&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;352&#x22; y=&#x22;128&#x22;>OBS_INCLUDE(0)</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;352&#x22; y=&#x22;108&#x22;>L0 *= rec[1]</text>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-026&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 544.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 26"
  loading="lazy"
/>

```python theme={null}
detectors, observables = sampler.sample(5, separate_observables=True)
print(detectors)
print(observables)
```

```text title="Output" theme={null}
[[False]
 [False]
 [False]
 [False]
 [False]]
[[False]
 [ True]
 [False]
 [False]
 [ True]]
```

Finally, Tsim allows to compute probability values for target states via the `CompiledStateProbs` sampler.

```python theme={null}
import numpy as np
from tsim.sampler import CompiledStateProbs

sampler = CompiledStateProbs(c)
```

```python theme={null}
sampler.probability_of(np.array([0, 0]), batch_size=1)
```

```text title="Output" theme={null}
array([0.5], dtype=float32)
```

```python theme={null}
sampler.probability_of(np.array([0, 1]), batch_size=1)
```

```text title="Output" theme={null}
array([0.], dtype=float32)
```

```python theme={null}
sampler.probability_of(np.array([1, 0]), batch_size=1)
```

```text title="Output" theme={null}
array([0.], dtype=float32)
```

```python theme={null}
sampler.probability_of(np.array([1, 1]), batch_size=1)
```

```text title="Output" theme={null}
array([0.5], dtype=float32)
```

## Visualization

Tsim supports multiple ways of visualizing quantum circuits.

The `timeline-svg` diagram shows the circuit as a time-ordered sequence of gates.

```python theme={null}
c = Circuit("""
    QUBIT_COORDS(0, 0) 0  # specifies qubit coordinates for the "timeslice-svg" diagram
    QUBIT_COORDS(1, 1) 1
    H 0
    TICK
    T 0
    H 0
    TICK
    CNOT 0 1
    TICK
    DEPOLARIZE2(0.1) 0 1
    TICK
    R_Z(0.2) 1
    TICK
    M 0 1
    DETECTOR rec[-1] rec[-2]
    OBSERVABLE_INCLUDE(0) rec[-1]
""")
c.diagram("timeline-svg", height=170)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-027&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:801.4285714285714px; height:170.0px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:1056.0px; height:224.0px; transform:scale(0.7589285714285714);&#x22;>
<svg width=&#x22;1056.0&#x22; height=&#x22;224.0&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 1056 224&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_lines&#x22;>
<path id=&#x22;qubit_line:0&#x22; d=&#x22;M64,64 L1024,64 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;64&#x22;>q0</text>
<path id=&#x22;qubit_line:1&#x22; d=&#x22;M64,128 L1024,128 &#x22; stroke=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;end&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;64&#x22; y=&#x22;128&#x22;>q1</text>
</g>
<rect x=&#x22;80&#x22; y=&#x22;48&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;192&#x22; y=&#x22;64&#x22;>COORDS(0,0)</text>
<rect x=&#x22;80&#x22; y=&#x22;112&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;192&#x22; y=&#x22;128&#x22;>COORDS(1,1)</text>
<rect x=&#x22;336&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;352&#x22; y=&#x22;64&#x22;>H</text>
<path d=&#x22;M68,40 L68,32 L380,32 L380,40 &#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<path d=&#x22;M68,184 L68,192 L380,192 L380,184 &#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<rect x=&#x22;400&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;416&#x22; y=&#x22;64&#x22;>T</text><rect x=&#x22;464&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;480&#x22; y=&#x22;64&#x22;>H</text>
<path d=&#x22;M388,40 L388,32 L508,32 L508,40 &#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<path d=&#x22;M388,184 L388,192 L508,192 L508,184 &#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<path d=&#x22;M544,64 L544,128 &#x22; stroke=&#x22;black&#x22;/>
<circle cx=&#x22;544&#x22; cy=&#x22;64&#x22; r=&#x22;12&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle cx=&#x22;544&#x22; cy=&#x22;128&#x22; r=&#x22;12&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<path d=&#x22;M532,128 L556,128 M544,116 L544,140 &#x22; stroke=&#x22;black&#x22;/>
<path d=&#x22;M608,64 L608,128 &#x22; stroke=&#x22;black&#x22;/>
<rect x=&#x22;592&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;608&#x22; y=&#x22;64&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>2</tspan></text>
<rect x=&#x22;592&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;608&#x22; y=&#x22;128&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>2</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;608&#x22; y=&#x22;148&#x22;>0.1</text>
<rect x=&#x22;656&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;672&#x22; y=&#x22;128&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;14&#x22;>Z</tspan></text><text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;black&#x22; x=&#x22;672&#x22; y=&#x22;148&#x22;>0.2π</text>
<rect x=&#x22;720&#x22; y=&#x22;48&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;736&#x22; y=&#x22;64&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;736&#x22; y=&#x22;44&#x22;>rec[0]</text>
<rect x=&#x22;720&#x22; y=&#x22;112&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;736&#x22; y=&#x22;128&#x22; fill=&#x22;white&#x22;>M</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;736&#x22; y=&#x22;108&#x22;>rec[1]</text>
<rect x=&#x22;784&#x22; y=&#x22;48&#x22; width=&#x22;224&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;896&#x22; y=&#x22;64&#x22;>DETECTOR</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;896&#x22; y=&#x22;44&#x22;>D0 = rec[1]*rec[0]</text>
<rect x=&#x22;784&#x22; y=&#x22;112&#x22; width=&#x22;160&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;lightgray&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;16&#x22; x=&#x22;864&#x22; y=&#x22;128&#x22;>OBS_INCLUDE(0)</text>
<text text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;8&#x22; x=&#x22;864&#x22; y=&#x22;108&#x22;>L0 *= rec[1]</text>
<path d=&#x22;M708,40 L708,32 L1020,32 L1020,40 &#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<path d=&#x22;M708,184 L708,192 L1020,192 L1020,184 &#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-027&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 1056.0;
var natH = 224.0;
var scale = 0.7589285714285714;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="174"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 27"
  loading="lazy"
/>

When `TICK` instructions are present, each tick can be shown as a 2D time slice with the `timeslice-svg` diagram. Here, `QUBIT_COORDS` annotations can be used to specify the 2D coordinates of the qubits.

```python theme={null}
c.diagram("timeslice-svg", width=800, rows=1)
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}</style></head><body><div data-tsim-zoom=&#x22;tsim-zoom-028&#x22; style=&#x22;width:100%; height:100%; box-sizing:border-box; font-size:0; line-height:0; overflow:auto; background:white; border:none; position:relative;&#x22;>
<div style=&#x22;display:inline-block; overflow:hidden; width:800.0px; height:123.07669245068057px;&#x22;>
<div style=&#x22;transform-origin:0 0; display:block; width:1334.16px; height:205.255px; transform:scale(0.5996282304970918);&#x22;>
<svg width=&#x22;1334.16&#x22; height=&#x22;205.255&#x22; xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 1334.16 205.255&#x22; version=&#x22;1.1&#x22;>
<g id=&#x22;qubit_dots&#x22;>
<circle id=&#x22;qubit_dot:0:0_0:0&#x22; cx=&#x22;80&#x22; cy=&#x22;80&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:1:1_1:0&#x22; cx=&#x22;125.255&#x22; cy=&#x22;125.255&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:0:0_0:1&#x22; cx=&#x22;305.78&#x22; cy=&#x22;80&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:1:1_1:1&#x22; cx=&#x22;351.035&#x22; cy=&#x22;125.255&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:0:0_0:2&#x22; cx=&#x22;531.561&#x22; cy=&#x22;80&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:1:1_1:2&#x22; cx=&#x22;576.815&#x22; cy=&#x22;125.255&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:0:0_0:3&#x22; cx=&#x22;757.341&#x22; cy=&#x22;80&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:1:1_1:3&#x22; cx=&#x22;802.596&#x22; cy=&#x22;125.255&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:0:0_0:4&#x22; cx=&#x22;983.121&#x22; cy=&#x22;80&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:1:1_1:4&#x22; cx=&#x22;1028.38&#x22; cy=&#x22;125.255&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:0:0_0:5&#x22; cx=&#x22;1208.9&#x22; cy=&#x22;80&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle id=&#x22;qubit_dot:1:1_1:5&#x22; cx=&#x22;1254.16&#x22; cy=&#x22;125.255&#x22; r=&#x22;2&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
</g>
<rect x=&#x22;64&#x22; y=&#x22;64&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;80&#x22; y=&#x22;80&#x22;>H</text>
<rect x=&#x22;289.78&#x22; y=&#x22;64&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;305.78&#x22; y=&#x22;80&#x22;>T</text><rect x=&#x22;303.78&#x22; y=&#x22;80&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;319.78&#x22; y=&#x22;96&#x22;>H</text>
<path d=&#x22;M531.561,80 L576.815,125.255 &#x22; fill=&#x22;none&#x22; stroke=&#x22;black&#x22; stroke-width=&#x22;5&#x22;/>
<circle cx=&#x22;531.561&#x22; cy=&#x22;80&#x22; r=&#x22;12&#x22; stroke=&#x22;none&#x22; fill=&#x22;black&#x22;/>
<circle cx=&#x22;576.815&#x22; cy=&#x22;125.255&#x22; r=&#x22;12&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<path d=&#x22;M564.815,125.255 L588.815,125.255 M576.815,113.255 L576.815,137.255 &#x22; stroke=&#x22;black&#x22;/>
<path d=&#x22;M757.341,80 L802.596,125.255 &#x22; fill=&#x22;none&#x22; stroke=&#x22;black&#x22; stroke-width=&#x22;5&#x22;/>
<rect x=&#x22;741.341&#x22; y=&#x22;64&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;757.341&#x22; y=&#x22;80&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>2</tspan></text>
<rect x=&#x22;786.596&#x22; y=&#x22;109.255&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;pink&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;12&#x22; x=&#x22;802.596&#x22; y=&#x22;125.255&#x22;>DEP<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;10&#x22;>2</tspan></text>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;red&#x22; x=&#x22;802.596&#x22; y=&#x22;145.255&#x22;>0.1</text>
<rect x=&#x22;1012.38&#x22; y=&#x22;109.255&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;white&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;1028.38&#x22; y=&#x22;125.255&#x22;>R<tspan baseline-shift=&#x22;sub&#x22; font-size=&#x22;14&#x22;>Z</tspan></text><text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;10&#x22; stroke=&#x22;black&#x22; x=&#x22;1028.38&#x22; y=&#x22;145.255&#x22;>0.2π</text>
<rect x=&#x22;1192.9&#x22; y=&#x22;64&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;1208.9&#x22; y=&#x22;80&#x22; fill=&#x22;white&#x22;>M</text>
<rect x=&#x22;1238.16&#x22; y=&#x22;109.255&#x22; width=&#x22;32&#x22; height=&#x22;32&#x22; stroke=&#x22;black&#x22; fill=&#x22;black&#x22;/>
<text dominant-baseline=&#x22;central&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;monospace&#x22; font-size=&#x22;30&#x22; x=&#x22;1254.16&#x22; y=&#x22;125.255&#x22; fill=&#x22;white&#x22;>M</text>
<g id=&#x22;tick_borders&#x22;>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;serif&#x22; font-size=&#x22;18&#x22; transform=&#x22;rotate(90)&#x22; x=&#x22;102.627&#x22; y=&#x22;-199.255&#x22;>Tick 0</text>
<rect id=&#x22;tick_border:0:0_0:0&#x22; x=&#x22;0&#x22; y=&#x22;0&#x22; width=&#x22;205.255&#x22; height=&#x22;205.255&#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;serif&#x22; font-size=&#x22;18&#x22; transform=&#x22;rotate(90)&#x22; x=&#x22;102.627&#x22; y=&#x22;-425.035&#x22;>Tick 1</text>
<rect id=&#x22;tick_border:1:0_1:1&#x22; x=&#x22;225.78&#x22; y=&#x22;0&#x22; width=&#x22;205.255&#x22; height=&#x22;205.255&#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;serif&#x22; font-size=&#x22;18&#x22; transform=&#x22;rotate(90)&#x22; x=&#x22;102.627&#x22; y=&#x22;-650.815&#x22;>Tick 2</text>
<rect id=&#x22;tick_border:2:0_2:2&#x22; x=&#x22;451.561&#x22; y=&#x22;0&#x22; width=&#x22;205.255&#x22; height=&#x22;205.255&#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;serif&#x22; font-size=&#x22;18&#x22; transform=&#x22;rotate(90)&#x22; x=&#x22;102.627&#x22; y=&#x22;-876.596&#x22;>Tick 3</text>
<rect id=&#x22;tick_border:3:0_3:3&#x22; x=&#x22;677.341&#x22; y=&#x22;0&#x22; width=&#x22;205.255&#x22; height=&#x22;205.255&#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;serif&#x22; font-size=&#x22;18&#x22; transform=&#x22;rotate(90)&#x22; x=&#x22;102.627&#x22; y=&#x22;-1102.38&#x22;>Tick 4</text>
<rect id=&#x22;tick_border:4:0_4:4&#x22; x=&#x22;903.121&#x22; y=&#x22;0&#x22; width=&#x22;205.255&#x22; height=&#x22;205.255&#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
<text dominant-baseline=&#x22;hanging&#x22; text-anchor=&#x22;middle&#x22; font-family=&#x22;serif&#x22; font-size=&#x22;18&#x22; transform=&#x22;rotate(90)&#x22; x=&#x22;102.627&#x22; y=&#x22;-1328.16&#x22;>Tick 5</text>
<rect id=&#x22;tick_border:5:0_5:5&#x22; x=&#x22;1128.9&#x22; y=&#x22;0&#x22; width=&#x22;205.255&#x22; height=&#x22;205.255&#x22; stroke=&#x22;black&#x22; fill=&#x22;none&#x22;/>
</g>
</svg>
</div>
</div>
</div>
<script>
(function() {
var wrap = document.querySelector('[data-tsim-zoom=&#x22;tsim-zoom-028&#x22;]');
if (!wrap || wrap.dataset.tsimZoomInit) return;
wrap.dataset.tsimZoomInit = &#x22;1&#x22;;
var size = wrap.firstElementChild;
var xform = size.firstElementChild;
var natW = 1334.16;
var natH = 205.255;
var scale = 0.5996282304970918;
var cw = wrap.clientWidth;
if (cw > 0 && natW > 0) {
/* keep height-fit initial scale */
}
function apply() {
xform.style.transform = 'scale(' + scale + ')';
size.style.width = (natW * scale) + 'px';
size.style.height = (natH * scale) + 'px';
}
apply();
wrap.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var rect = wrap.getBoundingClientRect();
var mx = e.clientX - rect.left + wrap.scrollLeft;
var my = e.clientY - rect.top + wrap.scrollTop;
var factor = Math.exp(-e.deltaY * 0.01);
var newScale = Math.min(Math.max(0.02, scale * factor), 40);
var ratio = newScale / scale;
scale = newScale;
apply();
wrap.scrollLeft = mx * ratio - (e.clientX - rect.left);
wrap.scrollTop = my * ratio - (e.clientY - rect.top);
}
}, { passive: false });
})();
</script></body></html>"
  width="100%"
  height="127"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="Circuit diagram 28"
  loading="lazy"
/>

With the `pyzx` argument, the circuit can be visualized using the [pyzx](https://github.com/zxcalc/pyzx) as a ZX-diagram.

```python theme={null}
c.diagram("pyzx");
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}[id^=&#x22;graph-output-&#x22;]{width:100%;height:100%;overflow:auto;box-sizing:border-box;}</style></head><body><div style=&#x22;overflow:auto; background-color: white&#x22; id=&#x22;graph-output-001&#x22;></div><script type=&#x22;module&#x22;>
var d3;
if (d3 == null) { d3 = await import(&#x22;https://esm.sh/d3@5&#x22;); }
var _settings_colors = JSON.parse('{&#x22;edge&#x22;: &#x22;#000000&#x22;, &#x22;Hedge&#x22;: &#x22;#0088ff&#x22;, &#x22;Xedge&#x22;: &#x22;#999999&#x22;, &#x22;Bedge&#x22;: &#x22;#000000&#x22;, &#x22;HBedge&#x22;: &#x22;#0088ff&#x22;, &#x22;boundary&#x22;: &#x22;#000000&#x22;, &#x22;X&#x22;: &#x22;#ff8888&#x22;, &#x22;Y&#x22;: &#x22;#aabbff&#x22;, &#x22;Z&#x22;: &#x22;#ccffcc&#x22;, &#x22;H&#x22;: &#x22;#ffff66&#x22;, &#x22;W&#x22;: &#x22;#000000&#x22;, &#x22;Zalt&#x22;: &#x22;#ccffcc&#x22;, &#x22;Walt&#x22;: &#x22;#000000&#x22;, &#x22;Zbold&#x22;: &#x22;#ccffcc&#x22;, &#x22;Xbold&#x22;: &#x22;#ff8888&#x22;, &#x22;Xdark&#x22;: &#x22;#ff8888&#x22;, &#x22;Ydark&#x22;: &#x22;#aabbff&#x22;, &#x22;Zdark&#x22;: &#x22;#99dd99&#x22;}');
// PyZX - Python library for quantum circuit rewriting 
//        and optimisation using the ZX-calculus
// Copyright (C) 2018 - Aleks Kissinger and John van de Wetering

// Licensed under the Apache License, Version 2.0 (the &#x22;License&#x22;);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//    http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an &#x22;AS IS&#x22; BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// styling functions
function nodeColor(t) {
if (t == 0) return _settings_colors['boundary'];
else if (t == 1) return _settings_colors['Z']; // &#x22;#ccffcc&#x22;;
else if (t == 2) return _settings_colors['X']; // &#x22;#ff8888&#x22;;
else if (t == 3) return _settings_colors['H']; // &#x22;yellow&#x22;;
else if (t == 4) return _settings_colors['W']; // &#x22;black&#x22;;
else if (t == 5) return _settings_colors['Walt']; // &#x22;black&#x22;;
else if (t == 6) return _settings_colors['Zalt']; // &#x22;#ccffcc&#x22;;
else if (t == 7) return _settings_colors['Zbold']; // &#x22;#ccffcc&#x22; bold Z
else if (t == 8) return _settings_colors['Xbold']; // &#x22;#ff8888&#x22; bold X
}

function edgeColor(t) {
if (t == 1) return _settings_colors['edge']; //&#x22;black&#x22;;
else if (t == 2) return _settings_colors['Hedge']; // &#x22;#08f&#x22;;
else if (t == 3) return _settings_colors['Xedge']; // &#x22;gray&#x22;;
else if (t == 4) return _settings_colors['Bedge']; // &#x22;black&#x22; bold
else if (t == 5) return _settings_colors['HBedge']; // &#x22;#0088ff&#x22; bold hadamard
}

function isBoldEdge(t) {
return t == 4 || t == 5;
}

function webColor(t) {
if (t == 'X') return _settings_colors['Xdark'];
else if (t == 'Y') return _settings_colors['Ydark'];
else if (t == 'Z') return _settings_colors['Zdark'];
else if (t == 'I') return '#dddddd';
}

function nodeStyle(selected, t) {
var bold = (t == 7 || t == 8);
if (selected) return &#x22;stroke-width: &#x22; + (bold ? &#x22;4&#x22; : &#x22;2&#x22;) + &#x22;px; stroke: #00f&#x22;;
return &#x22;stroke-width: &#x22; + (bold ? &#x22;3&#x22; : &#x22;1.5&#x22;) + &#x22;px&#x22;;
}

var symbolGround = {
draw: function(context, size){
let s = size/2;

context.moveTo(0,-s);
context.lineTo(0,0);

context.moveTo(-s,0);
context.lineTo(s,0);

context.moveTo(-2*s/3,s/3);
context.lineTo(2*s/3,s/3);

context.moveTo(-s/3,2*s/3);
context.lineTo(s/3,2*s/3);
}
}

function showGraph(tag, graph, width, height, scale, node_size, auto_hbox, show_labels, scalar_str) {
var ntab = {};

var groundOffset = 2.5 * node_size;

graph.nodes.forEach(function(d) {
ntab[d.name] = d;
d.selected = false;
d.previouslySelected = false;
d.nhd = [];
});

var spiders_and_boundaries = graph.nodes.filter(function(d) {
return d.t != 3;
});

graph.links.forEach(function(d) {
var s = ntab[d.source];
var t = ntab[d.target];
d.source = s;
d.target = t;
s.nhd.push(t);
t.nhd.push(s);
});

graph.pauli_web.forEach(function(d) {
var s = ntab[d.source];
var t = ntab[d.target];
d.source = s;
d.target = t;
});

var shiftKey;

// SETUP SVG ITEMS

var svg = d3.select(tag)
//.attr(&#x22;tabindex&#x22;, 1)
.on(&#x22;keydown.brush&#x22;, function() {shiftKey = d3.event.shiftKey || d3.event.metaKey;})
.on(&#x22;keyup.brush&#x22;, function() {shiftKey = d3.event.shiftKey || d3.event.metaKey;})
//.each(function() { this.focus(); })
.append(&#x22;svg&#x22;)
.attr(&#x22;style&#x22;, &#x22;max-width: none; max-height: none&#x22;)
.attr(&#x22;width&#x22;, width)
.attr(&#x22;height&#x22;, height);

var web = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;web&#x22;)
.selectAll(&#x22;line&#x22;)
.data(graph.pauli_web)
.enter().append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, function(d) { return webColor(d.t); })
.attr(&#x22;fill&#x22;, &#x22;transparent&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 7px&#x22;);

var link = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;link&#x22;)
.selectAll(&#x22;line&#x22;)
.data(graph.links)
.enter().append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, function(d) { return edgeColor(d.t); })
.attr(&#x22;fill&#x22;, &#x22;transparent&#x22;)
.attr(&#x22;style&#x22;, function(d) { return isBoldEdge(d.t) ? &#x22;stroke-width: 3.5px&#x22; : &#x22;stroke-width: 1.5px&#x22;; });

var brush = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;brush&#x22;);

var node = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;node&#x22;)
.selectAll(&#x22;g&#x22;)
.data(graph.nodes)
.enter().append(&#x22;g&#x22;)
.attr(&#x22;transform&#x22;, function(d) {
return &#x22;translate(&#x22; + d.x + &#x22;,&#x22; + d.y +&#x22;)&#x22;;
});

// Draw a ground symbol connected to the node.
node.filter(function(d) { return d.ground; })
.append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 1.5px&#x22;)
.attr(&#x22;fill&#x22;, &#x22;none&#x22;)
.attr(&#x22;d&#x22;, &#x22;M 0 0 L 0 &#x22;+(groundOffset))
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);
node.filter(function(d) { return d.ground; })
.append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 1.5px&#x22;)
.attr(&#x22;fill&#x22;, &#x22;none&#x22;)
.attr(&#x22;d&#x22;, d3.symbol().type(symbolGround).size(node_size*1.5))
.attr(&#x22;transform&#x22;, &#x22;translate(0,&#x22;+groundOffset+&#x22;)&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

node.filter(function(d) { return d.t != 3 && d.t != 5 && d.t != 6; })
.append(&#x22;circle&#x22;)
.attr(&#x22;r&#x22;, function(d) {
if (d.t == 0) return 0.5 * node_size;
else if (d.t == 4) return 0.25 * node_size;
else return node_size;
})
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;stroke-width&#x22;, function(d) { return (d.t == 7 || d.t == 8) ? 3 : 1.5; })
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

var hbox = node.filter(function(d) { return d.t == 3; });

hbox.append(&#x22;rect&#x22;)
.attr(&#x22;x&#x22;, -0.75 * node_size).attr(&#x22;y&#x22;, -0.75 * node_size)
.attr(&#x22;width&#x22;, node_size * 1.5).attr(&#x22;height&#x22;, node_size * 1.5)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

// draw a triangle for d.t == 5
node.filter(function(d) { return d.t == 5; })
.append(&#x22;path&#x22;)
.attr(&#x22;d&#x22;, &#x22;M 0 0 L &#x22;+node_size+&#x22; &#x22;+node_size+&#x22; L -&#x22;+node_size+&#x22; &#x22;+node_size+&#x22; Z&#x22;)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;)
.attr(&#x22;transform&#x22;, &#x22;translate(&#x22; + (-node_size/2) + &#x22;, 0) rotate(-90)&#x22;);

// draw a square for Z box: d.t == 6
node.filter(function(d) { return d.t == 6; })
.append(&#x22;rect&#x22;)
.attr(&#x22;x&#x22;, -0.75 * node_size).attr(&#x22;y&#x22;, -0.75 * node_size)
.attr(&#x22;width&#x22;, node_size * 1.5).attr(&#x22;height&#x22;, node_size * 1.5)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

node.filter(function(d) { return d.phase != '' && d.phase.indexOf('[') === -1; })
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, 0.7 * node_size + 14)
.text(function (d) { return d.phase })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;12px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#00d&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');

node.filter(function(d) { return d.phase != '' && d.phase.indexOf('[') !== -1; })
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, -0.7 * node_size - 8)
.text(function (d) { return d.phase })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;12px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;black&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');

if (show_labels) {
node.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, -0.7 * node_size - 8)
.text(function (d) { return d.name; })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;10px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#999&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');
}

// Display the chosen data fields over the node.
node.filter(d => d.vdata.length > 0)
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, d => -0.7 * node_size - 14 - 10 * d.vdata.length)
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;8px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#c66&#x22;)
.attr('style', 'pointer-events: none; user-select: none;')
.selectAll(&#x22;tspan&#x22;)
.data(d => d.vdata)
.enter()
.append(&#x22;tspan&#x22;)
.attr(&#x22;x&#x22;, &#x22;0&#x22;)
.attr(&#x22;dy&#x22;, &#x22;1.2em&#x22;)
.text(x => x.join(&#x22;: &#x22;));

if (scalar_str != &#x22;&#x22;) {
svg.append(&#x22;text&#x22;)
.text(scalar_str)
.attr(&#x22;x&#x22;, 60).attr(&#x22;y&#x22;, 40)
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
}

function update_hboxes() {
if (auto_hbox) {
var pos = {};
hbox.attr(&#x22;transform&#x22;, function(d) {
// calculate barycenter of non-hbox neighbours, then nudge a bit
// to the NE.
var x=0,y=0,sz=0;
for (var i = 0; i < d.nhd.length; ++i) {
if (d.nhd[i].t != 3) {
sz++;
x += d.nhd[i].x;
y += d.nhd[i].y;
}
}

offset = 0.25 * scale;

if (sz != 0) {
x = (x/sz) + offset;
y = (y/sz) - offset;

while (pos[[x,y]]) {
x += offset;
}
d.x = x;
d.y = y;
pos[[x,y]] = true;
}

return &#x22;translate(&#x22;+d.x+&#x22;,&#x22;+d.y+&#x22;)&#x22;;
});
}
}

update_hboxes();

var link_curve = function(d) {
var x1 = d.source.x, x2 = d.target.x, y1 = d.source.y, y2 = d.target.y;
if (x1 == x2 && y1 == y2 && d.num_parallel == 1) {
var cx1 = x1 - 40;
var cy1 = y1 - 40;
var cx2 = x1 + 40;
var cy2 = y1 - 40;
return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
} else if (x1 == x2 && y1 == y2) {
var pos = d.index + 1;
var cx1 = x1 - 20 - pos * 10;
var cy1 = y1 - 20 - pos * 10;
var cx2 = x1 + 20 + pos * 10;
var cy2 = y1 - 20 - pos * 10;
return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
} else if (d.num_parallel == 1) {
return `M ${x1} ${y1} L ${x2} ${y2}`;
} else {
var dx = x2 - x1, dy = y2 - y1;
var midx = 0.5 * (x1 + x2), midy = 0.5 * (y1 + y2);
var pos = (d.index / (d.num_parallel-1)) - 0.5;
var cx = midx - pos * dy;
var cy = midy + pos * dx;
return `M ${x1} ${y1} Q ${cx} ${cy}, ${x2} ${y2}`;
// return `M ${x1} ${y1} L ${x2} ${y2}`;
}
};
link.attr(&#x22;d&#x22;, link_curve);


var web_curve = function(d) {
var x1 = d.source.x, x2 = (x1 + d.target.x)/2, y1 = d.source.y, y2 = (y1 + d.target.y)/2;
return `M ${x1} ${y1} L ${x2} ${y2}`;
}
web.attr(&#x22;d&#x22;, web_curve);

// EVENTS FOR DRAGGING AND SELECTION

node.on(&#x22;mousedown&#x22;, function(d) {
if (shiftKey) {
d3.select(this).selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, nodeStyle(d.selected = !d.selected, d.t));
d3.event.stopImmediatePropagation();
} else if (!d.selected) {
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(p) { return nodeStyle(p.selected = d === p, p.t); });
}
})
.call(d3.drag().on(&#x22;drag&#x22;, function(d) {
var dx = d3.event.dx;
var dy = d3.event.dy;
// node.filter(function(d) { return d.selected; })
//     .attr(&#x22;cx&#x22;, function(d) { return d.x += dx; })
//     .attr(&#x22;cy&#x22;, function(d) { return d.y += dy; });
node.filter(function(d) { return d.selected; })
.attr(&#x22;transform&#x22;, function(d) {
d.x += dx;
d.y += dy;
return &#x22;translate(&#x22; + d.x + &#x22;,&#x22; + d.y +&#x22;)&#x22;;
});

update_hboxes();

link.filter(function(d) { return d.source.selected || d.target.selected ||
(auto_hbox && d.source.t == 3); })
.attr(&#x22;d&#x22;, link_curve);
web.filter(function(d) { return d.source.selected || d.target.selected; })
.attr(&#x22;d&#x22;, web_curve);
}));

brush.call(d3.brush().keyModifiers(false)
.extent([[0, 0], [width, height]])
.on(&#x22;start&#x22;, function() {
if (d3.event.sourceEvent.type !== &#x22;end&#x22;) {
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(d) {
return nodeStyle(
d.selected = d.previouslySelected = shiftKey &&
d.selected, d.t);
});
}
})
.on(&#x22;brush&#x22;, function() {
if (d3.event.sourceEvent.type !== &#x22;end&#x22;) {
var selection = d3.event.selection;
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(d) {
return nodeStyle(d.selected = d.previouslySelected ^
(selection != null
&& selection[0][0] <= d.x && d.x < selection[1][0]
&& selection[0][1] <= d.y && d.y < selection[1][1]), d.t);
});
}
})
.on(&#x22;end&#x22;, function() {
if (d3.event.selection != null) {
d3.select(this).call(d3.event.target.move, null);
}
}));
}


showGraph('#graph-output-001',
JSON.parse('{&#x22;nodes&#x22;: [{&#x22;name&#x22;: &#x22;0&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;1&#x22;, &#x22;x&#x22;: 150.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 7, &#x22;phase&#x22;: &#x22;\u03c0/4&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;2&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;3&#x22;, &#x22;x&#x22;: 200.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 8, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;4&#x22;, &#x22;x&#x22;: 200.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 7, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;5&#x22;, &#x22;x&#x22;: 250.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 7, &#x22;phase&#x22;: &#x22;e0&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;6&#x22;, &#x22;x&#x22;: 250.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 7, &#x22;phase&#x22;: &#x22;e2&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;7&#x22;, &#x22;x&#x22;: 300.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 8, &#x22;phase&#x22;: &#x22;e1&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;8&#x22;, &#x22;x&#x22;: 400.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;rec[0]&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;9&#x22;, &#x22;x&#x22;: 300.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 8, &#x22;phase&#x22;: &#x22;e3&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;10&#x22;, &#x22;x&#x22;: 350.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 7, &#x22;phase&#x22;: &#x22;\u03c0/5&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;11&#x22;, &#x22;x&#x22;: 400.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;rec[1]&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;12&#x22;, &#x22;x&#x22;: 450.0, &#x22;y&#x22;: 225.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;13&#x22;, &#x22;x&#x22;: 450.0, &#x22;y&#x22;: 275.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;14&#x22;, &#x22;x&#x22;: 375.0, &#x22;y&#x22;: 175.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 2, &#x22;phase&#x22;: &#x22;det[0]&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;15&#x22;, &#x22;x&#x22;: 425.0, &#x22;y&#x22;: 175.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 2, &#x22;phase&#x22;: &#x22;obs[0]&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;16&#x22;, &#x22;x&#x22;: 375.0, &#x22;y&#x22;: 125.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;17&#x22;, &#x22;x&#x22;: 425.0, &#x22;y&#x22;: 100.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}], &#x22;links&#x22;: [{&#x22;source&#x22;: &#x22;0&#x22;, &#x22;target&#x22;: &#x22;1&#x22;, &#x22;t&#x22;: 5, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;1&#x22;, &#x22;target&#x22;: &#x22;4&#x22;, &#x22;t&#x22;: 5, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;2&#x22;, &#x22;target&#x22;: &#x22;3&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;3&#x22;, &#x22;target&#x22;: &#x22;6&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;3&#x22;, &#x22;target&#x22;: &#x22;4&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;4&#x22;, &#x22;target&#x22;: &#x22;5&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;5&#x22;, &#x22;target&#x22;: &#x22;7&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;6&#x22;, &#x22;target&#x22;: &#x22;9&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;7&#x22;, &#x22;target&#x22;: &#x22;8&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;12&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;14&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;9&#x22;, &#x22;target&#x22;: &#x22;10&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;10&#x22;, &#x22;target&#x22;: &#x22;11&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;11&#x22;, &#x22;target&#x22;: &#x22;13&#x22;, &#x22;t&#x22;: 4, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;11&#x22;, &#x22;target&#x22;: &#x22;14&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;11&#x22;, &#x22;target&#x22;: &#x22;15&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;14&#x22;, &#x22;target&#x22;: &#x22;16&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;15&#x22;, &#x22;target&#x22;: &#x22;17&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}], &#x22;pauli_web&#x22;: []}'), 500, 325.0, 50,
10.0, false, false, '');
</script></body></html>"
  width="100%"
  height="337"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="ZX diagram 1"
  loading="lazy"
/>

The `pyzx-meas` and `pyzx-dets` diagrams show ZX diagrams where outputs represent probabilities of measurement outcomes for measurement and detector/observables, respectively.

```python theme={null}
c.diagram("pyzx-meas", scale_horizontally=2);
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}[id^=&#x22;graph-output-&#x22;]{width:100%;height:100%;overflow:auto;box-sizing:border-box;}</style></head><body><div style=&#x22;overflow:auto; background-color: white&#x22; id=&#x22;graph-output-002&#x22;></div><script type=&#x22;module&#x22;>
var d3;
if (d3 == null) { d3 = await import(&#x22;https://esm.sh/d3@5&#x22;); }
var _settings_colors = JSON.parse('{&#x22;edge&#x22;: &#x22;#000000&#x22;, &#x22;Hedge&#x22;: &#x22;#0088ff&#x22;, &#x22;Xedge&#x22;: &#x22;#999999&#x22;, &#x22;Bedge&#x22;: &#x22;#000000&#x22;, &#x22;HBedge&#x22;: &#x22;#0088ff&#x22;, &#x22;boundary&#x22;: &#x22;#000000&#x22;, &#x22;X&#x22;: &#x22;#ff8888&#x22;, &#x22;Y&#x22;: &#x22;#aabbff&#x22;, &#x22;Z&#x22;: &#x22;#ccffcc&#x22;, &#x22;H&#x22;: &#x22;#ffff66&#x22;, &#x22;W&#x22;: &#x22;#000000&#x22;, &#x22;Zalt&#x22;: &#x22;#ccffcc&#x22;, &#x22;Walt&#x22;: &#x22;#000000&#x22;, &#x22;Zbold&#x22;: &#x22;#ccffcc&#x22;, &#x22;Xbold&#x22;: &#x22;#ff8888&#x22;, &#x22;Xdark&#x22;: &#x22;#ff8888&#x22;, &#x22;Ydark&#x22;: &#x22;#aabbff&#x22;, &#x22;Zdark&#x22;: &#x22;#99dd99&#x22;}');
// PyZX - Python library for quantum circuit rewriting 
//        and optimisation using the ZX-calculus
// Copyright (C) 2018 - Aleks Kissinger and John van de Wetering

// Licensed under the Apache License, Version 2.0 (the &#x22;License&#x22;);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//    http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an &#x22;AS IS&#x22; BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// styling functions
function nodeColor(t) {
if (t == 0) return _settings_colors['boundary'];
else if (t == 1) return _settings_colors['Z']; // &#x22;#ccffcc&#x22;;
else if (t == 2) return _settings_colors['X']; // &#x22;#ff8888&#x22;;
else if (t == 3) return _settings_colors['H']; // &#x22;yellow&#x22;;
else if (t == 4) return _settings_colors['W']; // &#x22;black&#x22;;
else if (t == 5) return _settings_colors['Walt']; // &#x22;black&#x22;;
else if (t == 6) return _settings_colors['Zalt']; // &#x22;#ccffcc&#x22;;
else if (t == 7) return _settings_colors['Zbold']; // &#x22;#ccffcc&#x22; bold Z
else if (t == 8) return _settings_colors['Xbold']; // &#x22;#ff8888&#x22; bold X
}

function edgeColor(t) {
if (t == 1) return _settings_colors['edge']; //&#x22;black&#x22;;
else if (t == 2) return _settings_colors['Hedge']; // &#x22;#08f&#x22;;
else if (t == 3) return _settings_colors['Xedge']; // &#x22;gray&#x22;;
else if (t == 4) return _settings_colors['Bedge']; // &#x22;black&#x22; bold
else if (t == 5) return _settings_colors['HBedge']; // &#x22;#0088ff&#x22; bold hadamard
}

function isBoldEdge(t) {
return t == 4 || t == 5;
}

function webColor(t) {
if (t == 'X') return _settings_colors['Xdark'];
else if (t == 'Y') return _settings_colors['Ydark'];
else if (t == 'Z') return _settings_colors['Zdark'];
else if (t == 'I') return '#dddddd';
}

function nodeStyle(selected, t) {
var bold = (t == 7 || t == 8);
if (selected) return &#x22;stroke-width: &#x22; + (bold ? &#x22;4&#x22; : &#x22;2&#x22;) + &#x22;px; stroke: #00f&#x22;;
return &#x22;stroke-width: &#x22; + (bold ? &#x22;3&#x22; : &#x22;1.5&#x22;) + &#x22;px&#x22;;
}

var symbolGround = {
draw: function(context, size){
let s = size/2;

context.moveTo(0,-s);
context.lineTo(0,0);

context.moveTo(-s,0);
context.lineTo(s,0);

context.moveTo(-2*s/3,s/3);
context.lineTo(2*s/3,s/3);

context.moveTo(-s/3,2*s/3);
context.lineTo(s/3,2*s/3);
}
}

function showGraph(tag, graph, width, height, scale, node_size, auto_hbox, show_labels, scalar_str) {
var ntab = {};

var groundOffset = 2.5 * node_size;

graph.nodes.forEach(function(d) {
ntab[d.name] = d;
d.selected = false;
d.previouslySelected = false;
d.nhd = [];
});

var spiders_and_boundaries = graph.nodes.filter(function(d) {
return d.t != 3;
});

graph.links.forEach(function(d) {
var s = ntab[d.source];
var t = ntab[d.target];
d.source = s;
d.target = t;
s.nhd.push(t);
t.nhd.push(s);
});

graph.pauli_web.forEach(function(d) {
var s = ntab[d.source];
var t = ntab[d.target];
d.source = s;
d.target = t;
});

var shiftKey;

// SETUP SVG ITEMS

var svg = d3.select(tag)
//.attr(&#x22;tabindex&#x22;, 1)
.on(&#x22;keydown.brush&#x22;, function() {shiftKey = d3.event.shiftKey || d3.event.metaKey;})
.on(&#x22;keyup.brush&#x22;, function() {shiftKey = d3.event.shiftKey || d3.event.metaKey;})
//.each(function() { this.focus(); })
.append(&#x22;svg&#x22;)
.attr(&#x22;style&#x22;, &#x22;max-width: none; max-height: none&#x22;)
.attr(&#x22;width&#x22;, width)
.attr(&#x22;height&#x22;, height);

var web = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;web&#x22;)
.selectAll(&#x22;line&#x22;)
.data(graph.pauli_web)
.enter().append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, function(d) { return webColor(d.t); })
.attr(&#x22;fill&#x22;, &#x22;transparent&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 7px&#x22;);

var link = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;link&#x22;)
.selectAll(&#x22;line&#x22;)
.data(graph.links)
.enter().append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, function(d) { return edgeColor(d.t); })
.attr(&#x22;fill&#x22;, &#x22;transparent&#x22;)
.attr(&#x22;style&#x22;, function(d) { return isBoldEdge(d.t) ? &#x22;stroke-width: 3.5px&#x22; : &#x22;stroke-width: 1.5px&#x22;; });

var brush = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;brush&#x22;);

var node = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;node&#x22;)
.selectAll(&#x22;g&#x22;)
.data(graph.nodes)
.enter().append(&#x22;g&#x22;)
.attr(&#x22;transform&#x22;, function(d) {
return &#x22;translate(&#x22; + d.x + &#x22;,&#x22; + d.y +&#x22;)&#x22;;
});

// Draw a ground symbol connected to the node.
node.filter(function(d) { return d.ground; })
.append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 1.5px&#x22;)
.attr(&#x22;fill&#x22;, &#x22;none&#x22;)
.attr(&#x22;d&#x22;, &#x22;M 0 0 L 0 &#x22;+(groundOffset))
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);
node.filter(function(d) { return d.ground; })
.append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 1.5px&#x22;)
.attr(&#x22;fill&#x22;, &#x22;none&#x22;)
.attr(&#x22;d&#x22;, d3.symbol().type(symbolGround).size(node_size*1.5))
.attr(&#x22;transform&#x22;, &#x22;translate(0,&#x22;+groundOffset+&#x22;)&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

node.filter(function(d) { return d.t != 3 && d.t != 5 && d.t != 6; })
.append(&#x22;circle&#x22;)
.attr(&#x22;r&#x22;, function(d) {
if (d.t == 0) return 0.5 * node_size;
else if (d.t == 4) return 0.25 * node_size;
else return node_size;
})
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;stroke-width&#x22;, function(d) { return (d.t == 7 || d.t == 8) ? 3 : 1.5; })
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

var hbox = node.filter(function(d) { return d.t == 3; });

hbox.append(&#x22;rect&#x22;)
.attr(&#x22;x&#x22;, -0.75 * node_size).attr(&#x22;y&#x22;, -0.75 * node_size)
.attr(&#x22;width&#x22;, node_size * 1.5).attr(&#x22;height&#x22;, node_size * 1.5)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

// draw a triangle for d.t == 5
node.filter(function(d) { return d.t == 5; })
.append(&#x22;path&#x22;)
.attr(&#x22;d&#x22;, &#x22;M 0 0 L &#x22;+node_size+&#x22; &#x22;+node_size+&#x22; L -&#x22;+node_size+&#x22; &#x22;+node_size+&#x22; Z&#x22;)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;)
.attr(&#x22;transform&#x22;, &#x22;translate(&#x22; + (-node_size/2) + &#x22;, 0) rotate(-90)&#x22;);

// draw a square for Z box: d.t == 6
node.filter(function(d) { return d.t == 6; })
.append(&#x22;rect&#x22;)
.attr(&#x22;x&#x22;, -0.75 * node_size).attr(&#x22;y&#x22;, -0.75 * node_size)
.attr(&#x22;width&#x22;, node_size * 1.5).attr(&#x22;height&#x22;, node_size * 1.5)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

node.filter(function(d) { return d.phase != '' && d.phase.indexOf('[') === -1; })
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, 0.7 * node_size + 14)
.text(function (d) { return d.phase })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;12px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#00d&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');

node.filter(function(d) { return d.phase != '' && d.phase.indexOf('[') !== -1; })
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, -0.7 * node_size - 8)
.text(function (d) { return d.phase })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;12px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;black&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');

if (show_labels) {
node.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, -0.7 * node_size - 8)
.text(function (d) { return d.name; })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;10px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#999&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');
}

// Display the chosen data fields over the node.
node.filter(d => d.vdata.length > 0)
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, d => -0.7 * node_size - 14 - 10 * d.vdata.length)
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;8px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#c66&#x22;)
.attr('style', 'pointer-events: none; user-select: none;')
.selectAll(&#x22;tspan&#x22;)
.data(d => d.vdata)
.enter()
.append(&#x22;tspan&#x22;)
.attr(&#x22;x&#x22;, &#x22;0&#x22;)
.attr(&#x22;dy&#x22;, &#x22;1.2em&#x22;)
.text(x => x.join(&#x22;: &#x22;));

if (scalar_str != &#x22;&#x22;) {
svg.append(&#x22;text&#x22;)
.text(scalar_str)
.attr(&#x22;x&#x22;, 60).attr(&#x22;y&#x22;, 40)
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
}

function update_hboxes() {
if (auto_hbox) {
var pos = {};
hbox.attr(&#x22;transform&#x22;, function(d) {
// calculate barycenter of non-hbox neighbours, then nudge a bit
// to the NE.
var x=0,y=0,sz=0;
for (var i = 0; i < d.nhd.length; ++i) {
if (d.nhd[i].t != 3) {
sz++;
x += d.nhd[i].x;
y += d.nhd[i].y;
}
}

offset = 0.25 * scale;

if (sz != 0) {
x = (x/sz) + offset;
y = (y/sz) - offset;

while (pos[[x,y]]) {
x += offset;
}
d.x = x;
d.y = y;
pos[[x,y]] = true;
}

return &#x22;translate(&#x22;+d.x+&#x22;,&#x22;+d.y+&#x22;)&#x22;;
});
}
}

update_hboxes();

var link_curve = function(d) {
var x1 = d.source.x, x2 = d.target.x, y1 = d.source.y, y2 = d.target.y;
if (x1 == x2 && y1 == y2 && d.num_parallel == 1) {
var cx1 = x1 - 40;
var cy1 = y1 - 40;
var cx2 = x1 + 40;
var cy2 = y1 - 40;
return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
} else if (x1 == x2 && y1 == y2) {
var pos = d.index + 1;
var cx1 = x1 - 20 - pos * 10;
var cy1 = y1 - 20 - pos * 10;
var cx2 = x1 + 20 + pos * 10;
var cy2 = y1 - 20 - pos * 10;
return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
} else if (d.num_parallel == 1) {
return `M ${x1} ${y1} L ${x2} ${y2}`;
} else {
var dx = x2 - x1, dy = y2 - y1;
var midx = 0.5 * (x1 + x2), midy = 0.5 * (y1 + y2);
var pos = (d.index / (d.num_parallel-1)) - 0.5;
var cx = midx - pos * dy;
var cy = midy + pos * dx;
return `M ${x1} ${y1} Q ${cx} ${cy}, ${x2} ${y2}`;
// return `M ${x1} ${y1} L ${x2} ${y2}`;
}
};
link.attr(&#x22;d&#x22;, link_curve);


var web_curve = function(d) {
var x1 = d.source.x, x2 = (x1 + d.target.x)/2, y1 = d.source.y, y2 = (y1 + d.target.y)/2;
return `M ${x1} ${y1} L ${x2} ${y2}`;
}
web.attr(&#x22;d&#x22;, web_curve);

// EVENTS FOR DRAGGING AND SELECTION

node.on(&#x22;mousedown&#x22;, function(d) {
if (shiftKey) {
d3.select(this).selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, nodeStyle(d.selected = !d.selected, d.t));
d3.event.stopImmediatePropagation();
} else if (!d.selected) {
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(p) { return nodeStyle(p.selected = d === p, p.t); });
}
})
.call(d3.drag().on(&#x22;drag&#x22;, function(d) {
var dx = d3.event.dx;
var dy = d3.event.dy;
// node.filter(function(d) { return d.selected; })
//     .attr(&#x22;cx&#x22;, function(d) { return d.x += dx; })
//     .attr(&#x22;cy&#x22;, function(d) { return d.y += dy; });
node.filter(function(d) { return d.selected; })
.attr(&#x22;transform&#x22;, function(d) {
d.x += dx;
d.y += dy;
return &#x22;translate(&#x22; + d.x + &#x22;,&#x22; + d.y +&#x22;)&#x22;;
});

update_hboxes();

link.filter(function(d) { return d.source.selected || d.target.selected ||
(auto_hbox && d.source.t == 3); })
.attr(&#x22;d&#x22;, link_curve);
web.filter(function(d) { return d.source.selected || d.target.selected; })
.attr(&#x22;d&#x22;, web_curve);
}));

brush.call(d3.brush().keyModifiers(false)
.extent([[0, 0], [width, height]])
.on(&#x22;start&#x22;, function() {
if (d3.event.sourceEvent.type !== &#x22;end&#x22;) {
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(d) {
return nodeStyle(
d.selected = d.previouslySelected = shiftKey &&
d.selected, d.t);
});
}
})
.on(&#x22;brush&#x22;, function() {
if (d3.event.sourceEvent.type !== &#x22;end&#x22;) {
var selection = d3.event.selection;
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(d) {
return nodeStyle(d.selected = d.previouslySelected ^
(selection != null
&& selection[0][0] <= d.x && d.x < selection[1][0]
&& selection[0][1] <= d.y && d.y < selection[1][1]), d.t);
});
}
})
.on(&#x22;end&#x22;, function() {
if (d3.event.selection != null) {
d3.select(this).call(d3.event.target.move, null);
}
}));
}


showGraph('#graph-output-002',
JSON.parse('{&#x22;nodes&#x22;: [{&#x22;name&#x22;: &#x22;1&#x22;, &#x22;x&#x22;: 150.0, &#x22;y&#x22;: 100.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;\u03c0/4 + f1&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;8&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 150.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;9&#x22;, &#x22;x&#x22;: 150.0, &#x22;y&#x22;: 150.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;f0&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;14&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 100.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;7\u03c0/4 + f1&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;28&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 200.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;29&#x22;, &#x22;x&#x22;: 150.0, &#x22;y&#x22;: 200.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}], &#x22;links&#x22;: [{&#x22;source&#x22;: &#x22;1&#x22;, &#x22;target&#x22;: &#x22;8&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;28&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;14&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;9&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;9&#x22;, &#x22;target&#x22;: &#x22;29&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}], &#x22;pauli_web&#x22;: []}'), 200, 250, 50,
10.0, false, false, '');
</script></body></html>"
  width="100%"
  height="262"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="ZX diagram 2"
  loading="lazy"
/>

```python theme={null}
c.diagram("pyzx-dets", scale_horizontally=1.5);
```

<iframe
  srcDoc="<!doctype html><html><head><meta charset=&#x22;utf-8&#x22;><style>html,body{margin:0;padding:0;height:100%;overflow:hidden;}[id^=&#x22;graph-output-&#x22;]{width:100%;height:100%;overflow:auto;box-sizing:border-box;}</style></head><body><div style=&#x22;overflow:auto; background-color: white&#x22; id=&#x22;graph-output-003&#x22;></div><script type=&#x22;module&#x22;>
var d3;
if (d3 == null) { d3 = await import(&#x22;https://esm.sh/d3@5&#x22;); }
var _settings_colors = JSON.parse('{&#x22;edge&#x22;: &#x22;#000000&#x22;, &#x22;Hedge&#x22;: &#x22;#0088ff&#x22;, &#x22;Xedge&#x22;: &#x22;#999999&#x22;, &#x22;Bedge&#x22;: &#x22;#000000&#x22;, &#x22;HBedge&#x22;: &#x22;#0088ff&#x22;, &#x22;boundary&#x22;: &#x22;#000000&#x22;, &#x22;X&#x22;: &#x22;#ff8888&#x22;, &#x22;Y&#x22;: &#x22;#aabbff&#x22;, &#x22;Z&#x22;: &#x22;#ccffcc&#x22;, &#x22;H&#x22;: &#x22;#ffff66&#x22;, &#x22;W&#x22;: &#x22;#000000&#x22;, &#x22;Zalt&#x22;: &#x22;#ccffcc&#x22;, &#x22;Walt&#x22;: &#x22;#000000&#x22;, &#x22;Zbold&#x22;: &#x22;#ccffcc&#x22;, &#x22;Xbold&#x22;: &#x22;#ff8888&#x22;, &#x22;Xdark&#x22;: &#x22;#ff8888&#x22;, &#x22;Ydark&#x22;: &#x22;#aabbff&#x22;, &#x22;Zdark&#x22;: &#x22;#99dd99&#x22;}');
// PyZX - Python library for quantum circuit rewriting 
//        and optimisation using the ZX-calculus
// Copyright (C) 2018 - Aleks Kissinger and John van de Wetering

// Licensed under the Apache License, Version 2.0 (the &#x22;License&#x22;);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//    http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an &#x22;AS IS&#x22; BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// styling functions
function nodeColor(t) {
if (t == 0) return _settings_colors['boundary'];
else if (t == 1) return _settings_colors['Z']; // &#x22;#ccffcc&#x22;;
else if (t == 2) return _settings_colors['X']; // &#x22;#ff8888&#x22;;
else if (t == 3) return _settings_colors['H']; // &#x22;yellow&#x22;;
else if (t == 4) return _settings_colors['W']; // &#x22;black&#x22;;
else if (t == 5) return _settings_colors['Walt']; // &#x22;black&#x22;;
else if (t == 6) return _settings_colors['Zalt']; // &#x22;#ccffcc&#x22;;
else if (t == 7) return _settings_colors['Zbold']; // &#x22;#ccffcc&#x22; bold Z
else if (t == 8) return _settings_colors['Xbold']; // &#x22;#ff8888&#x22; bold X
}

function edgeColor(t) {
if (t == 1) return _settings_colors['edge']; //&#x22;black&#x22;;
else if (t == 2) return _settings_colors['Hedge']; // &#x22;#08f&#x22;;
else if (t == 3) return _settings_colors['Xedge']; // &#x22;gray&#x22;;
else if (t == 4) return _settings_colors['Bedge']; // &#x22;black&#x22; bold
else if (t == 5) return _settings_colors['HBedge']; // &#x22;#0088ff&#x22; bold hadamard
}

function isBoldEdge(t) {
return t == 4 || t == 5;
}

function webColor(t) {
if (t == 'X') return _settings_colors['Xdark'];
else if (t == 'Y') return _settings_colors['Ydark'];
else if (t == 'Z') return _settings_colors['Zdark'];
else if (t == 'I') return '#dddddd';
}

function nodeStyle(selected, t) {
var bold = (t == 7 || t == 8);
if (selected) return &#x22;stroke-width: &#x22; + (bold ? &#x22;4&#x22; : &#x22;2&#x22;) + &#x22;px; stroke: #00f&#x22;;
return &#x22;stroke-width: &#x22; + (bold ? &#x22;3&#x22; : &#x22;1.5&#x22;) + &#x22;px&#x22;;
}

var symbolGround = {
draw: function(context, size){
let s = size/2;

context.moveTo(0,-s);
context.lineTo(0,0);

context.moveTo(-s,0);
context.lineTo(s,0);

context.moveTo(-2*s/3,s/3);
context.lineTo(2*s/3,s/3);

context.moveTo(-s/3,2*s/3);
context.lineTo(s/3,2*s/3);
}
}

function showGraph(tag, graph, width, height, scale, node_size, auto_hbox, show_labels, scalar_str) {
var ntab = {};

var groundOffset = 2.5 * node_size;

graph.nodes.forEach(function(d) {
ntab[d.name] = d;
d.selected = false;
d.previouslySelected = false;
d.nhd = [];
});

var spiders_and_boundaries = graph.nodes.filter(function(d) {
return d.t != 3;
});

graph.links.forEach(function(d) {
var s = ntab[d.source];
var t = ntab[d.target];
d.source = s;
d.target = t;
s.nhd.push(t);
t.nhd.push(s);
});

graph.pauli_web.forEach(function(d) {
var s = ntab[d.source];
var t = ntab[d.target];
d.source = s;
d.target = t;
});

var shiftKey;

// SETUP SVG ITEMS

var svg = d3.select(tag)
//.attr(&#x22;tabindex&#x22;, 1)
.on(&#x22;keydown.brush&#x22;, function() {shiftKey = d3.event.shiftKey || d3.event.metaKey;})
.on(&#x22;keyup.brush&#x22;, function() {shiftKey = d3.event.shiftKey || d3.event.metaKey;})
//.each(function() { this.focus(); })
.append(&#x22;svg&#x22;)
.attr(&#x22;style&#x22;, &#x22;max-width: none; max-height: none&#x22;)
.attr(&#x22;width&#x22;, width)
.attr(&#x22;height&#x22;, height);

var web = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;web&#x22;)
.selectAll(&#x22;line&#x22;)
.data(graph.pauli_web)
.enter().append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, function(d) { return webColor(d.t); })
.attr(&#x22;fill&#x22;, &#x22;transparent&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 7px&#x22;);

var link = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;link&#x22;)
.selectAll(&#x22;line&#x22;)
.data(graph.links)
.enter().append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, function(d) { return edgeColor(d.t); })
.attr(&#x22;fill&#x22;, &#x22;transparent&#x22;)
.attr(&#x22;style&#x22;, function(d) { return isBoldEdge(d.t) ? &#x22;stroke-width: 3.5px&#x22; : &#x22;stroke-width: 1.5px&#x22;; });

var brush = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;brush&#x22;);

var node = svg.append(&#x22;g&#x22;)
.attr(&#x22;class&#x22;, &#x22;node&#x22;)
.selectAll(&#x22;g&#x22;)
.data(graph.nodes)
.enter().append(&#x22;g&#x22;)
.attr(&#x22;transform&#x22;, function(d) {
return &#x22;translate(&#x22; + d.x + &#x22;,&#x22; + d.y +&#x22;)&#x22;;
});

// Draw a ground symbol connected to the node.
node.filter(function(d) { return d.ground; })
.append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 1.5px&#x22;)
.attr(&#x22;fill&#x22;, &#x22;none&#x22;)
.attr(&#x22;d&#x22;, &#x22;M 0 0 L 0 &#x22;+(groundOffset))
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);
node.filter(function(d) { return d.ground; })
.append(&#x22;path&#x22;)
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;style&#x22;, &#x22;stroke-width: 1.5px&#x22;)
.attr(&#x22;fill&#x22;, &#x22;none&#x22;)
.attr(&#x22;d&#x22;, d3.symbol().type(symbolGround).size(node_size*1.5))
.attr(&#x22;transform&#x22;, &#x22;translate(0,&#x22;+groundOffset+&#x22;)&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

node.filter(function(d) { return d.t != 3 && d.t != 5 && d.t != 6; })
.append(&#x22;circle&#x22;)
.attr(&#x22;r&#x22;, function(d) {
if (d.t == 0) return 0.5 * node_size;
else if (d.t == 4) return 0.25 * node_size;
else return node_size;
})
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;stroke-width&#x22;, function(d) { return (d.t == 7 || d.t == 8) ? 3 : 1.5; })
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

var hbox = node.filter(function(d) { return d.t == 3; });

hbox.append(&#x22;rect&#x22;)
.attr(&#x22;x&#x22;, -0.75 * node_size).attr(&#x22;y&#x22;, -0.75 * node_size)
.attr(&#x22;width&#x22;, node_size * 1.5).attr(&#x22;height&#x22;, node_size * 1.5)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

// draw a triangle for d.t == 5
node.filter(function(d) { return d.t == 5; })
.append(&#x22;path&#x22;)
.attr(&#x22;d&#x22;, &#x22;M 0 0 L &#x22;+node_size+&#x22; &#x22;+node_size+&#x22; L -&#x22;+node_size+&#x22; &#x22;+node_size+&#x22; Z&#x22;)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;)
.attr(&#x22;transform&#x22;, &#x22;translate(&#x22; + (-node_size/2) + &#x22;, 0) rotate(-90)&#x22;);

// draw a square for Z box: d.t == 6
node.filter(function(d) { return d.t == 6; })
.append(&#x22;rect&#x22;)
.attr(&#x22;x&#x22;, -0.75 * node_size).attr(&#x22;y&#x22;, -0.75 * node_size)
.attr(&#x22;width&#x22;, node_size * 1.5).attr(&#x22;height&#x22;, node_size * 1.5)
.attr(&#x22;fill&#x22;, function(d) { return nodeColor(d.t); })
.attr(&#x22;stroke&#x22;, &#x22;black&#x22;)
.attr(&#x22;class&#x22;, &#x22;selectable&#x22;);

node.filter(function(d) { return d.phase != '' && d.phase.indexOf('[') === -1; })
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, 0.7 * node_size + 14)
.text(function (d) { return d.phase })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;12px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#00d&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');

node.filter(function(d) { return d.phase != '' && d.phase.indexOf('[') !== -1; })
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, -0.7 * node_size - 8)
.text(function (d) { return d.phase })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;12px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;black&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');

if (show_labels) {
node.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, -0.7 * node_size - 8)
.text(function (d) { return d.name; })
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;10px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#999&#x22;)
.attr('style', 'pointer-events: none; user-select: none;');
}

// Display the chosen data fields over the node.
node.filter(d => d.vdata.length > 0)
.append(&#x22;text&#x22;)
.attr(&#x22;y&#x22;, d => -0.7 * node_size - 14 - 10 * d.vdata.length)
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
.attr(&#x22;font-size&#x22;, &#x22;8px&#x22;)
.attr(&#x22;font-family&#x22;, &#x22;monospace&#x22;)
.attr(&#x22;fill&#x22;, &#x22;#c66&#x22;)
.attr('style', 'pointer-events: none; user-select: none;')
.selectAll(&#x22;tspan&#x22;)
.data(d => d.vdata)
.enter()
.append(&#x22;tspan&#x22;)
.attr(&#x22;x&#x22;, &#x22;0&#x22;)
.attr(&#x22;dy&#x22;, &#x22;1.2em&#x22;)
.text(x => x.join(&#x22;: &#x22;));

if (scalar_str != &#x22;&#x22;) {
svg.append(&#x22;text&#x22;)
.text(scalar_str)
.attr(&#x22;x&#x22;, 60).attr(&#x22;y&#x22;, 40)
.attr(&#x22;text-anchor&#x22;, &#x22;middle&#x22;)
}

function update_hboxes() {
if (auto_hbox) {
var pos = {};
hbox.attr(&#x22;transform&#x22;, function(d) {
// calculate barycenter of non-hbox neighbours, then nudge a bit
// to the NE.
var x=0,y=0,sz=0;
for (var i = 0; i < d.nhd.length; ++i) {
if (d.nhd[i].t != 3) {
sz++;
x += d.nhd[i].x;
y += d.nhd[i].y;
}
}

offset = 0.25 * scale;

if (sz != 0) {
x = (x/sz) + offset;
y = (y/sz) - offset;

while (pos[[x,y]]) {
x += offset;
}
d.x = x;
d.y = y;
pos[[x,y]] = true;
}

return &#x22;translate(&#x22;+d.x+&#x22;,&#x22;+d.y+&#x22;)&#x22;;
});
}
}

update_hboxes();

var link_curve = function(d) {
var x1 = d.source.x, x2 = d.target.x, y1 = d.source.y, y2 = d.target.y;
if (x1 == x2 && y1 == y2 && d.num_parallel == 1) {
var cx1 = x1 - 40;
var cy1 = y1 - 40;
var cx2 = x1 + 40;
var cy2 = y1 - 40;
return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
} else if (x1 == x2 && y1 == y2) {
var pos = d.index + 1;
var cx1 = x1 - 20 - pos * 10;
var cy1 = y1 - 20 - pos * 10;
var cx2 = x1 + 20 + pos * 10;
var cy2 = y1 - 20 - pos * 10;
return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
} else if (d.num_parallel == 1) {
return `M ${x1} ${y1} L ${x2} ${y2}`;
} else {
var dx = x2 - x1, dy = y2 - y1;
var midx = 0.5 * (x1 + x2), midy = 0.5 * (y1 + y2);
var pos = (d.index / (d.num_parallel-1)) - 0.5;
var cx = midx - pos * dy;
var cy = midy + pos * dx;
return `M ${x1} ${y1} Q ${cx} ${cy}, ${x2} ${y2}`;
// return `M ${x1} ${y1} L ${x2} ${y2}`;
}
};
link.attr(&#x22;d&#x22;, link_curve);


var web_curve = function(d) {
var x1 = d.source.x, x2 = (x1 + d.target.x)/2, y1 = d.source.y, y2 = (y1 + d.target.y)/2;
return `M ${x1} ${y1} L ${x2} ${y2}`;
}
web.attr(&#x22;d&#x22;, web_curve);

// EVENTS FOR DRAGGING AND SELECTION

node.on(&#x22;mousedown&#x22;, function(d) {
if (shiftKey) {
d3.select(this).selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, nodeStyle(d.selected = !d.selected, d.t));
d3.event.stopImmediatePropagation();
} else if (!d.selected) {
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(p) { return nodeStyle(p.selected = d === p, p.t); });
}
})
.call(d3.drag().on(&#x22;drag&#x22;, function(d) {
var dx = d3.event.dx;
var dy = d3.event.dy;
// node.filter(function(d) { return d.selected; })
//     .attr(&#x22;cx&#x22;, function(d) { return d.x += dx; })
//     .attr(&#x22;cy&#x22;, function(d) { return d.y += dy; });
node.filter(function(d) { return d.selected; })
.attr(&#x22;transform&#x22;, function(d) {
d.x += dx;
d.y += dy;
return &#x22;translate(&#x22; + d.x + &#x22;,&#x22; + d.y +&#x22;)&#x22;;
});

update_hboxes();

link.filter(function(d) { return d.source.selected || d.target.selected ||
(auto_hbox && d.source.t == 3); })
.attr(&#x22;d&#x22;, link_curve);
web.filter(function(d) { return d.source.selected || d.target.selected; })
.attr(&#x22;d&#x22;, web_curve);
}));

brush.call(d3.brush().keyModifiers(false)
.extent([[0, 0], [width, height]])
.on(&#x22;start&#x22;, function() {
if (d3.event.sourceEvent.type !== &#x22;end&#x22;) {
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(d) {
return nodeStyle(
d.selected = d.previouslySelected = shiftKey &&
d.selected, d.t);
});
}
})
.on(&#x22;brush&#x22;, function() {
if (d3.event.sourceEvent.type !== &#x22;end&#x22;) {
var selection = d3.event.selection;
node.selectAll(&#x22;.selectable&#x22;).attr(&#x22;style&#x22;, function(d) {
return nodeStyle(d.selected = d.previouslySelected ^
(selection != null
&& selection[0][0] <= d.x && d.x < selection[1][0]
&& selection[0][1] <= d.y && d.y < selection[1][1]), d.t);
});
}
})
.on(&#x22;end&#x22;, function() {
if (d3.event.selection != null) {
d3.select(this).call(d3.event.target.move, null);
}
}));
}


showGraph('#graph-output-003',
JSON.parse('{&#x22;nodes&#x22;: [{&#x22;name&#x22;: &#x22;1&#x22;, &#x22;x&#x22;: 200.0, &#x22;y&#x22;: 100.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;\u03c0/4 + f1&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;8&#x22;, &#x22;x&#x22;: 125.0, &#x22;y&#x22;: 150.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;12&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 250.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;f0&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;14&#x22;, &#x22;x&#x22;: 125.0, &#x22;y&#x22;: 100.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 1, &#x22;phase&#x22;: &#x22;7\u03c0/4 + f1&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;26&#x22;, &#x22;x&#x22;: 50.0, &#x22;y&#x22;: 200.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}, {&#x22;name&#x22;: &#x22;27&#x22;, &#x22;x&#x22;: 125.0, &#x22;y&#x22;: 175.0, &#x22;z&#x22;: 0.0, &#x22;t&#x22;: 0, &#x22;phase&#x22;: &#x22;&#x22;, &#x22;ground&#x22;: false, &#x22;vdata&#x22;: []}], &#x22;links&#x22;: [{&#x22;source&#x22;: &#x22;1&#x22;, &#x22;target&#x22;: &#x22;8&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;14&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;8&#x22;, &#x22;target&#x22;: &#x22;27&#x22;, &#x22;t&#x22;: 1, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}, {&#x22;source&#x22;: &#x22;12&#x22;, &#x22;target&#x22;: &#x22;26&#x22;, &#x22;t&#x22;: 2, &#x22;index&#x22;: 0, &#x22;num_parallel&#x22;: 1}], &#x22;pauli_web&#x22;: []}'), 250.0, 300, 50,
10.0, false, false, '');
</script></body></html>"
  width="100%"
  height="312"
  style={{border: "1px solid #eee", borderRadius: "0.5rem"}}
  title="ZX diagram 3"
  loading="lazy"
/>

## Detector Error Models

Tsim allows to compute detector error models from a circuit. The method `Circuit.detector_error_model()` computes a `stim.DetectorErrorModel` from the circuit. As opposed to Stim, detectors and observables need not be deterministic.

```python theme={null}
c = Circuit("""
    RX 0
    R 1
    CNOT 0 1
    DEPOLARIZE1(0.1) 0 1
    M 0 1
    DETECTOR rec[-1] rec[-2]
    DETECTOR rec[-1]
""")
c.detector_error_model()
```

```text title="Output" theme={null}
stim.DetectorErrorModel('''
    error(0.0666667) D0
    error(0.0666667) D0 D1
    error(0.5) D1
''')
```
