Skip to main content
IBM Quantum Platform

Variational Quantum Eigensolver (VQE)

Für dieses Modul müssen die Teilnehmer über eine funktionierende Python Umgebung verfügen und die neuesten Versionen der folgenden Pakete installiert haben:

  • qiskit
  • qiskit_ibm_runtime
  • qiskit-aer
  • qiskit.visualization
  • numpy
  • pylatexenc

Um diese Pakete einzurichten und zu installieren, lesen Sie die Anleitung Qiskit installieren. Um Jobs auf echten Quantencomputern ausführen zu können, müssen die Schüler ein IBM Cloud -Konto einrichten. Folgen Sie dazu den Schritten in der Anleitung zum Einrichten Ihres IBM Cloud -Kontos.

Dieses Modul wurde getestet und verbraucht etwa 8 Minuten QPU-Zeit. Dies ist eine Schätzung, und Ihr tatsächlicher Verbrauch kann davon abweichen.

# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'

Einführung

Seit der Entwicklung des quantenmechanischen Modells zu Beginn des 20. Jahrhunderts wissen die Wissenschaftler, dass die Elektronen nicht auf festen Bahnen um den Atomkern kreisen, sondern in Wahrscheinlichkeitsbereichen, den sogenannten Orbitalen, existieren. Diese Orbitale entsprechen bestimmten, diskreten Energieniveaus, die Elektronen einnehmen können. Elektronen befinden sich natürlicherweise in den niedrigsten verfügbaren Energieniveaus, dem so genannten Grundzustand. Wenn ein Elektron jedoch genügend Energie absorbiert, kann es auf ein höheres Energieniveau springen und in einen angeregten Zustand übergehen. Dieser angeregte Zustand ist vorübergehend, und das Elektron kehrt schließlich auf ein niedrigeres Energieniveau zurück und gibt die absorbierte Energie frei, oft in Form von Licht. Dieser grundlegende Prozess der Energieabsorption und -emission ist wichtig, um zu verstehen, wie Atome interagieren und Bindungen eingehen.

Wenn sich Atome zu Molekülen zusammenschließen, verbinden sich ihre Atomorbitale zu Molekülorbitalen. Die Anordnung und die Energieniveaus der Elektronen in diesen Molekülorbitalen bestimmen die Eigenschaften des entstehenden Moleküls und die Stärke der chemischen Bindungen. Bei der Bildung eines Wasserstoffmoleküls ( H2H_2 ) aus zwei einzelnen Wasserstoffatomen zum Beispiel besetzt das Elektron jedes Atoms ein Atomorbital. Wenn sich die Atome einander nähern, überschneiden sich diese Atomorbitale und verbinden sich zu neuen Molekülorbitalen - einem mit niedrigerer Energie (einem Bindungsorbital) und einem mit höherer Energie (einem Anti-Bindungsorbital). Die beiden Elektronen, jeweils eines von jedem Wasserstoffatom, besetzen bevorzugt das Bindungsorbital mit niedrigerer Energie, was zur Bildung einer stabilen kovalenten Bindung führt, die das H2H_2 Molekül zusammenhält. Der Energieunterschied zwischen den getrennten Atomen und dem gebildeten Molekül, insbesondere die Energie der Elektronen in den Molekülorbitalen, bestimmt die Stabilität und die Eigenschaften der Bindung.

In den folgenden Abschnitten werden wir diesen Prozess der Molekülbildung untersuchen und uns dabei auf das Molekül H2H_2 konzentrieren. Wir werden einen echten Quantencomputer in Kombination mit klassischen Optimierungstechniken verwenden, um die Energie dieses einfachen, aber grundlegenden Prozesses zu ermitteln. Mit diesem Experiment wird praktisch demonstriert, wie die Quantenberechnung zur Lösung von Problemen in der Computerchemie eingesetzt werden kann, und es werden Erkenntnisse über die Rolle der Elektronenenergie gewonnen.


VQE – Ein variationaler Quantenalgorithmus für Eigenwertprobleme

Approximationstechniken für die Chemie – Variationsprinzip und Basissatz

Erwin Schrödingers Beiträge zur Quantenmechanik beschränken sich nicht auf die Einführung eines neuen elektronischen Modells; im Grunde hat er die Wellenmechanik durch die Entwicklung der berühmten zeitabhängigen Schrödingergleichung begründet:

iℏddt∣ψ⟩=H^∣ψ⟩i\hbar \frac{d}{dt}|\psi\rangle = \hat{H}|\psi\rangle

Dabei ist H^\hat{H} der Hamilton-Operator, der die Gesamtenergie des Systems darstellt, und ∣ψ⟩|\psi\rangle ist die Wellenfunktion, die alle Informationen über den Quantenzustand des Systems enthält. (Hinweis: ddt\frac{d}{dt} ist die gesamte Zeitableitung, und wir beziehen den Energieeigenwert EE hier nicht explizit mit ein)

In vielen praktischen Anwendungen - z. B. bei der Bestimmung der zulässigen Energieniveaus von Atomen und Molekülen - verwenden wir jedoch stattdessen die zeitunabhängige Schrödingergleichung (Energieeigenwertgleichung), die von der zeitabhängigen Form abgeleitet wird, indem ein stationärer Zustand angenommen wird. Ein stationärer Zustand ist ein Quantenzustand, in dem sich die Wahrscheinlichkeitsdichte, ein Teilchen an einem bestimmten Punkt im Raum zu finden, im Laufe der Zeit nicht ändert.

H^∣ψ⟩=E∣ψ⟩\hat{H}|\psi\rangle = E|\psi\rangle

In dieser Form stellt EE den Energieeigenwert dar, der dem Quantenzustand ∣ψ⟩|\psi\rangle entspricht. Der Hamiltonian enthält verschiedene Energiebeiträge, wie die kinetische Energie von Elektronen und Kernen, die Anziehungskräfte zwischen Elektronen und Kernen und die Abstoßungskräfte zwischen Elektronen.

Die Lösung der Energieeigenwertgleichung ermöglicht es uns, die quantisierten Energieniveaus von atomaren und molekularen Systemen zu berechnen. Bei Molekülen ist es jedoch schwierig, sie genau zu lösen, da die Wellenfunktion Ψ\Psi, die die räumliche Verteilung der Elektronen beschreibt, komplex und hochdimensional ist.

Daher verwenden die Wissenschaftler Näherungstechniken, um praktische und genaue Lösungen zu erhalten. In dieser Arbeit werden wir uns auf zwei Schlüsselmethoden konzentrieren:

  1. Variationsprinzip

    Mit dieser Methode wird die Wellenfunktion angenähert und so angepasst, dass sie der Zielenergie, in der Regel der Grundzustandsenergie des Systems, so nahe wie möglich kommt. Der Grundgedanke des Variationsprinzips ist einfach:

    • Wenn wir eine Wellenfunktion Ψtrial\Psi_\text{trial} (eine "Versuchsfunktion") erraten, wird die daraus berechnete Energie immer gleich oder höher sein als die Grundzustandsenergie ( E0E_0 ) des Systems. Eapprox=⟨Ψtrial∣H^∣Ψtrial⟩⟨Ψtrial∣Ψtrial⟩≥E0E_\text{approx} = \frac{\langle \Psi_\text{trial}|\hat{H}|\Psi_\text{trial}\rangle}{\langle \Psi_\text{trial}|\Psi_\text{trial}\rangle} \geq E_0
    • Durch Anpassung der Parameter θ\theta in der Versuchsfunktion ∣Ψtrial(θ)⟩|\Psi_\text{trial}(\theta)\rangle können wir eine immer bessere Annäherung an die Energie des Grundzustands erreichen.
    • Ihre Genauigkeit hängt stark von der Wahl der Versuchswellenfunktion Ψtrial\Psi_\text{trial} ab. Eine schlecht gewählte Versuchsfunktion kann zu einer Energieschätzung führen, die alles andere als genau ist.
  2. Annäherung an die Basismenge

    Die zweite Annäherungsmethode kommt in der Phase der Konstruktion der Wellenfunktion zum Einsatz - der Basismengenansatz. In der Quantenchemie ist es fast unmöglich, die Schrödinger-Gleichung für Moleküle exakt zu lösen. Stattdessen nähern wir uns der komplexen Multi-Elektronen-Wellenfunktion an, indem wir sie aus einfacheren, vordefinierten mathematischen Funktionen aufbauen. Ein Basissatz ist im Wesentlichen eine Sammlung dieser bekannten mathematischen Funktionen, in der Regel zentriert auf die Atome im Molekül, die als Bausteine zur Darstellung der Form und des Verhaltens der Elektronen im System verwendet werden. Stellen Sie sich vor, Sie versuchen, eine detaillierte Skulptur nur mit einer Sammlung von Standard-LEGO-Steinen nachzubauen - je mehr Arten und Größen von Steinen Sie haben (je größer das Basisset), desto genauer können Sie die ursprüngliche Form nachbilden.

    Diese Basisfunktionen orientieren sich häufig an den analytischen Lösungen für einfache Systeme wie das Wasserstoffatom und nehmen Formen wie Gauß- oder Slater-Funktionen an, obwohl es sich dabei immer noch um Näherungen handelt. Anstatt mit den theoretisch "exakten", aber schwer zu handhabenden vollständigen Molekülorbitalen zu arbeiten, drücken wir sie als Linearkombination (eine Summe mit Koeffizienten) dieser Basisfunktionen aus. Diese Methode wird als Linearkombination von Atomorbitalen (LCAO) bezeichnet, wenn die Basisfunktionen Atomorbitalen ähneln. Durch Optimierung der Koeffizienten in dieser Linearkombination können wir die bestmögliche Näherungswellenfunktion und Energie innerhalb der Grenzen des gewählten Basissatzes finden.

    • Je mehr Funktionen im Basissatz enthalten sind, desto besser ist die Annäherung, aber dies geht mit einem höheren Rechenaufwand einher.
    • Ein kleiner Basissatz liefert eine grobe Schätzung, während ein großer Basissatz genauere Ergebnisse liefert, die allerdings mehr Rechenressourcen erfordern.

Zusammenfassend lässt sich sagen, dass wir, um die Berechnungen durchführbar zu machen und die Rechenkosten zu senken, das Variationsprinzip anwenden, indem wir die Wellenfunktion annähern, was den Rechenaufwand verringert und eine iterative Optimierung zur Minimierung der Energie ermöglicht. Der Basissatz-Ansatz vereinfacht die Berechnungen, indem er die Atomorbitale als eine Kombination von vordefinierten Funktionen darstellt, anstatt direkt eine kontinuierliche Wellenfunktion zu berechnen.

