SQD pro odhad energie chemického Hamiltoniánu
V této lekci použijeme SQD k odhadu energie základního stavu molekuly.
Konkrétně probereme následující témata pomocí krokového přístupu Qiskit pattern:
- Krok 1: Mapování problému na kvantové obvody a operátory
- Nastavení molekulárního Hamiltoniánu pro .
- Vysvětlení chemicky inspirovaného a hardwarově vhodného lokálního unitárního klastrového Jastrowa (LUCJ) [1]
- Krok 2: Optimalizace pro cílový hardware
- Optimalizace počtu hradel a rozložení ansatzu pro hardwarové spuštění
- Krok 3: Spuštění na cílovém hardwaru
- Spuštění optimalizovaného obvodu na skutečném QPU pro generování vzorků z podprostoru.
- Krok 4: Postprocessing výsledků
- Představení samokonzistentní smyčky pro obnovu konfigurací [2]
- Postprocessing úplné sady vzorků bitstringů s využitím předchozí znalosti počtu částic a průměrné orbitální obsazenosti vypočítané v poslední iteraci.
- Pravděpodobnostní tvorba dávek podvzorků z obnovených bitstringů.
- Projekce a diagonalizace molekulárního Hamiltoniánu nad každým navzorkovaným podprostorem.
- Uložení minimální nalezené energie základního stavu napříč všemi dávkami a aktualizace průměrné orbitální obsazenosti.
- Představení samokonzistentní smyčky pro obnovu konfigurací [2]
V průběhu lekce využijeme několik softwarových balíčků.
PySCFpro definici molekuly a nastavení Hamiltoniánu.- balíček
ffsimpro konstrukci LUCJ ansatzu. Qiskitpro transpilaci ansatzu pro hardwarové spuštění.Qiskit IBM Runtimepro spuštění obvodu na QPU a sběr vzorků.Qiskit addon SQDpro obnovu konfigurací a odhad energie základního stavu pomocí projekce na podprostor a maticové diagonalizace.
1. Mapování problému na kvantové obvody a operátory
Molekulární hamiltonián
Molekulární Hamiltonián má obecný tvar:
/ jsou fermionové kreační/anihilační operátory spojené s -tým prvkem bázové sady a spinem . a jsou jedno- a dvoučásticové elektronové integrály. Pomocí pySCF definujeme molekulu a spočítáme jedno- a dvoučásticové integrály Hamiltoniánu pro bázovou sadu 6-31g.
# Added by doQumentation — required packages for this notebook
!pip install -q ffsim matplotlib numpy pyscf qiskit qiskit-addon-sqd qiskit-ibm-runtime
import warnings
import pyscf
import pyscf.cc
import pyscf.mcscf
warnings.filterwarnings("ignore")
# Specify molecule properties
open_shell = False
spin_sq = 0
# Build N2 molecule
mol = pyscf.gto.Mole()
mol.build(
atom=[["N", (0, 0, 0)], ["N", (1.0, 0, 0)]], # Two N atoms 1 angstrom apart
basis="6-31g",
symmetry="Dooh",
)
# Define active space
n_frozen = 2
active_space = range(n_frozen, mol.nao_nr())
# Get molecular integrals
scf = pyscf.scf.RHF(mol).run()
num_orbitals = len(active_space)
n_electrons = int(sum(scf.mo_occ[active_space]))
num_elec_a = (n_electrons + mol.spin) // 2
num_elec_b = (n_electrons - mol.spin) // 2
cas = pyscf.mcscf.CASCI(scf, num_orbitals, (num_elec_a, num_elec_b))
mo = cas.sort_mo(active_space, base=0)
hcore, nuclear_repulsion_energy = cas.get_h1cas(mo) # hcore: one-body integrals
eri = pyscf.ao2mo.restore(1, cas.get_h2cas(mo), num_orbitals) # eri: two-body integrals
# Compute exact energy for comparison
exact_energy = cas.run().e_tot
converged SCF energy = -108.835236570774
CASCI E = -109.046671778080 E(CI) = -32.8155692383188 S^2 = 0.0000000
V této lekci použijeme Jordan-Wignerovu (JW) transformaci k mapování fermionové vlnové funkce na qubitovou vlnovou funkci, aby ji bylo možné připravit pomocí kvantového obvodu. JW transformace mapuje Fockův prostor fermionů v M prostorových orbitalech na Hilbertův prostor 2M qubitů, to znamená, že prostorový orbital se rozdělí na dva spinorbitaly, jeden spojený s elektronem se spinem nahoru () a druhý se spinem dolů (). Spinorbital může být obsazený nebo neobsazený. Obvykle, když mluvíme o počtu orbitalů, máme na mysli počet prostorových orbitalů. Počet spinorbitalů bude dvojnásobný. V kvantových obvodech budeme každý spinorbital reprezentovat jedním qubitem. Sada qubitů bude tedy reprezentovat orbitaly spin-up neboli -orbitaly a další sada bude reprezentovat orbitaly spin-down neboli -orbitaly. Například molekula pro bázovou sadu 6-31g má prostorových orbitalů (to jest + = spinorbitalů). Budeme tedy potřebovat qubitový kvantový obvod (později můžeme potřebovat další pomocné qubity, jak bude popsáno). Qubity se měří ve výpočetní bázi, čímž se generují bitstringy, které reprezentují elektronické konfigurace neboli (Slaterovy) determinanty. V této lekci budeme termíny bitstringy, konfigurace a determinanty používat zaměnitelně. Bitstringy nám říkají obsazenost elektronů ve spinorbitalech: na pozici bitu znamená, že odpovídající spinorbital je obsazený, zatímco znamená, že spinorbital je prázdný. Protože problémy elektronické struktury zachovávají částice, musí být obsazen pouze pevný počet spinorbitalů. Molekula má elektronů se spinem nahoru () a elektronů se spinem dolů (). Každý bitstring reprezentující a orbitaly tedy musí mít pro molekulu pět v každém.
1.1 Kvantový obvod pro generování vzorků: ansatz LUCJ
V této lekci použijeme ansatz lokálního unitárního coupled cluster Jastrow (LUCJ) \[1\] pro přípravu kvantového stavu a následné vzorkování. Nejprve vysvětlíme jednotlivé stavební bloky plného ansatzu UCJ a aproximace provedené v jeho lokální verzi. Následně pomocí balíčku ffsim sestavíme ansatz LUCJ a optimalizujeme jej pomocí transpileru Qiskit pro hardwarové spuštění.
Ansatz UCJ má následující tvar (pro součin vrstev nebo opakování operátoru UCJ).
kde je referenční stav, typicky brán jako Hartree-Fockův (HF) stav. Protože je Hartree-Fockův stav definován tak, že má obsazené orbitaly s nejnižšími čísly, příprava HF stavu bude zahrnovat aplikaci X gates pro nastavení qubits odpovídajících obsazeným orbitalům na jedničku. Například blok přípravy HF stavu pro 4 prostorové orbitaly a 2 spiny nahoru a 2 spiny dolů může vypadat následovně:
Jedno opakování operátoru UCJ se skládá z diagonální Coulombovy evoluce () obklopené orbitálními rotacemi ( a ).
Bloky orbitální rotace pracují na jednom druhu spinu ( (spin nahoru)/ (spin dolů)). Pro každý druh elektronu se orbitální rotace skládá z vrstvy jednoqubitových gates následovaných posloupností dvouqubitových Givensových rotačních gates ( gates).
Dvouqubitové gates působí na sousední spin-orbitaly (nejbližší sousední qubits), a tedy jsou implementovatelné na IBM® QPU bez nutnosti SWAP gates.
, také známý jako diagonální Coulombův operátor, se skládá ze tří bloků. Dva z nich pracují na stejných spinových sektorech ( a ) a jeden pracuje mezi dvěma spinovými sektory ().
Všechny bloky v se skládají z number-number gates [1]. Gate lze dále rozložit na gate následovaný dvěma jednoqubitovými gates působícími na dva samostatné qubits.
Stejnospinové složky ( a ) mají gates mezi všemi možnými dvojicemi qubits. Protože však supravodivé QPU mají omezenou konektivitu, je nutné qubits prohazovat, aby bylo možné realizovat gates mezi nesousedními qubits.
Zvažte například následující blok (nebo ) pro prostorové orbitaly. Pro lineární konektivitu qubits nejsou poslední tři gates přímo implementovatelné, protože pracují mezi nesousedními qubits (například Q0 a Q2 nejsou přímo propojeny). Proto potřebujeme SWAP gates, abychom je udělali sousedními (následující obrázek ukazuje příklad s SWAP gates).
Dále implementuje gates mezi stejně indexovanými orbitaly z různých spinových sektorů (například mezi a ). Podobně, pokud qubits nejsou fyzicky sousední na QPU, budou tyto gates také vyžadovat SWAPs.
Z výše uvedené diskuse vyplývá, že ansatz UCJ čelí určitým překážkám při HW spuštění, protože potřebuje SWAP gates kvůli interakcím mezi nesousedními qubits. Lokální varianta ansatzu UCJ, LUCJ, řeší tuto výzvu odstraněním některých z diagonálního Coulombova operátoru.
V blocích stejných druhů elektronů, a , ponecháváme pouze gates kompatibilní s konektivitou nejbližších sousedů a ve verzi LUCJ odstraňujeme gates mezi nesousedními qubits. Následující obrázek ukazuje blok LUCJ po odstranění nesousedních gates.
Dále verze LUCJ bloku , který pracuje mezi různými druhy elektronů, může mít různý tvar v závislosti na topologii zařízení.
I zde se verze LUCJ zbavuje nekompatibilních gates. Obrázek níže ukazuje varianty bloku pro různé topologie qubits včetně mřížkové, hexagonální, heavy-hex a lineární.
- Čtvercová: můžeme mít gates mezi všemi a orbitaly bez jakýchkoli SWAPs, a proto nepotřebujeme odstranit žádné gates.
- Heavy-hex: Interakce - jsou ponechány mezi každým . indexovaným (například 0., 4. a 8.) spin-orbitalem a jsou zprostředkovány ancillou, to znamená, že potřebujeme ancilla qubits mezi lineárními řetězy reprezentujícími a orbitaly. Toto uspořádání potřebuje omezený počet SWAPs.
- Hexagonální: Každý druhý orbital, například 0., 2. a 4. indexovaný orbital, se stává nejbližším sousedem, když jsou a rozloženy do dvou sousedních lineárních řetězů.
- Lineární: Propojený je pouze jeden a jeden orbital, což znamená, že blok bude mít pouze jeden gate.
Odstraněním gates z ansatzu UCJ pro sestavení verze LUCJ se sice stává HW kompatibilnější, ale ansatz ztrácí určitou expresivitu. Proto při použití ansatzu LUCJ může být potřeba více opakování () modifikovaného operátoru UCJ.
1.2 Inicializace ansatzu LUCJ
LUCJ je parametrizovaný ansatz a před hardwarovým spuštěním musíme parametry inicializovat. Jedním ze způsobů inicializace ansatzu je použití amplitud t1 a t2 z klasické metody coupled cluster singles and doubles (CCSD), kde amplitudy t1 jsou koeficienty operátorů jednoduchých excitací a amplitudy t2 jsou pro operátory dvojitých excitací.
Všimni si, že i když inicializace ansatzu LUCJ amplitudami t1 a t2 generuje slušné výsledky, parametry ansatzu mohou vyžadovat další optimalizaci.
# Get CCSD t2 amplitudes for initializing the ansatz
ccsd = pyscf.cc.CCSD(
scf, frozen=[i for i in range(mol.nao_nr()) if i not in active_space]
)
ccsd.run()
t1 = ccsd.t1
t2 = ccsd.t2
E(CCSD) = -109.0398256929733 E_corr = -0.20458912219883
1.3 Konstrukce ansatzu LUCJ pomocí ffsim
K vytvoření a inicializaci ansatzu s amplitudami t1 a t2 vypočítanými výše použijeme balíček ffsim. Protože naše molekula má Hartree-Fockův stav s uzavřenou slupkou, použijeme spinově vyváženou variantu ansatzu UCJ, UCJOpSpinBalanced.
Protože hardware IBM má topologii heavy-hex, přijmeme cik-cak vzor použitý v [1] a vysvětlený výše pro interakce qubits. V tomto vzoru jsou orbitaly (qubits) se stejným spinem propojeny lineární topologií (červené a modré kruhy). Kvůli topologii heavy-hex mají orbitaly pro různé spiny spojení mezi každým 4. orbitalem, to jest 0., 4., 8. a tak dále (fialové kruhy).

