Skip to content

Commit

Permalink
Add initial det/obs support to crumble, plus other polish (#773)
Browse files Browse the repository at this point in the history
Tagalong Stim diagram improvements:

- Change 3d matchgraph diagrams to use a slightly more 3d indicator for
detectors
- Change matchgraph diagrams to not decompose if decomposition produces
any errors
- Change matchgraph diagrams to draw hypererrors that flip an observable
in purple, instead of in blue

Crumble improvements:

- Fix hitting 1-9 on an MPP operation not inferring that it should mark
every target of the operation in their basis
- Add initial support for detectors
    - `d+#` to turn a marked flow into a detector
    - `o+#` to turn a marked flow into an observable
- Draw detecting regions of dets and obs as small squares on qubits at
each moment in the timeslice, and between moment in the timeline
- `j+#` to pick an arbitrary det or obs with a detection region going
through the current selection, and turn it into a
- `k+#` to add markers to dissipative gates overlapping the propagating
flow in the current layer
marked flow
- Fix feedback operations not being correctly ignored, or causing
non-feedback parts of an operation to be discarded
- Polish the scrubber
    - Move it to run horizontally along the timeline
    - Add visual hints of what's in each layer
- Polish the visuals
    - Improve the indication of marker flows beyond 4
- Make timeline view justify left when near start of circuit, and
justify right when near end of circuit, to always show as much
information as possible
- Only show timeline-to-timeslice qubit position indicators when
hovering over that qubit in the timeline
    - Fade out unused qubits more
    - Set the default polygon alpha lower, so they are more faded
- Fix several instances of fuzzy drawing due to off-by-0.5 coordinates
- Draw example polygons and markers in the toolbox to better indicate
what `P` and `#` do
- Add quality of life controls
    - Fix needing to often hit cltr+z twice in order to undo once
- Fix clicking on an example circuit link resulting in the undo history
being lost
- Press `F` to flip two qubit gates (e.g. exchange target and control)
        - Moved `C_XYZ` gate from `F` to `c+t`
- Press `G` to reverse the order of layers starting from the current
layer ending at first empty layer
- Press `>`, `<`, `^`, `v` to translate coordinates in the indicated
direction
    - Press `.` to translate circuit downright one half step
    - Press `home`/`end` to jump to start/end of circuit
    - Press `shift+q/e` to jump 5 layers at a time
- Added more example circuits, and moved examples behind a "show
examples" button
- Fix frame gate methods targeting indices instead of targets
- Add frame undo gate methods

- Fixes #771
- Fixes #715
- Fixes #738
  • Loading branch information
Strilanc authored Jun 4, 2024
1 parent 9c97029 commit 985d6a7
Show file tree
Hide file tree
Showing 59 changed files with 2,836 additions and 476 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ jobs:
- run: diff <(dev/gen_known_gates_for_js.sh) glue/crumble/test/generated_gate_name_list.test.js
- run: python doc/stim.pyi
- run: npm install -g [email protected] [email protected]
- run: diff <(dev/regen_crumble_to_cpp_string_write_to_stdout.sh) src/stim/diagram/crumble_data.cc
- run: diff <(dev/compile_crumble_into_cpp_string_file.sh) src/stim/diagram/crumble_data.cc
- run: pip install -e glue/sample
- run: diff <(python dev/gen_sinter_api_reference.py -dev) doc/sinter_api.md
test_generated_file_lists_are_fresh:
Expand Down
2 changes: 1 addition & 1 deletion MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ echo '#include "stim/diagram/crumble_data.h"'
echo '';
echo 'std::string stim_draw_internal::make_crumble_html() {'
echo ' std::string result;'
dev/regen_crumble_html.sh | python -c '
dev/compile_crumble_into_single_html_page.sh | python -c '
import sys
for line in sys.stdin:
for k in range(0, len(line), 1024):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ cd "$(git rev-parse --show-toplevel)"
cat glue/crumble/crumble.html | grep -v "^<script";
echo "<script>";
# HACK: this temp file is to work around https://github.com/rollup/rollup/issues/5097
rollup glue/crumble/main.js > tmp_crumble.tmp
rollup glue/crumble/main.js --silent > tmp_crumble.tmp
uglifyjs -c -m --mangle-props --toplevel < tmp_crumble.tmp;
rm tmp_crumble.tmp
echo "</script>";
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ set -e
cd "$( dirname "${BASH_SOURCE[0]}" )"
cd "$(git rev-parse --show-toplevel)"

dev/regen_crumble_to_cpp_string_write_to_stdout.sh > src/stim/diagram/crumble_data.cc
dev/compile_crumble_into_cpp_string_file.sh > src/stim/diagram/crumble_data.cc
53 changes: 41 additions & 12 deletions glue/crumble/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,29 @@ button (now labelled "Hide Import/Export") again.
<a name="keyboard-commands"></a>
## Keyboard Controls

**Markings**
**Pauli Propagation**

- `[XYZ]+[0-9]`: Place Pauli propagation markers at current selection.
The X, Y, or Z determines the basis of the marker.
The 1, 2, 3, or etc determines which of the tracked Pauli products is affected by the marker.
For example, `X+2` will place X type markers that multiply an X dependence into Pauli product #2.
The XYZ can be omitted, in which case the basis will be inferred based on the selected gates (for example, an RX gate implies X basis).
- `spacebar`: Clear all Pauli propagation markers at current selection.
- `P`: Add a background polygon with corners at the current selection.
The color of the polygon is affected by modifier keys: X, Y, Z, alt, shift.
- `#`: Puts a Pauli propagation marker at the current selection for the indexed Pauli product.
`#` can be any of 1, 2, 3, etc and determines which of the tracked Pauli products the marker goes into.
For example, `2` will place a marker that multiplies a Pauli term into tracked Pauli product #2.
The basis of the marker is inferred from context (e.g. if an `RX` gate is selected, it will be an `X` marker).
- `x+#`: Put an X-type Pauli propagation marker at the current selection for the indexed Pauli product.
- `y+#`: Put a Y-type Pauli propagation marker at the current selection for the indexed Pauli product.
- `z+#`: Put a Z-type Pauli propagation marker at the current selection for the indexed Pauli product.
- `d+#`: Converts the indexed Pauli product into a circuit `DETECTOR` declaration.
- `o+#`: Converts the indexed Pauli product into a circuit `OBSERVABLE_INCLUDE` declaration.
- `j+#`: Picks a `DETECTOR` or `OBSERVABLE_INCLUDE` declaration touching the current selection and converts it into a tracked Pauli product.
- `k+#`: Add a marker to any dissipative gate that the indexed Pauli product overlaps in the current layer.

**Editing**

- `p`: Add a background polygon with corners at the current selection.
The color of the polygon is affected by modifier keys: X, Y, Z, alt, shift.
- `e`: Move to next layer.
- `q`: Move to previous layer.
- `shift+e`: Move forward 5 layers.
- `shift+q`: Move backward 5 layers.
- `escape`: Unselect. Set current selection to the empty set.
- `delete`: Delete gates at current selection.
- `backspace`: Delete gates at current selection.
Expand All @@ -112,11 +122,20 @@ button (now labelled "Hide Import/Export") again.
- `ctrl+z`: Undo
- `ctrl+y`: Redo
- `ctrl+shift+z`: Redo
- `ctrl+c`: Copy selection to clipboard.
- `ctrl+v`: Past clipboard contents at current selection.
- `ctrl+x`: Cut selection to clipboard.
- `ctrl+c`: Copy selection to clipboard (or entire layer if nothing selected).
- `ctrl+v`: Past clipboard contents at current selection (or entire layer if nothing selected).
- `ctrl+x`: Cut selection to clipboard (or entire layer if nothing selected).
- `f`: Reverse direction of selected two qubit gates (e.g. exchange the controls and targets of a CNOT).
- `g`: Reverse order of circuit layers, from the current layer to the next empty layer.
- `home`: Jump to the first layer of the circuit.
- `end`: Jump to the last layer of the circuit.
- `t`: Rotate circuit 45 degrees clockwise.
- `shift+t`: Rotate circuit 45 degrees counter-clockwise.
- `v`: Translate circuit down one step.
- `^`: Translate circuit up one step.
- `>`: Translate circuit right one step.
- `<`: Translate circuit left one step.
- `.`: Translate circuit down and right by a half step.

**Single Qubit Gates**

Expand All @@ -137,7 +156,11 @@ Note: use `shift` to get the inverse of a gate.
- `m+r+x`: Overwrite selection with `MRX` gate
- `m+r+y`: Overwrite selection with `MRY` gate
- `m+r`: Overwrite selection with `MR` gate
- `f`: Overwrite selection with `C_XYZ` gate
- `c+t`: Overwrite selection with `C_XYZ` gate
- `j+x`: Overwrite selection with **j**ust a Pauli `X` gate
- `j+y`: Overwrite selection with **j**ust a Pauli `Y` gate
- `j+z`: Overwrite selection with **j**ust a Pauli `Z` gate
- `shift+c+t`: Overwrite selection with `C_ZYX` gate

**Two Qubit Gates**

Expand Down Expand Up @@ -165,6 +188,12 @@ Note: use `shift` to get the inverse of a gate.
- `c+m+y`: Overwrite selection with `MYY` gate targeting mouse
- `c+m+z`: Overwrite selection with `MZZ` gate targeting mouse

**Multi Qubit Gates**

- `m+p+x`: Overwrite selection with a single `MPP` gate targeting the tensor product of X on each selected qubit.
- `m+p+y`: Overwrite selection with a single `MPP` gate targeting the tensor product of Y on each selected qubit.
- `m+p+z`: Overwrite selection with a single `MPP` gate targeting the tensor product of Z on each selected qubit.

**Keyboard Buttons as Gate Adjectives**

Roughly speaking, the "keyboard language" for gates used by Crumble has the following "adjectives":
Expand Down
4 changes: 2 additions & 2 deletions glue/crumble/base/revision.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ class Revision {
* the previous state.
* @returns {void}
*/
startedWorkingOnCommit() {
this.isWorkingOnCommit = true;
startedWorkingOnCommit(newCheckpoint) {
this.isWorkingOnCommit = newCheckpoint !== this.history[this.index];
this._changes.send(undefined);
}

Expand Down
22 changes: 22 additions & 0 deletions glue/crumble/base/seq.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @param {!Iterable<TItem> | !Iterator<TItem>}items
* @param {!function(item: TItem): TKey} func
* @returns {!Map<TKey, !Array<TItem>>}
* @template TItem
* @template TKey
*/
function groupBy(items, func) {
let result = new Map();
for (let item of items) {
let key = func(item);
let group = result.get(key);
if (group === undefined) {
result.set(key, [item]);
} else {
group.push(item);
}
}
return result;
}

export {groupBy};
12 changes: 12 additions & 0 deletions glue/crumble/base/seq.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {assertThat, test} from "../test/test_util.js"
import {groupBy} from "./seq.js"

test("seq.groupBy", () => {
assertThat(groupBy([], e => e)).isEqualTo(new Map([]))
assertThat(groupBy([2, 3, 5, 11, 15, 17, 2], e => e % 5)).isEqualTo(new Map([
[1, [11]],
[2, [2, 17, 2]],
[3, [3]],
[0, [5, 15]],
]))
});
Loading

0 comments on commit 985d6a7

Please sign in to comment.