Estimasi energi ground-state rantai Heisenberg dengan VQE
Perkiraan penggunaan: 37 menit pada prosesor Heron (CATATAN: Ini hanya perkiraan. Waktu eksekusi aktualmu bisa berbeda.)
Hasil belajar
Setelah menyelesaikan tutorial ini, kamu diharapkan dapat memahami informasi berikut:
- Cara memodelkan rantai spin Heisenberg sebagai Hamiltonian kuantum menggunakan Qiskit
- Cara menggunakan optimizer SPSA untuk mengestimasi energi ground-state suatu sistem kuantum
- Cara mengeksekusi alur kerja variasional pada hardware kuantum IBM® menggunakan primitif dan sesi Qiskit Runtime
Prasyarat
Disarankan untuk terlebih dahulu mengenal topik-topik berikut:
Latar Belakang
Rantai spin Heisenberg adalah salah satu model yang paling banyak dipelajari dalam fisika materi terkondensasi dan kemagnetan kuantum. Model ini menggambarkan kisi satu dimensi dari spin kuantum yang saling berinteraksi, di mana spin-spin yang berdekatan saling terhubung melalui interaksi pertukaran. Hamiltonian untuk model Heisenberg isotropik dengan medan magnet eksternal diberikan oleh:
di mana , , dan adalah operator Pauli yang bekerja pada situs , jumlah berjalan atas pasangan tetangga terdekat, adalah konstanta kopling pertukaran (isotropik dalam tutorial ini), dan mewakili medan magnet eksternal yang bergantung pada situs. Dalam tutorial ini, nilai medan magnet diambil secara acak dari interval . Perlu diperhatikan bahwa dalam implementasi di bawah ini, himpunan pasangan "tetangga terdekat" ditentukan oleh kopling native backend hardware di antara qubit pertama, yang mungkin tidak membentuk rantai linear yang ketat tergantung pada topologi perangkat.
Memahami energi ground-state dari Hamiltonian ini sangat penting dalam fisika. State dasar mengkodekan informasi tentang transisi fase kuantum, struktur keterikatan (entanglement), dan pemesanan magnetik. Secara klasik, menghitung energi ground-state yang tepat menjadi sulit dilakukan seiring bertambahnya jumlah spin, karena dimensi ruang Hilbert bertumbuh secara eksponensial sebagai untuk spin. Hal ini menjadikannya kandidat alami untuk simulasi kuantum.
Variational Quantum Eigensolver (VQE) adalah algoritma hibrida kuantum-klasik yang dirancang untuk mengestimasi energi ground-state dari suatu Hamiltonian. Algoritma ini bekerja dengan menyiapkan state kuantum berparameter (disebut ansatz) pada komputer kuantum dan mengukur nilai ekspektasi . Optimizer klasik kemudian secara iteratif menyesuaikan parameter untuk meminimalkan energi ini, memanfaatkan prinsip variasional yang menjamin bahwa energi yang terukur selalu merupakan batas atas dari energi ground-state yang sebenarnya.
Dalam tutorial ini, kita menggunakan ansatz efficient_su2 dari library sirkuit Qiskit, yang membangun lapisan-lapisan rotasi qubit tunggal dan gerbang entangling. Optimasi dilakukan menggunakan algoritma Simultaneous Perturbation Stochastic Approximation (SPSA), yang cocok untuk hardware kuantum yang berisik karena mengestimasi gradien hanya dengan dua evaluasi fungsi per iterasi terlepas dari jumlah parameter.
Persyaratan
Sebelum memulai tutorial ini, pastikan kamu sudah menginstal hal-hal berikut:
- Qiskit SDK v2.0 atau lebih baru, dengan dukungan visualisasi
- Qiskit Runtime v0.44 atau lebih baru (
pip install qiskit-ibm-runtime)
Setup
# 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 bagian ini, kita akan membahas setiap langkah dari pola Qiskit dalam skala kecil, menjelaskan komponen-komponen kunci saat kita membangun alur kerja tersebut.
Langkah 1: Memetakan input klasik ke masalah kuantum
- Input: Jumlah spin
- Output: Ansatz dan Hamiltonian yang memodelkan rantai Heisenberg
Buat ansatz dan Hamiltonian yang memodelkan rantai Heisenberg 10-spin. Dalam langkah ini, kita akan membangun Hamiltonian Heisenberg 10-spin berdasarkan peta kopling backend yang paling tidak sibuk dan menyiapkan 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: Mengoptimalkan masalah untuk eksekusi hardware kuantum
- Input: Circuit abstrak, observable
- Output: Target Circuit dan observable, dioptimalkan untuk QPU yang dipilih
Gunakan fungsi generate_preset_pass_manager dari Qiskit untuk secara otomatis menghasilkan rutinitas optimasi untuk Circuit kita terhadap QPU yang dipilih. Kita pilih optimization_level=3, yang memberikan tingkat optimasi tertinggi dari preset pass manager. Kita juga menyertakan scheduling pass ALAPScheduleAnalysis dan PadDynamicalDecoupling untuk menekan kesalahan 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: Eksekusi menggunakan primitif Qiskit
- Input: Target Circuit dan observable
- Output: Hasil optimasi
Minimalkan estimasi energi ground-state sistem dengan mengoptimalkan parameter Circuit. Gunakan primitif Estimator dari Qiskit Runtime untuk mengevaluasi fungsi cost selama optimasi.
Karena kita sudah mengoptimalkan Circuit untuk backend di Langkah 2, kita bisa menghindari transpilasi di server Runtime dengan mengatur skip_transpilation=True dan melewatkan Circuit yang sudah dioptimalkan. Untuk demo ini, kita akan menjalankan pada QPU menggunakan primitif qiskit-ibm-runtime. Untuk menjalankan dengan primitif berbasis statevector qiskit, ganti blok kode yang menggunakan primitif Qiskit Runtime dengan blok yang dikomentari.
Dalam tutorial ini kita menggunakan Simultaneous Perturbation Stochastic Approximation (SPSA), yang merupakan optimizer berbasis gradien. Berikut ini kita berikan pengenalan singkat tentangnya, dan menyediakan kode untuk mengimplementasikan SPSA menggunakan Qiskit v2.0.
Memperkenalkan SPSA
Simultaneous Perturbation Stochastic Approximation (SPSA) [1] adalah algoritma optimasi yang memperkirakan seluruh vektor gradien hanya menggunakan dua pemanggilan fungsi di setiap iterasi. Misalkan adalah fungsi cost dengan parameter yang akan dioptimalkan, dan adalah vektor parameter pada langkah iterasi ke-. Untuk menghitung gradien, dibuat vektor acak berukuran , di mana setiap elemen , , diambil secara seragam dari . Selanjutnya, setiap elemen vektor acak dikalikan dengan nilai kecil untuk membuat perturbasi acak. Gradien kemudian diestimasi sebagai
Secara intuitif, karena perturbasi acak diterapkan selama estimasi gradien, diharapkan bahwa deviasi kecil pada nilai eksak yang berasal dari noise dapat ditoleransi dan diperhitungkan. Bahkan, SPSA khususnya dikenal sangat tahan terhadap noise, dan hanya memerlukan dua pemanggilan hardware untuk setiap iterasi. Oleh karena itu, ini adalah salah satu optimizer yang sangat disukai untuk mengimplementasikan algoritma variasional.
Dalam tutorial ini, hyperparameter untuk iterasi ke-, dan , dihitung sebagai
di mana nilai konstantanya adalah , , , , dan . Nilai-nilai ini dipilih dari [2]. Penyetelan hyperparameter yang tepat diperlukan untuk mendapatkan performa yang baik dari 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 mengatur maxiter = 50. Perlu diperhatikan bahwa karena setiap iterasi memerlukan dua pemanggilan fungsi untuk menghitung gradien, total jumlah pemanggilan fungsi akan menjadi . Nilai maxiter bisa ditingkatkan ke nilai yang lebih tinggi untuk estimasi energi 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: Post-process dan kembalikan hasil dalam format klasik yang diinginkan
- Input: Estimasi energi ground-state selama optimasi
- Output: Estimasi energi ground-state
print(f"Estimated ground state energy: {spsa_min}")
Estimated ground state energy: [-3.03842968]
results = {
"spsa": spsa_history,
}
visualize_results(spsa_history)
Contoh hardware skala besar
Contoh hardware skala besar tidak disertakan dalam tutorial ini. Seiring bertambahnya jumlah qubit, VQE menghadapi tantangan besar akibat fenomena barren plateau: gradien dari fungsi cost menghilang secara eksponensial seiring ukuran sistem, sehingga optimasi menjadi tidak layak secara praktis untuk sirkuit besar. Ditambah dengan noise hardware, ini berarti menskalakan VQE ke rantai spin yang lebih besar tidak menghasilkan hasil yang dapat direproduksi secara andal. Untuk pendekatan yang mengatasi keterbatasan ini, lihat bagian Langkah Berikutnya di bawah.
Tantangan
Sekarang kamu sudah memiliki implementasi VQE yang berfungsi untuk rantai Heisenberg, coba hal-hal berikut:
- Bereksperimen dengan kedalaman ansatz: Ubah parameter
repsdalamefficient_su2(misalnya, cobareps=1danreps=3). Bagaimana kedalaman ansatz memengaruhi estimasi energi ground-state dan kecepatan konvergensi? Pada titik mana kamu mulai mengamati hasil yang menurun atau ketidakstabilan? - Menyetel hyperparameter SPSA: Sesuaikan parameter jadwal learning rate (
a,c,alpha,gamma,A) dan amati bagaimana pengaruhnya terhadap konvergensi. Bisakah kamu menemukan konfigurasi yang konvergen lebih cepat dari nilai default yang digunakan di sini? - Membandingkan topologi kopling: Alih-alih menggunakan peta kopling native backend, coba bangun rantai linear tetangga terdekat yang sederhana dan bandingkan hasilnya. Bagaimana konektivitas hardware fisik memengaruhi kedalaman sirkuit yang ditranspilasi dan estimasi energi akhir?
Referensi
[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 Berikutnya
Jika kamu menemukan pekerjaan ini menarik, kamu mungkin tertarik dengan materi berikut:
- Coba Sample-based Quantum Diagonalization (SQD): Seperti yang ditunjukkan dalam tutorial ini, VQE menghadapi tantangan pada skala besar akibat barren plateau dan overhead pengukuran yang tinggi. IBM telah mengembangkan Sample-based Quantum Diagonalization (SQD) sebagai alternatif yang lebih skalabel. Tidak seperti VQE, SQD sepenuhnya menghindari optimasi variasional; sebaliknya, komputer kuantum menghasilkan sampel dan komputer klasik memproyeksikan Hamiltonian ke subruang yang direntang oleh sampel-sampel tersebut lalu mendiagonalisasikannya. Ini memberikan batas atas untuk energi ground-state dengan jauh lebih sedikit pengukuran dan tanpa kerentanan terhadap barren plateau. Ikuti tutorial SQD untuk melihat pendekatan ini beraksi.
- Jelajahi kursus Quantum Diagonalization Algorithms: Perdalam pemahamanmu tentang VQE dan SQD, termasuk trade-off keduanya, dalam kursus Quantum diagonalization algorithms di IBM Quantum Learning.