Überprüfen Sie Ihr Verständnis

Betrachten Sie die Versuchswellenfunktion Ψtrial(α,x)=Ae−αx2\Psi_\text{trial}(\alpha,x) = Ae^{- \alpha x^2}, wobei AA eine Normalisierungskonstante und α\alpha ein einstellbarer Parameter ist.

(a) Normalisieren Sie die Wellenfunktion des Versuchs, indem Sie AA so bestimmen, dass ∫−∞∞∣Ψtrial∣2dx=1\int_{-\infty}^{\infty} |\Psi_\text{trial}|^2 dx = 1 gilt.

  • Um die gegebene Versuchswellenfunktion zu normalisieren:

    ∫−∞∞∣Ψtrial∣2dx=∫−∞∞A2e−2αx2dx=1\int_{-\infty}^{\infty} |\Psi_\text{trial}|^2 dx = \int_{-\infty}^{\infty} A^2 e^{-2 \alpha x^2} dx = 1

    Verwenden Sie das Gaußsche Integral:

    ∫−∞∞e−ax2dx=πa, for a>0 \int_{-\infty}^{\infty} e^{-a x^2} dx = \sqrt{\frac{\pi}{a}} \text{, for } a>0

    a=2αa = 2\alpha einstellen und dann erhalten: A2πa=1A^2\sqrt{\frac{\pi}{a}} = 1 ∴A=(2απ)1/4\therefore A = (\frac{2\alpha}{\pi})^{1/4}

(b) Berechnen Sie den Erwartungswert des Hamilton-Operators H^\hat{H}, der durch folgende Gleichung gegeben ist: H^=−ℏ22md2dx2+V(x) \hat{H} = -\frac{\hbar^2}{2m} \frac{d^2}{dx^2} + V(x), wobei V(x)=12mω2x2V(x) = \frac{1}{2}m\omega^2x^2 gilt, was einem Potential für einen einfachen harmonischen Oszillator entspricht.

  • Der Hamilton-Operator für einen harmonischen Oszillator lautet:

    H^=−ℏ22md2dx2+12mω2x2\hat{H} = -\frac{\hbar^2}{2m} \frac{d^2}{dx^2} + \frac{1}{2} m \omega^2 x^2

    Erwartungswert der kinetischen Energie

    ⟨T⟩=−ℏ22m∫−∞∞Ψtrial∗d2dx2Ψtrialdx \langle T \rangle = -\frac{\hbar^2}{2m} \int_{-\infty}^{\infty} \Psi_\text{trial}^* \frac{d^2}{dx^2} \Psi_\text{trial} dx

    Nehmen Sie die zweite Ableitung:

    ddxΨtrial=−2αxAe−αx2\frac{d}{dx} \Psi_\text{trial} = -2\alpha x A e^{-\alpha x^2}

    d2dx2Ψtrial=Ae−αx2(4α2x2−2α)\frac{d^2}{dx^2} \Psi_\text{trial} = A e^{-\alpha x^2} (4\alpha^2 x^2 - 2\alpha)

    So:

    T=−ℏ22m∫−∞∞A2e−2αx2(4α2x2−2α)dxT = -\frac{\hbar^2}{2m} \int_{-\infty}^{\infty} A^2 e^{-2\alpha x^2} (4\alpha^2 x^2 - 2\alpha) dx

    Verwendung der Standardergebnisse des Gaußschen Integrals:

    ⟨T⟩=ℏ2α2m\langle T \rangle = \frac{\hbar^2 \alpha}{2m}

    Erwartungswert der potenziellen Energie

    ⟨V⟩=12mω2∫−∞∞x2∣Ψtrial∣2dx\langle V \rangle = \frac{1}{2} m \omega^2 \int_{-\infty}^{\infty} x^2 |\Psi_\text{trial}|^2 dx

    Verwenden:

    ∫−∞∞x2e−ax2dx=π2a3/2\int_{-\infty}^{\infty} x^2 e^{-a x^2} dx = \frac{\sqrt{\pi}}{2a^{3/2}}

    erhalten wir:

    ⟨V⟩=mω24α\langle V \rangle = \frac{m \omega^2}{4\alpha}

    Erwartungswert der Gesamtenergie

    ∴Eapprox(α)=ℏ2α2m+mω24α\therefore E_\text{approx}(\alpha) = \frac{\hbar^2 \alpha}{2m} + \frac{m \omega^2}{4\alpha}

(c) Bestimme mithilfe des Variationsprinzips die optimale Funktion α\alpha, indem du Eapprox(α)E_\text{approx}(\alpha) minimierst.

  • Optimieren Sie „ α\alpha “ für minimalen Energieverbrauch

    Unterscheiden

    ddα(ℏ2α2m+mω24α)=0\frac{d}{d\alpha} \left( \frac{\hbar^2 \alpha}{2m} + \frac{m \omega^2}{4\alpha} \right) = 0

    Lösen:

    ℏ22m−mω24α2=0\frac{\hbar^2}{2m} - \frac{m \omega^2}{4\alpha^2} = 0

    αopt=mω2ℏ\alpha_\text{opt} = \frac{m\omega}{2\hbar}

    Ersetzen Sie αopt\alpha_\text{opt} durch EapproxE_\text{approx} :

    ∴Eapprox=ℏω2\therefore E_\text{approx} = \frac{\hbar \omega}{2}

    die genau der Energie des Grundzustands des harmonischen Quantenoszillators entspricht.

VQE (Variational Quantum Eigensolver)

Der Variations-Quanten-Eigensolver (VQE) ist die Hauptmethode, mit der wir den H+H=H2H+H = H_2 Prozess erforschen werden, und hier werden wir einen Blick darauf werfen, was VQE ist und wie es funktioniert. Aber lassen Sie uns zunächst innehalten und eine sehr wichtige Sache durch die Check-in-Frage betrachten.

Überprüfen Sie Ihr Verständnis

Wenn wir bereits so viele Strategien für chemische Probleme haben, warum brauchen wir dann einen Quantencomputer? Und welchen Sinn hat es, Quantencomputer und klassische Computer gemeinsam zu nutzen?

  • Die Quanteninformatik hat die Chance, die Chemie zu revolutionieren, indem sie Probleme löst, mit denen klassische Computer aufgrund der exponentiellen Skalierung von Quantenzuständen zu kämpfen haben. Richard Feynman bemerkte berühmt, dass Berechnungen, die die Natur simulieren sollen, auch Quantenrechnungen sein müssen [ref 1].

    Beispielsweise würde die Simulation von Koffein mit dem einfachsten Basissatz ( STO-3G ) 104810^{48} Bits erfordern, viel mehr als die Gesamtzahl der Sterne im beobachtbaren Universum ( 102410^{24} ) [ref 2]. Ein Quantencomputer kann die elektronischen Orbitale von Koffein mit 160 Qubits beschreiben.

    Quantencomputer verarbeiten auf natürliche Weise Quantenwechselwirkungen unter Verwendung von Überlagerung und Verschränkung, was eine vielversprechende Möglichkeit für genaue Molekularsimulationen darstellt. Darüber hinaus können wir die Vorteile von Quantencomputern (Elektronensimulation) und klassischen Computern (Datenvor- und -nachverarbeitung, Verwaltung von Algorithmusprozessen, Optimierung usw.) kombinieren. Es wird erwartet, dass sie die Materialentdeckung, den Entwurf von Arzneimitteln und die Reaktionsvorhersage verbessern und kostspielige Versuch-und-Irrtum-Experimente reduzieren werden. [ref 3][ref 4]

    Wenn Sie wissen möchten, warum Quantencomputer für chemische Probleme benötigt werden und warum man sowohl Quanten- als auch klassische Rechenressourcen nutzen sollte, lesen Sie die folgenden Artikel:

Kehren wir nun zu VQE zurück.

VQE kombiniert die Leistung von Quantencomputern mit klassischen Computern, wobei im Wesentlichen Variationsprinzipien verwendet werden, um die Grundzustandsenergie des Systems zu ermitteln. Um VQE zu verstehen, muss man es zunächst in drei Teile zerlegen:

VQE-Arbeitsablauf

(Quanten-)Beobachtbare Größe: Der molekulare Hamilton-Operator (Energie eines Moleküls)

In der VQE ist der molekulare/atomare Hamiltonian eine Beobachtungsgröße, das heißt, wir können seinen Wert durch ein Experiment messen. Unser Ziel ist es, die niedrigstmögliche Energie (die Grundzustandsenergie) des Moleküls zu finden. Dazu verwenden wir einen Versuchsquantenzustand, der durch eine parametrisierte Quantenschaltung (Ansatz) erzeugt wird. Wir messen die Beobachtungsgröße und optimieren den Quantenzustand, bis wir die niedrigstmögliche Energie erreichen.

Der für den molekularen Hamiltonian verwendete Basissatz bestimmt die Anzahl der erforderlichen Qubits und wirkt sich direkt auf die Genauigkeit der VQE aus. Die Wahl des richtigen Basissatzes ist entscheidend für das Gleichgewicht zwischen Effizienz und Präzision. Um die Berechnungen zu vereinfachen, ohne den Basissatz zu ändern, können wir Strategien wie die Auferlegung von Symmetrie und die Reduzierung des aktiven Raums anwenden. Viele Moleküle haben eine symmetrische Form (wie ein Schmetterling oder eine Schneeflocke), d. h., einige Teile verhalten sich auf die gleiche Weise. Anstatt alles einzeln zu berechnen, können wir uns nur auf einzelne Teile konzentrieren und so Quantenressourcen einsparen und die Symmetrie nutzen. Bei der Aktivraumreduktion werden nur die wichtigen Orbitale berücksichtigt, da nicht alle Elektronen einen signifikanten Einfluss auf die Molekülenergie haben. Die Elektronen in der Nähe des Kerns bleiben meist unverändert, während andere die Bindung beeinflussen. Durch die Anwendung dieser Methoden können wir die VQE effizienter gestalten und gleichzeitig die Genauigkeit beibehalten.

Sobald wir einen molekularen Hamiltonian mit dem richtigen Basissatz und den oben genannten Strategien erhalten haben, müssen wir diesen Hamiltonian in einen für Quantencomputer geeigneten umwandeln. Die Zuordnung von Problemen zu Pauli-Operatoren kann recht kompliziert sein. Dies gilt insbesondere für die Quantenchemie, die mit ununterscheidbaren Teilchen (Elektronen) arbeitet, da Qubits unterscheidbar sind. Wir werden hier nicht auf die Einzelheiten der Zuordnungen eingehen, sondern verweisen Sie auf die folgenden Ressourcen. Eine allgemeine Diskussion über die Zuordnung eines Problems zu Quantenoperatoren findet sich in Quantum computing in practice. Eine ausführlichere Diskussion über die Abbildung von Chemieproblemen in Quantenoperatoren findet sich in Quantenchemie mit VQE.

Für dieses Modul werden wir Ihnen die entsprechenden (Ein-Qubit-)Hamiltonianer für HH und H2H_2 zur Verfügung stellen, damit wir uns auf die Verwendung des Quantencomputers konzentrieren können. Diese Ein-Qubit-Hamiltonianer werden mit Hilfe des STO-6G basissatzes und der Jordan-Wigner-Abbildung, die die einfachste Abbildung mit der einfachsten physikalischen Interpretation ist, weil sie die Besetzung eines Spin-Orbitals auf die Besetzung eines Qubits abbildet. Außerdem haben wir eine Qubit-Reduktionstechnik verwendet, indem wir eine Symmetrie des Hamilton-Operators ausnutzten, die die Muster im Verhalten von Spin-Besetzungen nutzt, um die Anzahl der Qubits zu reduzieren. Für das Molekül H2H_2 nehmen wir an, dass der Abstand zwischen den beiden Wasserstoffatomen 0.735 A˚\mathring A ist.

(Quanten-)Ansatz: Die Testwellenfunktion (Wie man mit einem Quantenschaltkreis einen trivialen Quantenzustand aufbaut)

Bei VQE besteht der Ansatz (Plural: Ansätze) aus zwei Hauptkomponenten. Die erste ist die Vorbereitung des Anfangszustands, bei der der Zustand des Qubits durch die Anwendung von Quantengattern ohne Variationsparameter hergestellt wird. Die zweite Komponente ist der parametrisierte Quantenschaltkreis, ein spezieller Quantenschaltkreis mit einstellbaren Parametern, ähnlich den Reglern eines Radios. Diese Parameter werden für den letzten Teil - den klassischen Optimierer - verwendet, um den bestmöglichen Grundzustand zu erreichen.

Im Abschnitt über das Variationsprinzip haben wir gelernt, dass die Qualität des Versuchszustands die Qualität der Ergebnisse des Variationsalgorithmus beeinflusst. Dies bedeutet, dass die Wahl eines guten Ansatzes bei VQE wichtig ist. Auch hier handelt es sich um ein umfangreiches und komplexes Thema. Wir werden hier nicht auf die verschiedenen Arten von Ansätzen oder ihre Ursprünge eingehen. Wenn Sie daran interessiert sind, mehr über parametrisierte Quantenschaltungen und Ansätze zu erfahren, können Sie die Lektion Ansätze und Variationsformen aus dem Kurs Entwurf von Variationsalgorithmen erkunden, die detaillierte Erklärungen und Beispiele zu Ansätzen enthält.

Da wir in diesem Modul einen Ein-Qubit-Hamiltonian verwenden werden, benötigen wir einen parametrisierten Ein-Qubit-Quantenkreis als Ansatz. Wir werden im folgenden Abschnitt drei Arten von Ein-Qubit-Ansätzen sehen. Wir werden sie vergleichen und die wichtigsten Überlegungen bei der Auswahl eines Ansatzes diskutieren.

(Klassischer) Optimierer: Feinabstimmung des Quantenschaltkreises

Sobald der Quantencomputer die Energie der Beobachtungsgröße aus dem Ansatz misst, werden die Parameter des Ansatzes und der Energiewert zur Abstimmung an den klassischen Optimierer geschickt. Dieser Optimierungsprozess wird auf einem klassischen Computer durchgeführt, typischerweise mit wissenschaftlichen Allzweckpaketen wie SciPy.

Der klassische Optimierer behandelt die gemessene Energie als eine Kostenfunktion. Bei Optimierungsproblemen ist eine Kostenfunktion (manchmal auch Zielfunktion genannt) eine mathematische Funktion, die misst, wie "gut" eine bestimmte Lösung ist. Das Ziel des Optimierers ist es, den Satz von Parametern zu finden, der diese Kostenfunktion minimiert. Im Zusammenhang mit der Suche nach der Grundzustandsenergie eines Moleküls dient die Energie selbst als Kostenfunktion - wir wollen die Parameter für unseren Quantenkreislauf (unsere "Lösung") finden, die die geringstmögliche Energie ergeben. Der klassische Optimierer verwendet diesen gemessenen Energiewert (die Kosten) und bestimmt den nächsten Satz von optimierten Parametern für den Quantenansatz. Diese aktualisierten Parameter werden dann an den Quantenschaltkreis zurückgesendet, und der Vorgang wird wiederholt. Bei jeder Iteration passt der klassische Optimierer die Parameter an, um zu versuchen, die Energie zu reduzieren (die Kostenfunktion zu minimieren), bis ein vordefiniertes Konvergenzkriterium erfüllt ist, das im Idealfall sicherstellt, dass die niedrigstmögliche Energie (die dem Grundzustand des Moleküls für diesen Bindungsabstand und Basissatz entspricht) gefunden wird.

Es gibt viele Optimierungsstrategien, die von wissenschaftlichen Paketen wie SciPy bereitgestellt werden. Weitere Informationen finden Sie in der Lektion Optimierungsschleifen des Kurses Entwurf von Variationsalgorithmen. Hier werden wir COBYLA (Constrained Optimization BY Linear Approximations) verwenden, einen Optimierungsalgorithmus, der für komplizierte Energielandschaften geeignet ist. Insbesondere versucht COBYLA nicht, einen Gradienten der untersuchten Funktion zu berechnen; dies wird als gradientenfreier Optimierer bezeichnet. Stellen Sie sich vor, Sie versuchen, mit geschlossenen Augen den höchsten Gipfel eines Gebirges zu finden. Da man nicht die ganze Landschaft überblicken kann, macht man kleine Schritte in verschiedene Richtungen und prüft dabei, ob man auf- oder absteigt. COBYLA arbeitet auf ähnliche Weise - es bewegt sich durch den Parameterraum, testet verschiedene Werte und verbessert allmählich das Ergebnis, bis es den besten Wert gefunden hat.

Jetzt können Sie eine VQE-Berechnung durchführen. Probieren Sie zu diesem Zweck die folgende Check-in-Frage aus, die den gesamten Prozess zusammenfasst.

Überprüfen Sie Ihr Verständnis

Füllen Sie die Lücken mit den richtigen Begriffen aus, um die Zusammenfassung des VQE-Prozesses zu vervollständigen, und klicken Sie anschließend, um Ihre Antworten zu überprüfen.

VQE ist ein Quantenvariationsalgorithmus, der die Möglichkeiten von (1) _________ und klassischem Rechnen kombiniert, um die (2) _____________ eines Moleküls zu finden. Der Prozess beginnt mit der Definition der (3) ____________, die die Gesamtenergie des Systems darstellt und bei Quantenmessungen als Observable dient. Als Nächstes bereiten wir einen (4) ____________ vor, eine Quantenschaltung mit einstellbaren Parametern, die die Versuchswellenfunktion des Moleküls darstellt. Diese Parameter werden mit einem (5) ____________, einem klassischen Algorithmus, der die Parameter iterativ anpasst, um die gemessene Energie zu minimieren, optimiert. In der obigen Diskussion haben wir den (6) ___________ Optimierer verwendet, der die Ansatzparameter verfeinert, ohne dass Ableitungsrechnungen erforderlich sind. Der Prozess wird fortgesetzt, bis wir (7) ____________ erreichen, was bedeutet, dass wir die niedrigste mögliche Energie des Moleküls gefunden haben.

Wortbank:

  • klassischer Optimierer
  • grundzustandsenergie
  • hardware-effizient
  • ansatz
  • molekularer Hamiltonian
  • COBYLA
  • Quantencomputing
  • Konvergenz
  • 1 → Quantencomputer

    2 → Grundzustandsenergie

    3 → molekularer Hamiltonian

    4 → Ansatz

    5 → klassischer Optimierer

    6 → COBYLA

    7 → Konvergenz


Berechnen Sie die Grundzustandsenergie eines Wasserstoffatoms mit VQE

Nun wollen wir das Gelernte nutzen, um die Energie des Grundzustands eines Wasserstoffatoms zu berechnen. Während des gesamten Moduls werden wir einen Rahmen für das Quantencomputing verwenden, der als "Qiskit-Muster" bekannt ist und Arbeitsabläufe in die folgenden Schritte unterteilt:

  • Schritt 1: Abbildung klassischer Eingaben auf ein Quantenproblem
  • Schritt 2: Optimieren des Problems für die Quantenausführung
  • Schritt 3: Ausführung mithilfe von „ IBM Quantum “-Primitiven
  • Schritt 4: Nachbearbeitung und klassische Analyse
Qiskit-Muster

Im Allgemeinen werden wir diese Schritte befolgen.

Beginnen wir damit, einige erforderliche Pakete zu installieren, darunter die Primitive aus „ IBM Quantum “. Außerdem werden wir den am wenigsten ausgelasteten Quantencomputer auswählen, der uns zur Verfügung steht.

Unten finden Sie einen Code, mit dem Sie Ihre Anmeldedaten bei der ersten Verwendung speichern können. Achten Sie darauf, dass Sie diese Informationen aus dem Notebook löschen, nachdem Sie es in Ihrer Umgebung gespeichert haben, damit Ihre Anmeldedaten nicht versehentlich weitergegeben werden, wenn Sie das Notebook freigeben. Weitere Anleitungen finden Sie unter Einrichten Ihres IBM Cloud Kontos und Initialisieren des Dienstes in einer nicht vertrauenswürdigen Umgebung.

# Load IBM Quantum Compute Service
from qiskit_ibm_runtime import QiskitRuntimeService

# Load the Runtime primitive and session
from qiskit_ibm_runtime import EstimatorV2 as Estimator

# Syntax for first saving your token.  Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform',
# instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')

# Load saved credentials
service = QiskitRuntimeService()

# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_brisbane")
print(backend.name)

Output:

ibm_brisbane

