Langkau ke kandungan utama

Formula berbilang produk untuk mengurangkan ralat Trotter

Anggaran penggunaan: Empat minit pada pemproses Heron r2 (NOTA: Ini hanyalah anggaran sahaja. Masa jalan sebenar anda mungkin berbeza.)

Hasil pembelajaran

  • Bagaimana formula multi-produk (MPF) mengurangkan ralat Trotter dalam simulasi Hamiltonian dengan menggabungkan nilai jangkaan daripada beberapa circuit cetek

  • Bila MPF bermanfaat berbanding formula produk standard dan bila ia bukan alat yang sesuai

  • Bagaimana untuk mengira pekali MPF statik dan dinamik menggunakan pakej qiskit_addon_mpf

  • Bagaimana untuk melaksanakan aliran kerja MPF secara hujung-ke-hujung pada perkakasan IBM Quantum®, termasuk transpilasi, mitigasi ralat, dan pasca-pemprosesan

Prasyarat

Latar belakang

Apakah formula multi-produk?

Apabila mensimulasikan sistem kuantum pada komputer kuantum, tugas utama ialah menganggarkan operator evolusi masa eiHte^{-iHt} untuk Hamiltonian HH. Pendekatan standard menggunakan formula produk (PF), juga dikenali sebagai penguraian Trotter-Suzuki. Ini menguraikan H=a=1dFaH = \sum_{a=1}^d F_a kepada terma yang unitari individunya eiFate^{-iF_a t} mudah dilaksanakan, dan kemudian menganggarkan evolusi penuh sebagai produk tersusun daripada unitari yang lebih ringkas ini.

Formula produk peringkat pertama (Lie-Trotter) ialah:

S1(t):=a=1deiFat,S_1(t) := \prod_{a=1}^d e^{-i F_a t},

yang menyebabkan ralat kuadratik: S1(t)=eiHt+O(t2)S_1(t) = e^{-iHt} + \mathcal{O}(t^2). Formula simetri peringkat lebih tinggi S2χ(t)S_{2\chi}(t), di mana χ\chi melabelkan peringkat formula produk simetri (lihat Ruj. [1]), menumpu lebih pantas sebagai eiHt+O(t2χ+1)e^{-iHt} + \mathcal{O}(t^{2\chi+1}), tetapi dengan kos circuit yang lebih dalam bagi setiap langkah.

Untuk mengurangkan ralat pada peringkat tetap χ\chi, seseorang biasanya membahagikan jumlah masa evolusi tt kepada kk langkah Trotter yang lebih kecil. Setiap langkah menganggarkan eiHt/ke^{-iHt/k} dengan formula produk dan langkah-langkah itu digabungkan:

eiHt[S2χ(t/k)]k.e^{-iHt} \approx \left[S_{2\chi}(t/k)\right]^k.

Untuk formula simetri peringkat 2χ2\chi, ralat Trotter baki kemudian berskala sebagai O ⁣(t2χ+1/k2χ)\mathcal{O}\!\left(t^{2\chi+1} / k^{2\chi}\right). Jadi meningkatkan kk dengan cepat menekan ralat Trotter — tetapi ia juga secara linear mendalamkan circuit, dan pada perkakasan hingar itu bermakna lebih banyak hingar gate yang terkumpul. Ketegangan antara ralat Trotter (memihak kepada kk yang lebih besar) dan hingar perkakasan (memihak kepada kk yang lebih kecil) inilah yang direka untuk diselesaikan oleh formula multi-produk. Perhatikan bahawa MPF adalah tentang menggabungkan hasil daripada pilihan kk yang berbeza pada peringkat χ\chi yang tetap — ia tidak mengubah peringkat formula produk asas.

Formula multi-produk (MPF) [1] membina gabungan linear berpemberat nilai jangkaan yang diperoleh daripada beberapa circuit Trotter yang lebih cetek, setiap satu menggunakan bilangan langkah Trotter yang berbeza k1,k2,,krk_1, k_2, \ldots, k_r (satu set rr bilangan langkah):

AMPF(t)=j=1rxjAkj(t),\langle A \rangle_{\text{MPF}}(t) = \sum_{j=1}^r x_j \, \langle A \rangle_{k_j}(t),

di mana Akj(t)\langle A \rangle_{k_j}(t) ialah nilai jangkaan bagi cerapan AA pada masa tt yang dianggarkan daripada circuit Trotter dengan langkah kjk_j, dan pekali {xj}j=1r\{x_j\}_{j=1}^r dipilih supaya terma ralat-Trotter utama dalam gabungan itu saling membatalkan. Kami akan meninjau semula ungkapan ini dalam Langkah 4, di mana kami menilainya secara eksplisit untuk menggabungkan hasil Trotter kami. Perkara praktikal utama ialah circuit paling dalam dalam MPF hanya memerlukan kmaxk_{\max} langkah, yang jauh lebih kecil daripada kk tunggal yang diperlukan untuk mencapai ralat Trotter berkesan yang sama secara langsung. Circuit yang lebih cetek menjadikan pendekatan MPF lebih sesuai untuk perkakasan hingar.

Bagaimana pekali ditentukan?

Terdapat dua keluarga pekali MPF:

Pekali statik tidak bergantung kepada Hamiltonian, keadaan awal, dan masa evolusi. Ia dijumpai dengan menyelesaikan sistem linear Ax=bAx = b yang menguatkuasakan pembatalan terma ralat Trotter utama. Untuk satu set langkah Trotter {kj}j=1r\{k_j\}_{j=1}^r yang digunakan dengan formula produk simetri peringkat 2χ2\chi, mengembangkan ralat Trotter dalam kuasa songsang kjk_j membawa kepada persamaan kekangan dalam bentuk:

j=1rxj=1,j=1rxjkjηn=0(n=0,,r2),\sum_{j=1}^r x_j = 1, \quad \sum_{j=1}^r \frac{x_j}{k_j^{\eta_n}} = 0 \quad (n = 0, \ldots, r-2),

di mana eksponen integer {ηn}\{\eta_n\} ialah peringkat terma ralat-Trotter berturutan bagi formula produk yang dipilih. Untuk PF simetri peringkat 2χ2\chi, ralat utama dalam [S2χ(t/k)]k\left[S_{2\chi}(t/k)\right]^k berskala sebagai 1/k2χ1/k^{2\chi}, dengan pembetulan seterusnya pada 1/k2χ+2,1/k2χ+4,1/k^{2\chi+2}, 1/k^{2\chi+4}, \ldots — jadi eksponennya ialah ηn=2χ+2n\eta_n = 2\chi + 2n. Untuk PF bukan-simetri, kedua-dua kuasa ganjil dan genap menyumbang dan ηn=2χ+n\eta_n = 2\chi + n. Lihat Ruj. [1] untuk terbitan penuh. Persamaan pertama dalam sistem di atas menjamin ketidakbiasan (MPF menghasilkan semula nilai jangkaan tepat dalam had kjk_j \to \infty), dan baki r1r-1 persamaan secara berturutan membatalkan r1r-1 terma ralat-Trotter pertama. Apabila norma-L1L_1 x1\|x\|_1 yang terhasil terlalu besar (yang memperkuatkan hingar pensampelan), kamu boleh sebaliknya menyelesaikan pengoptimuman anggaran yang menghadkan x1\|x\|_1 sambil meminimumkan Axb\|Ax - b\|.

