At1uri's picture
Upload folder using huggingface_hub
be4df46 verified
Raw History Blame Contribute Delete
52.9 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Quantum Portfolio Optimization Studio | QAOA & VQE</title> <!-- Tailwind CSS --> <script src="https://cdn.tailwindcss.com"></script> <!-- Plotly.js --> <script src="https://cdn.plot.ly/plotly-2.32.0.min.js"></script> <!-- KaTeX --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css"> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js"></script> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body);"></script> <script> tailwind.config = { darkMode: 'class', theme: { extend: { colors: { brand: { 50: '#f5f3ff', 100: '#ede9fe', 500: '#8b5cf6', 600: '#7c3aed', 700: '#6d28d9', 900: '#4c1d95', } } } } } </script> <style> body { background-color: #030712; color: #f3f4f6; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } .glass-panel { background: rgba(17, 24, 39, 0.75); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.08); } .neon-glow-purple { box-shadow: 0 0 25px rgba(139, 92, 246, 0.25); } .neon-border { border: 1px solid rgba(139, 92, 246, 0.35); } .quantum-wire { stroke: #4b5563; stroke-width: 2; } .quantum-gate { fill: #1f2937; stroke: #8b5cf6; stroke-width: 1.5; rx: 4; } .scrollbar-thin::-webkit-scrollbar { width: 6px; height: 6px; } .scrollbar-thin::-webkit-scrollbar-thumb { background: #374151; border-radius: 3px; } </style> </head> <body class="min-h-screen flex flex-col"> <!-- Top Navigation Header --> <header class="border-b border-gray-800 glass-panel sticky top-0 z-50 px-6 py-4"> <div class="max-w-7xl mx-auto flex flex-wrap items-center justify-between gap-4"> <div class="flex items-center space-x-3"> <div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-purple-600 via-indigo-600 to-blue-500 flex items-center justify-center text-white shadow-lg shadow-purple-500/30"> <svg class="w-6 h-6 animate-spin" style="animation-duration: 12s;" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" /> </svg> </div> <div> <div class="flex items-center space-x-2"> <h1 class="text-xl font-bold bg-gradient-to-r from-purple-400 via-indigo-300 to-blue-400 bg-clip-text text-transparent"> Quantum Portfolio Optimization Studio </h1> <span class="text-xs px-2 py-0.5 rounded-full bg-purple-500/20 text-purple-300 border border-purple-500/30 font-mono"> QAOA & VQE Engine </span> </div> <p class="text-xs text-gray-400">Variational Quantum Eigensolver & Ising Spin-Glass Combinatorial Arbitrage</p> </div> </div> <div class="flex items-center space-x-3 text-sm"> <a href="https://huggingface.co/At1uri" target="_blank" class="px-3 py-1.5 rounded-lg bg-gray-800 hover:bg-gray-700 text-gray-300 flex items-center space-x-2 border border-gray-700 transition"> <svg class="w-4 h-4 text-purple-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.53 1.032 1.53 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg> <span class="font-medium">At1uri Hub</span> </a> <div class="px-3 py-1.5 rounded-lg bg-purple-950/40 border border-purple-800/50 text-purple-300 font-mono text-xs flex items-center space-x-1.5"> <span class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></span> <span>Simulator: In-Browser Exact $\mathbb{C}^{2^n}$</span> </div> </div> </div> </header> <!-- Main Container --> <main class="max-w-7xl mx-auto px-6 py-8 flex-1 w-full space-y-8"> <!-- KPI Summary Cards --> <div class="grid grid-cols-2 md:grid-cols-5 gap-4"> <div class="glass-panel p-4 rounded-xl border border-gray-800"> <span class="text-xs text-gray-400 uppercase tracking-wider font-semibold">Quantum Algorithm</span> <div id="metric-algo" class="text-xl font-bold text-purple-400 mt-1">QAOA ($p=2$)</div> <div class="text-[11px] text-gray-500 mt-0.5">Alternating Unitary Layers</div> </div> <div class="glass-panel p-4 rounded-xl border border-gray-800"> <span class="text-xs text-gray-400 uppercase tracking-wider font-semibold">Quantum Energy $\langle \mathcal{H}_C \rangle$</span> <div id="metric-energy" class="text-xl font-bold text-amber-400 mt-1">-0.4285</div> <div class="text-[11px] text-gray-500 mt-0.5" id="metric-energy-delta">Error $\Delta E$: 0.0412</div> </div> <div class="glass-panel p-4 rounded-xl border border-gray-800"> <span class="text-xs text-gray-400 uppercase tracking-wider font-semibold">Ground State $E_0$</span> <div id="metric-ground" class="text-xl font-bold text-emerald-400 mt-1">-0.4697</div> <div class="text-[11px] text-gray-500 mt-0.5" id="metric-ground-state">Target: |1010⟩</div> </div> <div class="glass-panel p-4 rounded-xl border border-gray-800"> <span class="text-xs text-gray-400 uppercase tracking-wider font-semibold">Approximation Ratio $\alpha$</span> <div id="metric-ratio" class="text-xl font-bold text-cyan-400 mt-1">94.8%</div> <div class="text-[11px] text-gray-500 mt-0.5">$\frac{\langle \mathcal{H} \rangle - E_{\max}}{E_0 - E_{\max}}$</div> </div> <div class="glass-panel p-4 rounded-xl border border-gray-800 col-span-2 md:col-span-1"> <span class="text-xs text-gray-400 uppercase tracking-wider font-semibold">Bipartite Entanglement</span> <div id="metric-entropy" class="text-xl font-bold text-pink-400 mt-1">0.842 bits</div> <div class="text-[11px] text-gray-500 mt-0.5">Von Neumann $S(\rho_A)$</div> </div> </div> <!-- Controls & Configuration Grid --> <div class="grid grid-cols-1 lg:grid-cols-4 gap-6"> <!-- Configuration Sidebar --> <div class="glass-panel p-6 rounded-2xl border border-gray-800 space-y-6"> <div class="flex items-center justify-between pb-3 border-b border-gray-800"> <h2 class="text-base font-bold text-gray-200 flex items-center space-x-2"> <svg class="w-4 h-4 text-purple-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" /> </svg> <span>Quantum Engine Setup</span> </h2> <span class="w-2 h-2 rounded-full bg-purple-500"></span> </div> <!-- Algorithm Mode --> <div class="space-y-2"> <label class="text-xs font-semibold text-gray-300 block">Quantum Optimizer</label> <div class="grid grid-cols-2 gap-2"> <button id="btn-algo-qaoa" onclick="setAlgorithm('QAOA')" class="px-3 py-2 text-xs font-semibold rounded-lg bg-purple-600 text-white shadow-md shadow-purple-600/30 border border-purple-500 transition"> QAOA </button> <button id="btn-algo-vqe" onclick="setAlgorithm('VQE')" class="px-3 py-2 text-xs font-semibold rounded-lg bg-gray-800 text-gray-400 border border-gray-700 hover:text-white transition"> VQE (Ansatz) </button> </div> </div> <!-- Universe Preset --> <div class="space-y-2"> <label class="text-xs font-semibold text-gray-300 block">Asset Universe & Qubits ($n$)</label> <select id="select-universe" onchange="loadUniversePreset()" class="w-full bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-xs text-gray-200 focus:outline-none focus:border-purple-500"> <option value="tech4">4 Assets: Tech Giants (AAPL, MSFT, NVDA, GOOGL)</option> <option value="multi4">4 Assets: Multi-Asset Macro (Equities, Treasuries, Gold, BTC)</option> <option value="crypto5">5 Assets: Crypto High-Beta (BTC, ETH, SOL, AVAX, LINK)</option> <option value="energy6">6 Assets: Global Energy & Commodities (XOM, CVX, COP, GLD, USO, SLV)</option> </select> </div> <!-- Quantum Parameters --> <div class="space-y-4 pt-2 border-t border-gray-800/80"> <div> <div class="flex justify-between text-xs text-gray-300 mb-1"> <span>Risk Aversion ($q$)</span> <span id="label-q" class="font-mono text-purple-300">0.50</span> </div> <input id="input-q" type="range" min="0.05" max="1.5" step="0.05" value="0.50" oninput="updateParameters()" class="w-full accent-purple-500 cursor-pointer"> </div> <div> <div class="flex justify-between text-xs text-gray-300 mb-1"> <span>Target Cardinality ($K$)</span> <span id="label-k" class="font-mono text-purple-300">2 assets</span> </div> <input id="input-k" type="range" min="1" max="3" step="1" value="2" oninput="updateParameters()" class="w-full accent-purple-500 cursor-pointer"> </div> <div> <div class="flex justify-between text-xs text-gray-300 mb-1"> <span>Budget Penalty ($\lambda_{\text{pen}}$)</span> <span id="label-lambda" class="font-mono text-purple-300">1.20</span> </div> <input id="input-lambda" type="range" min="0.2" max="3.0" step="0.1" value="1.2" oninput="updateParameters()" class="w-full accent-purple-500 cursor-pointer"> </div> <div id="qaoa-layers-control"> <div class="flex justify-between text-xs text-gray-300 mb-1"> <span>Circuit Depth ($p$ layers)</span> <span id="label-depth" class="font-mono text-purple-300">2 layers</span> </div> <input id="input-depth" type="range" min="1" max="4" step="1" value="2" oninput="updateCircuitDepth()" class="w-full accent-purple-500 cursor-pointer"> </div> <div> <div class="flex justify-between text-xs text-gray-300 mb-1"> <span>Learning Rate ($\eta$)</span> <span id="label-lr" class="font-mono text-purple-300">0.08</span> </div> <input id="input-lr" type="range" min="0.01" max="0.30" step="0.01" value="0.08" oninput="document.getElementById('label-lr').innerText=this.value" class="w-full accent-purple-500 cursor-pointer"> </div> </div> <!-- Action Buttons --> <div class="space-y-2 pt-2"> <button id="btn-run" onclick="toggleOptimization()" class="w-full py-2.5 rounded-xl bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-500 hover:to-indigo-500 text-white font-semibold text-xs tracking-wide shadow-lg shadow-purple-600/30 flex items-center justify-center space-x-2 transition"> <svg id="icon-run" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg> <span id="text-run">Run Hybrid Optimizer</span> </button> <div class="grid grid-cols-2 gap-2"> <button onclick="stepOptimization()" class="py-2 rounded-lg bg-gray-800 hover:bg-gray-700 text-gray-300 text-xs font-medium border border-gray-700 transition"> Single Step </button> <button onclick="resetOptimizer()" class="py-2 rounded-lg bg-gray-800 hover:bg-gray-700 text-gray-300 text-xs font-medium border border-gray-700 transition"> Reset State </button> </div> </div> </div> <!-- Main Visualizations Area (3 cols) --> <div class="lg:col-span-3 space-y-6"> <!-- Convergence Trajectory & Probability Distribution --> <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="glass-panel p-5 rounded-2xl border border-gray-800 flex flex-col"> <div class="flex items-center justify-between mb-3"> <h3 class="text-sm font-bold text-gray-200 flex items-center space-x-2"> <span class="w-2.5 h-2.5 rounded-full bg-purple-500"></span> <span>Variational Energy Convergence</span> </h3> <span class="text-[11px] font-mono text-gray-400">$\langle \mathcal{H}_C \rangle \to E_0$</span> </div> <div id="chart-convergence" class="w-full h-64 flex-1"></div> </div> <div class="glass-panel p-5 rounded-2xl border border-gray-800 flex flex-col"> <div class="flex items-center justify-between mb-3"> <h3 class="text-sm font-bold text-gray-200 flex items-center space-x-2"> <span class="w-2.5 h-2.5 rounded-full bg-emerald-500"></span> <span>Basis State Probabilities $|\langle x | \psi \rangle|^2$</span> </h3> <span id="optimal-state-badge" class="text-[11px] font-mono px-2 py-0.5 rounded bg-emerald-500/20 text-emerald-300 border border-emerald-500/30"> Optimum: |1010⟩ </span> </div> <div id="chart-probabilities" class="w-full h-64 flex-1"></div> </div> </div> <!-- Quantum Circuit Schematic --> <div class="glass-panel p-5 rounded-2xl border border-gray-800 space-y-3"> <div class="flex items-center justify-between"> <h3 class="text-sm font-bold text-gray-200 flex items-center space-x-2"> <svg class="w-4 h-4 text-indigo-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" /> </svg> <span>Parameterized Quantum Circuit Schematic</span> </h3> <div class="text-[11px] text-gray-400 font-mono" id="circuit-summary"> 4 Qubits | Depth: 2 | Cost $U_C(\gamma)$ + Mixer $U_B(\beta)$ </div> </div> <div class="overflow-x-auto scrollbar-thin py-2"> <svg id="svg-circuit" class="w-full min-w-[650px] h-48 bg-gray-950/60 rounded-xl border border-gray-800/80 p-2"></svg> </div> </div> <!-- Bottom Diagnostics: Bloch Vectors & Entanglement --> <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="glass-panel p-5 rounded-2xl border border-gray-800"> <div class="flex items-center justify-between mb-3"> <h3 class="text-sm font-bold text-gray-200 flex items-center space-x-2"> <span class="w-2.5 h-2.5 rounded-full bg-blue-500"></span> <span>Single-Qubit Bloch Vector Projections</span> </h3> <span class="text-[11px] font-mono text-gray-400">$\mathbf{r}_i = (\langle X \rangle, \langle Y \rangle, \langle Z \rangle)$</span> </div> <div id="chart-bloch" class="w-full h-56"></div> </div> <div class="glass-panel p-5 rounded-2xl border border-gray-800"> <div class="flex items-center justify-between mb-3"> <h3 class="text-sm font-bold text-gray-200 flex items-center space-x-2"> <span class="w-2.5 h-2.5 rounded-full bg-pink-500"></span> <span>Ising Spin-Glass Coupling Matrix ($J_{ij}$)</span> </h3> <span class="text-[11px] font-mono text-gray-400">$\mathcal{H}_C = \sum h_i Z_i + \sum J_{ij} Z_i Z_j$</span> </div> <div id="chart-hamiltonian" class="w-full h-56"></div> </div> </div> </div> </div> <!-- Mathematical Theory & Rigorous Formulation Section --> <div class="glass-panel p-8 rounded-2xl border border-gray-800 space-y-6"> <div class="border-b border-gray-800 pb-4"> <h3 class="text-lg font-bold text-gray-100 flex items-center space-x-2"> <span class="text-purple-400">§</span> <span>Rigorous Quantum Mechanical Formulation & Spin Mapping</span> </h3> <p class="text-xs text-gray-400 mt-1">Mathematical mapping of Markowitz portfolio optimization onto quantum transverse-field Ising Hamiltonians</p> </div> <div class="grid grid-cols-1 md:grid-cols-3 gap-6 text-xs text-gray-300 leading-relaxed"> <div class="p-4 rounded-xl bg-gray-900/60 border border-gray-800 space-y-2"> <div class="font-bold text-purple-400 text-sm">1. QUBO to Ising Transformation</div> <p>Each binary portfolio decision variable $x_i \in \{0, 1\}$ is represented as a spin operator on the 2-dimensional Hilbert space $\mathcal{H}_2 \cong \mathbb{C}^2$:</p> <div class="font-mono p-2 bg-black/40 rounded border border-gray-800 text-[11px] text-indigo-300"> $$x_i \mapsto \frac{I - \sigma_i^z}{2}, \quad \sigma^z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}$$ </div> <p>Eigenstate $|0\rangle \to x_i = 0$ (unallocated) and $|1\rangle \to x_i = 1$ (allocated).</p> </div> <div class="p-4 rounded-xl bg-gray-900/60 border border-gray-800 space-y-2"> <div class="font-bold text-indigo-400 text-sm">2. QAOA Alternating Operators</div> <p>QAOA prepares the state $|\boldsymbol{\gamma}, \boldsymbol{\beta}\rangle = \prod_{l=1}^p e^{-i \beta_l \mathcal{H}_M} e^{-i \gamma_l \mathcal{H}_C} |+\rangle^{\otimes n}$.</p> <div class="font-mono p-2 bg-black/40 rounded border border-gray-800 text-[11px] text-indigo-300"> $$\mathcal{H}_M = \sum_{i=1}^n \sigma_i^x, \quad \mathcal{H}_C = \sum_i h_i \sigma_i^z + \sum_{i<j} J_{ij} \sigma_i^z \sigma_j^z$$ </div> <p>By Farhi et al. (2014), as $p \to \infty$, the state adiabatically converges to the exact ground state with approximation ratio $\alpha \to 1$.</p> </div> <div class="p-4 rounded-xl bg-gray-900/60 border border-gray-800 space-y-2"> <div class="font-bold text-pink-400 text-sm">3. Rayleigh-Ritz Variational Principle</div> <p>The Variational Quantum Eigensolver evaluates expectation values through the hardware-efficient ansatz $|\psi(\boldsymbol{\theta})\rangle$:</p> <div class="font-mono p-2 bg-black/40 rounded border border-gray-800 text-[11px] text-indigo-300"> $$\langle \mathcal{H}_C \rangle_{\boldsymbol{\theta}} = \sum_{x \in \{0, 1\}^n} |\langle x | \psi(\boldsymbol{\theta}) \rangle|^2 E(x) \ge E_0$$ </div> <p>Analytical parameter-shift gradients $\nabla_{\theta_k} \langle \mathcal{H} \rangle = \frac{\langle \mathcal{H} \rangle_{\theta_k + \frac{\pi}{2}} - \langle \mathcal{H} \rangle_{\theta_k - \frac{\pi}{2}}}{2}$ allow gradient descent without classical finite-difference truncation error.</p> </div> </div> </div> </main> <!-- Footer --> <footer class="border-t border-gray-800 glass-panel py-6 px-6 text-center text-xs text-gray-500"> <div class="max-w-7xl mx-auto flex flex-col sm:flex-row items-center justify-between gap-4"> <div> <span>Designed & Developed for </span> <a href="https://huggingface.co/At1uri" target="_blank" class="text-purple-400 hover:text-purple-300 font-semibold underline">At1uri Hub</a> <span> · High-Performance In-Browser Quantum Simulation Engine</span> </div> <div class="flex items-center space-x-4 text-gray-400"> <span>No Server Required</span> <span>·</span> <span>Exact Statevector $\in \mathbb{C}^{2^n}$</span> <span>·</span> <span>Zero Latency</span> </div> </div> </footer> <!-- Quantum Engine JavaScript Code --> <script> /* ===================================================================== QUANTUM COMPUTATIONAL SIMULATION & ALGORITHM ENGINE Pure JavaScript Client-Side Statevector Simulator ===================================================================== */ // Complex number utility functions function complex(re, im) { return { re: re, im: im }; } function c_add(a, b) { return { re: a.re + b.re, im: a.im + b.im }; } function c_sub(a, b) { return { re: a.re - b.re, im: a.im - b.im }; } function c_mul(a, b) { return { re: a.re * b.re - a.im * b.im, im: a.re * b.im + a.im * b.re }; } function c_exp(phi) { return { re: Math.cos(phi), im: Math.sin(phi) }; } function c_mag2(a) { return a.re * a.re + a.im * a.im; } // Pre-defined universes const UNIVERSES = { tech4: { names: ['AAPL', 'MSFT', 'NVDA', 'GOOGL'], mu: [0.18, 0.16, 0.34, 0.14], vol: [0.22, 0.20, 0.42, 0.24], corr: [ [1.00, 0.68, 0.62, 0.65], [0.68, 1.00, 0.64, 0.72], [0.62, 0.64, 1.00, 0.58], [0.65, 0.72, 0.58, 1.00] ] }, multi4: { names: ['SPY (Eq)', 'TLT (Bnd)', 'GLD (Gld)', 'BTC (Crp)'], mu: [0.12, 0.04, 0.08, 0.45], vol: [0.18, 0.15, 0.16, 0.65], corr: [ [1.00, -0.28, 0.12, 0.38], [-0.28, 1.00, 0.25, -0.15], [0.12, 0.25, 1.00, 0.10], [0.38, -0.15, 0.10, 1.00] ] }, crypto5: { names: ['BTC', 'ETH', 'SOL', 'AVAX', 'LINK'], mu: [0.42, 0.48, 0.65, 0.55, 0.40], vol: [0.60, 0.72, 0.88, 0.92, 0.75], corr: [ [1.00, 0.82, 0.68, 0.65, 0.70], [0.82, 1.00, 0.75, 0.74, 0.78], [0.68, 0.75, 1.00, 0.80, 0.66], [0.65, 0.74, 0.80, 1.00, 0.69], [0.70, 0.78, 0.66, 0.69, 1.00] ] }, energy6: { names: ['XOM', 'CVX', 'COP', 'GLD', 'USO', 'SLV'], mu: [0.14, 0.13, 0.16, 0.09, 0.12, 0.11], vol: [0.26, 0.25, 0.30, 0.16, 0.38, 0.28], corr: [ [1.00, 0.85, 0.78, 0.10, 0.72, 0.15], [0.85, 1.00, 0.80, 0.08, 0.70, 0.12], [0.78, 0.80, 1.00, 0.12, 0.75, 0.18], [0.10, 0.08, 0.12, 1.00, 0.15, 0.76], [0.72, 0.70, 0.75, 0.15, 1.00, 0.22], [0.15, 0.12, 0.18, 0.76, 0.22, 1.00] ] } }; // Global Quantum State Engine Variables let currentUniverseKey = 'tech4'; let currentAlgorithm = 'QAOA'; let numQubits = 4; let riskAversion = 0.50; let targetCardinality = 2; let budgetPenalty = 1.20; let circuitDepth = 2; let learningRate = 0.08; let isOptimizing = false; let optInterval = null; let currentStep = 0; // Parameters let qaoa_gamma = [0.35, 0.25, 0.15, 0.10]; let qaoa_beta = [0.55, 0.40, 0.25, 0.15]; let vqe_theta = []; // Dynamically sized for ansatz: numQubits * (depth + 1) // Convergence History let history_steps = []; let history_energy = []; let history_entropy = []; // Classical ground truth let classicalMinEnergy = 0; let classicalMaxEnergy = 0; let classicalOptimalBitstring = '0000'; let basisStateEnergies = []; // Hamiltonian parameters let h_vector = []; let J_matrix = []; let C_offset = 0; // Initialize State function initEngine() { loadUniversePreset(); } function setAlgorithm(algo) { currentAlgorithm = algo; document.getElementById('btn-algo-qaoa').className = algo === 'QAOA' ? "px-3 py-2 text-xs font-semibold rounded-lg bg-purple-600 text-white shadow-md shadow-purple-600/30 border border-purple-500 transition" : "px-3 py-2 text-xs font-semibold rounded-lg bg-gray-800 text-gray-400 border border-gray-700 hover:text-white transition"; document.getElementById('btn-algo-vqe').className = algo === 'VQE' ? "px-3 py-2 text-xs font-semibold rounded-lg bg-purple-600 text-white shadow-md shadow-purple-600/30 border border-purple-500 transition" : "px-3 py-2 text-xs font-semibold rounded-lg bg-gray-800 text-gray-400 border border-gray-700 hover:text-white transition"; document.getElementById('metric-algo').innerText = `${algo} (d=${circuitDepth})`; resetOptimizer(); } function loadUniversePreset() { currentUniverseKey = document.getElementById('select-universe').value; const univ = UNIVERSES[currentUniverseKey]; numQubits = univ.names.length; // Update max K slider const kSlider = document.getElementById('input-k'); kSlider.max = numQubits - 1; if (parseInt(kSlider.value) >= numQubits) { kSlider.value = Math.max(1, Math.floor(numQubits / 2)); } targetCardinality = parseInt(kSlider.value); document.getElementById('label-k').innerText = `${targetCardinality} assets`; computeIsingHamiltonian(); resetOptimizer(); } function updateParameters() { riskAversion = parseFloat(document.getElementById('input-q').value); targetCardinality = parseInt(document.getElementById('input-k').value); budgetPenalty = parseFloat(document.getElementById('input-lambda').value); document.getElementById('label-q').innerText = riskAversion.toFixed(2); document.getElementById('label-k').innerText = `${targetCardinality} assets`; document.getElementById('label-lambda').innerText = budgetPenalty.toFixed(2); computeIsingHamiltonian(); resetOptimizer(); } function updateCircuitDepth() { circuitDepth = parseInt(document.getElementById('input-depth').value); document.getElementById('label-depth').innerText = `${circuitDepth} layers`; document.getElementById('metric-algo').innerText = `${currentAlgorithm} (d=${circuitDepth})`; resetOptimizer(); } // Convert Mean-Variance-Cardinality QUBO to Longitudinal Ising Hamiltonian function computeIsingHamiltonian() { const univ = UNIVERSES[currentUniverseKey]; const n = numQubits; const mu = univ.mu; const vol = univ.vol; const corr = univ.corr; // Covariance matrix Sigma_ij = vol_i * vol_j * corr_ij const Sigma = []; for (let i = 0; i < n; i++) { Sigma[i] = []; for (let j = 0; j < n; j++) { Sigma[i][j] = vol[i] * vol[j] * corr[i][j]; } } // Linear coefficients h_i and Quadratic J_ij h_vector = new Array(n).fill(0); J_matrix = []; for (let i = 0; i < n; i++) J_matrix[i] = new Array(n).fill(0); C_offset = 0; // Analytical mapping from QUBO: Q_ii x_i + sum_{i<j} Q_ij x_i x_j // with x_i = (1 - Z_i)/2 const Q = []; for (let i = 0; i < n; i++) { Q[i] = new Array(n).fill(0); // Q_ii = q * Sigma_ii - mu_i + lambda * (1 - 2*K) Q[i][i] = riskAversion * Sigma[i][i] - mu[i] + budgetPenalty * (1 - 2 * targetCardinality); } for (let i = 0; i < n; i++) { for (let j = i + 1; j < n; j++) { // Q_ij = 2 * q * Sigma_ij + 2 * lambda const q_ij = 2 * riskAversion * Sigma[i][j] + 2 * budgetPenalty; Q[i][j] = q_ij; Q[j][i] = q_ij; } } // Map Q to Ising: // x_i = (1 - Z_i)/2, x_i x_j = (1 - Z_i - Z_j + Z_i Z_j)/4 let offset = budgetPenalty * (targetCardinality * targetCardinality); for (let i = 0; i < n; i++) { offset += Q[i][i] / 2; h_vector[i] -= Q[i][i] / 2; } for (let i = 0; i < n; i++) { for (let j = i + 1; j < n; j++) { offset += Q[i][j] / 4; h_vector[i] -= Q[i][j] / 4; h_vector[j] -= Q[i][j] / 4; J_matrix[i][j] = Q[i][j] / 4; J_matrix[j][i] = Q[i][j] / 4; } } C_offset = offset; // Compute exact classical energies for all 2^n basis states const numStates = 1 << n; basisStateEnergies = []; classicalMinEnergy = Infinity; classicalMaxEnergy = -Infinity; classicalOptimalBitstring = ''; for (let x = 0; x < numStates; x++) { let E = C_offset; // Z_i eigenvalue for basis state |x> is (-1)^{bit_i} // where bit_i is the i-th bit of x (0 -> +1, 1 -> -1) for (let i = 0; i < n; i++) { const bit_i = (x >> (n - 1 - i)) & 1; const z_i = bit_i === 0 ? 1 : -1; E += h_vector[i] * z_i; } for (let i = 0; i < n; i++) { const bit_i = (x >> (n - 1 - i)) & 1; const z_i = bit_i === 0 ? 1 : -1; for (let j = i + 1; j < n; j++) { const bit_j = (x >> (n - 1 - j)) & 1; const z_j = bit_j === 0 ? 1 : -1; E += J_matrix[i][j] * (z_i * z_j); } } basisStateEnergies.push({ state: x, energy: E, bitstring: x.toString(2).padStart(n, '0') }); if (E < classicalMinEnergy) { classicalMinEnergy = E; classicalOptimalBitstring = x.toString(2).padStart(n, '0'); } if (E > classicalMaxEnergy) { classicalMaxEnergy = E; } } document.getElementById('metric-ground').innerText = classicalMinEnergy.toFixed(4); document.getElementById('metric-ground-state').innerText = `Target: |${classicalOptimalBitstring}⟩`; document.getElementById('optimal-state-badge').innerText = `Optimum: |${classicalOptimalBitstring}⟩`; renderHamiltonianHeatmap(); } // Reset Optimizer state function resetOptimizer() { if (isOptimizing) toggleOptimization(); currentStep = 0; history_steps = []; history_energy = []; history_entropy = []; // Initialize parameters qaoa_gamma = [0.25, 0.20, 0.15, 0.10]; qaoa_beta = [0.45, 0.35, 0.25, 0.15]; const vqeParamCount = numQubits * (circuitDepth + 1); vqe_theta = []; for (let i = 0; i < vqeParamCount; i++) { vqe_theta.push(0.4 * Math.sin(i * 1.3)); } evaluateCurrentState(); drawCircuitSchematic(); } // Exact Quantum Statevector Evolution Engine function simulateCircuit() { const n = numQubits; const dim = 1 << n; let psi = []; if (currentAlgorithm === 'QAOA') { // Initial state: Equal superposition |+>^n const norm = 1.0 / Math.sqrt(dim); for (let i = 0; i < dim; i++) { psi.push(complex(norm, 0)); } // Apply p alternating QAOA layers for (let l = 0; l < circuitDepth; l++) { const gamma = qaoa_gamma[l]; const beta = qaoa_beta[l]; // 1. Cost Unitary: U_C(gamma) = exp(-i * gamma * H_C) // Since H_C is diagonal in computational basis, U_C applies phase exp(-i * gamma * E(x)) for (let x = 0; x < dim; x++) { const phase = -gamma * basisStateEnergies[x].energy; const u_phase = c_exp(phase); psi[x] = c_mul(psi[x], u_phase); } // 2. Mixer Unitary: U_B(beta) = prod_k exp(-i * beta * X_k) // Apply Rx(2 * beta) to each qubit k for (let k = 0; k < n; k++) { applySingleQubitGate(psi, n, k, [ [complex(Math.cos(beta), 0), complex(0, -Math.sin(beta))], [complex(0, -Math.sin(beta)), complex(Math.cos(beta), 0)] ]); } } } else { // VQE: Hardware-efficient ansatz // Initial state: |0>^n for (let i = 0; i < dim; i++) { psi.push(complex(i === 0 ? 1 : 0, 0)); } let paramIdx = 0; // Initial rotation layer for (let k = 0; k < n; k++) { const th = vqe_theta[paramIdx++] || 0; applyRyGate(psi, n, k, th); } // Repeated entangling layers for (let d = 0; d < circuitDepth; d++) { // Entanglement: Linear CNOT chain (k -> k+1) for (let k = 0; k < n - 1; k++) { applyCnotGate(psi, n, k, k + 1); } // Ring closure if n >= 4 if (n >= 4) applyCnotGate(psi, n, n - 1, 0); // Parameterized Ry rotations for (let k = 0; k < n; k++) { const th = vqe_theta[paramIdx++] || 0; applyRyGate(psi, n, k, th); } } } return psi; } // Apply single qubit 2x2 unitary matrix to qubit `target` (0 = MSB, n-1 = LSB) function applySingleQubitGate(psi, n, target, U) { const dim = 1 << n; const bitMask = 1 << (n - 1 - target); for (let i = 0; i < dim; i++) { if ((i & bitMask) === 0) { const j = i | bitMask; // pair with bit set const a = psi[i]; const b = psi[j]; // New amplitudes: U00*a + U01*b, U10*a + U11*b const new_a = c_add(c_mul(U[0][0], a), c_mul(U[0][1], b)); const new_b = c_add(c_mul(U[1][0], a), c_mul(U[1][1], b)); psi[i] = new_a; psi[j] = new_b; } } } function applyRyGate(psi, n, target, theta) { const c = Math.cos(theta / 2); const s = Math.sin(theta / 2); applySingleQubitGate(psi, n, target, [ [complex(c, 0), complex(-s, 0)], [complex(s, 0), complex(c, 0)] ]); } function applyCnotGate(psi, n, control, target) { const dim = 1 << n; const cMask = 1 << (n - 1 - control); const tMask = 1 << (n - 1 - target); for (let i = 0; i < dim; i++) { // If control is 1 and target is 0, swap with control=1, target=1 if ((i & cMask) !== 0 && (i & tMask) === 0) { const j = i | tMask; const temp = psi[i]; psi[i] = psi[j]; psi[j] = temp; } } } // Evaluate expectation values, entanglement, and diagnostics function evaluateCurrentState() { const psi = simulateCircuit(); const dim = 1 << numQubits; // 1. Compute Expectation Value <H_C> = sum P(x) * E(x) let energy = 0; const probs = []; for (let x = 0; x < dim; x++) { const p = c_mag2(psi[x]); probs.push(p); energy += p * basisStateEnergies[x].energy; } // 2. Approximation Ratio alpha in [0, 1] const denom = (classicalMinEnergy - classicalMaxEnergy); let ratio = denom !== 0 ? (energy - classicalMaxEnergy) / denom : 1.0; ratio = Math.max(0, Math.min(1.0, ratio)); // 3. Von Neumann Entanglement Entropy of qubit 0 vs rest // Partial trace rho_0 = Tr_{rest}(|psi><psi|) let r00 = 0, r11 = 0, r01_re = 0, r01_im = 0; const msbMask = 1 << (numQubits - 1); for (let i = 0; i < dim; i++) { const p = c_mag2(psi[i]); if ((i & msbMask) === 0) { r00 += p; const j = i | msbMask; const conj = { re: psi[j].re, im: -psi[j].im }; const cross = c_mul(psi[i], conj); r01_re += cross.re; r01_im += cross.im; } else { r11 += p; } } // Eigenvalues of 2x2 density matrix rho_0 const det = r00 * r11 - (r01_re * r01_re + r01_im * r01_im); const disc = Math.sqrt(Math.max(0, 1 - 4 * Math.max(0, det))); const lambda1 = Math.max(1e-12, (1 + disc) / 2); const lambda2 = Math.max(1e-12, (1 - disc) / 2); const entropy = -(lambda1 * Math.log2(lambda1) + lambda2 * Math.log2(lambda2)); // 4. Bloch vector coordinates per qubit: <X>, <Y>, <Z> const blochVectors = []; for (let k = 0; k < numQubits; k++) { const bitMask = 1 << (numQubits - 1 - k); let z_exp = 0, x_exp = 0, y_exp = 0; for (let i = 0; i < dim; i++) { const bit = (i & bitMask) === 0 ? 0 : 1; const p = c_mag2(psi[i]); z_exp += (bit === 0 ? 1 : -1) * p; if (bit === 0) { const j = i | bitMask; // <X> = 2 * Re(psi_0^* * psi_1) const c_cross = c_mul({ re: psi[i].re, im: -psi[i].im }, psi[j]); x_exp += 2 * c_cross.re; // <Y> = 2 * Im(psi_0^* * psi_1) y_exp += 2 * c_cross.im; } } blochVectors.push({ qubit: k, x: x_exp, y: y_exp, z: z_exp }); } // Record history history_steps.push(currentStep); history_energy.push(energy); history_entropy.push(entropy); // Update UI Metrics document.getElementById('metric-energy').innerText = energy.toFixed(4); const err = Math.abs(energy - classicalMinEnergy); document.getElementById('metric-energy-delta').innerText = `Error ΔE: ${err.toFixed(4)}`; document.getElementById('metric-ratio').innerText = `${(ratio * 100).toFixed(1)}%`; document.getElementById('metric-entropy').innerText = `${entropy.toFixed(3)} bits`; // Render Charts renderConvergenceChart(); renderProbabilityChart(probs); renderBlochChart(blochVectors); return energy; } // Step optimization via analytical parameter-shift rule / numerical gradient function stepOptimization() { currentStep++; const lr = parseFloat(document.getElementById('input-lr').value); if (currentAlgorithm === 'QAOA') { const delta = 0.04; for (let l = 0; l < circuitDepth; l++) { // Gradient wrt gamma_l const origG = qaoa_gamma[l]; qaoa_gamma[l] = origG + delta; const e_plus = computeEnergyOnly(); qaoa_gamma[l] = origG - delta; const e_minus = computeEnergyOnly(); qaoa_gamma[l] = origG - lr * ((e_plus - e_minus) / (2 * delta)); // Gradient wrt beta_l const origB = qaoa_beta[l]; qaoa_beta[l] = origB + delta; const eb_plus = computeEnergyOnly(); qaoa_beta[l] = origB - delta; const eb_minus = computeEnergyOnly(); qaoa_beta[l] = origB - lr * ((eb_plus - eb_minus) / (2 * delta)); } } else { // VQE Parameter shift rule: grad_k = (E(theta + pi/2) - E(theta - pi/2)) / 2 const shift = Math.PI / 2; for (let i = 0; i < vqe_theta.length; i++) { const orig = vqe_theta[i]; vqe_theta[i] = orig + shift; const e_plus = computeEnergyOnly(); vqe_theta[i] = orig - shift; const e_minus = computeEnergyOnly(); vqe_theta[i] = orig; const grad = (e_plus - e_minus) / 2.0; vqe_theta[i] -= lr * grad; } } evaluateCurrentState(); drawCircuitSchematic(); } function computeEnergyOnly() { const psi = simulateCircuit(); const dim = 1 << numQubits; let e = 0; for (let x = 0; x < dim; x++) { e += c_mag2(psi[x]) * basisStateEnergies[x].energy; } return e; } function toggleOptimization() { isOptimizing = !isOptimizing; const btn = document.getElementById('btn-run'); const text = document.getElementById('text-run'); if (isOptimizing) { text.innerText = "Pause Optimizer"; btn.className = "w-full py-2.5 rounded-xl bg-amber-600 hover:bg-amber-500 text-white font-semibold text-xs tracking-wide shadow-lg shadow-amber-600/30 flex items-center justify-center space-x-2 transition"; optInterval = setInterval(() => { stepOptimization(); if (currentStep >= 50) { toggleOptimization(); } }, 120); } else { clearInterval(optInterval); text.innerText = "Run Hybrid Optimizer"; btn.className = "w-full py-2.5 rounded-xl bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-500 hover:to-indigo-500 text-white font-semibold text-xs tracking-wide shadow-lg shadow-purple-600/30 flex items-center justify-center space-x-2 transition"; } } /* ===================================================================== PLOTLY RENDERING FUNCTIONS ===================================================================== */ function renderConvergenceChart() { const traceVQE = { x: history_steps, y: history_energy, mode: 'lines+markers', name: 'Quantum ⟨H_C⟩', line: { color: '#a855f7', width: 2.5 }, marker: { size: 5, color: '#c084fc' } }; const traceGround = { x: [0, Math.max(10, currentStep)], y: [classicalMinEnergy, classicalMinEnergy], mode: 'lines', name: 'Exact Ground State E0', line: { color: '#10b981', width: 2, dash: 'dash' } }; const layout = { paper_bgcolor: 'transparent', plot_bgcolor: 'transparent', margin: { l: 45, r: 20, t: 10, b: 35 }, xaxis: { title: { text: 'Optimization Step', font: { size: 10, color: '#9ca3af' } }, tickfont: { size: 9, color: '#9ca3af' }, gridcolor: '#1f2937', zeroline: false }, yaxis: { title: { text: 'Energy Eigenvalue', font: { size: 10, color: '#9ca3af' } }, tickfont: { size: 9, color: '#9ca3af' }, gridcolor: '#1f2937', zeroline: false }, legend: { font: { size: 9, color: '#d1d5db' }, orientation: 'h', y: 1.15, x: 0 }, showlegend: true }; Plotly.react('chart-convergence', [traceVQE, traceGround], layout, { responsive: true, displayModeBar: false }); } function renderProbabilityChart(probs) { const n = numQubits; const dim = 1 << n; const bitstrings = []; const colors = []; for (let x = 0; x < dim; x++) { const bs = x.toString(2).padStart(n, '0'); bitstrings.push('|' + bs + '⟩'); colors.push(bs === classicalOptimalBitstring ? '#10b981' : '#6366f1'); } const trace = { x: bitstrings, y: probs, type: 'bar', marker: { color: colors, line: { color: '#c084fc', width: 0.5 } } }; const layout = { paper_bgcolor: 'transparent', plot_bgcolor: 'transparent', margin: { l: 40, r: 15, t: 10, b: 45 }, xaxis: { tickfont: { size: 8, color: '#9ca3af' }, tickangle: -45, gridcolor: '#1f2937' }, yaxis: { title: { text: 'Sampling Probability', font: { size: 10, color: '#9ca3af' } }, tickfont: { size: 9, color: '#9ca3af' }, gridcolor: '#1f2937', range: [0, Math.max(0.4, Math.max(...probs) * 1.15)] }, showlegend: false }; Plotly.react('chart-probabilities', [trace], layout, { responsive: true, displayModeBar: false }); } function renderBlochChart(bloch) { const qLabels = bloch.map(b => `q${b.qubit}`); const traceX = { x: qLabels, y: bloch.map(b => b.x), name: '⟨X⟩', type: 'bar', marker: { color: '#ec4899' } }; const traceY = { x: qLabels, y: bloch.map(b => b.y), name: '⟨Y⟩', type: 'bar', marker: { color: '#eab308' } }; const traceZ = { x: qLabels, y: bloch.map(b => b.z), name: '⟨Z⟩', type: 'bar', marker: { color: '#3b82f6' } }; const layout = { paper_bgcolor: 'transparent', plot_bgcolor: 'transparent', barmode: 'group', margin: { l: 35, r: 15, t: 10, b: 30 }, xaxis: { tickfont: { size: 9, color: '#9ca3af' }, gridcolor: '#1f2937' }, yaxis: { range: [-1.05, 1.05], tickfont: { size: 9, color: '#9ca3af' }, gridcolor: '#1f2937' }, legend: { font: { size: 9, color: '#d1d5db' }, orientation: 'h', y: 1.2, x: 0.1 }, showlegend: true }; Plotly.react('chart-bloch', [traceX, traceY, traceZ], layout, { responsive: true, displayModeBar: false }); } function renderHamiltonianHeatmap() { const univ = UNIVERSES[currentUniverseKey]; const names = univ.names; const zValues = []; for (let i = 0; i < numQubits; i++) { zValues[i] = []; for (let j = 0; j < numQubits; j++) { zValues[i][j] = i === j ? h_vector[i] : J_matrix[i][j]; } } const trace = { z: zValues, x: names, y: names, type: 'heatmap', colorscale: 'Viridis', showscale: false }; const layout = { paper_bgcolor: 'transparent', plot_bgcolor: 'transparent', margin: { l: 65, r: 15, t: 10, b: 40 }, xaxis: { tickfont: { size: 9, color: '#9ca3af' } }, yaxis: { tickfont: { size: 9, color: '#9ca3af' } } }; Plotly.react('chart-hamiltonian', [trace], layout, { responsive: true, displayModeBar: false }); } // Interactive Circuit Schematic Drawer function drawCircuitSchematic() { const svg = document.getElementById('svg-circuit'); svg.innerHTML = ''; const n = numQubits; const wireHeight = 36; const startX = 60; let curX = startX; // Draw Wires & Labels for (let i = 0; i < n; i++) { const y = 30 + i * wireHeight; // Label const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', 15); text.setAttribute('y', y + 4); text.setAttribute('fill', '#9ca3af'); text.setAttribute('font-size', '11px'); text.setAttribute('font-family', 'monospace'); text.textContent = `|q${i}⟩`; svg.appendChild(text); // Wire const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', startX - 10); line.setAttribute('y1', y); line.setAttribute('x2', 650); line.setAttribute('y2', y); line.setAttribute('class', 'quantum-wire'); svg.appendChild(line); } if (currentAlgorithm === 'QAOA') { // Initial H gates for (let i = 0; i < n; i++) { drawGate(svg, curX, 30 + i * wireHeight, 'H', '#3b82f6'); } curX += 45; for (let l = 0; l < circuitDepth; l++) { // Barrier line drawBarrier(svg, curX, 15, 30 + (n - 1) * wireHeight + 15); curX += 15; // Cost Unitary block: Rz(h) & Rzz(J) for (let i = 0; i < n; i++) { const angle = (qaoa_gamma[l] * h_vector[i]).toFixed(2); drawGate(svg, curX, 30 + i * wireHeight, `Rz`, '#8b5cf6', `γh`); } curX += 45; // Entangling couplings Rzz for (let i = 0; i < Math.min(n - 1, 2); i++) { drawCnotGate(svg, curX, 30 + i * wireHeight, 30 + (i + 1) * wireHeight); curX += 30; } drawBarrier(svg, curX, 15, 30 + (n - 1) * wireHeight + 15); curX += 15; // Mixer Unitary: Rx(2*beta) for (let i = 0; i < n; i++) { const angle = (2 * qaoa_beta[l]).toFixed(2); drawGate(svg, curX, 30 + i * wireHeight, `Rx`, '#ec4899', `2β`); } curX += 45; } } else { // VQE: Ry and CNOT layers for (let l = 0; l <= circuitDepth; l++) { for (let i = 0; i < n; i++) { drawGate(svg, curX, 30 + i * wireHeight, 'Ry', '#8b5cf6', `θ`); } curX += 45; if (l < circuitDepth) { for (let i = 0; i < n - 1; i++) { drawCnotGate(svg, curX, 30 + i * wireHeight, 30 + (i + 1) * wireHeight); curX += 28; } } } } document.getElementById('circuit-summary').innerText = `${numQubits} Qubits | ${currentAlgorithm} | Depth: ${circuitDepth} | Width: ${curX}px`; } function drawGate(svg, x, y, label, color, sub) { const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); rect.setAttribute('x', x - 13); rect.setAttribute('y', y - 13); rect.setAttribute('width', 26); rect.setAttribute('height', 26); rect.setAttribute('fill', '#111827'); rect.setAttribute('stroke', color); rect.setAttribute('stroke-width', '1.5'); rect.setAttribute('rx', '4'); svg.appendChild(rect); const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', x); text.setAttribute('y', y + (sub ? 0 : 4)); text.setAttribute('text-anchor', 'middle'); text.setAttribute('fill', '#f3f4f6'); text.setAttribute('font-size', '10px'); text.setAttribute('font-weight', 'bold'); text.textContent = label; svg.appendChild(text); if (sub) { const subText = document.createElementNS('http://www.w3.org/2000/svg', 'text'); subText.setAttribute('x', x); subText.setAttribute('y', y + 8); subText.setAttribute('text-anchor', 'middle'); subText.setAttribute('fill', '#9ca3af'); subText.setAttribute('font-size', '7px'); subText.textContent = sub; svg.appendChild(subText); } } function drawCnotGate(svg, x, y1, y2) { const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', x); line.setAttribute('y1', y1); line.setAttribute('x2', x); line.setAttribute('y2', y2); line.setAttribute('stroke', '#06b6d4'); line.setAttribute('stroke-width', '1.5'); svg.appendChild(line); // Control circle (solid) const cCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); cCircle.setAttribute('cx', x); cCircle.setAttribute('cy', y1); cCircle.setAttribute('r', 3.5); cCircle.setAttribute('fill', '#06b6d4'); svg.appendChild(cCircle); // Target circle (plus) const tCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); tCircle.setAttribute('cx', x); tCircle.setAttribute('cy', y2); tCircle.setAttribute('r', 7); tCircle.setAttribute('fill', '#111827'); tCircle.setAttribute('stroke', '#06b6d4'); tCircle.setAttribute('stroke-width', '1.5'); svg.appendChild(tCircle); const crossH = document.createElementNS('http://www.w3.org/2000/svg', 'line'); crossH.setAttribute('x1', x - 5); crossH.setAttribute('y1', y2); crossH.setAttribute('x2', x + 5); crossH.setAttribute('y2', y2); crossH.setAttribute('stroke', '#06b6d4'); crossH.setAttribute('stroke-width', '1.5'); svg.appendChild(crossH); const crossV = document.createElementNS('http://www.w3.org/2000/svg', 'line'); crossV.setAttribute('x1', x); crossV.setAttribute('y1', y2 - 5); crossV.setAttribute('x2', x); crossV.setAttribute('y2', y2 + 5); crossV.setAttribute('stroke', '#06b6d4'); crossV.setAttribute('stroke-width', '1.5'); svg.appendChild(crossV); } function drawBarrier(svg, x, y1, y2) { const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', x); line.setAttribute('y1', y1); line.setAttribute('x2', x); line.setAttribute('y2', y2); line.setAttribute('stroke', '#4b5563'); line.setAttribute('stroke-width', '1'); line.setAttribute('stroke-dasharray', '3,3'); svg.appendChild(line); } // Run on window load window.addEventListener('DOMContentLoaded', () => { initEngine(); }); </script> </body> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quantum Portfolio Optimization Studio | QAOA & VQE</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-2.32.0.min.js"></script>
<!-- KaTeX -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body);"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
brand: {
50: '#f5f3ff',
100: '#ede9fe',
500: '#8b5cf6',
600: '#7c3aed',
700: '#6d28d9',
900: '#4c1d95',
}
}
}
}
}
</script>
<style>
body {
background-color: #030712;
color: #f3f4f6;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.glass-panel {
background: rgba(17, 24, 39, 0.75);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.neon-glow-purple {
box-shadow: 0 0 25px rgba(139, 92, 246, 0.25);
}
.neon-border {
border: 1px solid rgba(139, 92, 246, 0.35);
}
.quantum-wire {
stroke: #4b5563;
stroke-width: 2;
}
.quantum-gate {
fill: #1f2937;
stroke: #8b5cf6;
stroke-width: 1.5;
rx: 4;
}
.scrollbar-thin::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background: #374151;
border-radius: 3px;
}
</style>
</head>
<body class="min-h-screen flex flex-col">
<!-- Top Navigation Header -->
<header class="border-b border-gray-800 glass-panel sticky top-0 z-50 px-6 py-4">
<div class="max-w-7xl mx-auto flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-purple-600 via-indigo-600 to-blue-500 flex items-center justify-center text-white shadow-lg shadow-purple-500/30">
<svg class="w-6 h-6 animate-spin" style="animation-duration: 12s;" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" />
</svg>
</div>
<div>
<div class="flex items-center space-x-2">
<h1 class="text-xl font-bold bg-gradient-to-r from-purple-400 via-indigo-300 to-blue-400 bg-clip-text text-transparent">
Quantum Portfolio Optimization Studio
</h1>
<span class="text-xs px-2 py-0.5 rounded-full bg-purple-500/20 text-purple-300 border border-purple-500/30 font-mono">
QAOA & VQE Engine
</span>
</div>
<p class="text-xs text-gray-400">Variational Quantum Eigensolver & Ising Spin-Glass Combinatorial Arbitrage</p>
</div>
</div>
<div class="flex items-center space-x-3 text-sm">
<a href="https://huggingface.co/At1uri" target="_blank" class="px-3 py-1.5 rounded-lg bg-gray-800 hover:bg-gray-700 text-gray-300 flex items-center space-x-2 border border-gray-700 transition">
<svg class="w-4 h-4 text-purple-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.53 1.032 1.53 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>
<span class="font-medium">At1uri Hub</span>
</a>