Die Zelle unten ermöglicht es Ihnen, zwischen der Verwendung des Simulators und der realen Hardware während des gesamten Notebooks zu wechseln. Wir empfehlen, ihn jetzt auszuführen:

# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel

# Alternatively, load a fake backend with generic properties and define a simulator.


noise_model = NoiseModel.from_backend(backend)

# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)

Schritt 1: Das Problem auf Quantenschaltungen und Operatoren abbilden

Wir beginnen unsere VQE-Berechnung mit der Definition des Hamilton-Operators für das Wasserstoffmolekül ( H2H_2 ) bei einem bestimmten Bindungsabstand. Dieser Hamilton-Operator stellt die Gesamtenergie des Systems in Form von Qubit-Operatoren dar und wurde anhand eines Standardverfahrens aus dem molekularen System abgeleitet und abgebildet: 1) unter Verwendung des Basis-Satzes von STO-6G (einer spezifischen Sammlung mathematischer Funktionen zur Approximation der Elektronenorbitale), 2) Anwendung der Jordan-Wigner-Abbildung (eine Technik zur Übersetzung von Fermionenoperatoren, die Elektronen beschreiben, in Qubit-Operatoren) und 3) Durchführung einer Qubit-Reduktion unter Verwendung der Parität des Hamilton-Operators zur Vereinfachung des Problems.

Wie wir bereits erläutert haben, hängen die berechneten Grundzustandsenergien stark von der Auswahl des Basissatzes und der Molekülgeometrie (wie dem Bindungsabstand) ab. Für diese spezifische Konfiguration und nach diesen Transformationen ist der resultierende Qubit-Hamiltonian einfach:

H^=−0.2355I+0.2355Z\hat{H} = -0.2355 I + 0.2355 Z

Dabei steht II für den Identitätsoperator und ZZ für den Pauli-Z-Operator, der auf ein einzelnes Qubit wirkt. Die Koeffizienten werden aus den Integralen abgeleitet, die unter Verwendung des STO-6G Basissatzes bei diesem bestimmten Bindungsabstand mit der richtigen Transformation berechnet wurden.

Mit diesem definierten Hamiltonian können wir nun die VQE verwenden, um die Energie im Grundzustand zu berechnen. Es ist sinnvoll, die von uns berechnete Grundzustandsenergie mit den erwarteten Werten zu vergleichen. Für ein einzelnes, isoliertes Wasserstoffatom (H) beträgt die Grundzustandsenergie genau -0.5 Hartree (bei Abwesenheit relativistischer Effekte). Berechnen wir die exakte Grundzustandsenergie unseres spezifischen Qubit-Hamiltonianers, wie er oben definiert wurde, und vergleichen wir sie mit den einschlägigen bekannten Werten.

from qiskit.quantum_info import SparsePauliOp
import numpy as np

# Qubit Hamiltonian of the hydrogen atom generated by using STO-3G basis set and parity mapping
Hamiltonian = SparsePauliOp.from_list([("I", -0.2355), ("Z", 0.2355)])

# exact ground state energy of Hamiltonian

A = np.array(Hamiltonian)
eigenvalues, eigenvectors = np.linalg.eig(A)
print(
    "The exact ground state energy of the Hamiltonian is ",
    min(eigenvalues).real,
    "hartree",
)
h = min(eigenvalues.real)

Output:

The exact ground state energy of the Hamiltonian is  -0.471 hartree

Als Nächstes benötigen wir einen parametrisierten Quantenschaltkreis, einen Ansatz, um eine Versuchswellenfunktion Ψtrial\Psi_\text{trial} für den Grundzustand zu erstellen. Das Ziel ist es, die Parameter θ\theta zu finden, die den Energieerwartungswert ⟨ψ(θ)∣H^∣ψ(θ)⟩\langle\psi(\theta)|\hat{H}|\psi(\theta)\rangle minimieren. Die Wahl des Ansatzes ist von entscheidender Bedeutung, denn sie bestimmt die Menge der möglichen Quantenzustände, die unser Schaltkreis vorbereiten kann. Ein "guter" Ansatz ist ein Ansatz, der flexibel genug ist, um einen Zustand darzustellen, der dem wahren Grundzustand des von uns untersuchten Hamiltonianers sehr nahe kommt, der aber nicht so komplex ist, dass er zu viele Parameter oder zu tiefe Schaltkreise für aktuelle Quantencomputer erfordert.

Hier werden wir drei verschiedene Ein-Qubit-Ansätze ausprobieren, um zu sehen, welcher davon die möglichen Quantenzustände, die ein einzelnes Qubit einnehmen kann, besser "abdeckt". Die "Abdeckung" bezieht sich auf den Bereich der Quantenzustände, die der Ansatzschaltkreis durch Variation seiner Parameter erzeugen kann.

Wir werden drei Ansätze verwenden, die auf verschiedenen Kombinationen von Ein-Qubit-Rotationsgattern basieren:

  • Ein 1-Achsen-Rotationstor-Ansatz: Dieser Ansatz verwendet Rotationen um nur eine einzige Achse ( Rx(θ)R_x(\theta) ). Auf der Bloch-Kugel entspricht dies einer Bewegung nur entlang eines bestimmten Kreises. Diese Option ist am wenigsten flexibel und deckt nur eine begrenzte Anzahl von Staaten ab.
  • Zwei 2-Achsen-Rotationsgatteransätze: Diese Ansätze kombinieren Rotationen um zwei verschiedene Achsen ( Rx(θ1)Rz(θ2)R_x(\theta_1) R_z(\theta_2) und Rx(θ1)Rz(θ2)Rx(θ3)R_x(\theta_1) R_z(\theta_2) R_x(\theta_3) ). Dadurch können wir einen größeren Teil der Bloch-Kugel erreichen als mit einer einachsigen Drehung.

Der Vergleich der mit diesen drei Ansätzen erzielten VQE-Ergebnisse zeigt, wie sich die Flexibilität und die Zustandsraumabdeckung des Ansatzes auf unsere Fähigkeit auswirken, die wahre Grundzustandsenergie unseres vereinfachten Hamiltonians zu finden. Ein flexiblerer Ansatz hat das Potenzial, eine bessere Annäherung zu finden, aber er könnte auch schwieriger für den klassischen Optimierer sein.

from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import Statevector, DensityMatrix, Pauli

theta = Parameter("θ")
phi = Parameter("φ")
lam = Parameter("λ")

ansatz1 = QuantumCircuit(1)
ansatz1.rx(theta, 0)

ansatz2 = QuantumCircuit(1)
ansatz2.rx(theta, 0)
ansatz2.rz(phi, 0)

ansatz3 = QuantumCircuit(1)
ansatz3.rx(theta, 0)
ansatz3.rz(phi, 0)
ansatz3.rx(lam, 0)

Output:

<qiskit.circuit.instructionset.InstructionSet at 0x1059def80>

Erzeugen wir nun 5000 Zufallszahlen für jeden Parameter und zeichnen wir die Verteilung der zufälligen Quantenzustände auf, die von den drei Ansätzen mit diesen Zufallsparametern erzeugt werden. Sie können sich diese Parameter wie Drehungen um verschiedene Achsen auf einer Kugeloberfläche vorstellen. Um die Verteilung des Quantenzustands zu sehen, verwenden wir die Bloch-Kugel, eine dreidimensionale Kugel, die den Zustand eines einzelnen Qubits darstellt. Jeder Punkt auf der Kugel stellt einen möglichen Zustand des Qubits dar, wobei der Nord- und der Südpol wie die klassische "0" und "1" sind, das Qubit aber auch irgendwo dazwischen liegen kann, was spezielle Quanteneigenschaften wie Überlagerung zeigt. Bereiten Sie zunächst die notwendigen Funktionen für die Darstellung der 3D Bloch-Kugel vor und bereiten Sie 5000 Zufallsparameter vor.

import matplotlib.pyplot as plt


def plot_bloch(bloch_vectors):
    # Extract X, Y, Z coordinates for 3D projection
    X_coords = bloch_vectors[:, 0]
    Z_coords = bloch_vectors[:, 2]

    # Compute Y coordinates from X and Z to approximate the full Bloch sphere projection
    Y_coords = bloch_vectors[:, 1]

    # Create 3D plot
    fig = plt.figure(figsize=(8, 8))
    ax = fig.add_subplot(111, projection="3d")
    ax.scatter(X_coords, Y_coords, Z_coords, color="blue", alpha=0.6)

    # Labels and title
    ax.set_xlabel("X")
    ax.set_ylabel("Y")
    ax.set_zlabel("Z")
    ax.set_title("Parameterized 1-Qubit Circuit on 3D Bloch Sphere")

    # Set axis limits and make them equal
    ax.set_xlim([-1, 1])
    ax.set_ylim([-1, 1])
    ax.set_zlim([-1, 1])

    # Ensure equal aspect ratio for all axes
    ax.set_box_aspect([1, 1, 1])  # Equal scaling for x, y, z axes

    # Show grid
    ax.grid(True)

    plt.show()


num_samples = 5000  # Number of random states
theta_vals = np.random.uniform(0, 2 * np.pi, num_samples)
phi_vals = np.random.uniform(0, 2 * np.pi, num_samples)
lam_vals = np.random.uniform(0, 2 * np.pi, num_samples)

Schauen wir uns an, wie unser erster Ansatz funktioniert.

# List to store Bloch Sphere XZ coordinates
bloch_vectors = []

# Generate quantum states and extract Bloch vectors
for i in range(num_samples):
    # Create a circuit and bind parameters
    qc = ansatz1
    bound_qc = qc.assign_parameters({theta: theta_vals[i]})  # , lam: lam_vals[i]})
    state = Statevector.from_instruction(bound_qc)
    rho = DensityMatrix(state)

    X = rho.expectation_value(Pauli("X")).real
    Y = rho.expectation_value(Pauli("Y")).real
    Z = rho.expectation_value(Pauli("Z")).real
    bloch_vectors.append([X, Y, Z])  # Store X, Z components

# Convert to a numpy array for plotting
bloch_vectors = np.array(bloch_vectors)

plot_bloch(bloch_vectors)

Output:

Output of the previous code cell

Wir können sehen, dass unser erster Ansatz einen ringförmig verteilten Quantenzustand der Bloch-Kugel ergibt. Dies ist sinnvoll, da wir dem Ansatz nur einen einzigen Rotationsparameter gegeben haben. Sie kann daher nur um eine Achse gedrehte Zustände erzeugen. Ausgehend von dem Punkt (0,0,1)(0,0,1) und einer Drehung um eine Achse ergibt sich immer ein Ring. Prüfen wir nun unseren zweiten Ansatz, der zwei orthogonale Drehtore hat - Rx und Rz.

