Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
32b5170
add orbital entanglement diagram and svg save
Feb 26, 2026
a6353a7
add svg export for histogram and circuit
Feb 26, 2026
ed9db51
linting
Feb 26, 2026
b693c7b
allow grouping of selected orbitals
Feb 26, 2026
869d14c
resolve comments
Feb 27, 2026
b7c94ae
Make svg export listen to user changes in widget
Feb 27, 2026
3d16d3c
generalize to a chord diagram
Feb 27, 2026
1211573
linting
Feb 27, 2026
839b31c
code style fixes
Feb 27, 2026
273c218
unify svg generation remove dom shim
Feb 28, 2026
752865c
fix selection
Feb 28, 2026
adf2d12
remove domshim file
Feb 28, 2026
b2ba1fa
snapshot for working demo
Mar 24, 2026
541b0f6
save pre-merge
Mar 25, 2026
48ba65b
Merge remote-tracking branch 'origin/main' into jpu/orbital-entagleme…
Mar 25, 2026
8cb0e48
formatting
Mar 25, 2026
2948f3b
resolve some comments
Mar 25, 2026
bffa905
fix build
Mar 25, 2026
4155317
test again
Mar 30, 2026
78198ca
test
Mar 30, 2026
5919c0e
minor fixes
Mar 30, 2026
644cd10
remove all but the new widget
Mar 31, 2026
bb82e01
further reverts
Mar 31, 2026
48af091
generalize diagram
Mar 31, 2026
6a17ac0
update sample
Mar 31, 2026
9708ba8
fixes
Mar 31, 2026
7d3c5cc
remove unused var
Mar 31, 2026
85615cc
formatting
Mar 31, 2026
f6efb99
remove unused package
Mar 31, 2026
c1701ec
remove unused css
Mar 31, 2026
ba388eb
clear output in notebook
Mar 31, 2026
41e2baa
add support for multiple highlighted groups
Mar 31, 2026
ef339df
linting
Mar 31, 2026
862d315
cleaning and fixing limited color maps
Apr 7, 2026
726bb3d
Merge remote-tracking branch 'origin/main' into jpu/orbital-entagleme…
Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions samples/notebooks/orbital_entanglement.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "4ce65e98",
"metadata": {},
"source": [
"# Orbital Entanglement Chord Diagram — 250 Synthetic Orbitals\n",
"\n",
"Demonstrates the `Entanglement` JS widget for an orbital-entanglement use case on a large system with\n",
"synthetic single-orbital entropies and mutual information. Five highly entangled clusters are\n",
"highlighted with distinct outline colours and grouped together on the ring."
]
},
{
"cell_type": "markdown",
"id": "d2428548",
"metadata": {},
"source": [
"## 1 — Build synthetic data"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c033bd86",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"rng = np.random.default_rng(42)\n",
"\n",
"N = 250 # total orbitals\n",
"N_CORE = 50 # strongly-coupled subset to highlight\n",
"\n",
"# ── Single-orbital entropies ─────────────────────────────────────────\n",
"# Three regimes interleaved across the orbital indices:\n",
"# • ~50 \"core\" orbitals with high entropy (near ln 4)\n",
"# • ~60 \"medium\" orbitals with moderate entropy\n",
"# • ~140 \"spectator\" orbitals with a long decaying tail\n",
"s1 = np.zeros(N)\n",
"\n",
"all_indices = rng.permutation(N)\n",
"core_idx = np.sort(all_indices[:N_CORE])\n",
"medium_idx = np.sort(all_indices[N_CORE : N_CORE + 60])\n",
"tail_idx = np.sort(all_indices[N_CORE + 60 :])\n",
"\n",
"s1[core_idx] = rng.beta(2.5, 1.2, len(core_idx)) * np.log(4.0)\n",
"s1[medium_idx] = rng.beta(1.8, 3.0, len(medium_idx)) * np.log(4.0) * 0.5\n",
"s1[tail_idx] = np.sort(rng.exponential(0.03, len(tail_idx)))[::-1]\n",
"\n",
"# ── Mutual information matrix ──────────────────────────────────────\n",
"mi = np.zeros((N, N))\n",
"\n",
"# 1) Five intra-core clusters of ~10 orbitals each with strong MI\n",
"cluster_size = len(core_idx) // 5\n",
"clusters = []\n",
"for k in range(5):\n",
" cl = core_idx[k * cluster_size : (k + 1) * cluster_size]\n",
" clusters.append(cl)\n",
" for ii, i in enumerate(cl):\n",
" for j in cl[ii + 1 :]:\n",
" val = rng.beta(3, 1.5) * np.log(16.0) * 0.55\n",
" mi[i, j] = mi[j, i] = val\n",
"\n",
"# 2) Sparse inter-cluster core links\n",
"for ii, i in enumerate(core_idx):\n",
" for j in core_idx[ii + 1 :]:\n",
" if mi[i, j] == 0 and rng.random() < 0.15:\n",
" val = rng.exponential(0.08)\n",
" mi[i, j] = mi[j, i] = val\n",
"\n",
"# 3) Medium orbitals: moderate MI to a few core and medium neighbours\n",
"for i in medium_idx:\n",
" n_core_links = rng.integers(1, 4)\n",
" targets = rng.choice(core_idx, size=n_core_links, replace=False)\n",
" for j in targets:\n",
" val = rng.exponential(0.12)\n",
" mi[i, j] = mi[j, i] = val\n",
" n_med_links = rng.integers(0, 3)\n",
" others = rng.choice(\n",
" medium_idx[medium_idx != i],\n",
" size=min(n_med_links, len(medium_idx) - 1),\n",
" replace=False,\n",
" )\n",
" for j in others:\n",
" if mi[i, j] == 0:\n",
" val = rng.exponential(0.06)\n",
" mi[i, j] = mi[j, i] = val\n",
"\n",
"# 4) Tail orbitals: very sparse, weak links to core or medium\n",
"for i in tail_idx:\n",
" if rng.random() < 0.12:\n",
" pool = np.concatenate([core_idx, medium_idx])\n",
" j = rng.choice(pool)\n",
" val = rng.exponential(0.02)\n",
" mi[i, j] = mi[j, i] = val\n",
"\n",
"np.fill_diagonal(mi, 0.0)\n",
"\n",
"# All five highly-entangled clusters\n",
"region_a, region_b, region_c, region_d, region_e = clusters\n",
"\n",
"print(f\"{N} orbitals, 5 entangled clusters built ({cluster_size} orbitals each)\")\n",
"for name, region in zip(\"ABCDE\", clusters):\n",
" print(f\" Cluster {name}: {region.tolist()}\")\n",
"print(f\"s1 range: {s1.min():.4f} – {s1.max():.4f}\")\n",
"print(f\"MI range: {mi[mi > 0].min():.4f} – {mi.max():.4f}\")\n",
"print(f\"Non-zero MI pairs: {(mi > 0).sum() // 2}\")"
]
},
{
"cell_type": "markdown",
"id": "b35327c0",
"metadata": {},
"source": [
"## 2 — Display the interactive widget\n",
"\n",
"The `Entanglement` widget renders an orbital-entanglement chord diagram\n",
"directly in the notebook output. Arc length encodes single-orbital\n",
"entropy; chord thickness encodes mutual information. Five highly\n",
"entangled regions (clusters of strongly-coupled orbitals) are each\n",
"outlined in a different colour and, when the grouping toggle is active,\n",
"placed adjacent on the ring."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7469867d",
"metadata": {},
"outputs": [],
"source": [
"from qsharp_widgets import Entanglement\n",
"\n",
"widget = Entanglement(\n",
" s1_entropies=s1.tolist(),\n",
" mutual_information=mi.tolist(),\n",
" labels=[str(i) for i in range(N)],\n",
" groups={\n",
" \"Region A\": region_a.tolist(),\n",
" \"Region B\": region_b.tolist(),\n",
" \"Region C\": region_c.tolist(),\n",
" \"Region D\": region_d.tolist(),\n",
" \"Region E\": region_e.tolist(),\n",
" },\n",
" title=f\"Synthetic Orbital Entanglement — {N} orbitals (5 entangled regions)\",\n",
" group_selected=True,\n",
" gap_deg=0.6,\n",
" arc_width=0.05,\n",
" mi_threshold=0.01,\n",
" width=800,\n",
" height=880,\n",
")\n",
"widget"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading
Loading