⚛️ Quantum Computing Simulator

Interactive demonstrations of quantum algorithms with real-time visualizations

Quantum Algorithm Explorer

Discover the power of quantum computing through interactive simulations of the most important quantum algorithms.

🔢

Shor's Algorithm

Quantum integer factorization with exponential speedup over classical methods. Essential for cryptography and number theory.

🔍

Grover's Search

Quantum search algorithm providing quadratic speedup for unstructured database search problems.

🌐

QAOA

Quantum Approximate Optimization Algorithm for solving combinatorial optimization problems.

🧠

Quantum ML

Quantum machine learning for classification and clustering with potential quantum advantage.

Quantum Computing Principles

Superposition

Qubits can exist in multiple states simultaneously, enabling parallel computation across all possible states.

Entanglement

Quantum correlations between qubits that allow for coordinated operations and information sharing.

Interference

Quantum amplitudes can interfere constructively or destructively to amplify correct answers and cancel wrong ones.

🔢 Shor's Algorithm - Integer Factorization

Quantum State Evolution

|000⟩
100%

How Shor's Algorithm Works

1. Classical Preprocessing

Check if N is even or a perfect power. Choose random integer a < N and compute gcd(a, N).

2. Quantum Period Finding

Use quantum superposition and QFT to find the period r of f(x) = a^x mod N efficiently.

3. Classical Post-processing

Use the period r to compute gcd(a^(r/2) ± 1, N) to find non-trivial factors of N.

🔍 Grover's Search Algorithm

Search Space Visualization

How Grover's Algorithm Works

1. Superposition

Initialize all qubits in equal superposition using Hadamard gates to search all states simultaneously.

2. Oracle & Diffusion

Apply oracle to mark target state, then diffusion operator for amplitude amplification.

3. Measurement

After ~√N iterations, measure to find the target with high probability (quadratic speedup).

🌐 QAOA - Quantum Optimization

Cost Matrix

Green: positive coupling, Red: negative coupling

QAOA Algorithm Overview

1. Problem Encoding

Encode optimization problem as cost Hamiltonian with qubit interactions and constraints.

2. Variational Circuit

Apply alternating layers of cost and mixer Hamiltonians with optimizable parameters γ and β.

3. Classical Optimization

Use classical optimizer to find parameters minimizing the expectation value of the cost function.

🧠 Quantum Machine Learning

Training samples: 20

Test samples: 10

Features: 2D coordinates

Problem: Binary classification (x₁ + x₂ > 1)

Results

Run the quantum ML algorithm to see results.

Quantum Machine Learning

1. Feature Encoding

Encode classical data into quantum states using rotation gates and amplitude encoding techniques.

2. Variational Circuit

Apply parameterized quantum circuit with trainable parameters for learning representations.

3. Optimization

Use classical-quantum hybrid optimization to minimize loss function and improve performance.

💻 Production Code Examples

Real implementations in Q#, Qiskit, and Cirq for quantum development environments.

Shor's Algorithm - Q#

Microsoft Q# implementation

Q#
namespace Microsoft.Quantum.Samples {
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Measurement;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Convert;

    operation ShorAlgorithm(n : Int) : Int[] {
        mutable factors = new Int[0];
        
        // Check if n is even
        if (n % 2 == 0) {
            set factors += [2];
            set factors += [n / 2];
            return factors;
        }

        // Main Shor's algorithm loop
        for (attempt in 1..10) {
            let a = RandomInt(n - 2) + 2;
            let gcdResult = GreatestCommonDivisorI(a, n);
            
            if (gcdResult > 1) {
                set factors += [gcdResult];
                set factors += [n / gcdResult];
                return factors;
            }

            let period = QuantumPeriodFinding(a, n);
            
            if (period % 2 == 0) {
                let factor1 = GreatestCommonDivisorI(ModularExp(a, period/2, n) - 1, n);
                if (factor1 > 1 and factor1 < n) {
                    set factors += [factor1];
                    set factors += [n / factor1];
                    return factors;
                }
            }
        }
        return factors;
    }

    operation QuantumPeriodFinding(a : Int, n : Int) : Int {
        let numQubits = BitSizeI(n);
        use register = Qubit[2 * numQubits];
        let (input, output) = (register[0..numQubits-1], register[numQubits..2*numQubits-1]);
        
        // Create superposition
        ApplyToEach(H, input);
        
        // Quantum modular exponentiation
        ModularMultiplyByConstantLE(a, n, LittleEndian(output));
        
        // Inverse QFT
        Adjoint QFT(BigEndian(input));
        
        // Measure and return period
        let result = MeasureInteger(LittleEndian(input));
        ResetAll(register);
        return result;
    }
}

Grover's Algorithm - Qiskit

Python Qiskit implementation

Python
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit import Aer, execute
import numpy as np
import math