Pekali dinamik [2], [3] juga bergantung kepada Hamiltonian, keadaan awal, dan masa evolusi tt. Ia meminimumkan jarak norma-Frobenius antara keadaan berevolusi-masa yang sebenar dan penghampiran MPF:

ρ(t)μD(t)F2=1+i,jMij(t)xi(t)xj(t)2iLi(t)xi(t),\|\rho(t) - \mu^D(t)\|_F^2 = 1 + \sum_{i,j} M_{ij}(t)\, x_i(t)\, x_j(t) - 2\sum_i L_i(t)\, x_i(t),

di mana Mij(t)=Tr[ρki(t)ρkj(t)]M_{ij}(t) = \mathrm{Tr}[\rho_{k_i}(t)\,\rho_{k_j}(t)] ialah matriks Gram bagi pertindihan antara keadaan berevolusi-Trotter untuk bilangan langkah yang berbeza ki,kjk_i, k_j, dan Li(t)=Tr[ρ(t)ρki(t)]L_i(t) = \mathrm{Tr}[\rho(t)\,\rho_{k_i}(t)] mengukur pertindihan dengan keadaan tepat (anggaran). Dalam tutorial ini kuantiti-kuantiti ini dikira dengan cekap menggunakan kaedah rangkaian-tensor, khususnya backend berasaskan TeNPy dalam qiskit_addon_mpf.

Bila menggunakan MPF

MPF paling bermanfaat apabila:

  • Kedalaman circuit ialah kesesakan. Jika hingar perkakasan menghadkan kedalaman yang boleh kamu jalankan, gunakan MPF untuk mencapai ketepatan Trotter berkesan yang lebih tinggi daripada circuit yang lebih cetek.

  • Kamu memerlukan nilai jangkaan yang tepat, bukan penyediaan keadaan penuh. MPF beroperasi pada peringkat nilai jangkaan — ia menggabungkan nombor klasik, bukan keadaan kuantum. Oleh itu ia ideal untuk anggaran cerapan apabila menggunakan Estimator primitive.

  • Kamu menggabungkan bilangan bilangan-langkah Trotter yang sederhana. Biasanya menggabungkan r=3r = 355 bilangan langkah kjk_j yang berbeza sudah memadai untuk membatalkan beberapa terma ralat-Trotter utama sambil mengekalkan x1\|x\|_1 pada tahap terkawal.

Bila MPF mungkin tidak membantu

  • Masa evolusi yang sangat singkat. Apabila tt cukup kecil sehingga formula Trotter peringkat rendah tunggal sudah tepat, overhed menjalankan pelbagai circuit adalah tidak perlu.

  • Tugas penyediaan-keadaan. MPF menghasilkan nilai jangkaan yang diperbetulkan, bukan keadaan kuantum yang diperbetulkan. Jika kamu memerlukan keadaan berevolusi-masa yang sebenar (contohnya, sebagai input kepada subrutin kuantum yang lain), MPF tidak terpakai.

  • Bilangan langkah Trotter yang melanggar rejim penumpuan. Terbitan pekali-statik mengembangkan setiap [S2χ(t/kj)]kj\left[S_{2\chi}(t/k_j)\right]^{k_j} individu sebagai siri dalam t/kjt/k_j; pengembangan ini hanya menumpu dengan baik apabila t/kmin1t/k_{\min} \lesssim 1. Jika kmink_{\min} dipilih terlalu kecil untuk tt yang diberikan, circuit paling cetek berada jauh di luar rejim gangguan, terma ralat peringkat-lebih-tinggi yang tidak dibatalkan oleh MPF menjadi besar, dan pembatalan mungkin memerlukan pekali yang besar. Norma-L1L_1 x1\|x\|_1 ialah diagnostik praktikal: apabila x11\|x\|_1 \gg 1, overhed pensampelan x12\propto \|x\|_1^2 mungkin mengatasi pengurangan ralat-Trotter. Lihat panduan mengenai memilih langkah Trotter untuk butiran.

Apa yang tutorial ini merangkumi

Tutorial ini melalui aliran kerja MPF hujung-ke-hujung dalam dua peringkat. Pertama, satu contoh simulator skala kecil (rantaian Heisenberg 10-qubit) menunjukkan cara menyediakan masalah, mengira pekali MPF statik dan dinamik, dan membandingkan nilai jangkaan yang terhasil dengan pendiagonalan tepat. Kemudian, satu contoh perkakasan skala besar (rantaian XXZ 50-qubit) menunjukkan cara mentranspilasi, melaksanakan pada perkakasan IBM Quantum dengan mitigasi ralat, dan pasca-memproses hasil menggunakan pekali MPF. Sepanjangnya, kami menggunakan pakej qiskit_addon_mpf bersama alat Qiskit standard.

Keperluan

Sebelum memulakan tutorial ini, pastikan kamu telah memasang perkara berikut:

  • Qiskit SDK v2.0 atau lebih baru, dengan sokongan visualisasi

  • Qiskit Runtime v0.22 atau lebih baru (pip install qiskit-ibm-runtime)

  • Simulator Qiskit Aer (pip install qiskit-aer)

  • MPF Qiskit addon dengan backend TeNPy (pip install "qiskit-addon-mpf[tenpy]")

  • Utiliti addon Qiskit (pip install qiskit-addon-utils)

  • SciPy (pip install scipy)

Persediaan

Di bawah kami mengumpul semua import pakej yang digunakan sepanjang tutorial ini dalam satu sel. Kami juga mentakrifkan pass transpiler CollectAndCollapse yang menggabungkan putaran rxx dan ryy bersebelahan menjadi satu XXPlusYYGate. Pass ini digunakan semasa pembinaan circuit dalam Langkah 1 (untuk mengekalkan bilangan gate rendah) dan secara tidak langsung apabila kami mengekstrak struktur berlapis untuk MPF dinamik dalam Langkah 4 (TeNPy mengharapkan gate dua-qubit, bukan pasangan putaran yang tidak digabungkan).

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-addon-mpf qiskit-addon-utils qiskit-aer qiskit-ibm-runtime scipy
import warnings

import numpy as np
import matplotlib.pyplot as plt
from functools import partial
from copy import deepcopy

from qiskit import QuantumCircuit
from qiskit.quantum_info import Pauli, SparsePauliOp, Statevector
from qiskit.synthesis import SuzukiTrotter
from qiskit.transpiler import CouplingMap, PassManager
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import XXPlusYYGate
from qiskit.transpiler.passes.optimization.collect_and_collapse import (
CollectAndCollapse,
collect_using_filter_function,
collapse_to_operation,
)

from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService

from qiskit_addon_utils.problem_generators import (
generate_xyz_hamiltonian,
generate_time_evolution_circuit,
)
from qiskit_addon_utils.slicing import slice_by_depth
from qiskit_addon_mpf.static import setup_static_lse
from qiskit_addon_mpf.dynamic import setup_dynamic_lse
from qiskit_addon_mpf.costs import (
setup_exact_problem,
setup_sum_of_squares_problem,
setup_frobenius_problem,
)
from qiskit_addon_mpf.backends.tenpy_layers import (
LayerModel,
LayerwiseEvolver,
)
from qiskit_addon_mpf.backends.tenpy_tebd import MPOState, MPS_neel_state

from scipy.linalg import expm

# Suppress TeNPy's `unit_cell_width` future-API warning. The default
# (`unit_cell_width=len(sites)`) is correct for Chain lattices, which is what
# `CouplingMap.from_line(...)` produces here, so the warning is informational.
warnings.filterwarnings(
"ignore",
message=r".*unit_cell_width.*",
category=UserWarning,
)

