QAOA (Quantum Approximate Optimization Algorithm) ist ein Algorithmus, der das Ging-Modell unter Verwendung eines Quantencomputers vom Typ Quantum Gate optimiert. Darüber hinaus ist VQE (Variational Quantum Eigensolver) ein Algorithmus, der die Eigenwerte einer Matrix unter Verwendung eines Quantencomputers vom Typ Quantum Gate findet und häufig für quantenchemische Berechnungen verwendet wird.
In den letzten Jahren wurde die Entwicklung von QAOA und VQE aktiv vorangetrieben, da selbst ein Quantencomputer ohne Fehlerkorrektur recht gut funktioniert.
Auf der Ebene der Quantencomputerbibliotheken wird QAOA häufig als eine Art VQE behandelt, und Blueqat behandelt QAOA auch als eine Art VQE.
Gegeben eine Matrix $ \ hat H $ namens Hamiltonian. Für diese Matrix ist $ \ boldsymbol {X ein Vektor der Norm 1 mit dem kleinsten $ \ boldsymbol {X} \ cdot \ hat H \ boldsymbol {X} $ (wobei $ \ cdot $ das innere Produkt ist). VQE / QAOA kann das Problem lösen, wie hoch der Wert von $ \ boldsymbol {X} \ cdot \ hat H \ boldsymbol {X} $ bei der Suche nach} $ ist. Abhängig von der Form des Hamilton-Operators und dem Zweck der Lösung des Problems wird es als QAOA oder VQE bezeichnet.
Außerdem wird $ \ boldsymbol {X} \ cdot \ hat H \ boldsymbol {X} $ auch als "Energie" bezeichnet. Dies liegt daran, dass dies in der Quantenmechanik tatsächlich der Energiegleichung entspricht.
Wenn dies effizient gelöst werden kann
Es gibt Anwendungen wie.
Quantencomputer sind gut darin, riesige Matrizen zu erzeugen, sie mit Vektoren zu multiplizieren, die als Quantenbits bezeichnet werden, und Bitfolgen gemäß der resultierenden Wahrscheinlichkeitsverteilung abzutasten.
Ein Quantencomputer ist ungefähr eine Vorrichtung, die eine "Quantenschaltung" betreibt, die durch Kombinieren von Quantengattern hergestellt wird. Wenn Sie eine Quantenschaltung passieren, wird die Bitfolge abgetastet.
Da $ \ boldsymbol {X} \ cdot \ hat H \ boldsymbol {X} $ aus dem Abtastergebnis der Bitfolge erhalten werden kann, übergeben Sie die Quantenschaltung an den Quantencomputer, während Sie die Quantenschaltung nach und nach ändern, und dann $ \ Finden Sie eine Quantenschaltung, die das Boldsymbol {X} \ cdot \ hat H \ Boldsymbol {X} $ minimiert.
Wenn du es willst
Kann erhalten werden.
Einige Quantengatter entsprechen der Operation "Quantenbit drehen". Indem der Drehwinkel als Parameter verwendet wird, ist es möglich, eine Quantenschaltung gemäß dem Parameter zu erzeugen.
Da der Winkel nur ein Gleitkommawert ist, Parameter (Gleitkomma-Typ) → Quantenschaltung → Abtastergebnis der Bitfolge → Energie (Gleitkomma-Typ) Sie können sich das als "Funktion vorstellen, die einen Gleitkommatyp zurückgibt, wenn Sie ihm einen Gleitkommatyp geben".
Wenn Sie diese Funktion minimieren, erhalten Sie das gewünschte Ergebnis. Oft wird für diese Optimierungen "scipy.optimize.minimize" verwendet. In einigen Fällen kann die Bayes'sche Optimierung usw. verwendet werden.
In der tatsächlichen Maschine des Quantencomputers wurde die Bitfolge durch Abtasten erhalten (indem viele Male dieselbe Quantenschaltung berechnet und das Ergebnis viele Male genommen wurde). Dies liegt daran, dass der interne Zustand des Quantencomputers (manchmal als Zustandsvektor, Wellenfunktion usw. bezeichnet) nicht so extrahiert werden kann, wie er ist.
Andererseits kann im Fall des Simulators, da der interne Zustand als Array gespeichert ist, er so extrahiert werden, wie er ist, und die Wahrscheinlichkeitsverteilung der Bitfolge kann effizienter erhalten werden als die mehrfache Berechnung derselben Quantenschaltung.
Beim Lesen von VQE- und QAOA-Papieren ist es sehr wichtig zu berücksichtigen, ob es sich um einen Simulator oder eine tatsächliche Maschine handelt, da dies nicht nur die Berechnungsgeschwindigkeit, sondern auch die Berechnungsgenauigkeit beeinflusst.
Mit anderen Worten, das ist es.
In QAOA wird der Hamilton-Operator nur unter Verwendung der sogenannten Z-ZZ-Wechselwirkung beschrieben, ähnlich dem durch Quantenglühen gelösten Ising-Modell.
Betrachten Sie q (0) ―― 2 * q (1) ―― 3 * q (0) * q (1)
als einfaches QUBO. Sei "q (0)" und "q (1)" die Quantenbits, und wenn einer der Werte 0 und 1 genommen wird, wird diese Kombination verwendet, um diese Gleichung zu minimieren.
Wenn es 2 Variablen sind, können Sie es von Hand schlagen,
q(0) |
q(1) |
q(0) - 2 * q(1) - 3 * q(0) * q(1) |
---|---|---|
0 | 0 | 0 - 20 - 30*0 = 0 |
1 | 0 | 1 - 20 - 31*0 = 1 |
0 | 1 | 0 - 21 - 30*1 = -2 |
1 | 1 | 1 - 21 - 31*1 = -4 |
Daher wird der Minimalwert bei (1, 1) angenommen. Um danach zu fragen
from blueqat.pauli import qubo_bit as q
from blueqat.vqe import Vqe, QaoaAnsatz
h = q(0) - 2 * q(1) - 3 * q(0) * q(1)
ansatz = QaoaAnsatz(h, 4) #Das zweite Argument ist, um wie viel die Parameter und Schaltungen erhöht werden sollen. Je mehr Sie haben, desto höher ist die Wahrscheinlichkeit des Lösens, aber das Lösen braucht Zeit
runner = Vqe(ansatz)
result = runner.run()
print(result.most_common())
Und das Ergebnis ist
(((1, 1), 0.944590105656669),)
Und (1, 1) wurde mit einer Wahrscheinlichkeit von 94% oder mehr erhalten.
qubo_bit
Lassen Sie die Dokumentzeichenfolge weg. qubo_bit ist einfach so.
def qubo_bit(n):
return 0.5 - 0.5*Z[n]
Dies ist eine Umschreibung dessen, was in den Bits von QUBO ($ q_i \ in \ {0, 1 \}
Z
ist in blueqat.pauli
als chaotisch definiert, aber wenn es für VQE oder QAOA verwendet wird,
Wird verwendet. Ebenfalls,
Es ist eine Beziehung geworden.
Die Zeitentwicklung ist eine sehr wichtige Berechnung in VQE und QAOA. Eigentlich würde ich mich freuen, wenn ich die zeitliche Entwicklung von Hamiltonian $ \ hat H $ schreiben könnte, also würde ich gerne den Typ "Ausdruck" im Laufe der Zeit entwickeln, aber es ist im Allgemeinen schwierig, ihn mit einer Kombination von Toren zu schreiben, und normalerweise handelt es sich um eine ungefähre Berechnung durch Suzuki Trotter-Erweiterung usw. Getan werden. Andererseits kann der "Term" -Typ, der nur aus Multiplikation besteht, durch Kombinieren von Gates leicht zeitlich entwickelt werden.
QaoaAnsatz.__init__
Ansatz ist ein deutsches Wort, das auf Japanisch als "vorübergehend" übersetzt zu werden scheint, aber es ist ein Kandidat für $ \ boldsymbol {X} $ in $ \ boldsymbol {X} \ cdot \ hat H \ boldsymbol {X} $. In VQE ist es durchaus möglich, auf diese Weise eine Quantenschaltung aufzurufen, die für $ \ boldsymbol {X} $ in Frage kommt. Wie wir später sehen werden, ist die wichtigste Methode in "QaoaAnsatz" "get_circuit ()", die für die Erstellung einer Quantenschaltung aus Parametern verantwortlich ist.
class QaoaAnsatz(AnsatzBase):
def __init__(self, hamiltonian, step=1, init_circuit=None):
super().__init__(hamiltonian, step * 2)
self.hamiltonian = hamiltonian.to_expr().simplify()
if not self.check_hamiltonian():
raise ValueError("Hamiltonian terms are not commutable")
self.step = step
self.n_qubits = self.hamiltonian.max_n() + 1
if init_circuit:
self.init_circuit = init_circuit
if init_circuit.n_qubits > self.n_qubits:
self.n_qubits = init_circuit.n_qubits
else:
self.init_circuit = Circuit(self.n_qubits).h[:]
self.init_circuit.make_cache()
self.time_evolutions = [term.get_time_evolution() for term in self.hamiltonian]
#Von der Elternklasse__init__Hier klicken
class AnsatzBase:
def __init__(self, hamiltonian, n_params):
self.hamiltonian = hamiltonian
self.n_params = n_params
self.n_qubits = self.hamiltonian.max_n() + 1
Was an die übergeordnete Klasse __init__
übergeben werden soll, ist hamiltonian
($ \ hat H $), die Anzahl der Parameter und die Anzahl der Quantenbits.
Die Anzahl der Parameter wird doppelt so hoch wie die Anzahl der Schritte übergeben.
Außerdem muss "hamiltonian" den Typ mit "hamiltonian.to_expr ()" abgleichen. Simplify () "und" simplify () "werden verwendet, um zusätzliche Begriffe zu entfernen oder zu kombinieren.
check_hamiltonian
prüft, ob es sich um einen geeigneten Hamiltonian für QAOA handelt.
Als Anfangsschaltung werden, sofern nicht anders angegeben, alle mit "H" multiplizierten Quantenbits übergeben. Dies entspricht dem Beginn des Temperns ab dem Zustand, in dem zuerst ein laterales Magnetfeld angelegt wird, wie es beim Quantenglühen genannt wird.
Wenn Sie make_cache ()
aufrufen, führen einige Simulatoren bis zu diesem Zeitpunkt Quantenberechnungen durch und speichern die Ergebnisse.
Von nun an werde ich die anfängliche Schaltung mit einem mehrmals hinzugefügten Gate verschieben, so dass auf diese Weise unnötige Berechnungen reduziert werden können.
self.time_evolutions = [term.get_time_evolution () für term in self.hamiltonian]
extrahiert den term
type term
aus dem Expr
type hamiltonian
, um eine Funktion für die Zeitentwicklung zu erhalten. Ich werde.
Vqe.__init__
class Vqe:
def __init__(self, ansatz, minimizer=None, sampler=None):
self.ansatz = ansatz
self.minimizer = minimizer or get_scipy_minimizer(
method="Powell",
options={"ftol": 5.0e-2, "xtol": 5.0e-2, "maxiter": 1000}
)
self.sampler = sampler or non_sampling_sampler
self._result = None
Es werden drei Objekte benötigt: "Ansatz", "Minimierer" und "Sampler".
Wenn Sie "Minimizer" und "Sampler" weglassen, werden die Standardwerte verwendet.
minimizer
ist eine Funktion zur Minimierung und standardmäßig eine Umhüllung von scipy.optimize.minimize
.
Sampler
ist eine Funktion zum Ausführen der eigentlichen Maschine oder des Simulators und zum Abrufen des Sampling-Ergebnisses. Der Simulator wird standardmäßig verwendet.
Wenn Sie diese in die vorherige Abbildung einfügen, ist dies wie folgt. Ich habe es weggelassen, weil die Figur kompliziert wird, aber ansatz berechnet auch die Energie aus dem Stichprobenergebnis. (Da wir Hamiltonian für die Energieberechnung benötigen, lassen wir das Objekt, das Hamiltonian hat, dies tun.)
Vqe.run()
def run(self, verbose=False):
objective = self.ansatz.get_objective(self.sampler)
if verbose:
def verbose_objective(objective):
def f(params):
val = objective(params)
print("params:", params, "val:", val)
return val
return f
objective = verbose_objective(objective)
params = self.minimizer(objective, self.ansatz.n_params)
c = self.ansatz.get_circuit(params)
return VqeResult(self, params, c)
if verbose:
Das Folgende ist nur ein Chaos für diejenigen, die die Parameter und Energieänderungen sehen wollen, so dass Sie sich nicht zu viele Sorgen machen müssen, wenn Sie es ignorieren
get_objective (Sampler)
Es ist ein einfacher Prozess.
get_objective
def get_objective(self, sampler):
"""Get an objective function to be optimized."""
def objective(params):
circuit = self.get_circuit(params)
circuit.make_cache()
return self.get_energy(circuit, sampler)
return objective
Die Zielfunktion ist genau so wie in der Abbildung
params
und erstellen Sie eine QuantenschaltungEs ist ein Fluss geworden.
Für die auf diese Weise erhaltene Zielfunktion werden die Parameter durch "Minimierer" optimiert, so dass sich herausstellt, dass es wirklich wie in der Abbildung gezeigt funktioniert.
VQE und QAOA sind keine komplizierten Algorithmen, solange Sie den Ablauf verstehen können. Dieses Mal habe ich versucht, in die Abbildung zu schreiben, während ich die Quelle gelesen habe, wie es tatsächlich funktioniert.
Ich habe das Modul so gestaltet, dass die Autorität so weit wie möglich an die Kinderklasse delegiert wird, damit sie so locker wie möglich gekoppelt ist. Der Schlüssel zu VQE ist jedoch "wie man die Parameter optimiert". Insbesondere bei chemischen Berechnungen können Sie die aus der Molekülstruktur erhaltenen Parameter als Anfangswerte verwenden und mit allem, was Sie verwenden können, optimieren. Ich will das tun.
Dies ist eine sehr inkompatible Idee mit der aktuellen Struktur von VQE-Modulen.
Derzeit erhält der Minimierer keine Informationen darüber, welche Funktion optimiert werden soll, außer der Funktion selbst und der Anzahl der Parameter. Der Inhalt der Funktion ist als Black Box optimiert.
Wie kann ich das Modul zur besseren Optimierung wieder zusammenbauen? (Im Moment denke ich daran, das Vqe-Objekt zu erben und es als Methode zu verwenden, anstatt den Minimierer von außen zu übergeben.)
Es gibt auch ein Problem mit der Interaktion mit "Sampler". Im aktuellen "Sampler" wurde angenommen, dass jeder Schaltkreis einzeln ausgeführt wird. Mit IBM Q können jedoch mehrere Schaltkreise gepackt und auf einen Quantencomputer in der Cloud übertragen werden. In IBM Q ist es normal, dass die Wartezeit länger als die Berechnungszeit ist, und das Packen und Ausführen mehrerer Schaltkreise kann viel Zeit sparen. Wie können wir es also schaffen, dass mehrere Schaltkreise zusammen gepackt werden können? (Ich bekomme nur eine Liste der Schaltkreise, führe sie alle zusammen aus und gebe eine Liste der Ergebnisse usw. zurück.)
Blueqat hat viele Sorgen um die Softwareentwicklung und nicht um die beschissene Quantenberechnung. Da es sich um Open Source-Software handelt, suche ich jemanden, der bei der Entwicklung hilft. Wenn Sie von Ihren Fähigkeiten überzeugt sind, lassen Sie es uns bitte wissen.
Recommended Posts