Hasarindu Perera commited on
chore: update demo for v0.10.0 — new encoders, Audit tab, barren plateau badge, rff fix
Browse files- app.py +120 -57
- requirements.txt +1 -1
app.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""QuPrep — HuggingFace Spaces demo (v0.
|
| 2 |
|
| 3 |
from __future__ import annotations
|
| 4 |
|
|
@@ -89,14 +89,15 @@ SAMPLES = {
|
|
| 89 |
# ---------------------------------------------------------------------------
|
| 90 |
|
| 91 |
ENCODINGS = [
|
| 92 |
-
"angle", "entangled_angle", "amplitude", "basis", "iqp",
|
| 93 |
"reupload", "hamiltonian", "zz_feature_map", "pauli_feature_map",
|
| 94 |
-
"random_fourier", "tensor_product", "qaoa_problem",
|
| 95 |
]
|
| 96 |
|
| 97 |
ENCODING_DESC = {
|
| 98 |
"angle": "Ry/Rx/Rz rotation per feature. NISQ-safe, depth O(1).",
|
| 99 |
"entangled_angle": "Rotation + CNOT entangling layers. NISQ-safe.",
|
|
|
|
| 100 |
"amplitude": "Feature vector as quantum state amplitudes. Qubit-efficient.",
|
| 101 |
"basis": "Binary features encoded as X gates. NISQ-safe.",
|
| 102 |
"iqp": "Havlíček ZZ feature map. Good for kernel methods.",
|
|
@@ -107,8 +108,28 @@ ENCODING_DESC = {
|
|
| 107 |
"random_fourier": "RBF kernel approximation via random Fourier features.",
|
| 108 |
"tensor_product": "Ry+Rz per qubit — full Bloch sphere, qubit-efficient.",
|
| 109 |
"qaoa_problem": "QAOA-inspired feature map. Features as cost Hamiltonian parameters.",
|
|
|
|
| 110 |
}
|
| 111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
FRAMEWORKS = ["qasm", "qiskit", "pennylane", "cirq", "tket", "braket", "qsharp", "iqm"]
|
| 113 |
|
| 114 |
TASKS = ["classification", "regression", "kernel", "qaoa", "simulation"]
|
|
@@ -197,39 +218,9 @@ def _get_exporter(framework: str):
|
|
| 197 |
return _map.get(framework, _map["qasm"])()
|
| 198 |
|
| 199 |
def _prepare_rff(X_full, X_slice, framework):
|
| 200 |
-
"""
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
enc = RandomFourierEncoder()
|
| 204 |
-
enc.fit(X_full)
|
| 205 |
-
ds = Dataset(data=X_slice,
|
| 206 |
-
feature_names=[f"f{i}" for i in range(X_slice.shape[1])],
|
| 207 |
-
feature_types=["continuous"] * X_slice.shape[1],
|
| 208 |
-
metadata={})
|
| 209 |
-
encoded_list = enc.encode_batch(ds)
|
| 210 |
-
exporter = _get_exporter(framework)
|
| 211 |
-
circuits = [exporter.export(e) for e in encoded_list]
|
| 212 |
-
|
| 213 |
-
from quprep.validation.cost import CostEstimate
|
| 214 |
-
n_qubits = enc.n_components
|
| 215 |
-
cost = CostEstimate(
|
| 216 |
-
encoding="random_fourier",
|
| 217 |
-
n_features=X_slice.shape[1],
|
| 218 |
-
n_qubits=n_qubits,
|
| 219 |
-
gate_count=n_qubits,
|
| 220 |
-
circuit_depth=1,
|
| 221 |
-
two_qubit_gates=0,
|
| 222 |
-
nisq_safe=True,
|
| 223 |
-
warning=None,
|
| 224 |
-
)
|
| 225 |
-
|
| 226 |
-
class _FakeResult:
|
| 227 |
-
pass
|
| 228 |
-
r = _FakeResult()
|
| 229 |
-
r.circuits = circuits
|
| 230 |
-
r.encoded = encoded_list
|
| 231 |
-
r.cost = cost
|
| 232 |
-
return r
|
| 233 |
|
| 234 |
def _reducer_kwargs(X_slice, X_full, n_qubits):
|
| 235 |
"""Return (kwargs_dict, clamp_note) — applies PCA reducer if budget < n_features.
|
|
@@ -247,7 +238,7 @@ def _encode_tabular(X, encoding, framework, n_samples, n_qubits):
|
|
| 247 |
import quprep as qd
|
| 248 |
X_slice = X[:max(1, n_samples)]
|
| 249 |
if encoding == "random_fourier":
|
| 250 |
-
return _prepare_rff(X, X_slice, framework)
|
| 251 |
kw, note = _reducer_kwargs(X_slice, X, n_qubits)
|
| 252 |
return qd.prepare(X_slice, encoding=encoding, framework=framework, **kw), note
|
| 253 |
|
|
@@ -255,7 +246,7 @@ def _encode_image(X, encoding, framework, n_samples, n_qubits=0):
|
|
| 255 |
import quprep as qd
|
| 256 |
X_slice = X[:max(1, n_samples)]
|
| 257 |
if encoding == "random_fourier":
|
| 258 |
-
return _prepare_rff(X, X_slice, framework)
|
| 259 |
kw, note = _reducer_kwargs(X_slice, X, n_qubits)
|
| 260 |
return qd.prepare(X_slice, encoding=encoding, framework=framework, **kw), note
|
| 261 |
|
|
@@ -269,7 +260,7 @@ def _encode_timeseries(X, encoding, framework, n_samples, n_qubits=0, window=4):
|
|
| 269 |
X_win = ds_win.data
|
| 270 |
X_slice = X_win[:max(1, n_samples)]
|
| 271 |
if encoding == "random_fourier":
|
| 272 |
-
return _prepare_rff(X_win, X_slice, framework)
|
| 273 |
kw, note = _reducer_kwargs(X_slice, X_win, n_qubits)
|
| 274 |
return qd.prepare(X_slice, encoding=encoding, framework=framework, **kw), note
|
| 275 |
|
|
@@ -279,7 +270,7 @@ def _encode_text(sentences, encoding, framework, n_qubits=0):
|
|
| 279 |
dataset = TextIngester(method="tfidf", max_features=8).load(sentences)
|
| 280 |
X = dataset.data
|
| 281 |
if encoding == "random_fourier":
|
| 282 |
-
return _prepare_rff(X, X, framework)
|
| 283 |
kw, note = _reducer_kwargs(X, X, n_qubits)
|
| 284 |
return qd.prepare(X, encoding=encoding, framework=framework, **kw), note
|
| 285 |
|
|
@@ -404,6 +395,26 @@ def run_convert(source, csv_file, sample_name, hf_name, hf_split,
|
|
| 404 |
</div>{warn}
|
| 405 |
</div>"""
|
| 406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 407 |
n_circ = len(circuits)
|
| 408 |
shape = f"{X_num.shape[0]}×{X_num.shape[1]}" if X_num.ndim == 2 else str(len(X))
|
| 409 |
status = f"✓ {dtype} · {shape} → {n_circ} circuit(s) | showing sample 0"
|
|
@@ -595,6 +606,54 @@ def run_suggest(source, csv_file, sample_name, hf_name, hf_split, task, max_qubi
|
|
| 595 |
# Fingerprint
|
| 596 |
# ---------------------------------------------------------------------------
|
| 597 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 598 |
def run_fingerprint(source, csv_file, sample_name, hf_name, hf_split,
|
| 599 |
encoding, framework, reducer_type, n_components, n_qubits,
|
| 600 |
use_scaler, scaler_strategy,
|
|
@@ -607,21 +666,7 @@ def run_fingerprint(source, csv_file, sample_name, hf_name, hf_split,
|
|
| 607 |
if dtype not in ("tabular", "image", "timeseries"):
|
| 608 |
return "", "<p style='color:#fbbf24'>⚠️ Fingerprinting works on numeric data (tabular / image / time series).</p>"
|
| 609 |
X_use = X
|
| 610 |
-
|
| 611 |
-
"angle": qd.AngleEncoder,
|
| 612 |
-
"amplitude": qd.AmplitudeEncoder,
|
| 613 |
-
"basis": qd.BasisEncoder,
|
| 614 |
-
"iqp": qd.IQPEncoder,
|
| 615 |
-
"entangled_angle": qd.EntangledAngleEncoder,
|
| 616 |
-
"reupload": qd.ReUploadEncoder,
|
| 617 |
-
"hamiltonian": qd.HamiltonianEncoder,
|
| 618 |
-
"zz_feature_map": qd.ZZFeatureMapEncoder,
|
| 619 |
-
"pauli_feature_map": qd.PauliFeatureMapEncoder,
|
| 620 |
-
"random_fourier": qd.RandomFourierEncoder,
|
| 621 |
-
"tensor_product": qd.TensorProductEncoder,
|
| 622 |
-
"qaoa_problem": qd.QAOAProblemEncoder,
|
| 623 |
-
}
|
| 624 |
-
encoder_cls = _enc_map.get(encoding, qd.AngleEncoder)
|
| 625 |
encoder = encoder_cls()
|
| 626 |
if hasattr(encoder, "fit"):
|
| 627 |
encoder.fit(X_use)
|
|
@@ -743,7 +788,7 @@ with gr.Blocks(title="QuPrep — Quantum Data Preparation") as demo:
|
|
| 743 |
with gr.Column(scale=1, elem_id="header-left"):
|
| 744 |
gr.HTML("""
|
| 745 |
<p style="margin:0 0 2px;font-size:1.5rem;font-weight:700;color:#e2e8f0">⚛️ QuPrep</p>
|
| 746 |
-
<p style="margin:0 0 14px;font-size:0.9rem;font-weight:500;color:#a78bfa">v0.
|
| 747 |
<p style="margin:0 0 14px;font-size:0.85rem;color:#94a3b8;line-height:1.6">
|
| 748 |
The missing preprocessing layer between classical datasets and quantum computing.
|
| 749 |
</p>
|
|
@@ -898,6 +943,22 @@ with gr.Blocks(title="QuPrep — Quantum Data Preparation") as demo:
|
|
| 898 |
|
| 899 |
sug_btn.click(fn=_sug, inputs=_inputs(sug_task, sug_max), outputs=sug_out)
|
| 900 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 901 |
# Fingerprint ──────────────────────────────────────────────────────
|
| 902 |
with gr.TabItem("Fingerprint"):
|
| 903 |
with gr.Row():
|
|
@@ -974,12 +1035,14 @@ Connect → Ingest → Clean → Reduce → Normalise → Encode → Export
|
|
| 974 |
Supports tabular, image, time series, graph, and text data.
|
| 975 |
Data connectors: HuggingFace Hub, OpenML, Kaggle, CSV/NumPy upload.
|
| 976 |
|
| 977 |
-
### Supported encodings (
|
| 978 |
| Encoding | Qubits | NISQ-safe |
|
| 979 |
|---|---|---|
|
| 980 |
| Angle | d | ✓ |
|
|
|
|
| 981 |
| Amplitude | ⌈log₂d⌉ | ✗ |
|
| 982 |
| Basis | d | ✓ |
|
|
|
|
| 983 |
| IQP | d | conditional |
|
| 984 |
| Entangled Angle | d | ✓ |
|
| 985 |
| Re-Upload | d | ✓ |
|
|
|
|
| 1 |
+
"""QuPrep — HuggingFace Spaces demo (v0.10.0)"""
|
| 2 |
|
| 3 |
from __future__ import annotations
|
| 4 |
|
|
|
|
| 89 |
# ---------------------------------------------------------------------------
|
| 90 |
|
| 91 |
ENCODINGS = [
|
| 92 |
+
"angle", "entangled_angle", "dense_angle", "amplitude", "basis", "iqp",
|
| 93 |
"reupload", "hamiltonian", "zz_feature_map", "pauli_feature_map",
|
| 94 |
+
"random_fourier", "tensor_product", "qaoa_problem", "discretized",
|
| 95 |
]
|
| 96 |
|
| 97 |
ENCODING_DESC = {
|
| 98 |
"angle": "Ry/Rx/Rz rotation per feature. NISQ-safe, depth O(1).",
|
| 99 |
"entangled_angle": "Rotation + CNOT entangling layers. NISQ-safe.",
|
| 100 |
+
"dense_angle": "Ry+Rz per qubit — 2 features per qubit, halves qubit count vs angle. New in v0.10.",
|
| 101 |
"amplitude": "Feature vector as quantum state amplitudes. Qubit-efficient.",
|
| 102 |
"basis": "Binary features encoded as X gates. NISQ-safe.",
|
| 103 |
"iqp": "Havlíček ZZ feature map. Good for kernel methods.",
|
|
|
|
| 108 |
"random_fourier": "RBF kernel approximation via random Fourier features.",
|
| 109 |
"tensor_product": "Ry+Rz per qubit — full Bloch sphere, qubit-efficient.",
|
| 110 |
"qaoa_problem": "QAOA-inspired feature map. Features as cost Hamiltonian parameters.",
|
| 111 |
+
"discretized": "Continuous → binary string with configurable precision. QUBO-ready. New in v0.10.",
|
| 112 |
}
|
| 113 |
|
| 114 |
+
# Shared encoder name → class map (used by Convert, Audit, Fingerprint)
|
| 115 |
+
def _get_enc_map(qd):
|
| 116 |
+
return {
|
| 117 |
+
"angle": qd.AngleEncoder,
|
| 118 |
+
"entangled_angle": qd.EntangledAngleEncoder,
|
| 119 |
+
"dense_angle": qd.DenseAngleEncoder,
|
| 120 |
+
"amplitude": qd.AmplitudeEncoder,
|
| 121 |
+
"basis": qd.BasisEncoder,
|
| 122 |
+
"iqp": qd.IQPEncoder,
|
| 123 |
+
"reupload": qd.ReUploadEncoder,
|
| 124 |
+
"hamiltonian": qd.HamiltonianEncoder,
|
| 125 |
+
"zz_feature_map": qd.ZZFeatureMapEncoder,
|
| 126 |
+
"pauli_feature_map": qd.PauliFeatureMapEncoder,
|
| 127 |
+
"random_fourier": qd.RandomFourierEncoder,
|
| 128 |
+
"tensor_product": qd.TensorProductEncoder,
|
| 129 |
+
"qaoa_problem": qd.QAOAProblemEncoder,
|
| 130 |
+
"discretized": qd.DiscretizedEncoder,
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
FRAMEWORKS = ["qasm", "qiskit", "pennylane", "cirq", "tket", "braket", "qsharp", "iqm"]
|
| 134 |
|
| 135 |
TASKS = ["classification", "regression", "kernel", "qaoa", "simulation"]
|
|
|
|
| 218 |
return _map.get(framework, _map["qasm"])()
|
| 219 |
|
| 220 |
def _prepare_rff(X_full, X_slice, framework):
|
| 221 |
+
"""v0.10.0: RandomFourierEncoder is now auto-fit by Pipeline — plain prepare() works."""
|
| 222 |
+
import quprep as qd
|
| 223 |
+
return qd.prepare(X_slice, encoding="random_fourier", framework=framework), None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
|
| 225 |
def _reducer_kwargs(X_slice, X_full, n_qubits):
|
| 226 |
"""Return (kwargs_dict, clamp_note) — applies PCA reducer if budget < n_features.
|
|
|
|
| 238 |
import quprep as qd
|
| 239 |
X_slice = X[:max(1, n_samples)]
|
| 240 |
if encoding == "random_fourier":
|
| 241 |
+
return _prepare_rff(X, X_slice, framework)
|
| 242 |
kw, note = _reducer_kwargs(X_slice, X, n_qubits)
|
| 243 |
return qd.prepare(X_slice, encoding=encoding, framework=framework, **kw), note
|
| 244 |
|
|
|
|
| 246 |
import quprep as qd
|
| 247 |
X_slice = X[:max(1, n_samples)]
|
| 248 |
if encoding == "random_fourier":
|
| 249 |
+
return _prepare_rff(X, X_slice, framework)
|
| 250 |
kw, note = _reducer_kwargs(X_slice, X, n_qubits)
|
| 251 |
return qd.prepare(X_slice, encoding=encoding, framework=framework, **kw), note
|
| 252 |
|
|
|
|
| 260 |
X_win = ds_win.data
|
| 261 |
X_slice = X_win[:max(1, n_samples)]
|
| 262 |
if encoding == "random_fourier":
|
| 263 |
+
return _prepare_rff(X_win, X_slice, framework)
|
| 264 |
kw, note = _reducer_kwargs(X_slice, X_win, n_qubits)
|
| 265 |
return qd.prepare(X_slice, encoding=encoding, framework=framework, **kw), note
|
| 266 |
|
|
|
|
| 270 |
dataset = TextIngester(method="tfidf", max_features=8).load(sentences)
|
| 271 |
X = dataset.data
|
| 272 |
if encoding == "random_fourier":
|
| 273 |
+
return _prepare_rff(X, X, framework)
|
| 274 |
kw, note = _reducer_kwargs(X, X, n_qubits)
|
| 275 |
return qd.prepare(X, encoding=encoding, framework=framework, **kw), note
|
| 276 |
|
|
|
|
| 395 |
</div>{warn}
|
| 396 |
</div>"""
|
| 397 |
|
| 398 |
+
# Barren plateau badge (tabular/image/timeseries only, silent on error)
|
| 399 |
+
if X_num.ndim == 2 and X_num.size > 0 and dtype not in ("graph", "text"):
|
| 400 |
+
try:
|
| 401 |
+
from quprep.core.dataset import Dataset as _DS
|
| 402 |
+
_bp = qd.detect_barren_plateau(
|
| 403 |
+
_get_enc_map(qd).get(encoding, qd.AngleEncoder)(),
|
| 404 |
+
_DS(data=X_num[:5]),
|
| 405 |
+
cost_type="local",
|
| 406 |
+
)
|
| 407 |
+
_col = {"none": "#4ade80", "mild": "#fbbf24",
|
| 408 |
+
"high": "#fb923c", "severe": "#f87171"}.get(_bp.risk_level, "#94a3b8")
|
| 409 |
+
cost_html += f"""
|
| 410 |
+
<div style="margin-top:10px;padding:8px 14px;background:#1e293b;border-radius:8px">
|
| 411 |
+
<span style="color:#94a3b8;font-size:0.78rem">Barren plateau</span>
|
| 412 |
+
<span style="float:right;color:{_col};font-weight:700;font-size:0.85rem">{_bp.risk_level.upper()}</span>
|
| 413 |
+
<div style="clear:both;color:#64748b;font-size:0.72rem;margin-top:2px">depth {_bp.circuit_depth} · {_bp.n_qubits} qubits</div>
|
| 414 |
+
</div>"""
|
| 415 |
+
except Exception:
|
| 416 |
+
pass
|
| 417 |
+
|
| 418 |
n_circ = len(circuits)
|
| 419 |
shape = f"{X_num.shape[0]}×{X_num.shape[1]}" if X_num.ndim == 2 else str(len(X))
|
| 420 |
status = f"✓ {dtype} · {shape} → {n_circ} circuit(s) | showing sample 0"
|
|
|
|
| 606 |
# Fingerprint
|
| 607 |
# ---------------------------------------------------------------------------
|
| 608 |
|
| 609 |
+
def run_audit(source, csv_file, sample_name, hf_name, hf_split, encoding, qubit_budget):
|
| 610 |
+
"""preprocessing_report() — structured dataset audit before encoding."""
|
| 611 |
+
try:
|
| 612 |
+
import quprep as qd
|
| 613 |
+
dtype, X, cols = load_data(source, csv_file, sample_name, hf_name, hf_split)
|
| 614 |
+
except Exception as exc:
|
| 615 |
+
return f"<p style='color:#f87171'>❌ {exc}</p>"
|
| 616 |
+
|
| 617 |
+
if dtype != "tabular":
|
| 618 |
+
return "<p style='color:#fbbf24'>⚠️ Audit works on tabular data only.</p>"
|
| 619 |
+
|
| 620 |
+
try:
|
| 621 |
+
ds = qd.NumpyIngester().load(X)
|
| 622 |
+
enc = _get_enc_map(qd).get(encoding, qd.AngleEncoder)()
|
| 623 |
+
budget = int(qubit_budget) if qubit_budget > 0 else X.shape[1]
|
| 624 |
+
report = qd.preprocessing_report(ds, encoder=enc, qubit_budget=budget)
|
| 625 |
+
except Exception as exc:
|
| 626 |
+
return f"<p style='color:#f87171'>❌ {exc}</p>"
|
| 627 |
+
|
| 628 |
+
sev_color = "#4ade80" if report.n_issues == 0 else ("#fbbf24" if report.n_issues <= 2 else "#f87171")
|
| 629 |
+
recs_html = "".join(
|
| 630 |
+
f"<li style='margin:4px 0;color:#cbd5e1;font-size:0.85rem'>{r}</li>"
|
| 631 |
+
for r in report.recommendations
|
| 632 |
+
) if report.recommendations else "<li style='color:#4ade80'>No issues — data looks healthy.</li>"
|
| 633 |
+
|
| 634 |
+
return f"""
|
| 635 |
+
<div style="font-family:sans-serif;font-size:0.9rem;line-height:1.6">
|
| 636 |
+
<div style="display:flex;align-items:center;gap:12px;margin-bottom:16px">
|
| 637 |
+
<span style="font-size:2rem;font-weight:700;color:{sev_color}">{report.n_issues}</span>
|
| 638 |
+
<span style="color:#94a3b8">issue(s) found · encoding={encoding} · qubit budget={budget}</span>
|
| 639 |
+
</div>
|
| 640 |
+
<div style="background:#1e293b;border-radius:8px;padding:14px 18px">
|
| 641 |
+
<div style="color:#64748b;font-size:0.78rem;font-weight:600;margin-bottom:8px;text-transform:uppercase;letter-spacing:.05em">Recommendations</div>
|
| 642 |
+
<ul style="margin:0;padding-left:18px">{recs_html}</ul>
|
| 643 |
+
</div>
|
| 644 |
+
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px">
|
| 645 |
+
<div style="background:#1e293b;border-radius:8px;padding:10px 14px">
|
| 646 |
+
<div style="color:#64748b;font-size:0.78rem">Shape</div>
|
| 647 |
+
<div style="font-weight:600">{X.shape[0]} × {X.shape[1]}</div>
|
| 648 |
+
</div>
|
| 649 |
+
<div style="background:#1e293b;border-radius:8px;padding:10px 14px">
|
| 650 |
+
<div style="color:#64748b;font-size:0.78rem">Encoder</div>
|
| 651 |
+
<div style="font-weight:600">{encoding}</div>
|
| 652 |
+
</div>
|
| 653 |
+
</div>
|
| 654 |
+
</div>"""
|
| 655 |
+
|
| 656 |
+
|
| 657 |
def run_fingerprint(source, csv_file, sample_name, hf_name, hf_split,
|
| 658 |
encoding, framework, reducer_type, n_components, n_qubits,
|
| 659 |
use_scaler, scaler_strategy,
|
|
|
|
| 666 |
if dtype not in ("tabular", "image", "timeseries"):
|
| 667 |
return "", "<p style='color:#fbbf24'>⚠️ Fingerprinting works on numeric data (tabular / image / time series).</p>"
|
| 668 |
X_use = X
|
| 669 |
+
encoder_cls = _get_enc_map(qd).get(encoding, qd.AngleEncoder)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 670 |
encoder = encoder_cls()
|
| 671 |
if hasattr(encoder, "fit"):
|
| 672 |
encoder.fit(X_use)
|
|
|
|
| 788 |
with gr.Column(scale=1, elem_id="header-left"):
|
| 789 |
gr.HTML("""
|
| 790 |
<p style="margin:0 0 2px;font-size:1.5rem;font-weight:700;color:#e2e8f0">⚛️ QuPrep</p>
|
| 791 |
+
<p style="margin:0 0 14px;font-size:0.9rem;font-weight:500;color:#a78bfa">v0.10.0 · Quantum Data Preparation</p>
|
| 792 |
<p style="margin:0 0 14px;font-size:0.85rem;color:#94a3b8;line-height:1.6">
|
| 793 |
The missing preprocessing layer between classical datasets and quantum computing.
|
| 794 |
</p>
|
|
|
|
| 943 |
|
| 944 |
sug_btn.click(fn=_sug, inputs=_inputs(sug_task, sug_max), outputs=sug_out)
|
| 945 |
|
| 946 |
+
# Audit ────────────────────────────────────────────────────────────
|
| 947 |
+
with gr.TabItem("Audit"):
|
| 948 |
+
with gr.Row():
|
| 949 |
+
with gr.Column(scale=1):
|
| 950 |
+
aud_enc = gr.Dropdown(choices=ENCODINGS, value="angle", label="Target encoding")
|
| 951 |
+
aud_qsl = gr.Slider(0, 30, value=0, step=1, label="Qubit budget (0 = n_features)")
|
| 952 |
+
aud_btn = gr.Button("Audit →", variant="primary")
|
| 953 |
+
gr.HTML('<p style="font-size:0.82rem;color:#475569;margin:8px 0">Checks NaN, outliers, qubit budget, class imbalance, and encoder compatibility before you encode. Tabular data only.</p>')
|
| 954 |
+
with gr.Column(scale=3):
|
| 955 |
+
aud_out = gr.HTML(value="<p style='color:#475569;padding:24px 0'>Click <strong>Audit →</strong></p>")
|
| 956 |
+
|
| 957 |
+
def _aud(src, csv, samp, hfn, hfs, enc, nq):
|
| 958 |
+
return run_audit(_src(src), csv, samp, hfn, hfs, enc, nq)
|
| 959 |
+
|
| 960 |
+
aud_btn.click(fn=_aud, inputs=_inputs(aud_enc, aud_qsl), outputs=aud_out)
|
| 961 |
+
|
| 962 |
# Fingerprint ──────────────────────────────────────────────────────
|
| 963 |
with gr.TabItem("Fingerprint"):
|
| 964 |
with gr.Row():
|
|
|
|
| 1035 |
Supports tabular, image, time series, graph, and text data.
|
| 1036 |
Data connectors: HuggingFace Hub, OpenML, Kaggle, CSV/NumPy upload.
|
| 1037 |
|
| 1038 |
+
### Supported encodings (15)
|
| 1039 |
| Encoding | Qubits | NISQ-safe |
|
| 1040 |
|---|---|---|
|
| 1041 |
| Angle | d | ✓ |
|
| 1042 |
+
| Dense Angle *(v0.10)* | ⌈d/2⌉ | ✓ |
|
| 1043 |
| Amplitude | ⌈log₂d⌉ | ✗ |
|
| 1044 |
| Basis | d | ✓ |
|
| 1045 |
+
| Discretized *(v0.10)* | d×bits | ✓ |
|
| 1046 |
| IQP | d | conditional |
|
| 1047 |
| Entangled Angle | d | ✓ |
|
| 1048 |
| Re-Upload | d | ✓ |
|
requirements.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
quprep[qiskit,pennylane,cirq,tket,braket,qsharp,viz,huggingface,openml,image,text]
|
| 2 |
gradio>=4.0
|
| 3 |
pandas
|
| 4 |
numpy
|
|
|
|
| 1 |
+
quprep[qiskit,pennylane,cirq,tket,braket,qsharp,viz,huggingface,openml,image,text]==0.10.0
|
| 2 |
gradio>=4.0
|
| 3 |
pandas
|
| 4 |
numpy
|