Instance a rozšíření
Tato kapitola pokryje několik kvantových variačních algoritmů, včetně
- Variační kvantový řešič vlastních čísel (VQE)
- Subspace Search VQE (SSVQE)
- Variational Quantum Deflation (VQD)
- Quantum Sampling Regression (QSR)
Pomocí těchto algoritmů se seznámíme s několika návrhovými myšlenkami, které lze začlenit do vlastních variačních algoritmů, jako jsou váhy, penalizace, převzorkování a podvzorkování. Doporučujeme ti, abys s těmito koncepty experimentoval a podělil se o svá zjištění s komunitou.
Framework Qiskit patterns se vztahuje na všechny tyto algoritmy – jednotlivé kroky však explicitně vyjmenujeme pouze v prvním příkladu.
Variační kvantový řešič vlastních čísel (VQE)
VQE je jedním z nejpoužívanějších variačních kvantových algoritmů a tvoří šablonu, na které mohou stavět další algoritmy.
Krok 1: Mapování klasických vstupů na kvantový problém
Teoretické uspořádání
Uspořádání VQE je jednoduché:
- Příprava referenčních operátorů
- Začínáme ze stavu a přecházíme do referenčního stavu
- Aplikace variační formy k vytvoření ansatzu
- Přecházíme ze stavu do
- Bootstrap při , pokud máme podobný problém (obvykle zjištěný pomocí klasické simulace nebo vzorkování)
- Každý optimalizátor bude bootstrapován odlišně, což vede k počáteční sadě vektorů parametrů (například z počátečního bodu ).
- Vyhodnocení nákladové funkce pro všechny připravené stavy na kvantovém počítači.
- Použití klasického optimalizátoru k výběru další sady parametrů .
- Opakování procesu, dokud není dosaženo konvergence.
Jedná se o jednoduchou klasickou optimalizační smyčku, ve které vyhodnocujeme nákladovou funkci. Některé optimalizátory mohou vyžadovat více vyhodnocení k výpočtu gradientu, určení další iterace nebo posouzení konvergence.
Zde je příklad pro následující pozorovatelnou:
Implementace
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime scipy
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit.library import TwoLocal
import numpy as np
theta_list = (2 * np.pi * np.random.rand(1, 8)).tolist()
observable = SparsePauliOp.from_list([("II", 2), ("XX", -2), ("YY", 3), ("ZZ", -3)])
reference_circuit = QuantumCircuit(2)
reference_circuit.x(0)
variational_form = TwoLocal(
2,
rotation_blocks=["rz", "ry"],
entanglement_blocks="cx",
entanglement="linear",
reps=1,
)
ansatz = reference_circuit.compose(variational_form)
ansatz.decompose().draw("mpl")
def cost_func_vqe(parameters, ansatz, hamiltonian, estimator):
"""Return estimate of energy from estimator
Parameters:
params (ndarray): Array of ansatz parameters
ansatz (QuantumCircuit): Parameterized ansatz circuit
hamiltonian (SparsePauliOp): Operator representation of Hamiltonian
estimator (Estimator): Estimator primitive instance
Returns:
float: Energy estimate
"""
estimator_job = estimator.run([(ansatz, hamiltonian, [parameters])])
estimator_result = estimator_job.result()[0]
cost = estimator_result.data.evs[0]
return cost
from qiskit.primitives import StatevectorEstimator
estimator = StatevectorEstimator()
Tuto nákladovou funkci můžeme použít k výpočtu optimálních parametrů
# SciPy minimizer routine
from scipy.optimize import minimize
x0 = np.ones(8)
result = minimize(
cost_func_vqe, x0, args=(ansatz, observable, estimator), method="COBYLA"
)
result
message: Optimization terminated successfully.
success: True
status: 1
fun: -5.999999982445723
x: [ 1.741e+00 9.606e-01 1.571e+00 2.115e-05 1.899e+00
1.243e+00 6.063e-01 6.063e-01]
nfev: 136
maxcv: 0.0
Krok 2: Optimalizace problému pro kvantové spouštění
Vybereme nejméně vytížený backend a naimportujeme potřebné komponenty z qiskit_ibm_runtime.
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime import Session, EstimatorOptions
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
print(backend)
<IBMBackend('ibm_brisbane')>
Circuit transpilujeme pomocí přednastaveného pass manageru s úrovní optimalizace 3 a na pozorovatelnou veličinu použijeme odpovídající rozložení.
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
isa_ansatz = pm.run(ansatz)
isa_observable = observable.apply_layout(layout=isa_ansatz.layout)
Krok 3: Spuštění pomocí primitiv Qiskit Runtime
Nyní jsme připraveni spustit náš výpočet na hardwaru IBM Quantum®. Protože minimalizace nákladové funkce je vysoce iterativní, spustíme Runtime session. Díky tomu budeme muset čekat ve frontě pouze jednou. Jakmile úloha začne běžet, každá iterace s aktualizovanými parametry proběhne okamžitě.
x0 = np.ones(8)
estimator_options = EstimatorOptions(resilience_level=1, default_shots=10_000)
with Session(backend=backend) as session:
estimator = Estimator(mode=session, options=estimator_options)
result = minimize(
cost_func_vqe,
x0,
args=(isa_ansatz, isa_observable, estimator),
method="COBYLA",
options={"maxiter": 200, "disp": True},
)
session.close()
print(result)
Krok 4: Zpracování výsledků do klasického formátu
Vidíme, že minimalizační rutina úspěšně skončila, což znamená, že jsme dosáhli výchozí tolerance klasického optimalizátoru COBYLA. Pokud potřebujeme přesnější výsledek, můžeme specifikovat menší toleranci. To může být skutečně nutné, protože výsledek se lišil o několik procent oproti výsledku získanému výše simulátorem.
Získaná hodnota x je aktuální nejlepší odhad parametrů, které minimalizují nákladovou funkci. Pokud iterujeme pro získání vyšší přesnosti, měly by se tyto hodnoty použít místo původně použitého x0 (vektoru jedniček).
Nakonec poznamenejme, že funkce byla v procesu optimalizace vyhodnocena 96krát. To se může lišit od počtu optimalizačních kroků, protože některé optimalizátory vyžadují více vyhodnocení funkce v jednom kroku, například při odhadu gradientu.
VQE hledající podprostory (SSVQE)
SSVQE je varianta VQE, která umožňuje získat prvních vlastních hodnot pozorovatelné veličiny s vlastními hodnotami , kde . Bez újmy na obecnosti předpokládáme, že . SSVQE zavádí novou myšlenku tím, že přidává váhy, které pomáhají upřednostnit optimalizaci členu s největší váhou.
Abychom tento algoritmus implementovali, potřebujeme vzájemně ortogonálních referenčních stavů , což znamená pro . Tyto stavy lze sestrojit pomocí Pauliho operátorů. Cenová funkce tohoto algoritmu pak je:
kde je libovolné kladné číslo takové, že pokud , pak , a je uživatelem definovaná variační forma.
Algoritmus SSVQE se opírá o skutečnost, že vlastní stavy odpovídající různým vlastním hodnotám jsou vzájemně ortogonální. Konkrétně lze skalární součin a vyjádřit jako:
První rovnost platí, protože je kvantový operátor, a je tedy unitární. Poslední rovnost platí díky ortogonalitě referenčních stavů . Skutečnost, že ortogonalita je zachována při unitárních transformacích, hluboce souvisí s principem zachování informace, jak je vyjádřen v kvantové informační vědě. Z tohoto pohledu neunitární transformace představují procesy, při nichž je informace buď ztracena, nebo vnesena.
Váhy pomáhají zajistit, aby všechny stavy byly vlastními stavy. Pokud se váhy dostatečně liší, bude během optimalizace upřednostněn člen s největší vahou (tj. ) před ostatními. V důsledku toho se výsledný stav stane vlastním stavem odpovídajícím . Protože jsou vzájemně ortogonální, zbývající stavy k němu budou ortogonální, a tedy budou obsaženy v podprostoru odpovídajícím vlastním hodnotám .
Aplikací stejného argumentu na zbývající členy bude další prioritou člen s vahou , takže bude vlastním stavem odpovídajícím a ostatní členy budou obsaženy ve vlastním prostoru .
Induktivním uvažováním odvodíme, že bude přibližným vlastním stavem pro
Teoretické uspořádání
SSVQE lze shrnout následovně:
- Připravte několik referenčních stavů aplikací unitárního operátoru U_R na k různých stavů výpočetní báze
- Tento algoritmus vyžaduje použití vzájemně ortogonálních referenčních stavů , takže pro .
- Aplikujte variační formu na každý referenční stav, což vede k následujícímu ansatzu .
- Použijte bootstrap při , pokud je k dispozici podobný problém (obvykle nalezený prostřednictvím klasické simulace nebo vzorkování).
- Vyhodnoťte cenovou funkci pro všechny připravené stavy na kvantovém počítači.
- To lze rozdělit na výpočet střední hodnoty pro pozorovatelnou veličinu a vynásobení tohoto výsledku hodnotou .
- Poté cenová funkce vrátí součet všech vážených středních hodnot.
- Použijte klasický optimalizátor k určení další sady parametrů .
- Opakujte výše uvedené kroky, dokud nebude dosaženo konvergence.
V testu budete rekonstruovat cenovou funkci SSVQE, ale máme následující úryvek, který vám pomůže s řešením:
import numpy as np
def cost_func_ssvqe(
params, initialized_anastz_list, weights, ansatz, hamiltonian, estimator
):
# """Return estimate of energy from estimator
# Parameters:
# params (ndarray): Array of ansatz parameters
# initialized_anastz_list (list QuantumCircuit): Array of initialised ansatz with reference
# weights (list): List of weights
# ansatz (QuantumCircuit): Parameterized ansatz circuit
# hamiltonian (SparsePauliOp): Operator representation of Hamiltonian
# estimator (Estimator): Estimator primitive instance
# Returns:
# float: Weighted energy estimate
# """
energies = []
# Define SSVQE
weighted_energy_sum = np.dot(energies, weights)
return weighted_energy_sum
Variační kvantová deflace (VQD)
VQD je iterativní metoda, která rozšiřuje VQE tak, aby místo pouze nejnižší vlastní hodnoty získala prvních vlastních hodnot pozorovatelné s vlastními hodnotami , kde . Ve zbytku této sekce budeme bez ztráty obecnosti předpokládat, že . VQD zavádí pojem penalizační ceny, která vede optimalizační proces.
VQD zavádí penalizační člen, označený jako , který vyvažuje příspěvek každého překryvového členu k ceně. Tento penalizační člen slouží k penalizaci optimalizačního procesu, pokud není dosaženo ortogonality. Tuto podmínku zavádíme proto, že vlastní stavy pozorovatelné, nebo hermitovského operátoru, odpovídající různým vlastním hodnotám jsou vždy vzájemně ortogonální, nebo je lze takovými učinit v případě degenerace či opakovaných vlastních hodnot. Vynucením ortogonality s vlastním stavem odpovídajícím tedy efektivně optimalizujeme nad podprostorem, který odpovídá zbývajícím vlastním hodnotám . Zde je nejnižší vlastní hodnotou ze zbývajících vlastních hodnot, a proto lze optimální řešení nového problému získat pomocí variačního teorému.
Obecná myšlenka VQD spočívá v tom, že se běžně použije VQE k získání nejnižší vlastní hodnoty spolu s odpovídajícím (přibližným) vlastním stavem pro nějaký optimální vektor parametrů . Poté, abychom získali další vlastní hodnotu , místo minimalizace cenové funkce optimalizujeme:
Kladná hodnota by ideálně měla být větší než .
Tím se zavádí nová cenová funkce, kterou lze chápat jako omezenou úlohu, v níž minimalizujeme s podmínkou, že stav musí být ortogonální k dříve získanému , přičemž funguje jako penalizační člen, pokud podmínka není splněna.
Alternativně lze tuto novou úlohu interpretovat jako spuštění VQE nad novou pozorovatelnou: