Download index.html from At1uri/quantum-portfolio-optimization-studio: direct link, hf CLI and curl.
- Browser
- Download file 52.9 kB
-
https://huggingface.co/spaces/At1uri/quantum-portfolio-optimization-studio/resolve/main/index.html
- Command line
-
hf download hf://spaces/At1uri/quantum-portfolio-optimization-studio/index.html
-
curl -L -o index.html https://huggingface.co/spaces/At1uri/quantum-portfolio-optimization-studio/resolve/main/index.html
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>
<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>