Langkau ke kandungan utama

Bermula dengan formula berbilang hasil darab (MPF)

Mula dengan Formula Berbilang Hasil Darab (MPF)​

Versi pakej

Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan menggunakan versi ini atau yang lebih baharu.

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 pakej qiskit-addon-mpf, menggunakan evolusi masa model Ising sebagai contoh. Dengan pakej ini, anda boleh membina Formula Berbilang Hasil Darab (MPF) yang boleh mencapai ralat Trotter yang lebih rendah pada pengukuran observable. Alat yang disediakan membolehkan anda menentukan pemberat MPF yang dipilih, yang kemudiannya boleh digunakan untuk menggabungkan semula nilai jangkaan yang dianggarkan dari beberapa Circuit evolusi masa, setiap satu dengan bilangan langkah Trotter yang berbeza.

Mulakan dengan mempertimbangkan Hamiltonian model Ising dengan 10 tapak:

HIsing=βˆ‘i=19Ji,(i+1)ZiZi+1+βˆ‘i=110hiXiH_{\text{Ising}} = \sum_{i=1}^9 J_{i,(i+1)}Z_iZ_{i+1} + \sum_{i=1}^{10} h_i X_i

di mana Ji,(i+1)J_{i,(i+1)} adalah kekuatan gandingan dan hih_i adalah kekuatan medan magnet luaran. Untuk menyediakan masalah, observable yang akan diukur adalah jumlah pemagnetan sistem

⟨M⟩=βˆ‘i=110⟨Zi⟩.\langle M \rangle = \sum_{i=1}^{10} \langle Z_i \rangle.

Coretan kod di bawah menyediakan Hamiltonian rantai Ising menggunakan pakej qiskit-addon-utils, dan menentukan 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])

Seterusnya anda menyediakan MPF. Pilihan pertama yang perlu dibuat adalah sama ada pekali akan bersifat statik (bebas masa) atau dinamik; tutorial ini menggunakan MPF statik. Pilihan seterusnya adalah set nilai kjk_j. Ini menentukan berapa banyak sebutan yang akan ada dalam MPF, serta berapa banyak langkah Trotter yang digunakan oleh setiap sebutan untuk mensimulasikan evolusi masa. Pemilihan nilai kjk_j adalah heuristik, jadi anda perlu mendapatkan set nilai kjk_j yang "baik" sendiri. Baca panduan untuk mencari set nilai yang baik di penghujung halaman bermula.

Kemudian, setelah nilai kjk_j ditentukan, anda boleh menyediakan sistem persamaan, Ax=bAx=b, untuk diselesaikan. Matriks AA juga ditentukan oleh formula hasil darab yang digunakan. Pilihan di sini adalah peringkat-nya, yang ditetapkan kepada 22 dalam contoh ini, serta sama ada formula hasil darab hendaklah simetri, yang ditetapkan kepada True untuk contoh ini. Coretan kod di bawah memilih jumlah masa untuk mengevolusi sistem, nilai kjk_j yang digunakan, dan set persamaan untuk diselesaikan menggunakan kaedah 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 dibentuk, ia boleh diselesaikan sama ada secara tepat atau melalui model anggaran menggunakan jumlah kuasa dua (atau norma Frobenius untuk pekali dinamik; lihat rujukan API untuk maklumat lanjut). Pilihan untuk menggunakan model anggaran biasanya timbul apabila norma pekali untuk set nilai kjk_j yang dipilih dianggap terlalu tinggi dan set nilai kjk_j yang berbeza tidak boleh dipilih. Panduan ini menunjukkan kedua-duanya untuk membandingkan keputusan.

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 ]
nota

Objek LSE juga mempunyai kaedah LSE.solve(), yang akan menyelesaikan sistem persamaan secara tepat. Sebab setup_exact_problem() digunakan dalam panduan ini adalah untuk menunjukkan antara muka yang disediakan oleh kaedah anggaran yang lain.

Sediakan dan laksanakan Circuit Trotter​

Setelah pekali xjx_j diperoleh, langkah terakhir adalah menjana Circuit evolusi masa untuk peringkat dan set langkah kjk_j yang dipilih bagi MPF. Pakej qiskit-addon-utils boleh mempercepatkan 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)

Output of the previous code cell

circuits[1].draw("mpl", fold=-1)

Output of the previous code cell

circuits[2].draw("mpl", fold=-1)

Output of the previous code cell

Setelah Circuit ini dibina, anda boleh mentranspilnya dan melaksanakannya menggunakan QPU. Untuk contoh ini, kita hanya akan menggunakan salah satu simulator bebas hingar untuk menunjukkan cara ralat Trotter dikurangkan.

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 keputusan​

Setelah Circuit dilaksanakan, merekonstruksi keputusan adalah agak mudah. Seperti yang disebutkan dalam halaman gambaran keseluruhan MPF, observable kita direkonstruksi melalui jumlah berwajaran

⟨M⟩=βˆ‘jxj⟨Mj⟩.\langle M \rangle = \sum_j x_j \langle M_j \rangle.

di mana xjx_j adalah pekali yang kita temui dan ⟨Mj⟩\langle M_j \rangle adalah anggaran observable βˆ‘i⟨Zi⟩\sum_i \langle Z_i \rangle untuk setiap Circuit. Kemudian kita boleh bandingkan keputusan yang diperoleh dengan nilai tepat menggunakan pakej 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 anda dapat melihat bahawa MPF telah mengurangkan ralat Trotter berbanding dengan yang diperoleh hanya dengan satu PF dengan kj=19k_j=19. Walau bagaimanapun, model anggaran menghasilkan nilai jangkaan yang lebih buruk daripada model tepat. Ini menunjukkan kepentingan menggunakan kriteria penumpuan yang ketat pada model anggaran dan mencari set nilai kjk_j yang "baik".

Source: IBM Quantum docs β€” updated 13 Feb 2026
English version on doQumentation β€” updated 7 Mei 2026
This translation based on the English version of 11 Mac 2026