"""
Vector Healing page — interactive demo for
ia_utils.vector_healing.enhanced_dense_healing_hybrid. The same engine also
runs, for real, inside the Quantum Simulator page's VQE/MD telemetry
pipeline (see ui_pages/ai_middleware.py) — this page is the sandbox where
you can dial the corruption knobs yourself and watch it work.
"""
import numpy as np
import matplotlib.pyplot as plt
import streamlit as st
from ia_utils.vector_healing import enhanced_dense_healing_hybrid
from ui_pages.components import render_ai_shield_card, render_page_banner, render_run_guard, render_matplotlib_figure
HIDDEN_DIM = 6
def _generate_corrupted_sequence(n_steps, hidden_dim, anomaly_pct, rng):
t = np.linspace(0, 4 * np.pi, n_steps)
freqs = rng.uniform(0.8, 1.2, size=hidden_dim)
phases = rng.uniform(0, 2 * np.pi, size=hidden_dim)
ideal = np.stack([np.sin(freqs[d] * t + phases[d]) for d in range(hidden_dim)], axis=1)
corrupted = ideal + rng.normal(0, 0.05, size=ideal.shape)
n_anomalies = max(1, int(round(n_steps * anomaly_pct / 100.0)))
anomaly_idx = rng.choice(n_steps, size=min(n_anomalies, n_steps), replace=False)
kinds = rng.choice(["nan", "inf", "spike"], size=len(anomaly_idx))
for idx, kind in zip(anomaly_idx, kinds):
dim = int(rng.integers(0, hidden_dim))
if kind == "nan":
corrupted[idx, dim] = np.nan
elif kind == "inf":
corrupted[idx, dim] = np.inf if rng.random() < 0.5 else -np.inf
else:
corrupted[idx, dim] = ideal[idx, dim] + rng.choice([-1.0, 1.0]) * rng.uniform(3.0, 6.0)
return ideal, corrupted
def render():
render_page_banner(
"AI Vector Healing Dashboard",
"""ia_utils.vector_healing.enhanced_dense_healing_hybrid è uno scudo anti-crash
per sequenze di vettori (es. hidden states): ripulisce NaN/Inf,
poi decide passo per passo — tramite la logica Φ-trigger di
dense_evolution.healing — se il valore fa parte di un cambio di tendenza
genuino (lasciato passare) o di uno spike isolato/rumore (sostituito con la mediana
locale). Lo stesso scudo protegge in produzione anche la telemetria VQE/MD del Quantum
Simulator.""",
accent="#00e5ff", bg_from="#001014", bg_to="#012026",
)
with st.sidebar:
st.header("⚙️ Configurazione")
n_steps = st.slider("Numero di step / token", min_value=10, max_value=150, value=80)
anomaly_pct = st.slider(
"Percentuale anomalie (NaN / Inf / Spike)", min_value=5, max_value=30, value=10
)
run_clicked = st.button("🚀 Genera ed Esegui Healing", type="primary")
if run_clicked:
rng = np.random.default_rng()
ideal, corrupted = _generate_corrupted_sequence(n_steps, HIDDEN_DIM, anomaly_pct, rng)
healed, metadata = enhanced_dense_healing_hybrid(corrupted)
st.session_state["healing_result"] = {
"ideal": ideal,
"corrupted": corrupted,
"healed": healed,
"metadata": metadata,
"n_steps": n_steps,
}
result = render_run_guard(
"healing_result",
message="Configura i parametri nella sidebar e premi **Genera ed Esegui Healing** per iniziare.",
)
if result is None:
return
ideal, corrupted, healed, metadata = (
result["ideal"], result["corrupted"], result["healed"], result["metadata"]
)
render_ai_shield_card("AI Vector-Healing Shield", metadata)
with st.container(border=True):
st.subheader("📈 Confronto vettoriale")
channel = st.selectbox(
"Dimensione da visualizzare",
options=list(range(HIDDEN_DIM)),
format_func=lambda d: f"Canale {d}",
)
x = np.arange(result["n_steps"])
ideal_channel = ideal[:, channel]
fig, ax = plt.subplots(figsize=(11, 5))
ax.plot(x, ideal_channel, label="Ideale", color="#888888", linewidth=1.5, linestyle="--")
ax.plot(x, corrupted[:, channel], label="Corrotto", color="#ff4b4b", linewidth=1.2, alpha=0.75)
ax.plot(x, healed[:, channel], label="Curato", color="#00c853", linewidth=2.2)
margin = 1.5
ax.set_ylim(ideal_channel.min() - margin, ideal_channel.max() + margin)
ax.set_xlabel("Step / Token")
ax.set_ylabel(f"Valore (canale {channel})")
ax.set_title("Vector Healing — Ideale vs Corrotto vs Curato")
ax.legend(loc="upper right")
ax.grid(alpha=0.2)
render_matplotlib_figure(fig)