def grover_algorithm(oracle_function, num_qubits):
    qreg = QuantumRegister(num_qubits)
    creg = ClassicalRegister(num_qubits)
    circuit = QuantumCircuit(qreg, creg)
    
    # Initialize superposition
    circuit.h(range(num_qubits))
    
    # Calculate optimal iterations
    num_items = 2**num_qubits
    num_iterations = int(math.pi/4 * math.sqrt(num_items))
    
    # Grover iterations
    for iteration in range(num_iterations):
        oracle_function(circuit, qreg)
        diffusion_operator(circuit, qreg, num_qubits)
    
    circuit.measure(qreg, creg)
    return circuit

def oracle_function(circuit, qreg, target_state=5):
    # Mark target state |101⟩
    circuit.ccz(qreg[0], qreg[2], qreg[1])

def diffusion_operator(circuit, qreg, num_qubits):
    circuit.h(range(num_qubits))
    circuit.x(range(num_qubits))
    
    if num_qubits == 3:
        circuit.ccz(qreg[0], qreg[1], qreg[2])
    
    circuit.x(range(num_qubits))
    circuit.h(range(num_qubits))

def run_grover_search():
    num_qubits = 3
    circuit = grover_algorithm(oracle_function, num_qubits)
    
    backend = Aer.get_backend('qasm_simulator')
    job = execute(circuit, backend, shots=1024)
    result = job.result()
    counts = result.get_counts(circuit)
    
    return counts, circuit

QAOA - Cirq

Google Cirq implementation

Python
import cirq
import numpy as np
from scipy.optimize import minimize

def qaoa_circuit(qubits, gamma, beta, problem_hamiltonian):
    circuit = cirq.Circuit()
    
    # Initial superposition
    circuit.append(cirq.H.on_each(*qubits))
    
    # QAOA layers
    p = len(gamma)
    for layer in range(p):
        circuit.append(problem_unitary(qubits, gamma[layer], problem_hamiltonian))
        circuit.append(mixer_unitary(qubits, beta[layer]))
    
    return circuit

def problem_unitary(qubits, gamma, edges):
    for i, j, weight in edges:
        yield cirq.ZZ(qubits[i], qubits[j]) ** (gamma * weight / np.pi)

def mixer_unitary(qubits, beta):
    for qubit in qubits:
        yield cirq.X(qubit) ** (beta / np.pi)

def solve_max_cut_qaoa(graph_edges, num_qubits, p=1):
    qubits = cirq.LineQubit.range(num_qubits)
    simulator = cirq.Simulator()
    
    # Initial parameters
    initial_params = np.random.uniform(0, 2*np.pi, 2*p)
    
    # Optimization
    result = minimize(
        lambda params: -qaoa_expectation_value(params, qubits, graph_edges, simulator),
        initial_params,
        method='COBYLA'
    )
    
    return {
        'solution': get_best_solution(result.x, qubits, graph_edges, simulator),
        'parameters': result.x,
        'iterations': result.nfev
    }

Quantum ML - Qiskit

Quantum machine learning implementation

Python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit import Parameter
import numpy as np

class QuantumClassifier:
    def __init__(self, num_qubits, num_layers=2):
        self.num_qubits = num_qubits
        self.num_layers = num_layers
        self.parameters = None
    
    def feature_encoding(self, x):
        circuit = QuantumCircuit(self.num_qubits)
        for i, feature in enumerate(x[:self.num_qubits]):
            circuit.ry(2 * np.arcsin(np.sqrt(feature)), i)
        return circuit
    
    def variational_circuit(self, params):
        circuit = QuantumCircuit(self.num_qubits)
        param_idx = 0
        
        for layer in range(self.num_layers):
            # Rotation gates
            for qubit in range(self.num_qubits):
                circuit.ry(params[param_idx], qubit)
                param_idx += 1
                circuit.rz(params[param_idx], qubit)
                param_idx += 1
            
            # Entangling gates
            for i in range(self.num_qubits - 1):
                circuit.cx(i, i + 1)
        
        return circuit
    
    def predict(self, x, params):
        circuit = self.feature_encoding(x)
        circuit = circuit.compose(self.variational_circuit(params))
        
        # Measurement and expectation value calculation
        backend = Aer.get_backend('statevector_simulator')
        job = execute(circuit, backend)
        result = job.result()
        statevector = result.get_statevector()
        
        # Calculate expectation value of Z measurement on first qubit
        expectation = np.real(np.conj(statevector) @ pauli_z_matrix @ statevector)
        return expectation
    
    def train(self, X_train, y_train, epochs=100):
        num_params = self.num_layers * self.num_qubits * 2
        params = np.random.uniform(0, 2*np.pi, num_params)
        
        def cost_function(params):
            total_loss = 0
            for x, y in zip(X_train, y_train):
                pred = self.predict(x, params)
                total_loss += (pred - y)**2
            return total_loss / len(X_train)
        
        result = minimize(cost_function, params, method='COBYLA')
        self.parameters = result.x
        return result