import ffsim
from qiskit import QuantumCircuit, QuantumRegister
n_reps = 2
alpha_alpha_indices = [(p, p + 1) for p in range(num_orbitals - 1)]
alpha_beta_indices = [(p, p) for p in range(0, num_orbitals, 4)]
ucj_op = ffsim.UCJOpSpinBalanced.from_t_amplitudes(
t2=t2,
t1=t1,
n_reps=n_reps,
interaction_pairs=(alpha_alpha_indices, alpha_beta_indices),
)
nelec = (num_elec_a, num_elec_b)
# create an empty quantum circuit
qubits = QuantumRegister(2 * num_orbitals, name="q")
circuit = QuantumCircuit(qubits)
# prepare Hartree-Fock state as the reference state and append it to the quantum circuit
circuit.append(ffsim.qiskit.PrepareHartreeFockJW(num_orbitals, nelec), qubits)
# apply the UCJ operator to the reference state
circuit.append(ffsim.qiskit.UCJOpSpinBalancedJW(ucj_op), qubits)
circuit.measure_all()
# circuit.decompose().draw("mpl", scale=0.5, fold=-1)
Ansatz LUCJ s opakovanými vrstvami lze optimalizovat sloučením některých sousedních bloků. Zvažme případ pro n_reps=2. Dva bloky orbitální rotace uprostřed lze sloučit do jednoho bloku orbitální rotace. Balíček ffsim má pass manager s názvem ffsim.qiskit.PRE_INIT k optimalizaci obvodu sloučením takových sousedních bloků.
