Skip to content

Commit

Permalink
Example circuits
Browse files Browse the repository at this point in the history
  • Loading branch information
Strilanc committed Jun 3, 2024
1 parent 0f98f54 commit 5e41107
Show file tree
Hide file tree
Showing 6 changed files with 726 additions and 163 deletions.
1 change: 1 addition & 0 deletions glue/crumble/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ button (now labelled "Hide Import/Export") again.
- `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**

Expand Down
8 changes: 6 additions & 2 deletions glue/crumble/circuit/circuit.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ function splitUncombinedTargets(targets) {
/**
* @param {!Float32Array} args
* @param {!Array.<!string>} combinedTargets
* @param {!boolean} convertIntoOtherGates
* @returns {!Operation}
*/
function simplifiedMPP(args, combinedTargets) {
function simplifiedMPP(args, combinedTargets, convertIntoOtherGates) {
let bases = '';
let qubits = [];
for (let t of combinedTargets) {
Expand All @@ -87,7 +88,10 @@ function simplifiedMPP(args, combinedTargets) {
}
}

let gate = GATE_MAP.get('M' + bases);
let gate = undefined;
if (convertIntoOtherGates) {
gate = GATE_MAP.get('M' + bases);
}
if (gate === undefined) {
gate = GATE_MAP.get('MPP:' + bases);
}
Expand Down
182 changes: 164 additions & 18 deletions glue/crumble/crumble.html

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions glue/crumble/editor/editor_state.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,63 @@ class EditorState {
this.obs_val_draw_state = /** @type {!ObservableValue<StateSnapshot>} */ new ObservableValue(this.toSnapshot(undefined));
}

flipTwoQubitGateOrderAtFocus(preview) {
let newCircuit = this.copyOfCurCircuit();
let layer = newCircuit.layers[this.curLayer];
let flipped_op_first_targets = new Set();
let pairs = [
['CX', 'reverse'],
['CY', 'reverse'],
['XCY', 'reverse'],
['CXSWAP', 'reverse'],
['XCZ', 'reverse'],
['XCY', 'reverse'],
['YCX', 'reverse'],
['SWAPCX', 'reverse'],
['RX', 'MX'],
['R', 'M'],
['RY', 'MY'],
];
let rev = new Map();
for (let p of pairs) {
rev.set(p[0], p[1]);
rev.set(p[1], p[0]);
}
for (let q of this.focusedSet.keys()) {
let op = layer.id_ops.get(newCircuit.coordToQubitMap().get(q));
if (op !== undefined && rev.has(op.gate.name)) {
flipped_op_first_targets.add(op.id_targets[0]);
}
}
for (let q of flipped_op_first_targets) {
let op = layer.id_ops.get(q);
let other = rev.get(op.gate.name);
if (other === 'reverse') {
layer.id_ops.get(q).id_targets.reverse();
} else {
op.gate = GATE_MAP.get(other);
}
}
this.commit_or_preview(newCircuit, preview);
}

reverseLayerOrderFromFocusToEmptyLayer(preview) {
let newCircuit = this.copyOfCurCircuit();
let end = this.curLayer;
while (end < newCircuit.layers.length && !newCircuit.layers[end].empty()) {
end += 1;
}
let layers = [];
for (let k = this.curLayer; k < end; k++) {
layers.push(newCircuit.layers[k]);
}
layers.reverse();
for (let k = this.curLayer; k < end; k++) {
newCircuit.layers[k] = layers[k - this.curLayer];
}
this.commit_or_preview(newCircuit, preview);
}

/**
* @return {!Circuit}
*/
Expand Down Expand Up @@ -557,6 +614,44 @@ class EditorState {
this.commit_or_preview(newCircuit, preview);
}

addDissipativeOverlapToMarkers(preview, marker_index) {
let newCircuit = this.copyOfCurCircuit();
let prop = PropagatedPauliFrames.fromCircuit(newCircuit, marker_index);

let k = this.curLayer;
let before = k === 0 ? new PropagatedPauliFrameLayer(new Map(), new Set(), []) : prop.atLayer(k - 0.5);
let after = prop.atLayer(k + 0.5);
let layer = newCircuit.layers[k];
for (let q of new Set([...before.bases.keys(), ...after.bases.keys()])) {
let b1 = before.bases.get(q);
let b2 = after.bases.get(q);
let op = layer.id_ops.get(q);
if (op === undefined) {
continue;
}
let name = op.gate.name;
let basis = undefined;
if (name === 'R' || name === 'M' || name === 'MR') {
basis = 'Z'
} else if (name === 'RX' || name === 'MX' || name === 'MRX') {
basis = 'X'
} else if (name === 'RY' || name === 'MY' || name === 'MRY') {
basis = 'Y'
} else {
continue;
}
if (b1 !== undefined || b2 !== undefined) {
layer.markers.push(new Operation(
GATE_MAP.get(`MARK${basis}`),
new Float32Array([marker_index]),
new Uint32Array([q]),
));
}
}

this.commit_or_preview(newCircuit, preview);
}

moveDetOrObsAtFocusIntoMarker(preview, marker_index) {
let circuit = this.copyOfCurCircuit();

Expand Down
58 changes: 3 additions & 55 deletions glue/crumble/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ function makeChordHandlers() {
res.set(`${key}+d`, preview => editorState.writeMarkerToDetector(preview, val));
res.set(`${key}+o`, preview => editorState.writeMarkerToObservable(preview, val));
res.set(`${key}+j`, preview => editorState.moveDetOrObsAtFocusIntoMarker(preview, val));
res.set(`${key}+k`, preview => editorState.addDissipativeOverlapToMarkers(preview, val));
}

let defaultPolygonAlpha = 0.25;
Expand All @@ -254,61 +255,8 @@ function makeChordHandlers() {
res.set('m+p+x', preview => editorState.writeGateToFocus(preview, make_mpp_gate("X".repeat(editorState.focusedSet.size)), []));
res.set('m+p+y', preview => editorState.writeGateToFocus(preview, make_mpp_gate("Y".repeat(editorState.focusedSet.size)), []));
res.set('m+p+z', preview => editorState.writeGateToFocus(preview, make_mpp_gate("Z".repeat(editorState.focusedSet.size)), []));
res.set('f', preview => {
let newCircuit = editorState.copyOfCurCircuit();
let layer = newCircuit.layers[editorState.curLayer];
let flipped_op_first_targets = new Set();
let pairs = [
['CX', 'reverse'],
['CY', 'reverse'],
['XCY', 'reverse'],
['CXSWAP', 'reverse'],
['XCZ', 'reverse'],
['XCY', 'reverse'],
['YCX', 'reverse'],
['SWAPCX', 'reverse'],
['RX', 'MX'],
['R', 'M'],
['RY', 'MY'],
];
let rev = new Map();
for (let p of pairs) {
rev.set(p[0], p[1]);
rev.set(p[1], p[0]);
}
for (let q of editorState.focusedSet.keys()) {
let op = layer.id_ops.get(newCircuit.coordToQubitMap().get(q));
if (op !== undefined && rev.has(op.gate.name)) {
flipped_op_first_targets.add(op.id_targets[0]);
}
}
for (let q of flipped_op_first_targets) {
let op = layer.id_ops.get(q);
let other = rev.get(op.gate.name);
if (other === 'reverse') {
layer.id_ops.get(q).id_targets.reverse();
} else {
op.gate = GATE_MAP.get(other);
}
}
editorState.commit_or_preview(newCircuit, preview);
});
res.set('g', preview => {
let newCircuit = editorState.copyOfCurCircuit();
let end = editorState.curLayer;
while (end < newCircuit.layers.length && !newCircuit.layers[end].empty()) {
end += 1;
}
let layers = [];
for (let k = editorState.curLayer; k < end; k++) {
layers.push(newCircuit.layers[k]);
}
layers.reverse();
for (let k = editorState.curLayer; k < end; k++) {
newCircuit.layers[k] = layers[k - editorState.curLayer];
}
editorState.commit_or_preview(newCircuit, preview);
});
res.set('f', preview => editorState.flipTwoQubitGateOrderAtFocus(preview));
res.set('g', preview => editorState.reverseLayerOrderFromFocusToEmptyLayer(preview));
res.set('shift+>', preview => editorState.applyCoordinateTransform((x, y) => [x + 1, y], preview, false));
res.set('shift+<', preview => editorState.applyCoordinateTransform((x, y) => [x - 1, y], preview, false));
res.set('shift+v', preview => editorState.applyCoordinateTransform((x, y) => [x, y + 1], preview, false));
Expand Down
Loading

0 comments on commit 5e41107

Please sign in to comment.