Penganggaran tenaga keadaan-asas rantaian Heisenberg dengan VQE
Anggaran penggunaan: 37 minit pada pemproses Heron (NOTA: Ini adalah anggaran sahaja. Masa jalan sebenar anda mungkin berbeza.)
Hasil pembelajaran
Selepas melengkapkan tutorial ini, kamu boleh menjangka untuk memahami maklumat berikut:
- Cara memodelkan rantaian spin Heisenberg sebagai Hamiltonian kuantum menggunakan Qiskit
- Cara menggunakan pengoptimum SPSA untuk menganggar tenaga keadaan-asas sistem kuantum
- Cara melaksanakan aliran kerja variatif pada perkakasan kuantum IBM® menggunakan primitif dan sesi Qiskit Runtime
Prasyarat
Adalah disyorkan agar kamu membiasakan diri dengan topik-topik ini:
Latar Belakang
Rantaian spin Heisenberg adalah salah satu model yang paling banyak dikaji dalam fizik jirim terkondensasi dan kemagnetan kuantum. Ia menggambarkan kekisi satu dimensi spin kuantum yang berinteraksi, di mana spin jiran terdekat diganding melalui interaksi pertukaran. Hamiltonian bagi model Heisenberg isotropik dengan medan magnet luaran diberikan oleh:
di mana , , dan adalah operator Pauli yang bertindak pada tapak , jumlah merangkumi pasangan jiran terdekat, adalah pemalar gandingan pertukaran (isotropik dalam tutorial ini), dan mewakili medan magnet luaran yang bergantung pada tapak. Dalam tutorial ini, nilai medan magnet disampel secara rawak daripada selang . Perlu diingat bahawa dalam pelaksanaan di bawah, set pasangan "jiran terdekat" ditentukan oleh gandingan asal backend perkakasan di antara qubit pertama, yang mungkin tidak membentuk rantaian linear yang ketat bergantung pada topologi peranti.
Memahami tenaga keadaan-asas Hamiltonian ini adalah penting secara asasi dalam fizik. Keadaan asas mengekod maklumat tentang peralihan fasa kuantum, struktur keterjalin, dan susunan magnet. Secara klasik, mengira tenaga keadaan-asas yang tepat menjadi tidak tertangani apabila bilangan spin bertambah, kerana dimensi ruang Hilbert berskala secara eksponen sebagai untuk spin. Ini menjadikannya calon semula jadi untuk simulasi kuantum.
Penyelesai Nilai Eigen Kuantum Variatif (VQE) adalah algoritma kuantum-klasik hibrid yang direka untuk menganggar tenaga keadaan-asas Hamiltonian. Ia berfungsi dengan menyediakan keadaan kuantum berparameter (dipanggil ansatz) pada komputer kuantum dan mengukur nilai jangkaan . Pengoptimum klasik kemudian menyesuaikan parameter secara berulang untuk meminimumkan tenaga ini, memanfaatkan prinsip variatif yang menjamin bahawa tenaga yang diukur sentiasa merupakan batas atas kepada tenaga keadaan-asas yang sebenar.
Dalam tutorial ini, kita menggunakan ansatz efficient_su2 daripada pustaka Circuit Qiskit, yang membina lapisan putaran satu-qubit dan get berjalin. Pengoptimuman dijalankan menggunakan algoritma Simultaneous Perturbation Stochastic Approximation (SPSA), yang sesuai untuk perkakasan kuantum berderau kerana ia menganggar kecerunan menggunakan hanya dua penilaian fungsi setiap lelaran tanpa mengira bilangan parameter.
Keperluan
Sebelum memulakan tutorial ini, pastikan anda telah memasang perkara berikut:
- Qiskit SDK v2.0 atau lebih baharu, dengan sokongan visualisasi
- Qiskit Runtime v0.44 atau lebih baharu (
pip install qiskit-ibm-runtime)
Persediaan
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime
import numpy as np
import matplotlib.pyplot as plt
from typing import Sequence
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import BaseEstimatorV2
from qiskit.circuit.library import XGate
from qiskit.circuit.library import efficient_su2
from qiskit.transpiler import PassManager
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)
from qiskit_ibm_runtime import QiskitRuntimeService, Session, EstimatorV2
def visualize_results(results):
plt.plot(results["cost_history"], lw=2)
plt.xlabel("Number of function evaluations")
plt.ylabel("Energy")
plt.show()
Contoh skala kecil
Dalam bahagian ini, kita akan melalui setiap langkah corak Qiskit pada skala kecil, menerangkan komponen utama semasa kita membina aliran kerja.
Langkah 1: Petakan input klasik kepada masalah kuantum
- Input: Bilangan spin
- Output: Ansatz dan Hamiltonian yang memodelkan rantaian Heisenberg
Bina ansatz dan Hamiltonian yang memodelkan rantaian Heisenberg 10-spin. Dalam langkah ini, kita akan membina Hamiltonian Heisenberg 10-spin melalui peta gandingan backend yang paling kurang sibuk dan menyediakan ansatz efficient_su2.
num_spins = 10
ansatz = efficient_su2(num_qubits=num_spins, reps=2)
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, min_num_qubits=num_spins, simulator=False
)
coupling = backend.target.build_coupling_map()
reduced_coupling = coupling.reduce(list(range(num_spins)))
edge_list = reduced_coupling.graph.edge_list()
ham_list = []
for edge in edge_list:
ham_list.append(("ZZ", edge, 0.5))
ham_list.append(("YY", edge, 0.5))
ham_list.append(("XX", edge, 0.5))
for qubit in reduced_coupling.physical_qubits:
ham_list.append(("Z", [qubit], np.random.random() * 2 - 1))
hamiltonian = SparsePauliOp.from_sparse_list(ham_list, num_qubits=num_spins)
ansatz.draw("mpl", style="iqp")

