L'ansatz
Guarda Victoria Lipinska che spiega cos'Γ¨ un ansatz e perchΓ© Γ¨ importante nel contesto di un eigensolver quantistico variazionale (VQE).
Riferimentiβ
I seguenti articoli sono citati nel video sopra.
- The theory of variational hybrid quantum-classical algorithms, McClean, et al.
- Quantum Chemistry in the Age of Quantum Computing, Cao, et al.
- Noisy intermediate-scale quantum (NISQ) algorithms, Bharti, et al.
- The Variational Quantum Eigensolver: A review of methods and best practices, Tilly, et al.
- Hardware-efficient Variational Quantum Eigensolver for Small Molecules and Quantum Magnets, Kandala, et al.
- Quantum computational chemistry, McArdle, et al.
Codice dell'ansatzβ
Nella lezione precedente hai creato un Hamiltoniano che descrive l'energia della molecola di interesse e lo hai mappato in un formato utile per un computer quantistico. Il VQE utilizza un circuito variazionale per preparare stati quantistici. Questi stati vengono poi utilizzati per determinare il valore atteso dell'Hamiltoniano (l'energia). I parametri del circuito variazionale vengono variati finchΓ© il calcolo non converge a un valore atteso minimo. Nel contesto della chimica quantistica, questo dovrebbe corrispondere all'energia dello stato fondamentale. Questa lezione si concentra sul circuito variazionale, detto anche ansatz (una parola tedesca che significa "approccio" o "metodo"). In questa lezione imparerai
- l'insieme degli ansatz precostruiti disponibili nella libreria di circuiti
- Come specificare o modificare le caratteristiche di un ansatz
- Come costruire il tuo ansatz personalizzato
- esempi di ansatz buoni e cattivi
La libreria di circuiti Qiskit contiene molte categorie di circuiti utilizzabili come ansatz. Qui limiteremo la discussione ai circuiti two-local (circuiti composti da gate che agiscono su al massimo due qubit alla volta). Efficient SU2 Γ¨ un ansatz comunemente usato.
Un circuito efficient_su_2 Γ¨ composto da strati di operazioni su singolo qubit nello spazio SU(2) (gruppo speciale unitario di grado 2, come i gate di rotazione di Pauli) e entanglement CX. Γ un pattern euristico utile in algoritmi quantistici variazionali come VQE e circuiti di classificazione nel machine learning quantistico (QML).
Iniziamo con un circuito efficient_su2 a quattro qubit con due tipi di gate SU(2), ad esempio rx e y. Specifichiamo anche uno schema di entanglement e il numero di ripetizioni. Se usi semplicemente .draw() sui circuiti, otterrai una rappresentazione piuttosto astratta. Un diagramma di circuito piΓΉ comprensibile si ottiene usando .decompose().draw(), e qui utilizzeremo output = "mpl".
# Added by doQumentation β required packages for this notebook
!pip install -q qiskit
from qiskit.circuit.library import efficient_su2
SU2_ansatz = efficient_su2(4, su2_gates=["rx", "y"], entanglement="linear", reps=1)
print(SU2_ansatz.draw())
SU2_ansatz.decompose().draw(output="mpl")
βββββββββββββββββ ββββββββββββ βββββ
q_0: β€ Rx(ΞΈ[0]) ββ€ Y ββββ βββ€ Rx(ΞΈ[4]) βββββ€ Y ββββββββββββββββββββββ
ββββββββββββ€βββββ€βββ΄ββββββββββββββββββ΄ββββ΄ββββ βββββ
q_1: β€ Rx(ΞΈ[1]) ββ€ Y ββ€ X βββββββ βββββββ€ Rx(ΞΈ[5]) βββββ€ Y ββββββββββ
ββββββββββββ€βββββ€βββββ βββ΄ββ ββββββββββββββββ΄ββββ΄βββββββββ
q_2: β€ Rx(ΞΈ[2]) ββ€ Y ββββββββββ€ X βββββββββββ βββββββ€ Rx(ΞΈ[6]) ββ€ Y β
ββββββββββββ€βββββ€ βββββ βββ΄ββ ββββββββββββ€βββββ€
q_3: β€ Rx(ΞΈ[3]) ββ€ Y ββββββββββββββββββββββ€ X ββββββ€ Rx(ΞΈ[7]) ββ€ Y β
βββββββββββββββββ βββββ βββββββββββββββββ
I gate SU(2) compaiono all'inizio e alla fine, con l'ordine e gli elementi specificati in su2_gates = [...]. Lo schema di entanglement linear significa che i gate CX scorrono tra i qubit numerati in sequenza, creando entanglement tra 0 e 1, poi tra 1 e 2, e così via lungo una diagonale nel circuito. Come ci si può aspettare, impostare reps = 2 aggiunge semplicemente uno strato di entanglement e uno strato finale SU(2). Impostare reps = n corrisponde a n strati di entanglement, con strati SU(2) tra di essi e a ciascuna estremità .
SU2_ansatz2 = efficient_su2(
4, su2_gates=["rx", "y", "z"], entanglement="linear", reps=2
)
SU2_ansatz2.decompose().draw(output="mpl")
Esistono diversi altri schemi di entanglement. Due degni di nota sono circular e full. L'entanglement circolare Γ¨ identico a quello lineare, ma con un gate CX aggiuntivo che crea entanglement tra il primo e l'ultimo qubit. Lo schema di entanglement full include un gate CX tra ogni coppia di qubit. Nota che per un circuito a N qubit, questo corrisponde a gate , e puΓ² diventare computazionalmente costoso.
SU2_ansatz3 = efficient_su2(
4, su2_gates=["rx", "y", "z"], entanglement="circular", reps=1
)
SU2_ansatz3.decompose().draw(output="mpl")
SU2_ansatz4 = efficient_su2(4, su2_gates=["rx", "y", "z"], entanglement="full", reps=1)
SU2_ansatz4.decompose().draw(output="mpl")
Puoi monitorare la profonditΓ dei tuoi circuiti usando .depth(), o a volte .decompose().depth().
print(SU2_ansatz4.decompose().depth())
11
Una generalizzazione dell'efficient_su2 è il circuito two-local, che è a sua volta un caso speciale dei circuiti n-local. I circuiti two-local contengono anch'essi blocchi SU(2) (o blocchi di rotazione) e blocchi di entanglement. Qui siamo liberi di specificare il tipo di gate di entanglement che vogliamo usare, ad esempio gate CRX. In questo esempio, tutti i gate accettano un parametro, ma non è necessario che sia così. Si potrebbero usare, ad esempio, gate di rotazione Y e gate di entanglement CX.
from qiskit.circuit.library import n_local
rotation_blocks = ["ry"]
entanglement_blocks = ["crx"]
two_ansatz = n_local(
4, rotation_blocks, entanglement_blocks, "linear", insert_barriers=True, reps=2
)
two_ansatz.decompose().draw(output="mpl")
L'ultimo ansatz di cui parleremo per nome Γ¨ il Pauli-two-design. Questo circuito contiene una rotazione iniziale di , e gli strati di rotazione contengono rotazioni di Pauli su singolo qubit, dove l'asse Γ¨ scelto uniformemente a caso tra X, Y e Z. Gli strati di entanglement sono composti da gate CZ a coppie con una profonditΓ totale di due. Nota la differenza nella profonditΓ dell'entanglement (e del circuito totale) tra questo pauli_two_design e, ad esempio, l'efficient_su2.
from qiskit.circuit.library import pauli_two_design
PtwoD_ansatz = pauli_two_design(5, reps=1, seed=10599, insert_barriers=True)
PtwoD_ansatz.decompose().draw(output="mpl")
Questi circuiti variazionali precostruiti sono utili euristiche sia per raggiungere il livello desiderato di entanglement sia per limitare la profonditΓ del circuito. Ma non c'Γ¨ nulla di magico in essi. Sei libero di costruire il tuo circuito variazionale. Questo puΓ² essere vantaggioso nei casi in cui sai qualcosa sull'entanglement dello stato target del tuo sistema.
Per creare il tuo ansatz, basta costruire un circuito quantistico in cui un sottoinsieme di gate sia funzione degli elementi di un vettore di parametri ("theta" nell'esempio a tre qubit qui sotto).
from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
n = 3
theta = ParameterVector("ΞΈ", length=n)
qc = QuantumCircuit(n)
qc.h(0)
qc.h(2)
for i in range(n - 1):
qc.cx(i, i + 1)
qc.cz(0, n - 1)
qc.barrier()
for i in range(n):
qc.ry(theta[i], i)
qc.barrier()
qc.cz(0, n - 1)
for i in reversed(range(n - 1)):
qc.cx(i, i + 1)
qc.h(0)
qc.h(1)
own_ansatz = qc
print(own_ansatz.depth())
qc.draw("mpl")
9
In generale, la scelta del miglior ansatz Γ¨ un'arte; il miglior ansatz Γ¨ quello che ti aiuta a raggiungere il target nel minor numero di passi di ottimizzazione. Γ piΓΉ facile identificare ansatz che probabilmente saranno cattivi. Ad esempio, una maggiore profonditΓ del circuito tende ad accumular errori. La mitigazione degli errori puΓ² aiutare, ma Γ¨ buona pratica mantenere la profonditΓ del circuito il piΓΉ bassa possibile. Non saltare perΓ² l'entanglement necessario. Potresti avere uno stato target che richiede uno schema di entanglement completo. Di seguito sono mostrati due esempi che sono probabilmente scelte sbagliate per ragioni abbastanza evidenti. La scelta di un buon ansatz verrΓ ripresa nelle sezioni successive nel contesto dei test di convergenza.
Il primo circuito Γ¨ probabilmente una scelta sbagliata perchΓ© l'ultimo qubit non Γ¨ affatto in entanglement con gli altri. Non vi Γ¨, infatti, alcuna azione computazionalmente significativa sull'ultimo qubit. Con ogni probabilitΓ , l'ultimo qubit dovrebbe essere o portato in entanglement con gli altri oppure rimosso dal calcolo.
n = 4
theta = ParameterVector("ΞΈ", length=n)
qc = QuantumCircuit(n)
qc.h(0)
qc.h(2)
for i in range(n - 2):
qc.cx(i, i + 1)
qc.cz(0, n - 2)
qc.barrier()
for i in range(n):
qc.ry(theta[i], i)
qc.barrier()
qc.cz(0, n - 2)
for i in reversed(range(n - 2)):
qc.cx(i, i + 1)
qc.h(0)
qc.h(1)
own_ansatz2 = qc
print(own_ansatz2.depth())
qc.draw("mpl")
9
Quest'ultimo circuito Γ¨ probabilmente una scelta sbagliata perchΓ© la profonditΓ del gate Γ¨ molto elevata, e ripetere lo strato di entanglement quattro volte non darΓ probabilmente un risultato sostanzialmente migliore dello stato target rispetto a due o tre ripetizioni.
su2_ansatz_long = efficient_su2(
4, su2_gates=["rx", "y", "z"], entanglement="linear", reps=4
)
print(su2_ansatz_long.decompose().depth())
su2_ansatz_long.decompose().draw(output="mpl")
24
Questi circuiti non sono "completi" nel senso che ci sono ancora parametri sconosciuti e variabili da inserire in molti dei gate. Tali parametri vengono scelti effettuando tentativi successivi e aggiornando i parametri per abbassare il valore atteso della funzione di costo (nel contesto della chimica, tipicamente l'energia dello stato fondamentale). In una o anche in poche dimensioni, questo Γ¨ banale. Ma il circuito sopra ha 20 parametri variazionali, il che significa che trovare lo stato target con l'energia minima implica la ricerca in uno spazio a 20 dimensioni (un altro motivo per non includere gate non necessari nel circuito). Γ qui che entrano in gioco gli algoritmi di ottimizzazione classici, e questo Γ¨ l'argomento della prossima lezione.