German
Sprachen
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

Bemerkung

Diese Seite wurde aus tutorials/circuits_advanced/1_advanced_circuits.ipynb generiert.

Variational Quantum Deflation (VQD) Algorithmus

This notebook demostrates how to use Qiskit’s implementation of the Variational Quantum Deflation (VQD) algorithm for computing higher energy states of a Hamiltonian, as introduced in this reference paper.

Einführung

VQD ist ein Quantenalgorithmus, der eine Variationsmethode verwendet, um die k Eigenwerte des Hamiltonian H eines gegebenen Systems zu finden.

Der Algorithmus berechnet die angeregten Zustandsenergien von verallgemeinerten Hamiltonian durch Optimierung über eine modifizierte Kostenfunktion. Jeder aufeinanderfolgende Eigenwert wird iterativ berechnet, indem ein Überlappungsterm mit allen zuvor berechneten Eigenzuständen, die minimiert werden müssen, eingeführt wird. Dadurch wird sichergestellt, dass Eigenzustände mit höherer Energie gefunden werden.

Vollständiges Funktionsbeispiel für VQD

Der erste Schritt des VQD-Arbeitsablaufs besteht darin, einen Qubit-Operator, einen Ansatz und einen Optimierer zu erstellen. Für dieses Beispiel können Sie das H2-Molekül verwenden, das Ihnen bereits bekannt vorkommen sollte, wenn Sie die vorherigen VQE-Tutorials absolviert haben:

[1]:
from qiskit.quantum_info import SparsePauliOp

H2_op = SparsePauliOp.from_list(
    [
        ("II", -1.052373245772859),
        ("IZ", 0.39793742484318045),
        ("ZI", -0.39793742484318045),
        ("ZZ", -0.01128010425623538),
        ("XX", 0.18093119978423156),
    ]
)

Sie können z. B. einen TwoLocal-Ansatz mit drei Qubits aufstellen und SLSQP als Optimierungsmethode wählen.

[2]:
from qiskit.circuit.library import TwoLocal
from qiskit.algorithms.optimizers import SLSQP

ansatz = TwoLocal(3, rotation_blocks=["ry", "rz"], entanglement_blocks="cz", reps=1)

optimizer = SLSQP()
ansatz.decompose().draw('mpl')
[2]:
../../_images/tutorials_algorithms_04_vqd_6_0.png

The next step of the workflow is to define the required primitives for running VQD. This algorithm requires two different primitive instances: one Estimator for computing the expectation values for the „VQE part“ of the algorithm, and one Sampler. The sampler will be passed along to the StateFidelity subroutine that will be used to compute the cost for higher energy states. There are several methods that you can use to compute state fidelities, but to keep things simple, you can use the ComputeUncompute method already available in qiskit.algorithm.state_fidelities.

[3]:
from qiskit.primitives import Sampler, Estimator
from qiskit.algorithms.state_fidelities import ComputeUncompute

estimator = Estimator()
sampler = Sampler()
fidelity = ComputeUncompute(sampler)

Um den VQD-Algorithmus einzurichten, ist es wichtig, zwei zusätzliche Eingaben zu definieren: die Anzahl der zu berechnenden Energiezustände (k) und die Betas, die in der ursprünglichen VQD-Veröffentlichung definiert wurden. In diesem Beispiel wird die Anzahl der Zustände (k) auf drei gesetzt, was bedeutet, dass zusätzlich zum Grundzustand zwei angeregte Zustände berechnet werden.

Die betas gleichen den Beitrag jedes Überlappungsterms zur Kostenfunktion aus und sind ein optionales Argument in der VQD Konstruktion. Wenn sie nicht vom Benutzer gesetzt werden, können sie für Eingabeoperatoren vom Typ SparsePauliOp automatisch ausgewertet werden. Bitte beachten Sie, dass Sie, wenn Sie Ihre eigenen betas setzen wollen, eine Liste von Werten der Länge k bereitstellen sollten.

[4]:
k = 3
betas = [33, 33, 33]

You are almost ready to run the VQD algorithm, but let’s define a callback first to store intermediate values:

[5]:
counts = []
values = []
steps = []

def callback(eval_count, params, value, meta, step):
    counts.append(eval_count)
    values.append(value)
    steps.append(step)

Schließlich kann man VQD instanziieren und die Eigenwerte für den gewählten Operator berechnen.

[6]:
from qiskit.algorithms.eigensolvers import VQD

vqd = VQD(estimator, fidelity, ansatz, optimizer, k=k, betas=betas, callback=callback)
result = vqd.compute_eigenvalues(operator = H2_op)
vqd_values = result.optimal_values

Sie können die drei Zustandsenergien als Teil des VQD-Ergebnisses sehen:

[7]:
print(vqd_values)
[-1.85727464 -1.2445845  -0.88272229]

Und wir können die durch den Callback gespeicherten Werte verwenden, um die Energiekonvergenz für jeden Zustand darzustellen:

[8]:
import numpy as np
import pylab

pylab.rcParams["figure.figsize"] = (12, 8)

steps = np.asarray(steps)
counts = np.asarray(counts)
values = np.asarray(values)

for i in range(1,4):
    _counts = counts[np.where(steps == i)]
    _values = values[np.where(steps == i)]
    pylab.plot(_counts, _values, label=f"State {i-1}")

pylab.xlabel("Eval count")
pylab.ylabel("Energy")
pylab.title("Energy convergence for each computed state")
pylab.legend(loc="upper right");
../../_images/tutorials_algorithms_04_vqd_18_0.png

Dieses Molekül kann mit der Klasse NumPyEigensolver exakt gelöst werden, was einen Referenzwert ergibt, den man mit dem VQD-Ergebnis vergleichen kann:

[9]:
from qiskit.algorithms.eigensolvers import NumPyEigensolver
from qiskit.opflow import PauliSumOp

exact_solver = NumPyEigensolver(k=3)
exact_result = exact_solver.compute_eigenvalues(PauliSumOp(H2_op))
ref_values = exact_result.eigenvalues

Let’s see a comparison of the exact result with the previously computed VQD eigenvalues:

[10]:
print(f"Reference values: {ref_values}")
print(f"VQD values: {vqd_values}")
Reference values: [-1.85727503 -1.24458455 -0.88272215]
VQD values: [-1.85727464 -1.2445845  -0.88272229]

Wie Sie sehen können, stimmt das Ergebnis von VQD mit den Werten der exakten Lösung überein und erweitert VQE, um auch angeregte Zustände zu berechnen.

[11]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.22.2
qiskit-aer0.11.1
qiskit-ignis0.7.1
qiskit-ibmq-provider0.19.2
qiskit0.39.2
System information
Python version3.10.2
Python compilerClang 13.0.0 (clang-1300.0.29.30)
Python buildv3.10.2:a58ebcc701, Jan 13 2022 14:50:16
OSDarwin
CPUs8
Memory (Gb)64.0
Fri Dec 09 14:27:13 2022 CET

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.