-
Notifications
You must be signed in to change notification settings - Fork 0
3. Gradiente VQE Differenze Finite vs PSR Esatta
Due script calcolano lo stesso gradiente
-
vqe_gradient.py— differenze finite classiche,$h=10^{-5}$ , un singolo circuito per volta. -
vqe_jax_grad.py/tests/test_vqe_jax_gradient.py— Parameter-Shift Rule, batchata su JAX.
Questo capitolo racconta anche un bug reale trovato e corretto durante l'audit su dense-evolution 8.1.21, perché capirlo è essenziale per non ripeterlo altrove.
DenseSVSimulator.run_parametric_batch_jit(base_circuit, parameter_batch) assegna una colonna di parameter_batch a ogni gate rx/ry/rz/p, in ordine di apparizione nel circuito — anche se l'argomento passato è un float letterale, non solo per i placeholder stringa. Il letterale viene ignorato.
L'ansatz di vqe_jax_grad.py ha, a ry = 10 slot parametrici. La griglia originale, però, aveva solo 2 colonne fisse [theta, -theta]. Risultato: solo il primo legame riceveva i valori giusti; gli altri 9 slot finivano fuori indice, e JAX — che non solleva errore su un accesso array fuori range, ma clippa silenziosamente all'ultimo indice valido — restituiva lo stesso valore clippato per tutti loro invece dell'angolo corretto.
Verificato empiricamente: costruendo la stessa griglia bacata e confrontandola con un circuito singolo dove OGNI legame riceve esplicitamente l'angolo corretto, la differenza sull'energia era enorme (fino a
Anche dopo aver corretto il conteggio delle colonne, restava un problema più sottile: la formula usata,
shiftava la variabile condivisa tests/test_analytical.py::test_psr_exactness_ry_z su un singolo
Shiftare una variabile condivisa che guida più gate conflagra i contributi di ciascuno. Verificato: la formula "condivisa" poteva discordare dal vero gradiente anche del 100%, segno incluso.
dove ogni
Verificato contro differenze finite indipendenti: accordo a
Costo: per un ansatz a run_parametric_batch_jit per punto.
vqe_jax_gradient.csv/.png sono stati rigenerati: 73.500 tracce invece di 10.500, ~570s invece di 58s su CPU — la differenza di costo è genuina, non un rallentamento accidentale.
tests/test_vqe_jax_gradient.py::test_vqe_jax_batch_grid_has_one_column_per_rotation_slot blocca la regressione sul conteggio colonne; test_vqe_jax_exact_psr_gradient_matches_finite_difference (5 valori di vqe_gradient.py (il riferimento a differenze finite) è validato in tests/test_integration_smoke.py contro un circuito PennyLane indipendente, chiamando la funzione reale calcola_energia_vqe, non una copia.
Aggiornamento: il bug di run_parametric_batch_jit descritto sopra è stato segnalato a monte (Dense-Evolution#6) e corretto in dense-evolution 8.1.28 — ora solleva ValueError su un mismatch di colonne invece di clippare in silenzio. Il fix qui (griglia a 10 colonne) resta corretto e necessario indipendentemente dalla versione del pacchetto.
vqe_gradient.py condivide lo stesso
La somma cinetica di calcola_energia_vqe è periodica (
Trovato un bug di distrazione mio durante la derivazione, utile da ricordare: la prima verifica contro calcola_energia_vqe non tornava (differenza reale, non rumore) — la formula assumeva legami a catena aperta (5, come negli script molecolari) invece di periodici (6, con il giro). Confrontare sempre contro la funzione vera dello script prima di fidarsi di una derivazione a mano, anche quando "sembra" già verificata contro una propria ricostruzione del circuito.
Verificato esatto (precisione macchina, calcola_energia_vqe su tutto lo sweep, inclusi i checkpoint stampati — es. energia_forma_chiusa() in scripts/vqe_gradient.py. tests/test_integration_smoke.py::test_vqe_gradient_closed_form_matches_real_circuit_exactly verifica l'identità su 7 punti lungo il range.
◀ Capitolo 2 · Home · Capitolo 4 ▶
Dense-Evolution-Ising-Tests · MIT License © 2026 Salvatore Pennacchio (tatopenn-cell) · dipende da Dense-Evolution (Business Source License 1.1)