UNPKG

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
// 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); } } }