Memulai dengan multi-product formulas (MPF)
Mulai dengan Multi-product formulas (MPFs)β
Versi paket
Kode di halaman ini dikembangkan menggunakan persyaratan berikut. Kami menyarankan menggunakan versi ini atau yang lebih baru.
qiskit[all]~=2.3.0
qiskit-addon-utils~=0.3.0
qiskit-addon-mpf~=0.3.0
scipy~=1.16.3
Panduan ini menunjukkan cara menggunakan paket qiskit-addon-mpf, dengan evolusi waktu model Ising sebagai contoh. Dengan paket ini, kamu bisa membangun Multi-Product Formula (MPF) yang dapat mencapai error Trotter lebih rendah pada pengukuran observable. Alat yang disediakan memungkinkan kamu menentukan bobot dari MPF yang dipilih, yang kemudian bisa digunakan untuk menggabungkan kembali nilai ekspektasi yang diestimasi dari beberapa Circuit evolusi waktu, masing-masing dengan jumlah langkah Trotter yang berbeda.
Mulailah dengan mempertimbangkan Hamiltonian dari model Ising dengan 10 situs:
di mana adalah kekuatan kopling dan adalah kekuatan medan magnet eksternal. Untuk menyiapkan masalah ini, observable yang akan diukur adalah total magnetisasi sistem
Cuplikan kode di bawah ini menyiapkan Hamiltonian dari rantai Ising menggunakan paket qiskit-addon-utils, dan mendefinisikan observable yang akan diukur.
# Added by doQumentation β required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-mpf qiskit-addon-utils scipy
from qiskit.transpiler import CouplingMap
from qiskit.synthesis import SuzukiTrotter
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import StatevectorEstimator
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_addon_utils.problem_generators import (
generate_xyz_hamiltonian,
generate_time_evolution_circuit,
)
from qiskit_addon_mpf.costs import (
setup_exact_problem,
setup_sum_of_squares_problem,
)
from qiskit_addon_mpf.static import setup_static_lse
from scipy.linalg import expm
import numpy as np
# Generate some coupling map to use for this example
coupling_map = CouplingMap.from_line(10, bidirectional=False)
# Get a qubit operator describing the Ising field model
hamiltonian = generate_xyz_hamiltonian(
coupling_map,
coupling_constants=(0.0, 0.0, 1.0),
ext_magnetic_field=(0.4, 0.0, 0.0),
)
print(f"Hamiltonian:\n {hamiltonian}\n")
L = coupling_map.size()
observable = SparsePauliOp.from_sparse_list(
[("Z", [i], 1 / L / 2) for i in range(L)], num_qubits=L
)
print(f"Observable:\n {observable}")
Hamiltonian:
SparsePauliOp(['IIIIIIIZZI', 'IIIIIZZIII', 'IIIZZIIIII', 'IZZIIIIIII', 'IIIIIIIIZZ', 'IIIIIIZZII', 'IIIIZZIIII', 'IIZZIIIIII', 'ZZIIIIIIII', 'IIIIIIIIIX', 'IIIIIIIIXI', 'IIIIIIIXII', 'IIIIIIXIII', 'IIIIIXIIII', 'IIIIXIIIII', 'IIIXIIIIII', 'IIXIIIIIII', 'IXIIIIIIII', 'XIIIIIIIII'],
coeffs=[1. +0.j, 1. +0.j, 1. +0.j, 1. +0.j, 1. +0.j, 1. +0.j, 1. +0.j, 1. +0.j,
1. +0.j, 0.4+0.j, 0.4+0.j, 0.4+0.j, 0.4+0.j, 0.4+0.j, 0.4+0.j, 0.4+0.j,
0.4+0.j, 0.4+0.j, 0.4+0.j])
Observable:
SparsePauliOp(['IIIIIIIIIZ', 'IIIIIIIIZI', 'IIIIIIIZII', 'IIIIIIZIII', 'IIIIIZIIII', 'IIIIZIIIII', 'IIIZIIIIII', 'IIZIIIIIII', 'IZIIIIIIII', 'ZIIIIIIIII'],
coeffs=[0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j,
0.05+0.j, 0.05+0.j, 0.05+0.j])
Selanjutnya kamu menyiapkan MPF. Pilihan pertama yang harus dibuat adalah apakah koefisien akan bersifat statis (tidak bergantung waktu) atau dinamis; tutorial ini menggunakan MPF statis. Pilihan berikutnya adalah sekumpulan nilai . Ini menentukan berapa banyak suku yang akan ada dalam MPF, serta berapa banyak langkah Trotter yang digunakan setiap suku untuk mensimulasikan evolusi waktu. Pemilihan nilai bersifat heuristik, sehingga kamu perlu mendapatkan sekumpulan nilai yang "baik" sendiri. Baca panduan untuk menemukan sekumpulan nilai yang baik di akhir halaman memulai.
Kemudian, setelah nilai ditentukan, kamu bisa menyiapkan sistem persamaan, , untuk diselesaikan. Matriks juga ditentukan oleh formula produk yang digunakan. Pilihannya adalah orde-nya, yang diset ke dalam contoh ini, serta apakah formula produk harus bersifat simetris, yang diset ke True untuk contoh ini. Cuplikan kode di bawah ini memilih total waktu untuk mengevolusi sistem, nilai yang akan digunakan, dan sekumpulan persamaan untuk diselesaikan menggunakan metode qiskit_addon_mpf.static.setup_static_lse.
time = 8.0
trotter_steps = (8, 12, 19)
lse = setup_static_lse(trotter_steps, order=2, symmetric=True)
print(lse)
LSE(A=array([[1.00000000e+00, 1.00000000e+00, 1.00000000e+00],
[1.56250000e-02, 6.94444444e-03, 2.77008310e-03],
[2.44140625e-04, 4.82253086e-05, 7.67336039e-06]]), b=array([1., 0., 0.]))
Setelah sistem persamaan linear diinstansiasi, sistem itu bisa diselesaikan secara eksak atau melalui model aproksimasi menggunakan jumlah kuadrat (atau norma Frobenius untuk koefisien dinamis; lihat referensi API untuk informasi lebih lanjut). Pilihan untuk menggunakan model aproksimasi biasanya muncul ketika norma koefisien untuk sekumpulan nilai yang dipilih dianggap terlalu tinggi dan sekumpulan nilai yang berbeda tidak bisa dipilih. Panduan ini mendemonstrasikan keduanya untuk membandingkan hasilnya.
model_exact, coeffs_exact = setup_exact_problem(lse)
model_approx, coeffs_approx = setup_sum_of_squares_problem(
lse, max_l1_norm=3.0
)
model_exact.solve()
model_approx.solve()
print(f"Exact solution: {coeffs_exact.value}")
print(f"Approximate solution: {coeffs_approx.value}")
Exact solution: [ 0.17239057 -1.19447005 2.02207947]
Approximate solution: [-0.40454257 0.57553173 0.8290123 ]
Objek LSE juga memiliki metode LSE.solve(), yang akan menyelesaikan sistem persamaan secara eksak. Alasan setup_exact_problem() digunakan dalam panduan ini adalah untuk mendemonstrasikan antarmuka yang disediakan oleh metode aproksimasi lainnya.
Siapkan dan jalankan Circuit Trotterβ
Sekarang setelah koefisien diperoleh, langkah terakhir adalah menghasilkan Circuit evolusi waktu untuk orde dan sekumpulan langkah yang dipilih dari MPF. Paket qiskit-addon-utils bisa mempercepat proses ini.
circuits = []
for k in trotter_steps:
circ = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(order=2, reps=k),
time=time,
)
circuits.append(circ)
circuits[0].draw("mpl", fold=-1)
circuits[1].draw("mpl", fold=-1)
circuits[2].draw("mpl", fold=-1)
Setelah Circuit-circuit ini dibuat, kamu bisa melakukan transpilasi dan menjalankannya menggunakan QPU. Untuk contoh ini, kita akan menggunakan salah satu simulator bebas noise untuk mendemonstrasikan bagaimana error Trotter berkurang.
backend = GenericBackendV2(num_qubits=10)
transpiler = generate_preset_pass_manager(
optimization_level=2, backend=backend
)
transpiled_circuits = [transpiler.run(circ) for circ in circuits]
estimator = StatevectorEstimator()
job = estimator.run([(circ, observable) for circ in transpiled_circuits])
result = job.result()
mpf_evs = [res.data.evs for res in result]
print(mpf_evs)
[array(0.23799162), array(0.35754312), array(0.38649906)]
Rekonstruksi hasilβ
Sekarang setelah Circuit-circuit dijalankan, merekonstruksi hasilnya cukup mudah. Seperti yang disebutkan di halaman gambaran umum MPF, observable kita direkonstruksi melalui jumlah berbobot
di mana adalah koefisien yang kita temukan dan adalah estimasi observable untuk setiap Circuit. Kita kemudian bisa membandingkan hasil yang diperoleh dengan nilai eksak menggunakan paket scipy.linalg.
exp_H = expm(-1j * time * hamiltonian.to_matrix())
initial_state = np.zeros(exp_H.shape[0])
initial_state[0] = 1.0
time_evolved_state = exp_H @ initial_state
exact_obs = (
time_evolved_state.conj() @ observable.to_matrix() @ time_evolved_state
)
# Print out the different observable measurements
print(f"Exact value: {exact_obs.real}")
print(f"PF with 19 steps: {mpf_evs[-1]}")
print(f"MPF using exact solution: {mpf_evs @ coeffs_exact.value}")
print(f"MPF using approximate solution: {mpf_evs @ coeffs_approx.value}")
Exact value: 0.4006024248789992
PF with 19 steps: 0.3864990619977402
MPF using exact solution: 0.3954847855979902
MPF using approximate solution: 0.4299121425348959
Di sini kamu bisa melihat bahwa MPF telah mengurangi error Trotter dibandingkan dengan yang diperoleh hanya dengan satu PF dengan . Namun, model aproksimasi menghasilkan nilai ekspektasi yang lebih buruk daripada model eksak. Ini menunjukkan pentingnya menggunakan kriteria konvergensi yang ketat pada model aproksimasi dan menemukan sekumpulan nilai yang "baik".