quaco.js
Version:
A lightweight modular Quantum Computing Simulator in JavaScript. Supports qubits, quantum gates, entanglement, circuits, algorithms, and visualization.
115 lines (97 loc) • 3.66 kB
JavaScript
// src/Algorithms/Grover.js
import { Simulator } from '../Simulator.js';
import { QuantumGate } from '../QuantumGate.js';
/**
* Grover's Search Algorithm Simulator
*/
export class Grover {
/**
* Runs Grover's algorithm to find the marked item.
* @param {number} numQubits - number of search qubits
* @param {number} markedItem - integer (0 to 2^numQubits - 1)
* @returns {string} - measured marked item
*/
static run(numQubits, markedItem) {
const N = 1 << numQubits; // 2^n
const iterations = Math.floor(Math.PI / 4 * Math.sqrt(N));
const sim = new Simulator(numQubits);
// Step 1: Hadamard on all qubits (uniform superposition)
for (let i = 0; i < numQubits; i++) {
sim.addGate(QuantumGate.hadamard(), i);
}
// Step 2: Grover Iterations
for (let iter = 0; iter < iterations; iter++) {
// Oracle step: flip the phase of the marked item
Grover.applyOracle(sim, numQubits, markedItem);
// Diffusion step: invert about the mean
Grover.applyDiffusion(sim, numQubits);
}
// Step 3: Measurement
const result = sim.run(1); // Single run
return result;
}
/**
* Oracle: Flip phase of markedItem
* (In real quantum, you use a quantum oracle. Here we simulate.)
*/
static applyOracle(sim, numQubits, markedItem) {
const markedBits = markedItem.toString(2).padStart(numQubits, '0').split('').map(b => parseInt(b));
// Apply X gates to bits that are 0 in the marked item
for (let i = 0; i < numQubits; i++) {
if (markedBits[i] === 0) {
sim.addGate(QuantumGate.x(), i);
}
}
// Apply multi-controlled Z (simulate with trick — apply Z on |111..⟩ state)
if (numQubits > 1) {
// Apply Hadamard to last qubit
sim.addGate(QuantumGate.hadamard(), numQubits - 1);
// Apply multi-controlled NOT
for (let i = 0; i < numQubits - 1; i++) {
sim.addCNOT(i, numQubits - 1);
}
// Apply Hadamard to last qubit
sim.addGate(QuantumGate.hadamard(), numQubits - 1);
} else {
// For 1 qubit case, just apply Z
sim.addGate(QuantumGate.z(), 0);
}
// Undo X gates
for (let i = 0; i < numQubits; i++) {
if (markedBits[i] === 0) {
sim.addGate(QuantumGate.x(), i);
}
}
}
/**
* Diffusion Operator: Invert about the mean
*/
static applyDiffusion(sim, numQubits) {
// Hadamard all
for (let i = 0; i < numQubits; i++) {
sim.addGate(QuantumGate.hadamard(), i);
}
// X all
for (let i = 0; i < numQubits; i++) {
sim.addGate(QuantumGate.x(), i);
}
// Controlled-Z
if (numQubits > 1) {
sim.addGate(QuantumGate.hadamard(), numQubits - 1);
for (let i = 0; i < numQubits - 1; i++) {
sim.addCNOT(i, numQubits - 1);
}
sim.addGate(QuantumGate.hadamard(), numQubits - 1);
} else {
sim.addGate(QuantumGate.z(), 0);
}
// X all
for (let i = 0; i < numQubits; i++) {
sim.addGate(QuantumGate.x(), i);
}
// Hadamard all
for (let i = 0; i < numQubits; i++) {
sim.addGate(QuantumGate.hadamard(), i);
}
}
}