Below is a four-qubit linear cluster state. Each qubit starts in the ∣+⟩ state and adjacent pairs are entangled with a controlled-Z gate. Pick a measurement angle ϕ (in the XY-plane of the Bloch sphere) for each qubit from left to right. The outcome of each measurement randomly gives ±1, but the angle you choose steers the logical operation applied to the remaining qubits.
<!-- MBQC demo — 4-qubit linear cluster state driven by measurements -->
<p class="hint">A 4-qubit linear cluster state: each qubit starts in |+⟩ and neighbors are entangled. Choose a measurement angle φ for each qubit and press <b>Measure qubit</b>. The outcome ±1 is random — your angle steers the logical gate. The correction rule shows how adaptive feed-forward tames randomness.</p>
<div id="cluster" class="cluster-wrap"></div>
<div id="status" class="status"></div>
<div class="btns">
<button id="btn-run" type="button">Measure qubit 1</button>
<button id="btn-reset" type="button" class="ghost">Reset</button>
</div>
/* Styles for the MBQC cluster-state demo */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; padding: .5rem; }
.hint { font-size: .88rem; color: #444; margin: 0 0 .8rem; line-height: 1.5; }
.cluster-wrap { display: flex; align-items: center; gap: 0; margin-bottom: .6rem; overflow-x: auto; }
.qubit-col { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.wire { width: 32px; height: 2px; background: #adb1b8; margin-top: 28px; flex-shrink: 0; }
.qubit-box { width: 64px; padding: .45rem .3rem; border-radius: 10px; border: 1.5px solid #cdd9e3;
background: #e8eef3; text-align: center; }
.qubit-box.measured { background: #f0f4f8; border-color: #b0bec5; opacity: .72; }
.qubit-box.active { border-color: #1d3557; background: #dce8f5; }
.qubit-label { font: 700 13px ui-monospace, monospace; color: #1d3557; margin-bottom: .2rem; }
.qubit-label.measured-lbl { color: #888; }
.angle-row { display: flex; align-items: center; gap: 4px; justify-content: center; }
.angle-row label { font-size: .75rem; color: #555; }
select { font: 13px system-ui; border: 1px solid #adb1b8; border-radius: 5px;
padding: 2px 4px; background: #fff; cursor: pointer; }
select:disabled { opacity: .45; cursor: default; }
.outcome-row { font: 700 13px ui-monospace, monospace; min-height: 1.2em; color: #555; }
.outcome-row.plus { color: #0a7d33; }
.outcome-row.minus { color: #c92f3c; }
.corr-row { font-size: .7rem; color: #888; min-height: 1em; }
.status { font-size: .95rem; font-weight: 600; min-height: 1.5em; margin-bottom: .4rem; }
.status.ok { color: #0a7d33; }
.status.info { color: #1d3557; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
button:disabled { opacity: .45; cursor: default; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// Measurement-Based Quantum Computing demo
// We simulate a 4-qubit linear cluster state. Qubits are measured left
// to right; each measurement angle phi determines the logical gate applied.
const QUBITS = 4;
// Measurement angles in the XY plane of the Bloch sphere (degrees)
const ANGLE_OPTIONS = [0, 45, 90, 135, 180, 225, 270, 315];
// Simulation state
let outcomes = []; // measurement outcomes: +1 or -1
let corrections = []; // whether a Pauli-X correction is needed after each measurement
let step = 0; // which qubit we are about to measure
let running = false;
function buildUI() {
const wrap = document.getElementById('cluster');
wrap.innerHTML = '';
for (let i = 0; i < QUBITS; i++) {
if (i > 0) {
// entanglement wire between adjacent qubits
const wire = document.createElement('div');
wire.className = 'wire';
wrap.appendChild(wire);
}
const col = document.createElement('div');
col.className = 'qubit-col';
col.id = 'col-' + i;
const box = document.createElement('div');
box.className = 'qubit-box' + (i === 0 ? ' active' : '');
box.id = 'box-' + i;
const lbl = document.createElement('div');
lbl.className = 'qubit-label';
// qubit label (1-indexed for display)
lbl.textContent = 'q' + (i + 1);
lbl.id = 'lbl-' + i;
const angleRow = document.createElement('div');
angleRow.className = 'angle-row';
const angleLbl = document.createElement('label');
angleLbl.textContent = 'φ='; // phi symbol
const sel = document.createElement('select');
sel.id = 'sel-' + i;
sel.disabled = i !== 0;
ANGLE_OPTIONS.forEach(deg => {
const opt = document.createElement('option');
opt.value = deg;
opt.textContent = deg + '°';
if (deg === 0) opt.selected = true;
sel.appendChild(opt);
});
angleRow.appendChild(angleLbl);
angleRow.appendChild(sel);
const outcomeRow = document.createElement('div');
outcomeRow.className = 'outcome-row';
outcomeRow.id = 'out-' + i;
const corrRow = document.createElement('div');
corrRow.className = 'corr-row';
corrRow.id = 'corr-' + i;
box.appendChild(lbl);
box.appendChild(angleRow);
box.appendChild(outcomeRow);
box.appendChild(corrRow);
col.appendChild(box);
wrap.appendChild(col);
}
}
// Simulate measuring qubit i at angle phi (degrees) in the XY plane.
function measureQubit(i, phiDeg) {
// Outcome is truly random in a real quantum device
const outcome = Math.random() < 0.5 ? 1 : -1;
outcomes[i] = outcome;
// Adaptive feed-forward: if outcome is -1 we need a Pauli-X correction
// on the NEXT qubit to keep the logical computation on track
const needsCorr = outcome === -1;
corrections[i] = needsCorr;
return outcome;
}
function describeOp(phiDeg) {
// Return a human-readable label for the logical gate selected by phi
if (phiDeg === 0) return 'X';
if (phiDeg === 90) return 'H';
if (phiDeg === 45) return 'T';
if (phiDeg === 135) return 'S·H'; // S·H
return 'φ=' + phiDeg + '°';
}
async function runStep() {
if (step >= QUBITS || running) return;
running = true;
document.getElementById('btn-run').disabled = true;
const i = step;
const sel = document.getElementById('sel-' + i);
const phi = parseInt(sel.value, 10);
sel.disabled = true;
// Mark this qubit as measured
const box = document.getElementById('box-' + i);
box.classList.remove('active');
box.classList.add('measured');
document.getElementById('lbl-' + i).classList.add('measured-lbl');
const outcome = measureQubit(i, phi);
const outEl = document.getElementById('out-' + i);
outEl.textContent = 's = ' + (outcome === 1 ? '+1' : '-1');
outEl.className = 'outcome-row ' + (outcome === 1 ? 'plus' : 'minus');
const corrEl = document.getElementById('corr-' + i);
if (corrections[i] && i < QUBITS - 1) {
// Correction propagated to next qubit
corrEl.textContent = '↳ Pauli-X correction applied';
} else if (!corrections[i]) {
corrEl.textContent = '↳ no correction needed';
}
step++;
if (step < QUBITS) {
// Unlock the next qubit for selection
const nextSel = document.getElementById('sel-' + step);
nextSel.disabled = false;
const nextBox = document.getElementById('box-' + step);
nextBox.classList.add('active');
setStatus(fmt('Qubit measured — now select φ for qubit %step%.', { step: step }), 'info');
document.getElementById('btn-run').disabled = false;
document.getElementById('btn-run').textContent = fmt('Measure qubit %step%%v%', { step: step, v: 1 });
} else {
// All qubits measured — summarize
const plusCount = outcomes.filter(o => o === 1).length;
const op = describeOp(phi);
setStatus(fmt('Computation complete. %plusCount% qubits gave +1. Final logical gate: %op%. The cluster state is consumed.', { plusCount: plusCount, op: op }), 'ok');
document.getElementById('btn-run').textContent = 'All qubits measured';
}
running = false;
}
function setStatus(t, cls) {
const s = document.getElementById('status');
s.textContent = t;
s.className = 'status ' + cls;
}
function reset() {
outcomes = [];
corrections = [];
step = 0;
running = false;
buildUI();
setStatus('Select an angle φ and measure qubit 1.', 'info');
document.getElementById('btn-run').disabled = false;
document.getElementById('btn-run').textContent = 'Measure qubit 1';
}
document.getElementById('btn-run').addEventListener('click', runStep);
document.getElementById('btn-reset').addEventListener('click', reset);
buildUI();
setStatus('Select an angle φ and measure qubit 1.', 'info');
<!-- MBQC demo — 4-qubit linear cluster state driven by measurements -->
<p class="hint">A 4-qubit linear cluster state: each qubit starts in |+⟩ and neighbors are entangled. Choose a measurement angle φ for each qubit and press <b>Measure qubit</b>. The outcome ±1 is random — your angle steers the logical gate. The correction rule shows how adaptive feed-forward tames randomness.</p>
<div id="cluster" class="cluster-wrap"></div>
<div id="status" class="status"></div>
<div class="btns">
<button id="btn-run" type="button">Measure qubit 1</button>
<button id="btn-reset" type="button" class="ghost">Reset</button>
</div>
/* Styles for the MBQC cluster-state demo */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; padding: .5rem; }
.hint { font-size: .88rem; color: #444; margin: 0 0 .8rem; line-height: 1.5; }
.cluster-wrap { display: flex; align-items: center; gap: 0; margin-bottom: .6rem; overflow-x: auto; }
.qubit-col { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.wire { width: 32px; height: 2px; background: #adb1b8; margin-top: 28px; flex-shrink: 0; }
.qubit-box { width: 64px; padding: .45rem .3rem; border-radius: 10px; border: 1.5px solid #cdd9e3;
background: #e8eef3; text-align: center; }
.qubit-box.measured { background: #f0f4f8; border-color: #b0bec5; opacity: .72; }
.qubit-box.active { border-color: #1d3557; background: #dce8f5; }
.qubit-label { font: 700 13px ui-monospace, monospace; color: #1d3557; margin-bottom: .2rem; }
.qubit-label.measured-lbl { color: #888; }
.angle-row { display: flex; align-items: center; gap: 4px; justify-content: center; }
.angle-row label { font-size: .75rem; color: #555; }
select { font: 13px system-ui; border: 1px solid #adb1b8; border-radius: 5px;
padding: 2px 4px; background: #fff; cursor: pointer; }
select:disabled { opacity: .45; cursor: default; }
.outcome-row { font: 700 13px ui-monospace, monospace; min-height: 1.2em; color: #555; }
.outcome-row.plus { color: #0a7d33; }
.outcome-row.minus { color: #c92f3c; }
.corr-row { font-size: .7rem; color: #888; min-height: 1em; }
.status { font-size: .95rem; font-weight: 600; min-height: 1.5em; margin-bottom: .4rem; }
.status.ok { color: #0a7d33; }
.status.info { color: #1d3557; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
button:disabled { opacity: .45; cursor: default; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// Measurement-Based Quantum Computing demo
// We simulate a 4-qubit linear cluster state. Qubits are measured left
// to right; each measurement angle phi determines the logical gate applied.
const QUBITS = 4;
// Measurement angles in the XY plane of the Bloch sphere (degrees)
const ANGLE_OPTIONS = [0, 45, 90, 135, 180, 225, 270, 315];
// Simulation state
let outcomes = []; // measurement outcomes: +1 or -1
let corrections = []; // whether a Pauli-X correction is needed after each measurement
let step = 0; // which qubit we are about to measure
let running = false;
function buildUI() {
const wrap = document.getElementById('cluster');
wrap.innerHTML = '';
for (let i = 0; i < QUBITS; i++) {
if (i > 0) {
// entanglement wire between adjacent qubits
const wire = document.createElement('div');
wire.className = 'wire';
wrap.appendChild(wire);
}
const col = document.createElement('div');
col.className = 'qubit-col';
col.id = 'col-' + i;
const box = document.createElement('div');
box.className = 'qubit-box' + (i === 0 ? ' active' : '');
box.id = 'box-' + i;
const lbl = document.createElement('div');
lbl.className = 'qubit-label';
// qubit label (1-indexed for display)
lbl.textContent = 'q' + (i + 1);
lbl.id = 'lbl-' + i;
const angleRow = document.createElement('div');
angleRow.className = 'angle-row';
const angleLbl = document.createElement('label');
angleLbl.textContent = 'φ='; // phi symbol
const sel = document.createElement('select');
sel.id = 'sel-' + i;
sel.disabled = i !== 0;
ANGLE_OPTIONS.forEach(deg => {
const opt = document.createElement('option');
opt.value = deg;
opt.textContent = deg + '°';
if (deg === 0) opt.selected = true;
sel.appendChild(opt);
});
angleRow.appendChild(angleLbl);
angleRow.appendChild(sel);
const outcomeRow = document.createElement('div');
outcomeRow.className = 'outcome-row';
outcomeRow.id = 'out-' + i;
const corrRow = document.createElement('div');
corrRow.className = 'corr-row';
corrRow.id = 'corr-' + i;
box.appendChild(lbl);
box.appendChild(angleRow);
box.appendChild(outcomeRow);
box.appendChild(corrRow);
col.appendChild(box);
wrap.appendChild(col);
}
}
// Simulate measuring qubit i at angle phi (degrees) in the XY plane.
function measureQubit(i, phiDeg) {
// Outcome is truly random in a real quantum device
const outcome = Math.random() < 0.5 ? 1 : -1;
outcomes[i] = outcome;
// Adaptive feed-forward: if outcome is -1 we need a Pauli-X correction
// on the NEXT qubit to keep the logical computation on track
const needsCorr = outcome === -1;
corrections[i] = needsCorr;
return outcome;
}
function describeOp(phiDeg) {
// Return a human-readable label for the logical gate selected by phi
if (phiDeg === 0) return 'X';
if (phiDeg === 90) return 'H';
if (phiDeg === 45) return 'T';
if (phiDeg === 135) return 'S·H'; // S·H
return 'φ=' + phiDeg + '°';
}
async function runStep() {
if (step >= QUBITS || running) return;
running = true;
document.getElementById('btn-run').disabled = true;
const i = step;
const sel = document.getElementById('sel-' + i);
const phi = parseInt(sel.value, 10);
sel.disabled = true;
// Mark this qubit as measured
const box = document.getElementById('box-' + i);
box.classList.remove('active');
box.classList.add('measured');
document.getElementById('lbl-' + i).classList.add('measured-lbl');
const outcome = measureQubit(i, phi);
const outEl = document.getElementById('out-' + i);
outEl.textContent = 's = ' + (outcome === 1 ? '+1' : '-1');
outEl.className = 'outcome-row ' + (outcome === 1 ? 'plus' : 'minus');
const corrEl = document.getElementById('corr-' + i);
if (corrections[i] && i < QUBITS - 1) {
// Correction propagated to next qubit
corrEl.textContent = '↳ Pauli-X correction applied';
} else if (!corrections[i]) {
corrEl.textContent = '↳ no correction needed';
}
step++;
if (step < QUBITS) {
// Unlock the next qubit for selection
const nextSel = document.getElementById('sel-' + step);
nextSel.disabled = false;
const nextBox = document.getElementById('box-' + step);
nextBox.classList.add('active');
setStatus(fmt('Qubit measured — now select φ for qubit %step%.', { step: step }), 'info');
document.getElementById('btn-run').disabled = false;
document.getElementById('btn-run').textContent = fmt('Measure qubit %step%%v%', { step: step, v: 1 });
} else {
// All qubits measured — summarize
const plusCount = outcomes.filter(o => o === 1).length;
const op = describeOp(phi);
setStatus(fmt('Computation complete. %plusCount% qubits gave +1. Final logical gate: %op%. The cluster state is consumed.', { plusCount: plusCount, op: op }), 'ok');
document.getElementById('btn-run').textContent = 'All qubits measured';
}
running = false;
}
function setStatus(t, cls) {
const s = document.getElementById('status');
s.textContent = t;
s.className = 'status ' + cls;
}
function reset() {
outcomes = [];
corrections = [];
step = 0;
running = false;
buildUI();
setStatus('Select an angle φ and measure qubit 1.', 'info');
document.getElementById('btn-run').disabled = false;
document.getElementById('btn-run').textContent = 'Measure qubit 1';
}
document.getElementById('btn-run').addEventListener('click', runStep);
document.getElementById('btn-reset').addEventListener('click', reset);
buildUI();
setStatus('Select an angle φ and measure qubit 1.', 'info');
Notice that the measurement outcome is random — you cannot control it. What you control is the angle. The correction step shows how adaptive feed-forward absorbs randomness: a −1 outcome triggers a Pauli correction on the next qubit so that the logical computation stays on track regardless of luck.
This is the core asymmetry of MBQC: the resource (the cluster state) is prepared ahead of time and consumed irreversibly. Computation flows forward like ink on paper — there is no going back.
Comments
Loading comments...