Langkah 2: Optimumkan masalah untuk pelaksanaan perkakasan kuantum
- Input: Circuit abstrak, boleh diperhatikan
- Output: Circuit sasaran dan boleh diperhatikan, dioptimumkan untuk QPU yang dipilih
Gunakan fungsi generate_preset_pass_manager daripada Qiskit untuk menjana rutin pengoptimuman secara automatik bagi Circuit kita berkenaan dengan QPU yang dipilih. Kita pilih optimization_level=3, yang memberikan tahap pengoptimuman tertinggi bagi pengurus laluan pratetap. Kita juga menyertakan laluan penjadualan ALAPScheduleAnalysis dan PadDynamicalDecoupling untuk mengurangkan ralat dekoherensi.
target = backend.target
pm = generate_preset_pass_manager(optimization_level=3, target=target)
pm.scheduling = PassManager(
[
ALAPScheduleAnalysis(durations=target.durations()),
PadDynamicalDecoupling(
durations=target.durations(),
dd_sequence=[XGate(), XGate()],
pulse_alignment=target.pulse_alignment,
),
]
)
isa_ansatz = pm.run(ansatz)
isa_observable = hamiltonian.apply_layout(isa_ansatz.layout)
isa_ansatz.draw("mpl", scale=0.6, style="iqp", fold=-1, idle_wires=False)