bloch_vectors = []

# Generate quantum states and extract Bloch vectors
for i in range(num_samples):
    # Create circuit and bind parameters
    qc = ansatz2
    bound_qc = qc.assign_parameters(
        {theta: theta_vals[i], phi: phi_vals[i]}
    )  # , lam: lam_vals[i]})
    state = Statevector.from_instruction(bound_qc)
    rho = DensityMatrix(state)

    X = rho.expectation_value(Pauli("X")).real
    Y = rho.expectation_value(Pauli("Y")).real
    Z = rho.expectation_value(Pauli("Z")).real
    bloch_vectors.append([X, Y, Z])  # Store X, Z components

# Convert to numpy array for plotting
bloch_vectors = np.array(bloch_vectors)

plot_bloch(bloch_vectors)

Output:

Output of the previous code cell

Hier können wir sehen, dass unser zweiter Ansatz einen größeren Teil der Bloch-Kugel abdeckt - aber beachten Sie, dass die Punkte um die Pole konzentrierter und um den Äquator verteilter sind. Nun ist es an der Zeit, unseren letzten Ansatz zu überprüfen.

bloch_vectors = []

# Generate quantum states and extract Bloch vectors
for i in range(num_samples):
    # Create circuit and bind parameters
    qc = ansatz3
    bound_qc = qc.assign_parameters(
        {theta: theta_vals[i], phi: phi_vals[i], lam: lam_vals[i]}
    )
    state = Statevector.from_instruction(bound_qc)
    rho = DensityMatrix(state)

    X = rho.expectation_value(Pauli("X")).real
    Y = rho.expectation_value(Pauli("Y")).real
    Z = rho.expectation_value(Pauli("Z")).real
    bloch_vectors.append([X, Y, Z])  # Store X, Z components

# Convert to numpy array for plotting
bloch_vectors = np.array(bloch_vectors)

plot_bloch(bloch_vectors)

Output:

Output of the previous code cell

Hier sehen Sie gleichmäßig verteilte Quantenzustände, die durch unseren letzten Ansatz erzeugt wurden.

Wie bereits erwähnt, ist es am besten, Kenntnisse über den gesuchten Grundzustand zu erlangen und einen Ansatz zu verwenden, der gut geeignet ist, um Zustände in der Nähe dieses Grundzustands zu untersuchen. Wenn wir zum Beispiel wüssten, dass unser Grundzustand in der Nähe eines Pols liegt, könnten wir Satz 2 wählen. Der Einfachheit halber bleiben wir bei Satz 3, der die gesamte Bloch-Sphäre gleichmäßig abtastet.

Nachdem wir nun unseren Ansatz ausgewählt haben, zeichnen wir die Schaltung.

# Pre-defined ansatz circuit and operator class for Hamiltonian

ansatz = ansatz3

num_params = ansatz.num_parameters
print("This circuit has ", num_params, "parameters")

ansatz.draw("mpl", style="iqp")

Output:

This circuit has  3 parameters
Output of the previous code cell

Schritt 2: Für die Zielhardware optimieren

Wenn wir eine Berechnung auf einem echten Quantencomputer durchführen, interessiert uns nicht nur die Logik der Quantenschaltung. Es geht auch darum, welche Operationen der jeweilige Quantencomputer ausführen kann und wo auf dem Quantencomputer sich die Qubits befinden, die wir verwenden. Stehen sie direkt nebeneinander? Sind sie weit voneinander entfernt? Daher besteht der nächste Schritt darin, unsere Schaltung mit Gattern umzuschreiben, die für den von uns verwendeten Quantencomputer geeignet sind, und die Anordnung der Qubits zu berücksichtigen. Dies kann durch transpilation geschehen - nach diesem Prozess können Sie sehen, wie unser einfacher Ansatz in einen anderen Satz von Gattern umgewandelt wird, und unsere abstrakten Qubits werden auf einem realen Quantencomputer in physikalische Qubits abgebildet.

from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

config = backend.configuration()

print("Backend: {config.backend_name}")
print("Native gates: ", config.supported_instructions, ",")


target = backend.target

pm = generate_preset_pass_manager(target=target, optimization_level=3)

ansatz_isa = pm.run(ansatz)

ansatz_isa.draw(output="mpl", idle_wires=False, style="iqp")

Output:

Backend: {config.backend_name}
Native gates:  ['ecr', 'id', 'delay', 'measure', 'reset', 'rz', 'sx', 'x'] ,
Output of the previous code cell

Sie können sehen, dass die rx, rz Gatter unseres Ansatzes in eine Reihe von rz, sx Gattern umgewandelt wurden, die die nativen Gatter unseres Backends sind. Außerdem können Sie sehen, dass unsere q0 jetzt auf das fünfte physikalische Qubit abgebildet ist. Wir müssen auch unseren Hamiltonian entsprechend diesen Änderungen abbilden, wie im folgenden Code:

Hamiltonian_isa = Hamiltonian.apply_layout(layout=ansatz_isa.layout)

Schritt 3: Auf der Zielhardware ausführen

Nun ist es an der Zeit, unsere VQE auf einer echten QPU laufen zu lassen. Dazu benötigen wir zunächst eine Kostenfunktion für den Optimierungsprozess, die den Erwartungswert des Hamiltonianers mit einem Quantenzustand, der durch den Ansatz erzeugt wird, auswertet. Kein Problem! Sie brauchen nicht alles selbst zu programmieren. Wir haben dafür eine Funktion vorbereitet, und alles, was Sie tun müssen, ist, die Zelle unten auszuführen.