# --- Helper: collect XX + YY rotations into a single gate ---
def filter_function(node):
return node.op.name in {"rxx", "ryy"}

collect_function = partial(
collect_using_filter_function,
filter_function=filter_function,
split_blocks=True,
min_block_size=1,
)

def collapse_to_xx_plus_yy(block):
param = 0.0
for node in block.data:
param += node.operation.params[0]
return XXPlusYYGate(param)

collapse_function = partial(
collapse_to_operation,
collapse_function=collapse_to_xx_plus_yy,
)

pm = PassManager()
pm.append(CollectAndCollapse(collect_function, collapse_function))

Contoh simulator skala kecil

Langkah 1: Petakan input klasik ke masalah kuantum

Kami bermula dengan model Heisenberg 10-qubit pada satu garisan, menggunakan keadaan Néel 010101\vert 0101\ldots01 \rangle sebagai keadaan awal. Hamiltonian ialah:

H^Heis=Ji=1L1(XiXi+1+YiYi+1+ZiZi+1),\hat{\mathcal{H}}_{\text{Heis}} = J \sum_{i=1}^{L-1} \left(X_i X_{i+1} + Y_i Y_{i+1} + Z_i Z_{i+1}\right),

di mana JJ ialah kekuatan gandingan jiran-terdekat. Kami mengukur korelator ZZ ZL/21ZL/2Z_{L/2-1} Z_{L/2} pada sepasang qubit di tengah rantaian, dan menggunakan langkah Trotter kj=[1,2,4]k_j = [1, 2, 4] dengan formula produk peringkat kedua.

L = 10

# Generate coupling map and Hamiltonian
coupling_map = CouplingMap.from_line(L, bidirectional=False)