Langkah 3: Laksanakan menggunakan primitif Qiskit
- Input: Circuit sasaran dan boleh diperhatikan
- Output: Keputusan pengoptimuman
Minimumkan tenaga keadaan-asas sistem yang dianggarkan dengan mengoptimumkan parameter Circuit. Gunakan primitif Estimator daripada Qiskit Runtime untuk menilai fungsi kos semasa pengoptimuman.
Memandangkan kita telah mengoptimumkan Circuit untuk backend dalam Langkah 2, kita boleh mengelak transpilasi pada pelayan Runtime dengan menetapkan skip_transpilation=True dan menghantar Circuit yang telah dioptimumkan. Untuk demo ini, kita akan jalankan pada QPU menggunakan primitif qiskit-ibm-runtime. Untuk menjalankan dengan primitif berasaskan statevector qiskit, gantikan blok kod yang menggunakan primitif Qiskit Runtime dengan blok yang dikomentari.
Dalam tutorial ini kita menggunakan Simultaneous Perturbation Stochastic Approximation (SPSA), iaitu pengoptimum berasaskan kecerunan. Seterusnya kita berikan pengenalan ringkas kepadanya, dan menyediakan kod untuk melaksanakan SPSA menggunakan Qiskit v2.0.
Memperkenalkan SPSA
Simultaneous Perturbation Stochastic Approximation (SPSA) [1] ialah algoritma pengoptimuman yang menganggar seluruh vektor kecerunan menggunakan hanya dua panggilan fungsi pada setiap lelaran. Biar ialah fungsi kos dengan parameter yang hendak dioptimumkan, dan ialah vektor parameter pada langkah ke- lelaran. Untuk mengira kecerunan, satu vektor rawak bersaiz diwujudkan, di mana setiap elemen , , disampel secara seragam daripada . Seterusnya, setiap elemen vektor rawak didarab dengan nilai kecil untuk mewujudkan gangguan rawak. Kecerunan kemudiannya dianggar sebagai
Secara intuitif, memandangkan gangguan rawak digunakan semasa anggaran kecerunan, adalah dijangka bahawa penyelewengan kecil dalam nilai tepat yang datang dari hingar boleh ditoleransi dan diambil kira. Malah, SPSA khususnya diketahui tahan terhadap hingar, dan hanya memerlukan dua panggilan perkakasan bagi setiap lelaran. Oleh itu, ia adalah salah satu pengoptimum yang sangat disukai untuk melaksanakan algoritma variatif.
Dalam tutorial ini, hiperparameter bagi lelaran ke-, dan , dikira sebagai
di mana nilai tetap diambil sebagai , , , , dan . Nilai-nilai ini dipilih daripada [2]. Penalaan hiperparameter yang sesuai adalah perlu untuk mendapatkan prestasi yang baik daripada SPSA.
def spsa(
fun, x0, args=(), A=30, alpha=0.9, a=0.3, c=0.1, gamma=0.4, maxiter=100
):
nparams = len(x0)
x = np.copy(x0)
for i in range(maxiter):
a_i = a / (A + i + 1) ** alpha
c_i = c / (i + 1) ** gamma
delta_i = np.random.choice([-1, 1], nparams)
# two hardware calls
eval_1 = fun(x + c_i * delta_i, *args)
eval_2 = fun(x - c_i * delta_i, *args)
# compute the gradient and update the parameters
grad = (eval_1 - eval_2) / (2 * c_i) * np.reciprocal(delta_i)
x = x - a_i * grad
return x
def cost_func(
params: Sequence,
ansatz: QuantumCircuit,
hamiltonian: SparsePauliOp,
estimator: BaseEstimatorV2,
cost_history_dict: dict,
) -> float:
"""Ground state energy evaluation."""
energy = (
estimator.run([(ansatz, hamiltonian, [params])]).result()[0].data.evs
)
cost_history_dict["iters"] += 1
cost_history_dict["prev_vector"] = list(params)
cost_history_dict["cost_history"].append(float(energy[0]))
print(
f"Fx Iters. done: {cost_history_dict['iters']} [Current cost: {round(energy[0], 5)}]",
end="\r",
)
return energy
def solve(x0, isa_ansatz, isa_observable, maxiter=150):
cost_history_dict = {
"prev_vector": None,
"iters": 0,
"cost_history": [],
"y_min": None,
}
# Evaluate the problem using a QPU via Qiskit IBM Runtime
with Session(backend=backend) as session:
estimator = EstimatorV2(mode=session)
estimator.skip_transpilation = True
estimator.options.environment.job_tags = ["TUT_HSVQE"]
x_opt = spsa(
cost_func,
x0=x0,
args=(isa_ansatz, isa_observable, estimator, cost_history_dict),
maxiter=maxiter,
)
y_min = cost_func(
x_opt, isa_ansatz, isa_observable, estimator, cost_history_dict
)
return y_min, cost_history_dict
np.random.seed(42)
num_params = ansatz.num_parameters
params = 2 * np.pi * np.random.random(num_params)
Di sini kita tetapkan maxiter = 50. Perlu diingat bahawa memandangkan setiap lelaran memerlukan dua panggilan fungsi untuk mengira kecerunan, jumlah panggilan fungsi akan menjadi . maxiter boleh ditingkatkan kepada sebarang nilai yang lebih tinggi untuk anggaran tenaga yang lebih baik.
maxiter = 50
spsa_min, spsa_history = solve(
params, isa_ansatz, isa_observable, maxiter=maxiter
)
Fx Iters. done: 101 [Current cost: -3.03843]
Langkah 4: Proses pasca dan kembalikan keputusan dalam format klasik yang dikehendaki
- Input: Anggaran tenaga keadaan-asas semasa pengoptimuman
- Output: Tenaga keadaan-asas yang dianggarkan
print(f"Estimated ground state energy: {spsa_min}")
Estimated ground state energy: [-3.03842968]
results = {
"spsa": spsa_history,
}
visualize_results(spsa_history)
Contoh perkakasan skala besar
Contoh perkakasan skala besar tidak disertakan dalam tutorial ini. Apabila bilangan qubit meningkat, VQE menghadapi cabaran besar disebabkan fenomena dataran tandus: kecerunan fungsi kos hilang secara eksponen mengikut saiz sistem, menjadikan pengoptimuman secara praktikal tidak boleh dilaksanakan untuk litar yang besar. Digabungkan dengan hingar perkakasan, ini bermakna mengembangkan VQE kepada rantaian spin yang lebih besar tidak menghasilkan keputusan yang boleh dihasilkan semula secara boleh dipercayai. Untuk pendekatan yang mengatasi batasan ini, lihat bahagian Langkah Seterusnya di bawah.
Cabaran
Kini kamu sudah mempunyai pelaksanaan VQE yang berfungsi untuk rantaian Heisenberg, cuba perkara berikut:
- Eksperimen dengan kedalaman ansatz: Ubah suai parameter
repsdalamefficient_su2(contohnya, cubareps=1danreps=3). Bagaimana kedalaman ansatz mempengaruhi tenaga keadaan-asas yang dianggarkan dan kelajuan penumpuan? Pada titik manakah kamu memerhatikan pulangan yang semakin berkurangan atau ketidakstabilan? - Laraskan hiperparameter SPSA: Sesuaikan parameter jadual kadar pembelajaran (
a,c,alpha,gamma,A) dan perhatikan bagaimana ia mempengaruhi penumpuan. Bolehkah kamu menemui konfigurasi yang menumpu lebih cepat daripada nilai lalai yang digunakan di sini? - Bandingkan topologi gandingan: Daripada menggunakan peta gandingan asal backend, cuba bina rantaian linear jiran terdekat yang mudah dan bandingkan hasilnya. Bagaimana kesambungan perkakasan fizikal mempengaruhi kedalaman litar yang ditranspilkan dan anggaran tenaga akhir?
Rujukan
[1] Spall, J. C. (2002). Implementation of the simultaneous perturbation algorithm for stochastic optimization. IEEE Transactions on Aerospace and Electronic Systems, 34(3), 817-823.
[2] Sahin, M. Emre, et al. (2025). Qiskit Machine Learning: an open-source library for quantum machine learning tasks at scale on quantum hardware and classical simulators. arXiv:2505.17756.
Langkah seterusnya
Jika anda mendapati kerja ini menarik, anda mungkin berminat dengan bahan berikut:
- Cuba Sample-based Quantum Diagonalization (SQD): Seperti yang ditunjukkan dalam tutorial ini, VQE menghadapi cabaran pada skala besar disebabkan dataran tandus dan overhed pengukuran yang tinggi. IBM telah membangunkan Sample-based Quantum Diagonalization (SQD) sebagai alternatif yang lebih berskala. Tidak seperti VQE, SQD mengelakkan pengoptimuman variatif sepenuhnya; sebaliknya, komputer kuantum menjana sampel dan komputer klasik memproyeksikan Hamiltonian ke atas subruang yang direntangi oleh sampel-sampel tersebut dan menyelesaikannya secara pepenjuru. Ini memberikan batas atas kepada tenaga keadaan-asas dengan pengukuran yang jauh lebih sedikit dan tanpa kerentanan terhadap dataran tandus. Ikuti tutorial SQD untuk melihat pendekatan ini dalam tindakan.
- Terokai kursus Quantum Diagonalization Algorithms: Dalami pemahaman kamu tentang VQE dan SQD, termasuk pertukaran antara keduanya, dalam kursus Algoritma penyelesaian pepenjuru kuantum di IBM Quantum Learning.