def cost_func(params, 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 (EstimatorV2): Estimator primitive instance
        cost_history_dict: Dictionary for storing intermediate results

    Returns:
        float: Energy estimate
    """
    pub = (ansatz, [hamiltonian], [params])
    result = estimator.run(pubs=[pub]).result()
    energy = result[0].data.evs[0]

    cost_history_dict["iters"] += 1
    cost_history_dict["prev_vector"] = params
    cost_history_dict["cost_history"].append(energy)
    print(f"Iters. done: {cost_history_dict['iters']} [Current cost: {energy}]")

    return energy

Schließlich bereiten wir Anfangsparameter für unseren Ansatz und seinen Optimierungsprozess vor. Sie können einfach alle Nullen oder Zufallswerte verwenden. Wir haben unten die Anfangsparameter ausgewählt, aber es steht Ihnen frei, die Zeilen in der Zelle zu kommentieren oder zu entkommentieren, um die Parameter nach dem Zufallsprinzip und gleichmäßig von 0 bis 2π2\pi zu wählen.

# x0 = np.random.uniform(0, 2*pi, 3)
x0 = [1, 1, 0]
# QPU Est. 2min for ibm_brisbane

from scipy.optimize import minimize
from qiskit_ibm_runtime import Batch

batch = Batch(backend=backend)

cost_history_dict = {
    "prev_vector": None,
    "iters": 0,
    "cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 10000

res = minimize(
    cost_func,
    x0,
    args=(ansatz_isa, Hamiltonian_isa, estimator),
    method="cobyla",
    options={"maxiter": 10, "tol": 0.01},
)

batch.close()

Output:

Iters. done: 1 [Current cost: -0.3361517318448143]
Iters. done: 2 [Current cost: -0.4682546422099432]
Iters. done: 3 [Current cost: -0.38985802144149584]
Iters. done: 4 [Current cost: -0.38319217316749354]
Iters. done: 5 [Current cost: -0.4628720756579032]
Iters. done: 6 [Current cost: -0.4683301936226905]
Iters. done: 7 [Current cost: -0.45480498699294747]
Iters. done: 8 [Current cost: -0.4690533242050814]
Iters. done: 9 [Current cost: -0.465867415110354]
Iters. done: 10 [Current cost: -0.4606882723137227]
h_vqe = res.fun
print("The reference ground state energy is ", min(eigenvalues))
print("The computed ground state energy is ", h_vqe)

Output:

The reference ground state energy is  (-0.471+0j)
The computed ground state energy is  -0.4690533242050814

Glückwunsch! Sie haben gerade Ihr erstes quantenchemisches Experiment erfolgreich abgeschlossen. Es ist ein Unterschied zwischen der exakten Grundzustandsenergie des Hamiltonian und unserer zu erkennen, aber da wir eine Standard-Fehlerminderungstechnik verwendet haben (die Auslesefehler korrigiert), ist der Unterschied gering. Das ist ein sehr guter Anfang!

Hinweis: Sie können ein besseres Ergebnis erzielen, indem Sie mit die Stufe der resilience_levelFehlerbehebung festlegen. Der Standardwert ist 1. Wenn Sie einen höheren Wert festlegen, wird mehr QPU-Zeit benötigt, aber möglicherweise ein besseres Ergebnis erzielt.

Schritt 4: Nachbearbeitung

Es ist an der Zeit, einen Blick darauf zu werfen, wie unser klassischer Optimierer funktioniert. Führen Sie die untenstehende Zelle aus und sehen Sie sich das Konvergenzmuster an.

fig, ax = plt.subplots()
x = np.linspace(0, 10, 10)

# Define the constant function
y_constant = np.full_like(x, h)
ax.plot(
    range(cost_history_dict["iters"]), cost_history_dict["cost_history"], label="VQE"
)
ax.set_xlabel("Iterations")
ax.set_ylabel("Cost (Hartree)")
ax.plot(y_constant, label="Target")
plt.legend()
plt.draw()

Output:

Output of the previous code cell

Wir begannen mit einem recht guten Ausgangswert, so dass wir in nur 10 Schritten einen guten Endwert erreichten. Sie können große und kleine Spitzen sehen, und das ist das typische Merkmal des COBYLA-Optimierers - er durchsucht den Raum, als ob er die Landschaft nicht sehen könnte, und passt die Schrittgrößen mit jeder Messung an.

Überprüfen Sie Ihr Verständnis

Was ist Ihre Beobachtung? Welcher Teil des obigen Prozesses kann verbessert werden, um Ergebnisse zu erhalten, die näher an den theoretischen Werten oder näher an der genauen Grundzustandsenergie des Hamiltonianers liegen? Was gibt es dabei zu beachten?

  • Der erste Punkt ist die Änderung der Basen, die für die Berechnung des Hamiltonian der Moleküle verwendet werden. Wie bereits erwähnt, ist die Grundzustandsenergie des H-Atoms bekanntlich -0.5 Hartree, und die von uns gewählte Basis STO-6G reicht nicht aus, um diesen Wert genau abzuleiten.

    Die Wahl einer komplexeren Basis erhöht die Anzahl der vom Hamiltonian verwendeten Qubits; daher müssen wir einen komplexeren und geeigneteren Ansatz für chemische Probleme wählen.

    Als Nächstes muss die Rauschunterdrückung in der QPU optimiert werden. Fortschrittlichere Techniken zur Fehlerbegrenzung führen zu besseren Ergebnissen, können aber länger dauern. Berücksichtigen Sie auch, wie die Website shot_number die Ergebnisse beeinflusst.

    Schließlich kann eine bessere Konvergenzleistung auch durch das Ausprobieren verschiedener Optimierer erreicht werden.


Berechnen Sie die Grundzustandsenergie des Wasserstoffmoleküls mit VQE

Nachdem wir uns den Gesamtprozess der VQE anhand von HH Atomen angesehen haben, werden wir nun die Grundzustandsenergie des H2H_2 Moleküls schneller berechnen.

Schritt 1: Das Problem auf Quantenschaltungen und Operatoren abbilden

Hier stellen wir Ihnen auch einen Ein-Qubit-Hamiltonian zur Verfügung, der die Basis STO-6G und die Jordan-Wigner-Transformation verwendet, mit einer Qubit-Reduktion durch Verwendung einer Symmetrie des Hamiltonian. Beachten Sie, dass wir einen atomaren Abstand zwischen zwei Wasserstoffatomen von 0.735 A˚\mathring A verwendet haben.

Anders als bei der Berechnung eines einzelnen Wasserstoffatoms ( HH ) muss bei der Berechnung des Grundzustands eines Wasserstoffmoleküls ( H2H_2 ) neben der Energie der elektronischen Orbitale auch die Abstoßungskraft zwischen den Kernen der beiden Wasserstoffatome berücksichtigt werden. In diesem Schritt geben wir diesen Wert als Konstante an, und wir werden diesen Wert im Check-in-Problem tatsächlich berechnen. H^=−1.04886I+−0.79674Z+0.18122X\hat{H} = -1.04886 I + -0.79674 Z + 0.18122 X

h2_hamiltonian = SparsePauliOp.from_list(
    [("I", -1.04886087), ("Z", -0.7967368), ("X", 0.18121804)]
)

# exact ground state energy of hamiltonian
nuclear_repulsion = 0.71997
A = np.array(h2_hamiltonian)
eigenvalues, eigenvectors = np.linalg.eig(A)
print("Electronic ground state energy (Hartree): ", min(eigenvalues).real)
print("Nuclear repulsion energy (Hartree): ", nuclear_repulsion)
print(
    "Total ground state energy (Hartree): ", min(eigenvalues).real + nuclear_repulsion
)
h2 = min(eigenvalues).real + nuclear_repulsion

Output:

Electronic ground state energy (Hartree):  -1.8659468547627318
Nuclear repulsion energy (Hartree):  0.71997
Total ground state energy (Hartree):  -1.1459768547627318

Schritt 2: Für die Zielhardware optimieren

Da die Anzahl der Qubits, die von der vorherigen VQE und dem Hamiltonian verwendet werden, die gleiche ist wie das Backend, das für die Ausführung verwendet werden soll, werden wir den bestehenden Ansatz und seine optimierte Form verwenden.

h2_hamiltonian_isa = h2_hamiltonian.apply_layout(layout=ansatz_isa.layout)

Schritt 3: Auf der Zielhardware ausführen

Jetzt ist es an der Zeit, die Berechnungen für die eigentliche QPU durchzuführen. Fast alles ist gleich, aber wir werden den entsprechenden Ausgangspunkt verwenden, um den Hamiltonian anzupassen. Außerdem werden in einem iterativen Teil einige der Einstellungen von Estimator, die zur Berechnung der Erwartungen des Hamiltonianers für den Ansatz in der QPU verwendet werden, etwas anders eingestellt als in den vorherigen Berechnungen. Wir werden diese Änderung in einer Check-in-Frage weiter erörtern.

x0 = [2, 0, 0]
# QPU time 4min for ibm_brisbane
batch = Batch(backend=backend)

cost_history_dict = {
    "prev_vector": None,
    "iters": 0,
    "cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 10000

res = minimize(
    cost_func,
    x0,
    args=(ansatz_isa, h2_hamiltonian_isa, estimator),
    method="cobyla",
    options={"maxiter": 15},
)

batch.close()

Output:

Iters. done: 1 [Current cost: -0.710621837568328]
Iters. done: 2 [Current cost: -0.2603208441168329]
Iters. done: 3 [Current cost: -0.25548711201326424]
Iters. done: 4 [Current cost: -0.581129450619904]
Iters. done: 5 [Current cost: -1.722920997605439]
Iters. done: 6 [Current cost: -1.6633324849371915]
Iters. done: 7 [Current cost: -1.8066989598929164]
Iters. done: 8 [Current cost: -1.8051093803839542]
Iters. done: 9 [Current cost: -1.802692217571555]
Iters. done: 10 [Current cost: -1.8233585485263144]
Iters. done: 11 [Current cost: -1.6904116652617205]
Iters. done: 12 [Current cost: -1.8245120321245392]
Iters. done: 13 [Current cost: -1.6837021361383608]
Iters. done: 14 [Current cost: -1.8166632606115467]
Iters. done: 15 [Current cost: -1.863446212658907]
h2_vqe = res.fun + nuclear_repulsion
print(
    "The reference ground state energy is ", min(eigenvalues).real + nuclear_repulsion
)
print("The computed ground state energy is ", h2_vqe)

Output:

The reference ground state energy is  -1.1459768547627318
The computed ground state energy is  -1.143476212658907

Obwohl die VQE theoretisch eine obere Schranke für die wahre Grundzustandsenergie darstellt, können praktische Implementierungen auf realer oder verrauschter simulierter Quantenhardware sowie Näherungen bei der Erstellung des Hamiltonians (wie Basissätze oder Qubit-Reduktion) Fehler einführen, die manchmal zu einer gemessenen Energie führen, die geringfügig niedriger ist als der exakte theoretische Wert oder eine bestimmte numerische Referenz. Trotz einiger Fehler scheinen die Ergebnisse zufriedenstellend zu sein, insbesondere in Anbetracht der geringen Anzahl von Schritten. Lassen Sie uns nun diese VQE-Berechnung abschließen, indem wir uns ansehen, wie der Optimierer arbeitet.

Schritt 4: Nachbearbeitung

fig, ax = plt.subplots()
x = np.linspace(0, 5, 15)

# Define the constant function
y_constant = np.full_like(x, min(eigenvalues))
ax.plot(
    range(cost_history_dict["iters"]), cost_history_dict["cost_history"], label="VQE"
)
ax.set_xlabel("Iterations")
ax.set_ylabel("Cost (Hartree)")
ax.plot(y_constant, label="Target")
plt.legend()
plt.draw()

Output:

Output of the previous code cell

Überprüfen Sie Ihr Verständnis

Berechnen wir die Kernabstoßungsenergie des Moleküls H2H_2, die wir als konstanten Wert einbeziehen ( 0.71997 Hartree).

H2 molekül

Bitte wende das Coulomb-Gesetz und die atomare Einheit an, um sicherzustellen, dass du den Wert in Hartreeerhältst.

  • Da beide Wasserstoffkerne positiv geladen sind, stoßen sie sich aufgrund der elektrostatischen Kraft gegenseitig ab. Diese Abstoßung wird durch das Coulombsche Gesetz beschrieben:

    Erepulsive=e24πϵ0RE_{repulsive} = \frac{e^2}{4\pi\epsilon_0R}

    wobei ee die Ladung des Protons, ϵ0\epsilon_0 die Dielektrizitätskonstante des Vakuums und RR der Abstand zwischen den beiden Kernen ist, gemessen in Metern oder Bohr-Radien in der Einheit Joule (J).

    Um diese Energie in Hartrees zu berechnen, müssen wir die obige Gleichung in das System der atomaren Einheiten (AU) umrechnen. In AU ist e2=1e^2 = 1, 4πϵ0=14\pi\epsilon_0=1 und der Bohr-Radius ( a0a_0 ) 1 und wird zur fundamentalen Längenskala in AU. Mit diesen Vereinfachungen reduziert sich das Coulombsche Gesetz auf:

    Erepulsion=1RE_{repulsion} = \frac{1}{R}

    wobei RR in Bohr-Radien ( a0a_0 ) gemessen werden muss.

    Um den angegebenen Kernabstand in A˚\r{A} in a0a_0 umzurechnen, benötigen wir diese Umrechnungsrelation:

    1A˚=1.88973a01\r{A} = 1.88973 a_0

    so wird aus 0.735A˚0.735\r{A} 0.735∗1.88973=1.38895a00.735 * 1.88973 = 1.38895 a_0.

    Daher ist die Kernabstoßungsenergie einer gegebenen H2H_2

    Erepulsion=1R=11.38895=0.71997HartreeE_{repulsion} = \frac{1}{R} = \frac{1}{1.38895} = 0.71997 Hartree


Berechne die Reaktionsenergie von H+H=H2H + H = H_2

Nutzen wir nun das, was wir erhalten haben! Sie haben VQE, einen Variationsquanten-Eigensolver, verwendet, um die Grundzustandsenergie des Atoms HH und des Moleküls H2H_2 zu berechnen. Es bleibt nur noch, die berechneten Werte zu verwenden, um die Reaktionsenergie des Prozesses H+H=H2H+H=H_2 zu erhalten.

Reaktionsenergie ist die Energieänderung, die auftritt, wenn Stoffe reagieren und neue Stoffe bilden. Stellen Sie sich vor, Sie bauen etwas: Manchmal müssen Sie Energie hineinstecken (wie beim Stapeln von Blöcken), und manchmal wird Energie freigesetzt (wie bei einer Kugel, die bergab rollt). In der Chemie nehmen Reaktionen entweder Energie auf (endotherm) oder setzen Energie frei (exotherm).

Die Reaktionsenergie des H+H=H2H+H = H_2 Prozesses kann mit der folgenden Formel berechnet werden:

Ereaction=EH2−(EH+EH)E_{reaction} = E_{H_2} - (E_H + E_H)

Führen Sie die nachstehende Zelle aus, um dies visuell zu veranschaulichen. Hier werden wir den exakten Grundzustandswert jedes Hamiltonianers verwenden und die Reaktionsenergie der exakten Lösung mit den VQE-Ergebnissen vergleichen.

# Theoretical values
E_H_theo = h.real
E_H2_theo = h2

# Experimental values
E_H_exp = h_vqe
E_H2_exp = h2_vqe

# Calculate reaction energies
E_reaction_theo = E_H2_theo - (2 * E_H_theo)
E_reaction_exp = E_H2_exp - (2 * E_H_exp)

# Set up the plot
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 3)
ax.set_ylim(-1.16, -0.93)  # Adjust y-axis range to highlight differences
ax.set_xticks([])
ax.set_ylabel("Energy (Hartree)")
ax.set_title("H + H → H₂ Reaction Energy Diagram")

# Plot theoretical energy levels
ax.hlines(
    y=2 * E_H_theo, xmin=0.5, xmax=1.3, linewidth=2, color="r", label="2H (Exact)"
)
ax.hlines(y=E_H2_theo, xmin=1.3, xmax=2, linewidth=2, color="b", label="H₂ (Exact)")

# Plot experimental energy levels
ax.hlines(
    y=2 * E_H_exp,
    xmin=0.5,
    xmax=1.5,
    linewidth=2,
    color="r",
    linestyle="dashed",
    label="2H (VQE)",
)
ax.hlines(
    y=E_H2_exp,
    xmin=1.5,
    xmax=2.5,
    linewidth=2,
    color="b",
    linestyle="dashed",
    label="H₂ (VQE)",
)

# Add labels
ax.text(
    1,
    2 * E_H_theo,
    f"2H: {2*E_H_theo:.4f}",
    verticalalignment="top",
    horizontalalignment="left",
)
ax.text(
    2,
    E_H2_theo,
    f"H₂: {E_H2_theo:.4f}",
    verticalalignment="top",
    horizontalalignment="left",
)
ax.text(
    1,
    2 * E_H_exp,
    f"2H_VQE: {2*E_H_exp:.4f}",
    verticalalignment="bottom",
    horizontalalignment="right",
)
ax.text(
    2,
    E_H2_exp,
    f"H₂_VQE: {E_H2_exp:.4f}",
    verticalalignment="bottom",
    horizontalalignment="right",
)

# Add arrows for reaction energy with ΔE label in the middle
mid_y_theo = (2 * E_H_theo + E_H2_theo) / 2
mid_y_exp = (2 * E_H_exp + E_H2_exp) / 2
ax.annotate(
    "",
    xy=(1.3, E_H2_theo),
    xytext=(1.3, 2 * E_H_theo),
    arrowprops=dict(arrowstyle="<->", color="g"),
)
ax.text(
    1.35, mid_y_theo, f"ΔE: {E_reaction_theo:.4f}", color="g", verticalalignment="top"
)

ax.annotate(
    "",
    xy=(1.5, E_H2_exp),
    xytext=(1.5, 2 * E_H_exp),
    arrowprops=dict(arrowstyle="<->", color="g", linestyle="dashed"),
)
ax.text(
    1.55,
    mid_y_exp,
    f"ΔE_VQE: {E_reaction_exp:.4f}",
    color="g",
    verticalalignment="center",
)

# Add legend
ax.legend()

plt.show()

Output:

Output of the previous code cell

Wie die Abbildung zeigt, sind die exakte Grundzustandsenergie der Hamiltonianer und die mit den VQE-Ergebnissen berechnete Reaktionsenergie trotz einiger Fehler ähnlich und liegen nahe an -0.2 Hartree.

Dabei ist zu beachten, dass die Reaktionsenergie dieses Prozesses einen negativen Wert hat, was bedeutet, dass die Energie durch den Prozess freigesetzt wird und das entstehende Molekül eine geringere Energie hat als zwei einzelne Atome.

  1. Fazit

Lassen Sie uns zusammenfassen, was wir bisher gelernt haben.

Zunächst haben wir uns zwei wichtige Näherungstechniken angesehen, die zur Lösung quantenchemischer Probleme benötigt werden: das Variationsprinzip und die Wahl der Basismengen, die beide für die VQE von grundlegender Bedeutung sind. Wir haben das Variationsprinzip von Hand erforscht und die Grundzustandsenergie des einfachen harmonischen Oszillators berechnet.

Als nächstes untersuchten wir VQE, einen weit verbreiteten Algorithmus zur Berechnung der Grundzustandsenergie eines Quantensystems. Wir haben den Code zur Berechnung der Grundzustandsenergien für atomaren Wasserstoff ( HH ) und das Wasserstoffmolekül ( H2H_2 ) ausgeführt. Insbesondere haben wir gelernt, dass es notwendig ist, den geeigneten molekularen Hamiltonian für das System zu erhalten und ihn in eine Form zu transformieren, die auf einem Quantencomputer ausführbar ist. Wir haben auch gesehen, dass der Ansatz, eine parametrisierte Quantenschaltung, benötigt wird, um Versuchsquantenzustände innerhalb der VQE vorzubereiten, und wir haben die Bedeutung der Wahl einer geeigneten Ansatz-Schaltungsstruktur diskutiert. Wir lernten auch, dass VQE auf einem iterativen Optimierungsprozess beruht, bei dem ein klassischer Computer den Quantenschaltkreis anleitet, den niedrigsten Energiezustand zu finden, und sahen, wie der Prozess konvergiert.

Schließlich verwendeten wir die berechneten Grundzustandsenergien von HH und H2H_2, die durch VQE erhalten wurden, um die Reaktionsenergie für den Prozess H+H→H2H + H \rightarrow H_2 zu berechnen.

VQE ist ein leistungsfähiger Quantenalgorithmus, der in naher Zukunft zum Einsatz kommen wird, aber es ist wichtig, sich seiner Grenzen bewusst zu sein. Die Leistung der VQE hängt in hohem Maße von der Wahl des Ansatzes ab - für größere, komplexere Moleküle wird es schwierig, einen effizient präparierbaren Ansatz zu finden, der den wahren Grundzustand genau darstellen kann. Außerdem ist die derzeitige Quanten-Hardware anfällig für Rauschen, was die Genauigkeit der VQE-Ergebnisse beeinträchtigen kann, insbesondere bei tieferen Schaltkreisen oder einer größeren Anzahl von Qubits. Trotz dieser Herausforderungen dient VQE als grundlegender Algorithmus, und in der laufenden Forschung werden anspruchsvollere Variationsmethoden und Techniken zur Fehlerminderung erforscht, um die Grenzen dessen zu erweitern, was in der Quantenchemie auf baldigen Quantencomputern möglich ist. So werden beispielsweise Algorithmen wie die Sample-basierte Quantendiagonalisierung (SQD) entwickelt, die die aus Quantenschaltungen gewonnenen Samples in Kombination mit der klassischen Diagonalisierung in einem Unterraum nutzen, um die Energieschätzung zu verbessern und einige der Einschränkungen der VQE, insbesondere hinsichtlich der Messeffizienz und der Rauschrobustheit, zu beheben.


Überprüfung und Fragen

Wichtige Konzepte:

  • Der Variations-Quantenalgorithmus ist ein Rechenparadigma, bei dem ein klassischer Computer und ein Quantencomputer zusammenarbeiten, um ein Problem zu lösen.
  • Bei VQE beginnen wir mit einem Hamiltonian unseres Systems und bilden ihn auf Qubits ab, die auf dem Quantencomputer ausgeführt werden. Wir wählen einen parametrisierten Quantenschaltkreis, einen Ansatz, und führen wiederholte Messungen durch, wobei wir die Parameter des Ansatzes variieren, bis der niedrigste Energiewert erreicht ist. Die Suche im Parameterraum erfolgt mit einem klassischen Optimierer. Um gute Ergebnisse zu erzielen, ist es notwendig, einen guten Ansatz und einen geeigneten Optimierer zu wählen.
  • Die Reaktionsenergie ist die gesamte Energieänderung bei einer chemischen Reaktion, die durch die Differenz zwischen der Energie der Reaktanten und der Produkte bestimmt wird.

True/false

  1. Das Variationsprinzip besagt, dass der Erwartungswert der Energie für jede Versuchswellenfunktion immer größer oder gleich der wahren Grundzustandsenergie ist.
  2. Ein Basissatz ist eine Sammlung von Funktionen, die zur Annäherung von Quantenwellenfunktionen verwendet werden.
  3. VQE ist ein Quantenalgorithmus, der zur exakten Lösung der Schrödinger-Gleichung für einen gegebenen Hamiltonian verwendet wird.
  4. Bei der VQE wird eine parametrisierte Quantenschaltung (ein Ansatz) zur Vorbereitung von Versuchswellenfunktionen verwendet.
  5. Die Wahl des Optimierers in VQE (z. B. COBYLA, SPSA oder ADAM) hat keinen Einfluss auf die Qualität des Ergebnisses.
  6. Qiskit's Estimator wird zur direkten Berechnung von Erwartungswerten von Hamiltonianern in VQE verwendet.

Multiple-Choice-Fragen:

  1. Welchen Zweck erfüllt der Hamiltonian in der VQE?
  • A) Erzeugung zufälliger Quantenzustände
  • B) Bestimmung der Energie von Quantenzuständen
  • C) Zur Optimierung von Quantenschaltungen
  • D) Um Verschränkung zu erzeugen
  1. Was ist das Hauptziel des VQE-Algorithmus?
  • A) Ermittlung der Grundzustandsenergie eines Hamiltonianers
  • B) Verschränkung zwischen Qubits erzeugen
  • C) Grovers Suche durchführen
  • D) Um die RSA-Verschlüsselung zu brechen
  1. Wie viele Quantenzustände werden in diesem Notizbuch erzeugt, um den Ansatz zu vergleichen?
  • A) 100
  • B) 1000
  • C) 5000
  • D) 10,000
  1. Warum ist ein klassischer Optimierer in VQE erforderlich?
  • A) Zur Durchführung von Quantenmessungen
  • B) Aktualisierung der Ansatzparameter zur Minimierung der Energie
  • C) Qubits verschränken
  • D) Zur Erzeugung von Quantenzufälligkeit
  1. Warum soll der Ansatz parametrisiert werden?
  • A) Ermöglichung der Vorbereitung von Quantenzuständen
  • B) Ermöglichung der Suche nach einem breiten Raum von Quantenzuständen
  • C) Reduzierung der Komplexität der Schaltung
  • D) Direkte Messung von Eigenwerten
  1. Welche der folgenden Aussagen über die Wahl eines guten Ansatzes ist am ehesten richtig?
  • A) Ein Ansatz muss Zustände erzeugen, die gleichmäßig über die Bloch-Sphäre verteilt sind, sonst ist er nicht erfolgreich.
  • B) Ein Ansatz sollte auf Ihr System zugeschnitten sein, um sicherzustellen, dass er Zustände nahe dem Grundzustand erzeugen kann.
  • C) Ein Ansatz sollte mit Hilfe seiner Variationsparameter Zufallszustände erzeugen.
  • D) Ein besserer Ansatz hat immer mehr Variationsparameter.

(Optional) Anhang: Optimierungsaufwand nach Ansatzkomplexität

VQE steht vor mehreren bekannten Herausforderungenref [6], und die folgenden stehen im Zusammenhang mit dem, was wir oben gelernt haben.

  1. Herausforderungen bei der Ansatzauswahl

Die Auswahl des richtigen Variationsansatzes stellt eine Herausforderung dar. Chemisch inspirierte Ansätze (wie UCCSD) bieten physikalische Genauigkeit, erfordern aber tiefe Schaltkreise, während hardware-effiziente Ansätze flache Schaltkreise haben, aber möglicherweise nicht physikalisch interpretierbar sind. Außerdem führen viele Ansätze übermäßige Variationsparameter ein, die nur wenig zur Verbesserung der Genauigkeit beitragen, aber die Optimierung erheblich erschweren.

  1. Schwierigkeiten bei der Optimierung

Die Optimierungslandschaft der VQE kann Regionen aufweisen, in denen die Gradienten exponentiell verschwinden (unfruchtbare Plateaus), was es für klassische Optimierer schwierig macht, die Variationsparameter effizient zu aktualisieren. Zu diesem Zweck haben die Forscher versucht, verschiedene Arten von Optimierern zu verwenden - gradientenbasierte und gradientenfreie, aber beide stehen vor Herausforderungen. Gradientenbasierte Optimierer leiden unter unfruchtbaren Plateaus, während gradientenfreie Methoden eine große Anzahl von Funktionsbewertungen erfordern.

  1. Optimierungs-Overhead

Eine weitere bekannte Herausforderung ist der Overhead des Optimierers, der mit dem Umfang des Problems zusammenhängt. Die für die VQE erforderlichen Quantenschaltungen werden mit zunehmender Problemgröße immer umfangreicher und komplexer, wodurch sich in der Regel auch die Anzahl der zu optimierenden Parameter erhöht. Der Optimierungsprozess wird mit zunehmender Anzahl von Parametern immer schwieriger, was zu einer langsamen Konvergenz und Schwierigkeiten bei der Suche nach der optimalen Lösung führt.

Hier werden wir diese Herausforderungen anhand der VQE für ein H2H_2 Molekül mit zwei verschiedenen Arten von Ansätzen untersuchen.

(Hinweis: Dies kann mehr QPU-Zeit in Anspruch nehmen; verwenden Sie daher einen Simulator, wenn Sie nicht genügend Zeit haben)

from qiskit.circuit import ParameterVector

num_iter = 4
alpha = ParameterVector("alpha", 3)
beta = ParameterVector("beta", 3 * num_iter)

# step1: Map problem to quantum circuits and operators
hamiltonian = SparsePauliOp.from_list(
    [("I", -1.04886087), ("Z", -0.7967368), ("X", 0.18121804)]
)

ansatz_1 = ansatz3
ansatz_2 = QuantumCircuit(1)
for i in range(num_iter):
    ansatz_2.rx(beta[i * 3 + 0], 0)
    ansatz_2.rz(beta[i * 3 + 1], 0)
    ansatz_2.rx(beta[i * 3 + 2], 0)
ansatz_1.draw("mpl")

Output:

Output of the previous code cell
ansatz_2.draw("mpl")

Output:

Output of the previous code cell
# Step 2: Optimize for target hardware

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)

ansatz_isa_1 = pm.run(ansatz_1)
ansatz_isa_2 = pm.run(ansatz_2)
hamiltonian_isa_1 = hamiltonian.apply_layout(layout=ansatz_isa_1.layout)
hamiltonian_isa_2 = hamiltonian.apply_layout(layout=ansatz_isa_2.layout)

Führen wir nun eine VQE mit einem Anfangspunkt aus lauter Einsen durch, mit maximal 20 Schritten, und vergleichen wir die Konvergenz beider Durchläufe.

# QPU time 3m 40s for ibm_brisbane
# Step 3: Execute on target hardware

from scipy.optimize import minimize

x0 = np.ones(ansatz_1.num_parameters)

batch = Batch(backend=backend)


cost_history_dict = {
    "prev_vector": None,
    "iters": 0,
    "cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 2048

res = minimize(
    cost_func,
    x0,
    args=(ansatz_isa_1, hamiltonian_isa_1, estimator),
    method="cobyla",
    options={"maxiter": 20},
)

batch.close()

Output:

Iters. done: 1 [Current cost: -0.8782202668652658]
Iters. done: 2 [Current cost: -0.43473160695469165]
Iters. done: 3 [Current cost: -0.4076372093159749]
Iters. done: 4 [Current cost: -1.3587839859772106]
Iters. done: 5 [Current cost: -1.774529906754082]
Iters. done: 6 [Current cost: -1.541934983115727]
Iters. done: 7 [Current cost: -1.2732403113465345]
Iters. done: 8 [Current cost: -1.820842221085785]
Iters. done: 9 [Current cost: -1.8065762857059005]
Iters. done: 10 [Current cost: -1.8126394095981146]
Iters. done: 11 [Current cost: -1.8205831886180421]
Iters. done: 12 [Current cost: -1.8086715778994924]
Iters. done: 13 [Current cost: -1.8307676638629322]
Iters. done: 14 [Current cost: -1.8177328827556327]
Iters. done: 15 [Current cost: -1.8179426218088064]
Iters. done: 16 [Current cost: -1.8109239667991088]
Iters. done: 17 [Current cost: -1.824271872489647]
Iters. done: 18 [Current cost: -1.813167587671394]
Iters. done: 19 [Current cost: -1.824647343397313]
Iters. done: 20 [Current cost: -1.8219785311686143]
# Save Cost_history as a new list
ansatz_1_history = cost_history_dict["cost_history"]
# QPU time 3m 40s for ibm_brisbane

x0 = np.ones(ansatz_2.num_parameters)

batch = Batch(backend=backend)


cost_history_dict = {
    "prev_vector": None,
    "iters": 0,
    "cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 2048

res = minimize(
    cost_func,
    x0,
    args=(ansatz_isa_2, hamiltonian_isa_2, estimator),
    method="cobyla",
    options={"maxiter": 20},
)

batch.close()

Output:

Iters. done: 1 [Current cost: -0.738191173881188]
Iters. done: 2 [Current cost: -0.42636037194506304]
Iters. done: 3 [Current cost: -1.3503788613797374]
Iters. done: 4 [Current cost: -0.9109204349776897]
Iters. done: 5 [Current cost: -0.9060873157510835]
Iters. done: 6 [Current cost: -0.7735065414083984]
Iters. done: 7 [Current cost: -1.586889197437709]
Iters. done: 8 [Current cost: -1.659215191584943]
Iters. done: 9 [Current cost: -1.245445981794618]
Iters. done: 10 [Current cost: -1.1608385766138023]
Iters. done: 11 [Current cost: -1.1551733876027737]
Iters. done: 12 [Current cost: -1.8143337768286332]
Iters. done: 13 [Current cost: -1.2510951563756598]
Iters. done: 14 [Current cost: -1.6918311531865413]
Iters. done: 15 [Current cost: -1.8163783305531838]
Iters. done: 16 [Current cost: -1.8434877732947152]
Iters. done: 17 [Current cost: -1.8461898233304472]
Iters. done: 18 [Current cost: -1.0346471214915485]
Iters. done: 19 [Current cost: -1.8322518854150687]
Iters. done: 20 [Current cost: -1.717144678705999]
ansatz_2_history = cost_history_dict["cost_history"]
fig, ax = plt.subplots()

# Define the constant function)
ax.plot(
    range(cost_history_dict["iters"]),
    ansatz_1_history,
    label="Ansatz with 3 parameters",
)
ax.plot(
    range(cost_history_dict["iters"]),
    ansatz_2_history,
    label="Ansatz with 12 parameters",
)
ax.set_xlabel("Iterations")
ax.set_ylabel("Cost (Hartree)")
plt.legend()
plt.draw()

Output:

Output of the previous code cell

Die obige Grafik zeigt deutlich, dass der Optimierungsprozess des Ansatzes mit mehr Variablen mehr Zeit benötigt, um eine stabile Konvergenz zu erreichen.

Anstatt sich auf einfache Ein-Qubit-Schaltungen und einen unkomplizierten Ansatz zu verlassen, steigt die Komplexität der Optimierung, wenn größere Quantenschaltungen und komplexere strukturierte Ansätze erforderlich sind. Dies verdeutlicht eine bekannte Herausforderung bei VQEs: den Overhead des Optimierers.

Forscher entwickeln weiterhin verschiedene fortschrittliche Methoden, mit denen Quantencomputer für chemische Probleme eingesetzt werden können. Unter können Sie auf eine Vielzahl IBM Quantum Learning von Lehrmaterialien zugreifen.


Referenzen

  • [ref 1 ] Richard P. Feynman, Simulating Physics with Computers, International Journal of Theoretical Physics, 1982.
  • [ref 2] Marov, M.Y. (2015). Die Struktur des Universums. In: Die Grundlagen der modernen Astrophysik. Springer, New York, NY.
  • [ref 3 ] Wie man schwierige verfahrenstechnische Probleme mit Quantencomputern löst, IBM Research Blog, 2023.
  • [ref 4 ] Y. Cao, J. Romero und A. Aspuru-Guzik, "Potential of quantum computing for drug discovery", in IBM Journal of Research and Development, vol. 62, no. 6, pp. 6:1-6:20, 1 Nov.-Dec. 2018
  • [ref 5 ] Present State of Molecular Structure Calculation, REv. Mod. Phys. 32, 170, 1960
  • [ref 6 ] Fedorov, D.A., Peng, B., Govind, N. et al. VQE-Methode: ein kurzer Überblick und aktuelle Entwicklungen. Mater-Theorie 6, 2 (2022)
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.