hamiltonian = generate_xyz_hamiltonian(
coupling_map,
coupling_constants=(1.0, 1.0, 1.0),
ext_magnetic_field=(0.0, 0.0, 0.0),
)
print(hamiltonian)
SparsePauliOp(['IIIIIIIXXI', 'IIIIIIIYYI', 'IIIIIIIZZI', 'IIIIIXXIII', 'IIIIIYYIII', 'IIIIIZZIII', 'IIIXXIIIII', 'IIIYYIIIII', 'IIIZZIIIII', 'IXXIIIIIII', 'IYYIIIIIII', 'IZZIIIIIII', 'IIIIIIIIXX', 'IIIIIIIIYY', 'IIIIIIIIZZ', 'IIIIIIXXII', 'IIIIIIYYII', 'IIIIIIZZII', 'IIIIXXIIII', 'IIIIYYIIII', 'IIIIZZIIII', 'IIXXIIIIII', 'IIYYIIIIII', 'IIZZIIIIII', 'XXIIIIIIII', 'YYIIIIIIII', 'ZZIIIIIIII'],
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,
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,
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])
# Observable: ZZ on the middle pair of qubits
observable = SparsePauliOp.from_sparse_list(
[("ZZ", (L // 2 - 1, L // 2), 1.0)], num_qubits=L
)
print(observable)
SparsePauliOp(['IIIIZZIIII'],
coeffs=[1.+0.j])
# MPF parameters
mpf_trotter_steps = [1, 2, 4]
order = 2
symmetric = False

trotter_times = np.arange(0.5, 1.55, 0.1)
exact_evolution_times = np.arange(trotter_times[0], 1.55, 0.05)

Bina circuit Trotter

Kami mencipta circuit yang melaksanakan evolusi-masa Trotter anggaran untuk setiap titik masa dan setiap bilangan langkah Trotter. Pass CollectAndCollapse yang ditakrifkan dalam seksyen Persediaan mengumpul putaran XX dan YY menjadi gate XX+YY tunggal, untuk bersedia untuk simulasi rangkaian-tensor yang lebih cekap kemudian.

# Initial Neel state preparation
initial_state_circ = QuantumCircuit(L)
initial_state_circ.x([i for i in range(L) if i % 2 != 0])

all_circs = []
for total_time in trotter_times:
mpf_trotter_circs = [
generate_time_evolution_circuit(
hamiltonian,
time=total_time,
synthesis=SuzukiTrotter(reps=num_steps, order=order),
)
for num_steps in mpf_trotter_steps
]

mpf_trotter_circs = pm.run(
mpf_trotter_circs
) # Collect XX and YY into XX + YY

mpf_circuits = [
initial_state_circ.compose(circuit) for circuit in mpf_trotter_circs
]
all_circs.append(mpf_circuits)
mpf_circuits[-1].draw("mpl", fold=-1)

Output of the previous code cell

Langkah 2: Optimumkan masalah untuk pelaksanaan perkakasan kuantum

Untuk contoh skala kecil kami menyasarkan simulator Aer. Dua transformasi berlaku sebelum circuit bersedia untuk dilaksanakan:

  1. Pengumpulan gate pada peringkat simulasi-Hamiltonian. Dalam sel Persediaan kami membina pass CollectAndCollapse yang menggabungkan putaran rxx dan ryy bersebelahan menjadi satu XXPlusYYGate. Kami sudah menggunakan pass ini apabila kami membina circuit Trotter dalam Langkah 1 (panggilan pm.run(...)). Ini mengurangkan bilangan gate dua-qubit dan menghasilkan struktur yang lebih sesuai untuk simulasi rangkaian-tensor bagi pengiraan pekali-dinamik kemudian.

  2. Menurunkan kepada ISA simulator. Di bawah kami menjalankan Qiskit preset pass manager pada optimization_level=3 untuk menurunkan setiap circuit Trotter kepada seni bina set-arahan (ISA) simulator.

aer_sim = AerSimulator()
pm_sim = generate_preset_pass_manager(backend=aer_sim, optimization_level=3)

isa_circs_all_times = [
pm_sim.run([deepcopy(c) for c in mpf_circuits])
for mpf_circuits in all_circs
]

Langkah 3: Jalankan menggunakan primitif Qiskit

Untuk contoh skala kecil kami menjalankan circuit Trotter yang diturunkan-ISA melalui primitive EstimatorV2 yang disokong oleh Aer. Berbuat demikian memberi kami nilai rujukan tanpa hingar untuk setiap pasangan (kj,t)(k_j, t) — ini adalah nilai Akj(t)\langle A \rangle_{k_j}(t) yang akan digabungkan oleh MPF dalam Langkah 4. Kami menyapu merentasi masa evolusi supaya kami boleh kemudian memplot lengkung siri-masa penuh setiap formula produk individu dan MPF.

estimator = Estimator(mode=aer_sim)

mpf_expvals_all_times, mpf_stds_all_times = [], []
for isa_circuits in isa_circs_all_times:
result = estimator.run(
[(circuit, observable) for circuit in isa_circuits], precision=0.005
).result()
mpf_expvals_all_times.append([res.data.evs for res in result])
mpf_stds_all_times.append([res.data.stds for res in result])

Langkah 4: Proses pasca dan kembalikan keputusan dalam format klasik yang dikehendaki

Langkah 4 ialah tempat MPF sebenarnya dibina. Walaupun pekali xjx_j dikira di sini (dan, untuk varian dinamik, pengiraan ini boleh menjadi intensif), secara konseptual ia adalah resipi klasik untuk menggabungkan pengukuran kuantum daripada Langkah 3 menjadi satu nilai jangkaan diperbetulkan tunggal — jadi kami menganggap keseluruhan aliran kerja pekali dan gabungan sebagai pasca-pemprosesan.

Untuk menilai sejauh mana MPF menjejaki dinamik sebenar, kami mula-mula mengira nilai jangkaan berevolusi-masa yang tepat dengan mengeksponenkan Hamiltonian secara langsung. Ini hanya boleh dilaksanakan kerana L=10L = 10; dalam contoh perkakasan skala besar di bawah kami perlu bergantung kepada anggaran rangkaian-tensor sebaliknya.

exact_expvals = []
for t in exact_evolution_times:
exp_H = expm(-1j * t * hamiltonian.to_matrix())
initial_state = Statevector(initial_state_circ).data
time_evolved_state = exp_H @ initial_state

exact_obs = (
time_evolved_state.conj()
@ observable.to_matrix()
@ time_evolved_state
).real
exact_expvals.append(exact_obs)

Pekali MPF statik

MPF statik menggunakan pekali xjx_j yang tidak bergantung kepada masa evolusi, Hamiltonian, dan keadaan awal. Kami menyediakan sistem linear Ax=bAx = b yang diterangkan dalam Latar Belakang dan menyelesaikan untuk pekali tersebut. Matriks AA ditentukan oleh bilangan langkah Trotter kjk_j, peringkat χ\chi formula produk, dan sama ada formula itu simetri (yang mengawal eksponen ηn\eta_n).

Untuk contoh skala kecil kami, kami menggunakan kj=[1,2,4]k_j = [1, 2, 4] dengan formula Suzuki-Trotter bukan-simetri peringkat-2χ=22\chi=2 (jadi χ=1\chi=1 dan ηn=2+n\eta_n = 2 + n, memberikan η0=2,η1=3\eta_0 = 2,\, \eta_1 = 3). Sistem tersebut menjadi:

A=[11111221421123143],b=[100].A = \begin{bmatrix} 1 & 1 & 1\\ 1 & \frac{1}{2^2} & \frac{1}{4^2} \\ 1 & \frac{1}{2^3} & \frac{1}{4^3} \\ \end{bmatrix}, \quad b = \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix}.

Baris pertama menguatkuasakan ketidakbiasan (jxj=1\sum_j x_j = 1); baris kedua dan ketiga masing-masing membatalkan terma ralat-Trotter utama 1/k21/k^2 dan peringkat-seterusnya 1/k31/k^3.

Sediakan LSE

Kami menggunakan setup_static_lse daripada qiskit_addon_mpf.static untuk menyusun matriks AA dan vektor sisi-kanan bb yang diterangkan di atas. Matriks AA bergantung bukan sahaja kepada kjk_j tetapi juga kepada pilihan formula produk kami — khususnya peringkat χ\chi dan sama ada ia simetri. Bendera symmetric mengawal corak eksponen ηn\eta_n (formula simetri hanya menghasilkan terma ralat-Trotter kuasa-genap; lihat Ruj. [1]). Perhatikan bahawa, seperti ditunjukkan dalam Ruj. [2], menetapkan symmetric=True tidak semestinya perlu walaupun apabila PF asas adalah simetri — LSE bukan-simetri kekal sah (ia menguatkuasakan kekangan tambahan yang tidak diperlukan).

Untuk contoh kami, kami sudah menetapkan order = 2 dan symmetric = False dalam Langkah 1.

lse = setup_static_lse(mpf_trotter_steps, order=order, symmetric=symmetric)

Periksa matriks AA dan vektor bb yang dibina untuk mengesahkan ia sepadan dengan sistem yang ditulis di atas.

lse.A
array([[1. , 1. , 1. ],
[1. , 0.25 , 0.0625 ],
[1. , 0.125 , 0.015625]])
lse.b
array([1., 0., 0.])

Dengan LSE di tangan, kami menyelesaikan untuk pekali statik xjx_j melalui lse.solve() (ini ialah penyelesaian langsung x=A1bx = A^{-1}b).

mpf_coeffs = lse.solve()
print(
f"The static coefficients associated with the ansatze are: {mpf_coeffs}"
)
The static coefficients associated with the ansatze are: [ 0.04761905 -0.57142857 1.52380952]
Optimumkan xx menggunakan model tepat

Sebagai alternatif kepada pengiraan x=A1bx = A^{-1}b, kamu boleh menggunakan setup_exact_model untuk membina contoh cvxpy.Problem yang menggunakan LSE sebagai kekangan dan penyelesaian optimalnya akan menghasilkan xx.

model_exact, coeffs_exact = setup_exact_problem(lse)
model_exact.solve()
print(coeffs_exact.value)
[ 0.04761905 -0.57142857 1.52380952]
print(
"L1 norm of the exact coefficients:",
np.linalg.norm(coeffs_exact.value, ord=1),
)
L1 norm of the exact coefficients: 2.1428571428556378
Optimumkan xx menggunakan model hampiran

Ia mungkin berlaku bahawa norma L1L_1 untuk set nilai kjk_j yang dipilih dianggap terlalu tinggi. Jika demikian dan kamu tidak boleh memilih set nilai kjk_j yang berbeza, kamu boleh menggunakan penyelesaian hampiran yang mengekang norma-L1L_1 kepada ambang yang dipilih sambil meminimumkan Axb\|Ax - b\|. Lihat panduan mengenai How to use the approximate model.

model_approx, coeffs_approx = setup_sum_of_squares_problem(
lse, max_l1_norm=1.5
)
model_approx.solve()
print(coeffs_approx.value)
print(
"L1 norm of the approximate coefficients:",
np.linalg.norm(coeffs_approx.value, ord=1),
)
[-1.10294118e-03 -2.48897059e-01 1.25000000e+00]
L1 norm of the approximate coefficients: 1.5

Pekali MPF dinamik

MPF statik membatalkan terma ralat-Trotter dengan cara yang agnostik-Hamiltonian dan agnostik-keadaan, jadi ia tidak semestinya menghasilkan ralat penghampiran sekecil mungkin untuk Hamiltonian dan keadaan awal tertentu. MPF dinamik (Ruj. [2], [3]) sebaliknya mencari pekali bergantung-masa xi(t)x_i(t) yang meminimumkan jarak norma-Frobenius ρ(t)μD(t)F2\|\rho(t) - \mu^D(t)\|_F^2 pada setiap masa tt. Seperti ditunjukkan dalam Latar Belakang, ini memerlukan matriks pertindihan Mij(t)M_{ij}(t) antara keadaan berevolusi-Trotter dan pertindihan Li(t)L_i(t) dengan keadaan tepat — kedua-duanya kami anggarkan menggunakan backend rangkaian-tensor (TeNPy) dalam qiskit_addon_mpf.

Untuk menyediakan LSE dinamik kami memerlukan tiga bahan:

  1. Satu kilang evolver anggaran yang addon akan jalankan untuk setiap kjk_j untuk menghasilkan ρkj(t)\rho_{k_j}(t) sebagai MPS/MPO. Kami membinanya daripada struktur berlapis circuit Trotter peringkat-22 (satu lapisan bagi setiap slice_by_depth), dibalut sebagai LayerwiseEvolver dengan parameter pemangkasan TeNPy.

  2. Satu kilang evolver tepat yang menghasilkan rujukan ketepatan-tinggi ρ(t)\rho(t). Kami menggunakan circuit Suzuki-Trotter peringkat-keempat langkah-masa-kecil (dt=0.1, order=4) sebagai proksi untuk evolusi tepat.

  3. Satu kilang identiti dan satu MPS keadaan-awal yang mengasaskan simulasi TeNPy.

Sel di bawah membina kilang evolver anggaran.

# Create approximate time-evolution circuits
single_2nd_order_circ = generate_time_evolution_circuit(
hamiltonian, time=1.0, synthesis=SuzukiTrotter(reps=1, order=order)
)
single_2nd_order_circ = pm.run(single_2nd_order_circ) # collect XX and YY

# Find layers in the circuit
layers = slice_by_depth(single_2nd_order_circ, max_slice_depth=1)

# Create tensor network models
models = [
LayerModel.from_quantum_circuit(layer, conserve="Sz") for layer in layers
]

# Create the time-evolution object
approx_factory = partial(
LayerwiseEvolver,
layers=models,
options={
"preserve_norm": False,
"trunc_params": {
"chi_max": 64,
"svd_min": 1e-8,
"trunc_cut": None,
},
"max_delta_t": 2,
},
)
amaran

Pilihan LayerwiseEvolver yang menentukan butiran simulasi rangkaian tensor mesti dipilih dengan teliti untuk mengelakkan penyediaan masalah pengoptimuman yang tidak jelas.

Kami menganggarkan keadaan berkembang masa yang tepat dengan formula Suzuki-Trotter peringkat keempat menggunakan langkah masa kecil dt=0.1. Parameter pemangkasan TeNPy boleh menjejaskan ketepatan, jadi penting untuk meneroka pelbagai nilai.

single_4th_order_circ = generate_time_evolution_circuit(
hamiltonian, time=1.0, synthesis=SuzukiTrotter(reps=1, order=4)
)
single_4th_order_circ = pm.run(single_4th_order_circ)
exact_model_layers = [
LayerModel.from_quantum_circuit(layer, conserve="Sz")
for layer in slice_by_depth(single_4th_order_circ, max_slice_depth=1)
]

exact_factory = partial(
LayerwiseEvolver,
layers=exact_model_layers,
dt=0.1,
options={
"preserve_norm": False,
"trunc_params": {
"chi_max": 64,
"svd_min": 1e-8,
"trunc_cut": None,
},
"max_delta_t": 2,
},
)

Akhir sekali, kami mentakrifkan identity_factory yang menghasilkan keadaan MPO awal dan menyediakan keadaan awal Néel sebagai MPS yang sepadan dengan kekisi yang digunakan oleh model Trotter berlapis.

def identity_factory():
return MPOState.initialize_from_lattice(models[0].lat, conserve=True)

mps_initial_state = MPS_neel_state(models[0].lat)

Dengan kilang-kilang tersebut sedia, kami kini mengira pekali dinamik pada setiap masa evolusi. Untuk setiap tt, setup_dynamic_lse membina matriks pertindihan berkaitan melalui TeNPy, dan setup_frobenius_problem mengembalikan cvxpy.Problem yang meminimumkan kos norma-Frobenius. Penyelesai mengembalikan pekali xj(t)x_j(t) yang disesuaikan untuk masa itu; kami mengumpulnya dalam mpf_dynamic_coeffs_list. Jika penyelesai gagal untuk tt tertentu, kami kembali kepada pekali sifar supaya gelung diteruskan.

mpf_dynamic_coeffs_list = []
for t in trotter_times:
print(f"Computing dynamic coefficients for time={t}")
lse = setup_dynamic_lse(
mpf_trotter_steps,
t,
identity_factory,
exact_factory,
approx_factory,
mps_initial_state,
)
problem, coeffs = setup_frobenius_problem(lse)
try:
problem.solve()
mpf_dynamic_coeffs_list.append(coeffs.value)
except Exception as error:
mpf_dynamic_coeffs_list.append(np.zeros(len(mpf_trotter_steps)))
print(error, "Calculation Failed for time", t)
print("")
Computing dynamic coefficients for time=0.5

Computing dynamic coefficients for time=0.6

Computing dynamic coefficients for time=0.7

Computing dynamic coefficients for time=0.7999999999999999

Computing dynamic coefficients for time=0.8999999999999999

Computing dynamic coefficients for time=0.9999999999999999

Computing dynamic coefficients for time=1.0999999999999999

Computing dynamic coefficients for time=1.1999999999999997

Computing dynamic coefficients for time=1.2999999999999998

Computing dynamic coefficients for time=1.4

Computing dynamic coefficients for time=1.4999999999999998

Gabungkan nilai jangkaan Trotter dengan pekali MPF

Kini kami menilai AMPF(t)=jxjAkj(t)\langle A \rangle_{\text{MPF}}(t) = \sum_j x_j \, \langle A \rangle_{k_j}(t) untuk setiap set pekali (statik-tepat, statik-anggaran, dan dinamik), merambatkan ralat piawai per-circuit, dan memplot siri masa yang terhasil terhadap lengkung pendiagonalan-tepat.

sym = {1: "^", 2: "s", 4: "p"}
# Get expectation values at all times for each Trotter step
for k, step in enumerate(mpf_trotter_steps):
trotter_curve, trotter_curve_error = [], []
for trotter_expvals, trotter_stds in zip(
mpf_expvals_all_times, mpf_stds_all_times
):
trotter_curve.append(trotter_expvals[k])
trotter_curve_error.append(trotter_stds[k])

plt.errorbar(
trotter_times,
trotter_curve,
yerr=trotter_curve_error,
alpha=0.5,
markersize=4,
marker=sym[step],
color="grey",
label=f"{mpf_trotter_steps[k]} Trotter steps",
)

# Get expectation values at all times for the static MPF with exact coeffs
exact_mpf_curve, exact_mpf_curve_error = [], []
for trotter_expvals, trotter_stds in zip(
mpf_expvals_all_times, mpf_stds_all_times
):
mpf_std = np.sqrt(
sum(
[
(coeff**2) * (std**2)
for coeff, std in zip(coeffs_exact.value, trotter_stds)
]
)
)
exact_mpf_curve_error.append(mpf_std)
exact_mpf_curve.append(trotter_expvals @ coeffs_exact.value)

plt.errorbar(
trotter_times,
exact_mpf_curve,
yerr=exact_mpf_curve_error,
markersize=4,
marker="o",
label="Static MPF - Exact",
color="purple",
)

# Get expectation values at all times for the static MPF with approximate coeffs
approx_mpf_curve, approx_mpf_curve_error = [], []
for trotter_expvals, trotter_stds in zip(
mpf_expvals_all_times, mpf_stds_all_times
):
mpf_std = np.sqrt(
sum(
[
(coeff**2) * (std**2)
for coeff, std in zip(coeffs_approx.value, trotter_stds)
]
)
)
approx_mpf_curve_error.append(mpf_std)
approx_mpf_curve.append(trotter_expvals @ coeffs_approx.value)

plt.errorbar(
trotter_times,
approx_mpf_curve,
yerr=approx_mpf_curve_error,
markersize=4,
marker="o",
label="Static MPF - Approx",
color="orange",
)

# Get expectation values at all times for the dynamic MPF
dynamic_mpf_curve, dynamic_mpf_curve_error = [], []
for trotter_expvals, trotter_stds, dynamic_coeffs in zip(
mpf_expvals_all_times, mpf_stds_all_times, mpf_dynamic_coeffs_list
):
mpf_std = np.sqrt(
sum(
[
(coeff**2) * (std**2)
for coeff, std in zip(dynamic_coeffs, trotter_stds)
]
)
)
dynamic_mpf_curve_error.append(mpf_std)
dynamic_mpf_curve.append(trotter_expvals @ dynamic_coeffs)

plt.errorbar(
trotter_times,
dynamic_mpf_curve,
yerr=dynamic_mpf_curve_error,
markersize=4,
marker="o",
label="Dynamic MPF",
color="pink",
)

# Exact expectation values
plt.plot(
exact_evolution_times,
exact_expvals,
color="red",
linestyle="--",
label="Exact time-evolution",
)

plt.title(f"$\\langle Z_{{{L//2-1}}} Z_{{{L//2}}} \\rangle$ vs time")
plt.xlabel("Time")
plt.ylabel("Expectation Value")
plt.legend(loc="upper center", bbox_to_anchor=(0.5, -0.2), ncol=2)
plt.grid(alpha=0.1)
plt.tight_layout()
plt.show()

Output of the previous code cell

Plot di atas menggambarkan interaksi antara ralat Trotter dan ralat pensampelan.

  • Ralat Trotter. Formula produk individu (penanda kelabu) menyimpang daripada lengkung tepat semakin banyak apabila masa meningkat. Circuit k=1k=1 mempunyai penyimpangan terbesar dan adalah yang paling cetek, tetapi ia juga sudah berada dalam rejim di mana t/k1t/k \gtrsim 1, jadi terma ralat utama 1/k21/k^{2} adalah besar. Gabungan MPF (penanda berwarna) membatalkan beberapa terma ralat-Trotter utama ini, jadi ia menjejaki lengkung tepat dengan lebih rapat berbanding mana-mana circuit kjk_j tunggal. Jurang yang tinggal mencerminkan terma Trotter peringkat-lebih-tinggi yang tidak dibatalkan oleh MPF: MPF statik peringkat-22, r=3r=3 hanya membunuh dua peringkat ralat pertama, dan pada t/kmint/k_{\min} yang besar, ekor yang tidak dibatalkan akhirnya mendominasi — jadi MPF tidak menjamin bahawa circuit yang sangat cetek kekal tepat pada sebarang masa.

  • Ralat pensampelan. Bar ralat yang lebih lebar pada lengkung MPF ialah akibat langsung daripada gabungan linear: merambatkan ralat piawai per-circuit yang bebas σkj\sigma_{k_j} memberikan jumlah varians σMPF2=jxj2σkj2\sigma_{\text{MPF}}^2 = \sum_j x_j^2 \, \sigma_{k_j}^2. Oleh itu, semakin besar x2\|x\|_2 (dan dalam praktiknya x1\|x\|_1, yang kami kawal), semakin banyak shot diperlukan untuk mencapai ketidakpastian sasaran tertentu. Ini ialah pertukaran di sebalik pilihan penyelesai-anggaran dalam Latar Belakang: kami mengekang x1\|x\|_1 untuk mengekalkan overhed ini terkawal. Yang penting, tidak seperti ralat Trotter, ralat pensampelan mengecil dengan 1/Nshots1/\sqrt{N_{\text{shots}}}, jadi ia sentiasa boleh dikurangkan dengan membelanjakan lebih banyak shot.

Dalam contoh perkakasan skala besar di bawah, hingar perkakasan memasuki sebagai punca ralat tambahan pada setiap Akj\langle A \rangle_{k_j}, yang serupa diperkuatkan oleh pekali MPF. Kami akan lihat bagaimana mitigasi ralat berinteraksi dengan MPF dalam seksyen tersebut.

Contoh perkakasan skala besar

Dalam seksyen ini kami meningkatkan skala masalah melebihi apa yang boleh disimulasikan secara tepat. Kami menghasilkan semula sebahagian hasil yang ditunjukkan dalam Ruj. [3], menggunakan rantaian XXZ 50-qubit pada masa t=3t = 3. Kami mengikuti aliran kerja empat-langkah yang sama seperti contoh skala kecil, kini menyasarkan perkakasan kuantum sebenar dengan mitigasi ralat. Seperti dalam templat, setiap langkah ditandakan secara inline dalam kod, dan satu langkah boleh merentasi pelbagai sel apabila output pertengahannya berbaloi diperiksa. Pemetaan itu mencerminkan contoh skala kecil: takrifkan Hamiltonian, pilih parameter Trotter, kira pekali MPF (statik dan dinamik), dan bina circuit. Perbezaan utama ialah:

  • Satu Hamiltonian XXZ pada 50 tapak dengan gandingan rawak yang diambil daripada U(0.5,1.5)\mathcal{U}(0.5, 1.5) (Ruj. [3]).

  • Satu formula Trotter peringkat kedua simetri dengan kj=[3,4,6]k_j = [3, 4, 6] (jadi χ=1\chi=1, symmetric=True).

  • Satu masa evolusi tetap tunggal t=3t = 3. Dengan kmin=3k_{\min}=3 ini memberikan t/kmin=1t/k_{\min}=1, mengekalkan konstituen cetek di dalam rejim penumpuan-Trotter di mana model ralat-utama yang MPF bergantung kepadanya adalah sah.

  • Satu larian perbandingan circuit tunggal tambahan dengan k=10k = 10 langkah Trotter, digunakan sebagai garis dasar. Kami memilih k=10k = 10 kerana kedalaman dua-qubitnya pada perkakasan lebih dalam daripada konstituen MPF paling dalam (kmax=6k_{\max}=6) ditambah overhed menjalankan pelbagai circuit MPF — cukup dalam untuk terhad-hingar, iaitu rejim di mana gabungan MPF dijangka mengatasi garis dasar circuit tunggal. Ia ialah perbandingan "circuit dalam tunggal" terhadap gabungan MPF, bukan circuit yang menyasarkan ralat Trotter berkesan MPF (yang memerlukan lebih banyak langkah).

Perhatikan bahawa walaupun kami masih dalam Langkah 1 di sini (pemetaan dan pembinaan circuit), kami juga mengira lebih awal pekali dinamik bersama-sama dengan pekali statik dalam sel ini. Pekali dinamik bergantung kepada HH dan tt tetapi bukan pada pengukuran kuantum, jadi ia boleh dikira pada bila-bila masa sebelum Langkah 4. Kami melakukannya sekarang untuk mengekalkan semua persediaan khusus-MPF di satu tempat.

# -------------------------Step 1-------------------------
L = 50
coupling_map = CouplingMap.from_line(L, bidirectional=False)

# XXZ Hamiltonian with random couplings (Ref. [3])
np.random.seed(0)
even_edges = list(coupling_map.get_edges())[::2]
odd_edges = list(coupling_map.get_edges())[1::2]

Js = np.random.uniform(0.5, 1.5, size=L)
hamiltonian = SparsePauliOp(Pauli("I" * L))
for i, edge in enumerate(even_edges + odd_edges):
hamiltonian += SparsePauliOp.from_sparse_list(
[
("XX", (edge), 2 * Js[i]),
("YY", (edge), 2 * Js[i]),
("ZZ", (edge), 4 * Js[i]),
],
num_qubits=L,
)

observable = SparsePauliOp.from_sparse_list(
[("ZZ", (L // 2 - 1, L // 2), 1.0)], num_qubits=L
)

total_time = 3
mpf_trotter_steps = [3, 4, 6]
order = 2
symmetric = True

# Static coefficients
lse = setup_static_lse(mpf_trotter_steps, order=order, symmetric=symmetric)
mpf_coeffs = lse.solve()
print(f"Static coefficients: {mpf_coeffs}")
print(f"L1 norm: {np.linalg.norm(mpf_coeffs, ord=1)}")

model_approx, coeffs_approx = setup_sum_of_squares_problem(
lse, max_l1_norm=2.0
)
model_approx.solve()
print(f"Approximate coefficients: {coeffs_approx.value}")
print(f"L1 norm (approx): {np.linalg.norm(coeffs_approx.value, ord=1)}")

# -------------------------Dynamic coefficients-------------------------
single_2nd_order_circ = generate_time_evolution_circuit(
hamiltonian, time=1.0, synthesis=SuzukiTrotter(reps=1, order=order)
)
single_2nd_order_circ = pm.run(single_2nd_order_circ)

layers = slice_by_depth(single_2nd_order_circ, max_slice_depth=1)
models = [
LayerModel.from_quantum_circuit(layer, conserve="Sz") for layer in layers
]

approx_factory = partial(
LayerwiseEvolver,
layers=models,
options={
"preserve_norm": False,
"trunc_params": {"chi_max": 64, "svd_min": 1e-8, "trunc_cut": None},
"max_delta_t": 4,
},
)

single_4th_order_circ = generate_time_evolution_circuit(
hamiltonian, time=1.0, synthesis=SuzukiTrotter(reps=1, order=4)
)
single_4th_order_circ = pm.run(single_4th_order_circ)
exact_model_layers = [
LayerModel.from_quantum_circuit(layer, conserve="Sz")
for layer in slice_by_depth(single_4th_order_circ, max_slice_depth=1)
]

exact_factory = partial(
LayerwiseEvolver,
layers=exact_model_layers,
dt=0.1,
options={
"preserve_norm": False,
"trunc_params": {"chi_max": 64, "svd_min": 1e-8, "trunc_cut": None},
"max_delta_t": 3,
},
)

def identity_factory():
return MPOState.initialize_from_lattice(models[0].lat, conserve=True)

mps_initial_state = MPS_neel_state(models[0].lat)

print(f"Computing dynamic coefficients for time={total_time}")
lse_dyn = setup_dynamic_lse(
mpf_trotter_steps,
total_time,
identity_factory,
exact_factory,
approx_factory,
mps_initial_state,
)
problem, coeffs_dyn = setup_frobenius_problem(lse_dyn)
try:
problem.solve()
mpf_dynamic_coeffs = coeffs_dyn.value
except Exception as error:
mpf_dynamic_coeffs = np.zeros(len(mpf_trotter_steps))
print(error, "Calculation Failed")

# -------------------------Step 1 (cont): Build circuits-------------------------
mpf_circuits = []
for k in mpf_trotter_steps:
circuit = QuantumCircuit(L)
circuit.x([i for i in range(L) if i % 2])
trotter_circ = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=k, order=order),
time=total_time,
)
circuit.compose(trotter_circ, qubits=range(L), inplace=True)
mpf_circuits.append(circuit)

# Baseline "single deep circuit" comparison run with k=10 Trotter steps.
# Its two-qubit depth is deeper than the deepest MPF constituent (k_max=6) plus
# the overhead of running multiple circuits, pushing it into the noise-limited
# regime where MPF is expected to outperform. It does NOT target the MPF's effective
# Trotter error (which would require many more steps).
comp_circuit = QuantumCircuit(L)
comp_circuit.x([i for i in range(L) if i % 2])
trotter_circ = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=10, order=order),
time=total_time,
)
comp_circuit.compose(trotter_circ, qubits=range(L), inplace=True)
mpf_circuits.append(comp_circuit)
Static coefficients: [ 0.42857143 -1.82857143 2.4 ]
L1 norm: 4.65714285714286
Approximate coefficients: [-0.4942491 0.40206845 1.09218065]
L1 norm (approx): 1.9884981979026675
Computing dynamic coefficients for time=3

Kini kami mengoptimumkan circuit untuk backend yang dipilih. Kami menggunakan Qiskit preset pass manager pada optimization_level=3, yang secara automatik memilih set qubit fizikal yang baik dan mengalih setiap circuit kepada topologi peranti.

# -------------------------Step 2-------------------------
service = QiskitRuntimeService()
# backend = service.least_busy(operational=True, simulator=False, min_num_qubits=L)
backend = service.backend("ibm_fez")
print(backend)

transpiler = generate_preset_pass_manager(
optimization_level=3, backend=backend
)
transpiled_circuits = [transpiler.run(circ) for circ in mpf_circuits]

isa_observables = [
observable.apply_layout(circ.layout) for circ in transpiled_circuits
]
<IBMBackend('ibm_fez')>

Menjalankan circuit yang lebih dalam pada perkakasan sebenar memerlukan mitigasi ralat yang agresif. Kami mengaktifkan penyahgandingan dinamik, twirling gate dan pengukuran, mitigasi ralat pengukuran, dan ekstrapolasi hingar-sifar (ZNE). Perhatikan bahawa faktor hingar ZNE yang kami gunakan di sini (1, 1.2, 1.4) adalah lebih kecil berbanding senario circuit cetek, kerana konstituen MPF yang lebih dalam sudah hampir dengan ambang hingar dan pembesaran hingar yang besar akan menolaknya melepasi titik di mana ekstrapolasi ZNE dipercayai.

Kami menghantar keempat-empat circuit (tiga konstituen MPF pada kj=[3,4,6]k_j = [3, 4, 6] ditambah garis dasar k=10k = 10) dalam satu tugasan Estimator.

# -------------------------Step 3-------------------------
estimator = Estimator(mode=backend)
estimator.options.default_shots = 30000

# Error suppression/mitigation
estimator.options.dynamical_decoupling.enable = True
estimator.options.twirling.enable_gates = True
estimator.options.twirling.enable_measure = True
estimator.options.twirling.num_randomizations = "auto"
estimator.options.twirling.strategy = "active-accum"
estimator.options.resilience.measure_mitigation = True
estimator.options.experimental.execution_path = "gen3-turbo"

estimator.options.resilience.zne_mitigation = True
estimator.options.resilience.zne.noise_factors = (1, 1.2, 1.4)
estimator.options.resilience.zne.extrapolator = "linear"

estimator.options.environment.job_tags = ["TUT_MPF"]

job_50 = estimator.run(
[
(circ, observable)
for circ, observable in zip(transpiled_circuits, isa_observables)
]
)

Kami menarik nilai jangkaan per-circuit dan sisihan piawai daripada hasil tugasan, kemudian menggabungkannya dengan setiap set pekali MPF seperti tepat dalam contoh skala kecil: AMPF=jxjAkj\langle A \rangle_{\text{MPF}} = \sum_j x_j \, \langle A \rangle_{k_j}, dengan varians yang dirambatkan σ2=jxj2σkj2\sigma^2 = \sum_j x_j^2 \sigma_{k_j}^2.

# -------------------------Step 4-------------------------
result = job_50.result()
evs = [res.data.evs for res in result]
std = [res.data.stds for res in result]

print(evs)
print(std)
[array(-0.07916195), array(-0.04479681), array(-0.2560756), array(-0.06045848)]
[array(0.04605538), array(0.10056336), array(0.14426151), array(0.04059092)]
exact_mpf_std = np.sqrt(
sum([(coeff**2) * (std**2) for coeff, std in zip(mpf_coeffs, std[:3])])
)
print(
"Exact static MPF expectation value: ",
evs[:3] @ mpf_coeffs,
"+-",
exact_mpf_std,
)
approx_mpf_std = np.sqrt(
sum(
[
(coeff**2) * (std**2)
for coeff, std in zip(coeffs_approx.value, std[:3])
]
)
)
print(
"Approximate static MPF expectation value: ",
evs[:3] @ coeffs_approx.value,
"+-",
approx_mpf_std,
)
dynamic_mpf_std = np.sqrt(
sum(
[
(coeff**2) * (std**2)
for coeff, std in zip(mpf_dynamic_coeffs, std[:3])
]
)
)
print(
"Dynamic MPF expectation value: ",
evs[:3] @ mpf_dynamic_coeffs,
"+-",
dynamic_mpf_std,
)
Exact static MPF expectation value: -0.5665938395816946 +- 0.3925273058119915
Approximate static MPF expectation value: -0.25856647611537903 +- 0.164249927266166
Dynamic MPF expectation value: -0.12667812062949296 +- 0.06059471006973169
sym = {3: "^", 4: "s", 6: "p"}
for k, step in enumerate(mpf_trotter_steps):
plt.errorbar(
k,
evs[k],
yerr=std[k],
alpha=0.5,
markersize=4,
marker=sym[step],
color="grey",
label=f"{mpf_trotter_steps[k]} Trotter steps",
)

plt.errorbar(
3,
evs[-1],
yerr=std[-1],
alpha=0.5,
markersize=8,
marker="x",
color="blue",
label="10 Trotter steps",
)

plt.errorbar(
4,
evs[:3] @ mpf_coeffs,
yerr=exact_mpf_std,
markersize=4,
marker="o",
color="purple",
label="Static MPF",
)

plt.errorbar(
5,
evs[:3] @ coeffs_approx.value,
yerr=approx_mpf_std,
markersize=4,
marker="o",
color="orange",
label="Approximate static MPF",
)

plt.errorbar(
6,
evs[:3] @ mpf_dynamic_coeffs,
yerr=dynamic_mpf_std,
markersize=4,
marker="o",
color="pink",
label="Dynamic MPF",
)

exact_obs = -0.24384471447172074 # Calculated via Tensor Network calculation
plt.axhline(
y=exact_obs, linestyle="--", color="red", label="Exact time-evolution"
)

plt.title(
f"$\\langle Z_{{{L//2-1}}} Z_{{{L//2}}} \\rangle$ at time {total_time} for the different methods"
)
plt.xlabel("Method")
plt.ylabel("Expectation Value")
plt.legend(loc="upper center", bbox_to_anchor=(0.5, -0.2), ncol=2)
plt.grid(alpha=0.1)
plt.tight_layout()
plt.show()

Output of the previous code cell

Beberapa pemerhatian mengenai hasil perkakasan di atas:

  • Semakin dalam bukan percuma pada perkakasan. Garis dasar circuit tunggal menceritakan kisah itu secara langsung: circuit k=6k = 6 pada asasnya tepat (0.256-0.256 berbanding rujukan 0.244-0.244), namun garis dasar k=10k = 10 yang lebih dalam adalah lebih teruk (0.061-0.061, terpesong 0.18\sim 0.18), bukan lebih baik. Sebaik sahaja ralat Trotter sudah kecil, menambah langkah kebanyakannya mendalamkan circuit dan mengumpul lebih banyak hingar gate dan dekoherens. Inilah rejim yang MPF direka untuknya: mencapai ketepatan circuit dalam menggunakan hanya konstituen cetek.

  • MPF norma-kecil mengatasi circuit dalam tunggal. MPF statik-anggaran (dihadkan pada x12\|x\|_1 \approx 2) mendarat pada 0.259-0.259, dalam 0.015\sim 0.015 daripada rujukan dan jauh lebih hampir berbanding garis dasar k=10k = 10. MPF dinamik (0.127-0.127) juga dengan selesa mengatasi garis dasar itu. Kedua-duanya hanya menggabungkan circuit cetek kj=[3,4,6]k_j = [3, 4, 6], namun memulihkan jawapan yang tidak dapat dicapai oleh circuit dalam tunggal.

  • Norma pekali lebih penting daripada optimaliti matematik. MPF statik-tepat mempunyai x1=4.66\|x\|_1 = 4.66 dan adalah penganggar yang paling teruk daripada semuanya (0.567-0.567, terpesong lebih daripada 0.30.3): norma pekali yang besar memperkuatkan hingar gate baki, dekoherens, dan ralat ZNE pada setiap Akj\langle A \rangle_{k_j} dengan faktor yang lebih kurang sama, mengatasi pembatalan ralat-Trotter yang diperolehnya. Mengehadkan norma (penyelesai statik-anggaran, x12\|x\|_1 \approx 2) menghapuskan pengatasan ini dan memberikan anggaran terbaik — walaupun pekalinya tidak lagi membatalkan ralat Trotter utama secara tepat.

  • Circuit cetek individu masih boleh bersaing. Konstituen tunggal k=6k = 6 (0.256-0.256) itu sendiri pada asasnya tepat di sini — pada larian ini ia malah sedikit lebih hampir berbanding MPF statik-anggaran. Masalahnya ialah kamu tidak tahu terlebih dahulu kk tunggal mana yang berada dalam titik manis "tertumpu tetapi belum terhad-hingar", dan pilihan yang kelihatan selamat iaitu semakin dalam (k=10k = 10) untuk menjamin penumpuan Trotter adalah tepat yang gagal. MPF memberikan gabungan berprinsip bagi circuit cetek yang tidak memerlukan meneka kedalaman yang betul.

Pengajaran praktikal ialah pada perkakasan, MPF harus dipadankan dengan mitigasi ralat yang kuat pada setiap Akj\langle A \rangle_{k_j} individu, norma-L1L_1 pekali harus dikekalkan sederhana (gunakan penyelesai anggaran, atau MPF dinamik), dan langkah Trotter kjk_j harus dipilih supaya t/kmin1t/k_{\min} \lesssim 1 — di sini kmin=3k_{\min} = 3 pada t=3t = 3 memberikan t/kmin=1t/k_{\min} = 1, mengekalkan konstituen di dalam rejim tertumpu di mana model ralat-utama yang MPF statik bergantung kepadanya adalah sah. Dengan pilihan tersebut, MPF norma-kecil di sini sepadan dengan circuit tunggal yang tertumpu manakala garis dasar naif "semakin dalam sahaja" tidak, memulihkan kelebihan kedalaman-berbanding-ketepatan yang ditunjukkan dalam Ruj. [3]. Perhatikan juga bahawa larian individu adalah hingar — pada penyerahan berbeza tugasan yang sama (atau backend yang berbeza), susunan tepat boleh berubah; trend yang teguh ialah MPF x1\|x\|_1-kecil berprestasi baik, MPF statik-tepat x1\|x\|_1-besar diperkuatkan oleh hingar perkakasan, dan circuit tunggal yang terlebih-dalam adalah terhad-hingar.

Langkah seterusnya

Cadangan

Jika kamu rasa kerja ini menarik, kamu mungkin berminat dengan bahan berikut:

Rujukan

[1] Vazquez, A. C., Egger, D. J., Ochsner, D., & Woerner, S. Well-conditioned multi-product formulas for hardware-friendly Hamiltonian simulation. Quantum, 7, 1067 (2023)

[2] Zhuk, S., Robertson, N. F., & Bravyi, S. Trotter error bounds and dynamic multi-product formulas for Hamiltonian simulation. Physical Review Research, 6(3), 033309 (2024)

[3] Robertson, N. F., et al. Tensor network enhanced dynamic multiproduct formulas. arXiv:2407.17405 (2024)