UNPKG

quaco.js

Version:

A lightweight modular Quantum Computing Simulator in JavaScript. Supports qubits, quantum gates, entanglement, circuits, algorithms, and visualization.

103 lines (88 loc) 3.58 kB
// src/QuantumRegister.js import { Complex } from './utils/Complex.js'; import { QuantumGate } from './QuantumGate.js'; import { MathUtils } from './utils/MathUtils.js'; /** * Represents a register of multiple qubits (n qubits). * Full quantum state is a 2^n dimensional vector. */ export class QuantumRegister { constructor(numQubits) { this.numQubits = numQubits; // Initialize state vector |00...0⟩ const size = 1 << numQubits; // 2^numQubits this.state = Array(size).fill(new Complex(0, 0)); this.state[0] = new Complex(1, 0); // Start in |00...0⟩ } /** * Applies a single-qubit gate to the specified qubit index. * @param {Complex[][]} gateMatrix - 2x2 matrix * @param {number} qubitIndex - index of target qubit (0 = least significant) */ applyGate(gateMatrix, qubitIndex) { const newState = new Array(this.state.length).fill(new Complex(0, 0)); for (let i = 0; i < this.state.length; i++) { // Check bit at qubitIndex const bit = (i >> qubitIndex) & 1; for (let j = 0; j < 2; j++) { // Flip bit at qubitIndex to j (0 or 1) const flipped = (i & (~(1 << qubitIndex))) | (j << qubitIndex); const gateElement = gateMatrix[j][bit]; newState[flipped] = newState[flipped].add( gateElement.mul(this.state[i]) ); } } this.state = MathUtils.normalize(newState); } /** * Applies a 2-qubit gate (like CNOT) to control and target qubits. * Only CNOT is supported in this version. * @param {number} controlQubit * @param {number} targetQubit */ applyCNOT(controlQubit, targetQubit) { const newState = new Array(this.state.length).fill(new Complex(0, 0)); for (let i = 0; i < this.state.length; i++) { const controlBit = (i >> controlQubit) & 1; let flipped = i; if (controlBit === 1) { // Flip target qubit flipped = i ^ (1 << targetQubit); } newState[flipped] = newState[flipped].add(this.state[i]); } this.state = MathUtils.normalize(newState); } /** * Measures the entire register, collapsing to one classical outcome. * @returns {string} bitstring, e.g., "001" */ measure() { const probabilities = this.state.map(amplitude => amplitude.abs2()); const rand = Math.random(); let cumulative = 0; for (let i = 0; i < probabilities.length; i++) { cumulative += probabilities[i]; if (rand < cumulative) { // Collapse to basis state |i⟩ this.state = Array(this.state.length).fill(new Complex(0, 0)); this.state[i] = new Complex(1, 0); return i.toString(2).padStart(this.numQubits, '0'); // binary string } } } /** * Prints the quantum register state. */ printState() { console.log("Quantum Register State:"); for (let i = 0; i < this.state.length; i++) { const amplitude = this.state[i]; if (!MathUtils.almostEqual(amplitude.abs2(), 0)) { const basis = `|${i.toString(2).padStart(this.numQubits, '0')}⟩`; console.log(`${amplitude.toString()} ${basis}`); } } } }