Spaces:
Runtime error
Runtime error
File size: 10,578 Bytes
d3527de 2c22ec7 64d0d65 2c22ec7 64d0d65 2c22ec7 64d0d65 2c22ec7 d3527de 4591829 d3527de 4591829 d3527de 4591829 d3527de | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | """
QAOA Pedagogical Tool β Main Entry Point
=========================================
Run with: streamlit run app.py
Navigation is driven entirely by st.session_state["page"].
The landing page renders three clickable module cards.
Each module page has a "β Back to Home" button.
"""
import streamlit as st
# ββ Page config (must be first Streamlit call) βββββββββββββββββββββββββββββββ
st.set_page_config(
page_title="QAOA Pedagogical Tool",
page_icon="βοΈ",
layout="wide",
initial_sidebar_state="collapsed",
)
# ββ Global CSS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
st.markdown("""
<style>
/* hide default Streamlit hamburger / footer */
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
/* global typography */
.block-container {padding-top: 2rem; padding-bottom: 2rem;}
/* ββ Landing card styles ββ */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.8rem;
margin-top: 2rem;
}
.card {
border-radius: 14px;
padding: 2rem 1.8rem;
cursor: pointer;
transition: transform 0.15s, box-shadow 0.15s;
border: 2px solid transparent;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 28px rgba(0,0,0,0.12);
}
.card-standard { background: #EEF2FF; border-color: #6366F1; }
.card-equality { background: #F5F3FF; border-color: #7C3AED; }
.card-inequality{ background: #F0FDFA; border-color: #0F766E; }
.card-icon { font-size: 2.8rem; margin-bottom: 0.6rem; }
.card-title { font-size: 1.35rem; font-weight: 700; margin-bottom: 0.4rem; }
.card-badge {
display: inline-block;
font-size: 0.72rem; font-weight: 600;
padding: 2px 10px; border-radius: 20px;
margin-bottom: 0.8rem;
}
.badge-std { background: #6366F1; color: white; }
.badge-eq { background: #7C3AED; color: white; }
.badge-ineq { background: #0F766E; color: white; }
.card-desc { font-size: 0.95rem; color: #475569; line-height: 1.55; }
/* math-box callout */
.math-box {
background: #F8FAFC;
border-left: 5px solid #6366F1;
padding: 14px 18px;
border-radius: 5px;
margin: 1rem 0;
font-family: "Georgia", serif;
font-size: 1.0rem;
}
</style>
""", unsafe_allow_html=True)
st.markdown("""
<style>
/* 1. Force the main container to hide horizontal overflow */
.main { overflow-x: hidden !important; }
/* 2. Prevent Plotly from triggering the IFrame Resizer loop */
div[data-testid="stPlotlyChart"] > div {
overflow: hidden !important;
}
/* 3. Add a tiny bottom margin to prevent the 'bottom-edge' jitter */
div[data-testid="stPlotlyChart"] {
margin-bottom: 20px !important;
}
</style>
""", unsafe_allow_html=True)
# ββ Session state initialisation ββββββββββββββββββββββββββββββββββββββββββββββ
if "page" not in st.session_state:
st.session_state["page"] = "home"
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# LANDING PAGE
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def render_home():
# ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
st.markdown(
'<h1 style="text-align:center;color:#1E293B;font-size:2.6rem;margin-bottom:0;">'
'QAOA Pedagogical Tool</h1>',
unsafe_allow_html=True,
)
st.markdown(
'<p style="text-align:center;color:#64748B;font-size:1.1rem;margin-top:0.4rem;">'
'An interactive step-by-step guide to the '
'Quantum Approximate Optimization Algorithm</p>',
unsafe_allow_html=True,
)
# ββ Quick-reference math ββββββββββββββββββββββββββββββββββββββββββββββββββ
st.markdown("---")
col_a, col_b, col_c = st.columns(3)
with col_a:
with st.container(border=True, height=120):
st.markdown("**QUBO β Hamiltonian**")
st.latex(r"x_i \to \frac{I - Z_i}{2}")
with col_b:
with st.container(border=True, height=120):
st.markdown("**Cost Layer**")
st.latex(r"U_C(\gamma) = e^{-i\gamma H_C}")
with col_c:
with st.container(border=True, height=120):
st.markdown("**Mixer Layer**")
st.latex(r"U_B(\beta) = e^{-i\beta \sum X_i}")
# ββ Module cards βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
st.markdown(
'<h2 style="text-align:center;color:#1E293B;margin-top:2rem;">Choose a Module</h2>',
unsafe_allow_html=True,
)
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("""
<div class="card card-standard">
<div class="card-icon">βοΈ</div>
<div class="card-title" style="color:#4338CA;">Standard QAOA</div>
<span class="card-badge badge-std">3 Qubits Β· Unconstrained</span>
<div class="card-desc">
Start here. Learn QUBO formulation, Hamiltonian mapping, and the
PhaseβProbability Disconnect from first principles.
<br><br>
<b>Problem:</b> Minimize C(x) = xβ + xβ β xβxβ
</div>
</div>
""", unsafe_allow_html=True)
if st.button("Open β", key="go_standard", use_container_width=False):
st.session_state["page"] = "standard"
st.rerun()
with col2:
st.markdown("""
<div class="card card-equality">
<div class="card-icon">π</div>
<div class="card-title" style="color:#6D28D9;">Equality Constraint</div>
<span class="card-badge badge-eq">3 Qubits Β· Penalty Method</span>
<div class="card-desc">
Learn how to encode equality constraints as quadratic penalty terms,
and see why this creates a fully-connected Kβ cost circuit.
<br><br>
<b>Problem:</b> Minimize C(x) = xβ + xβ β xβxβ<br>
<b>Constraint:</b> xβ + xβ + xβ = 1
</div>
</div>
""", unsafe_allow_html=True)
if st.button("Open β", key="go_equality", use_container_width=False):
st.session_state["page"] = "equality"
st.rerun()
with col3:
st.markdown("""
<div class="card card-inequality">
<div class="card-icon">π</div>
<div class="card-title" style="color:#0F766E;">Inequality Constraint</div>
<span class="card-badge badge-ineq">4 Qubits Β· Slack Variable</span>
<div class="card-desc">
Advanced module. Introduce a binary slack qubit to convert an
inequality into an equality, building a Kβ fully-connected circuit.
<br><br>
<b>Problem:</b> Minimize C(x) = xβ + xβ β xβxβ<br>
<b>Constraint:</b> xβ + xβ + xβ β₯ 2
</div>
</div>
""", unsafe_allow_html=True)
if st.button("Open β", key="go_inequality", use_container_width=False):
st.session_state["page"] = "inequality"
st.rerun()
# ββ How to use βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
st.markdown("---")
with st.expander("How to use this tool"):
st.markdown("""
Each module walks you through **six pedagogical steps**:
1. **Problem Formulation** β binary optimization problem + truth table
2. **QUBO Matrix** β encode the cost as a matrix
3. **Hamiltonian Mapping** β translate to quantum spin operators
4. **Circuit Construction** β see how each Hamiltonian term becomes a gate;
observe the **PhaseβProbability Disconnect** using sv_disc visualizations
5. **Interactive Simulation** β adjust Ξ³ and Ξ² sliders to explore the energy landscape
6. **COBYLA Optimization + Replay** β run the variational loop, then scrub through
the optimization history iteration by iteration
**PhaseβProbability Disconnect** (Step 4): Each disc represents one basis state.
The *radius* encodes the probability amplitude; the *angle* of the pointer encodes the quantum phase.
After the Cost Layer, all radii are equal (probabilities unchanged) but angles differ.
After the Mixer Layer, radii change β this is where interference converts phase into probability.
""")
# ββ Footer ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
st.markdown(
'<p style="text-align:center;color:#94A3B8;font-size:0.82rem;margin-top:3rem;">'
'Built with Qiskit Β· Streamlit Β· Plotly Β· sv_disc | '
'IEEE QSEEC 2026 Submission</p>',
unsafe_allow_html=True,
)
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# ROUTER
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def main():
page = st.session_state.get("page", "home")
if page == "home":
render_home()
elif page == "standard":
from pages.standard import render
render()
elif page == "equality":
from pages.equality import render
render()
elif page == "inequality":
from pages.inequality import render
render()
else:
st.session_state["page"] = "home"
st.rerun()
if __name__ == "__main__":
main()
|