Přeskočit na hlavní obsah
Tento projekt je v betě. Našel jsi chybu? Otevřít issue na GitHubu. Máš otázku nebo nápad? Zeptej se v Discussions — rádi si poslechneme tvou zpětnou vazbu!
Jaká je kvalita překladu na této stránce?

Jak tento balíček souvisí s ffsim

Důležité

Koncepty v tomto průvodci jsou dostupné pouze v Python API.

ffsim a tento balíček si práci dělí, nikoli překrývají, podle jediné hranice:

ffsim vlastníqiskit-fermions vlastní
Vysokoúrovňové operátory ansatzů (UCJOpSpinBalanced, UCCSDOpRestrictedReal a jejich sourozenci), sestavené z amplitud coupled-cluster nebo z vektoru parametrůFermionický obvod (FermionicCircuit), v nějž se tyto operátory změní, a jeho transpilaci na qubitový obvod v libovolném kódování fermion-na-qubit
Rychlá simulace v kompaktním prostoru s pevným počtem částicFramework mapperů a datové struktury operátorů, z nichž se obvod sestavuje

Praktický důsledek platí oběma směry. Matematika ansatzů žije v ffsim, takže UCJ a UCC berou jako vstup přímo operátor z ffsim. Naopak vlastní hradla Qiskit z ffsim jsou specifická pro Jordanovu-Wignerovu transformaci, takže přenesení jeho operátoru ansatzu sem ti přináší možnost převést ho přes jiné kódování.

Simulace je místo, kde se obě setkávají, a tento průvodce vysvětluje jak. ffsim je simulační backend tohoto balíčku, dostupný přes vlastní protokoly, nikoli přes obal: průvodce SKQD volá ffsim.apply_unitary(), ffsim.linear_operator() a ffsim.sample_state_vector() přímo na objektech FermionicCircuita FermionOperatorbez jakéhokoli kroku převodu.

Připojení k simulačnímu rozhraní ffsim​

ffsim je vysoce výkonný simulátor fermionických kvantových obvodů, který využívá zachování počtu částic a spinu Z k reprezentaci stavových vektorů kompaktněji než obecný 2n2^n-rozměrný qubitový stavový vektor. Definuje protokoly, které může implementovat jakýkoli objekt, aby se zapojil do jeho simulačního aparátu (viz qiskit_fermions.protocols pro vlastní protokoly tohoto balíčku, které sledují stejný návrh):

Tento balíček toto rozhraní implementuje: každé fermionické hradlo v qiskit_fermions.circuit.library poskytuje _apply_unitary_ a FermionOperator poskytuje _linear_operator_ a _trace_. Právě to činí operátory a obvody tohoto balíčku kompatibilními s ffsim, takže jeho nástroje na nich fungují nativně, bez kroku převodu. ffsim.apply_unitary() může simulovat FermionicCircuit od začátku do konce, ffsim.linear_operator() může diagonalizovat FermionOperator a vzorkovací nástroje jako ffsim.sample_state_vector() (použitý v průvodci SKQD k převodu simulovaného stavového vektoru na počty měření) fungují bez úprav.

To, co vrací _linear_operator_, je běžný LinearOperator ze SciPy, takže na něm fungují i scipy.sparse.linalg.eigsh() a další.

>>> import ffsim
>>> import numpy as np
>>>
>>> from qiskit_fermions.circuit import FermionicCircuit
>>> from qiskit_fermions.circuit.library import Evolution
>>> from qiskit_fermions.operators import FermionOperator, ann, cre
>>>
>>> norb, nelec = 2, (1, 1)
>>> hamiltonian = FermionOperator.from_terms([
... ([cre(0), ann(1)], 0.5),
... ([cre(1), ann(0)], 0.5),
... ])
>>>
>>> circuit = FermionicCircuit(2 * norb)
>>> circuit.append(Evolution(2 * norb, hamiltonian, time=1.0), circuit.modes)
>>>
>>> reference = ffsim.hartree_fock_state(norb, nelec)
>>> state = ffsim.apply_unitary(reference, circuit, norb=norb, nelec=nelec) # native ffsim call

Právě propojení přes protokoly ffsim to umožňuje: jeho aktivně vyvíjený ekosystém simulačních a vzorkovacích nástrojů se na obvody a operátory tohoto balíčku vztahuje beze změny a uživatelé, kteří už s ffsim pracují, mohou přimíchat hradla a operátory tohoto balíčku, aniž by se museli učit další simulační API.

ffsim je volitelná závislost​

ffsim je deklarován jako volitelný extra (pip install "qiskit-fermions[ffsim]", nebo tranzitivně přes [all]), hlídaný za běhu pomocí HAS_FFSIM (jak bylo ukázáno výše). Jeho instalace odemkne simulaci: ffsim.SupportsLinearOperator a ffsim.SupportsTrace jsou implementovány převodem FermionOperator tohoto balíčku na ffsim.FermionOperator, takže bez ffsim vyvolají MissingOptionalLibraryError. Nic, co nesimuluje (sestavování operátorů, jejich mapování a transpilace výsledných obvodů), ho nepotřebuje.

Fermionická simulace probíhá v sektoru s pevným počtem částic​

_apply_unitary_ i _linear_operator_ přijímají argument nelec a reprezentují stavový vektor v determinantové bázi s pevným počtem částic pro daný sektor (norb, nelec), v souladu s nastavením prostoru FCI v ffsim (a tranzitivně v PySCF), místo celého 2num_modes2^{\text{num\_modes}}-rozměrného prostoru, který by použil obecný qubitový simulátor. Je to mnohem menší prostor (jeho velikost je součinem binomických koeficientů, nikoli mocninou dvou), ale přichází s tvrdým omezením. Lze v něm reprezentovat jen operátory a hradla, která zachovávají počet částic (a v případě se spinem počet částic každého spinového druhu zvlášť). Operátor, jehož působení by přesunulo amplitudu na jiný počet částic, pro ni nemá kam dát.

ffsim to řeší tím, že takový operátor rovnou odmítne: jeho převod na lineární operátor vyvolá ValueError s uvedením, který zákon zachování selhává. To je správné výchozí chování, protože aplikace exp⁡(−itH)\exp(-i t H) pro hamiltonián HH s členem nezachovávajícím počet částic by jinak změnila údajně unitární mapu na neunitární a fyzikálně bezvýznamnou.

  • Evolution toto odmítnutí přebírá od operátoru, který vyvíjí.

  • OrbitalRotation kontroluje, že jeho (vnořená) rotační matice je ve spinovém případě blokově diagonální vzhledem k rozdělení alfa/beta, a pokud míchá spinové sektory, vyvolá ValueError.

>>> from qiskit_fermions.circuit.library import Evolution
>>>
>>> non_conserving = FermionOperator.from_terms([([cre(0), cre(1)], 1.0)]) # creates 2 particles
>>> gate = Evolution(2 * norb, non_conserving, time=1.0)
>>>
>>> try:
... gate._apply_unitary_(reference, norb, nelec, copy=True)
... except ValueError as exc:
... print("rejected:", exc)
rejected: The given FermionOperator could not be converted to a LinearOperator because it does not conserve particle number and the z component of spin. Conserves particle number: False Conserves spin z: False

Simulace, která nezachovává počet částic, je proto ve fermionovém prostoru z principu nedosažitelná, a to kvůli reprezentaci s pevným sektorem; je to cena za kompaktní prostor FCI, který vůbec umožňuje fermionovou simulaci zvládnout. Pokud tvůj algoritmus potřebuje operátory porušující počet částic (například kanál chyb nativní pro qubity nebo operátor sestavený pro namapovaný hamiltonián, který nezachovává počty částic člen po členu), nejprve transpiluj na qubity a výsledný QuantumCircuit simuluj místo toho simulátorem na úrovni qubitů. Funguje k tomu jakákoli cesta transpilace; podrobněji se jí věnují průvodci fermionovým obvodem a transpilací, ale rozumnou výchozí volbou je generate_preset_jw_pass_manager().

Bloková spinová konvence pro spinové systémy​

nelec má typ int | tuple[int, int] a právě jeho typ, nikoli samostatný příznak, určuje, které z podporovaných uspořádání módů se použije:

  • int vybírá bezspinovou interpretaci. norb módů se bere přímo jako bezspinové orbitaly a nelec je celkový počet částic.

  • Dvojice (n_alpha, n_beta) vybírá spinovou interpretaci 2 * norb módů podle pevné blokové spinové konvence. Módy 0 .. norb jsou orbitaly alfa (spin nahoru) a módy norb .. 2 * norb jsou orbitaly beta (spin dolů). Každý druh spinu se zachovává nezávisle; člen jen s alfa může přesunout elektron mezi módy alfa, ale nikdy do módu beta, a naopak.

Toto rozlišení probíhá v každém vstupním bodě protokolu ffsim v tomto balíčku (konstruktory hradel, implementace _apply_unitary_placed_ a kompilace sektorů v nativním jádru v Rustu) a je to konvence používaná v celých průvodcích LUCJ a SKQD (například InitializeModes.from_hartree_fock() zapisuje obsazení alfa do módů 0 .. n_alpha a obsazení beta do módů norb .. norb + n_beta). Stojí za to to porovnat s modulem qiskit_fermions.operators a obecně s FermionicCircuit, které používají obecné indexy módů bez vlastního spinového významu (viz průvodce fermionovým obvodem). Blokový spinový význam se uplatní až ve chvíli, kdy se volání simulace předá spinové nelec, nikoli přímo v reprezentaci operátoru nebo obvodu.

>>> from qiskit_fermions.circuit.library import InitializeModes
>>>
>>> norb, nelec = 3, (2, 1)
>>> init = InitializeModes.from_hartree_fock(norb, nelec)
>>> print([bool(occ) for occ in init.occupation]) # alpha modes 0,1; beta mode 3 (= norb + 0)
[True, True, False, True, False, False]

Další kroky​