Mensimulasikan model Ising ditendang dengan fungsi TEM
Kaedah Tensor-network Error Mitigation (TEM) daripada Algorithmiq ialah algoritma hibrid kuantum-klasik yang direka untuk melakukan mitigasi hingar sepenuhnya dalam peringkat post-processing klasik. Dengan TEM, pengguna boleh mengira nilai jangkaan pemboleh ukur, mengurangkan ralat yang disebabkan hingar yang tidak dapat dielakkan pada perkakasan kuantum dengan ketepatan dan kecekapan kos yang lebih tinggi, menjadikannya pilihan yang sangat menarik bagi penyelidik kuantum dan pengamal industri.
Tutorial ini menunjukkan bagaimana TEM boleh mendapatkan keputusan yang bermakna untuk dinamik sistem kuantum, yang tidak boleh diakses tanpa mitigasi ralat dan yang memerlukan sumber daya kuantum yang jauh lebih banyak jika kaedah mitigasi ralat lain seperti PEC dan ZNE digunakan.
Anggaran penggunaan: Buku nota ini menggunakan kira-kira 10 minit QPU pada peranti Heron r3. Masa runtime boleh bergantung secara ketara pada peranti yang dipilih. Anggaran penggunaan mengikut bahagian boleh didapati di bawah.
Menjalankan eksperimen fizik banyak-jasad dengan mitigasi ralat menggunakan fungsi TEM
Tutorial ini berdasarkan rujukan berikut: L. E. Fischer et al., Nat. Phys. (2026). Rujukan ini membincangkan simulasi sebenar pada perkakasan kuantum dengan hingga 91 qubit. Dalam tutorial ini, kita mencipta semula simulasi yang serupa pada saiz litar yang lebih kecil.
Model Ising ditendang sepadan dengan model Ising biasa:
yang padanya dikenakan tendangan melintang:
Matlamatnya adalah untuk mensimulasikan dinamik suatu keadaan di bawah Hamiltonian Ising ditendang melintang, yang evolusi masanya boleh dilaksanakan oleh unitary Floquet . Keadaan awal untuk dievolusi ialah yang mana qubit pertama berada dalam keadaan , manakala yang lain dipasangkan dan ditetapkan dalam keadaan Bell .
Kuantiti yang ingin kita perhatikan ialah fungsi korelasi. Kertas kerja rujukan membincangkan bagaimana kuantiti ini boleh ditulis semula sebagai operator Pauli pada qubit ke-. Selepas beberapa langkah masa fizikal , kita mengira nilai operator Pauli . Bergantung pada parameter sistem, nilai pemboleh ukur ini sama dengan nilai yang boleh dikira secara tepat, atau hanya boleh disimulasikan melalui kaedah anggaran. Khususnya, untuk ia sama dengan , yang merupakan nilai yang akan kita gunakan untuk menanda aras keputusan tutorial ini. Tambahan pula, pada langkah masa tertentu , adalah sifar. Untuk butiran mendapatkan nilai-nilai ini, dan untuk perbandingan dengan keputusan simulasi klasik anggaran di luar parameter ini, lihat L. E. Fischer et al., Nat. Phys. (2026).
TEM berfungsi dengan terlebih dahulu mencirikan hingar untuk setiap lapisan unik gate dua qubit dalam litar, serta mencirikan ralat bacaan. Kemudian, litar dilaksanakan pada mesin kuantum. Akhirnya, mitigasi ralat rangkaian tensor dilakukan pada sumber daya klasik di IBM Cloud® dan nilai yang dimitigasi dikembalikan. Dalam contoh ini, litar mempunyai dua lapisan unik untuk dicirikan.
Persediaan
Sebagai prasyarat, pastikan kebergantungan yang diperlukan dipasang.
%pip install numpy matplotlib qiskit qiskit-ibm-catalog qiskit-ibm-runtime pylatexenc qiskit_qasm3_import
import os
from matplotlib import pyplot as plt
import numpy as np
from qiskit.quantum_info import SparsePauliOp
from qiskit.qasm3 import load
from qiskit_ibm_catalog import QiskitFunctionsCatalog
Mitigasi ralat dengan TEM
Kami menyediakan di sini litar yang melaksanakan model Ising ditendang yang diterangkan di atas. Litar disediakan seperti berikut. Pertama, ada fasa penyediaan keadaan, di mana qubit pertama berada dalam keadaan , manakala yang lain dalam pasangan Bell . Ini diikuti oleh struktur bata yang melaksanakan evolusi unitary . Bilangan langkah masa fizikal sepadan dengan lapisan litar. Kod berikut memuat turun dua fail QASM yang diperlukan untuk tutorial ini.
# Download required QASM files
import urllib
urllib.request.urlretrieve(
"https://ibm.box.com/shared/static/swy5jtq309b0xpzluzlmsmj908yphes8.qasm",
"ki_30q.qasm",
)
urllib.request.urlretrieve(
"https://ibm.box.com/shared/static/et3gkodonw6gsp2trs43lzaozrdtiu7s.qasm",
"ki_12q.qasm",
)
Kita boleh menggambarkan versi kecil litar, dengan 12 qubit dan enam langkah masa:
# Parameters of the kicked Ising model
h = 0.0
num_qubits = 12
t_steps = 6
# Load the circuit for the kicked Ising model
small_circuit = load("ki_12q.qasm")
# Draw the circuit
small_circuit.draw("mpl", scale=0.25, fold=-1)

Seterusnya, bina pemboleh ukur, . Ia dibina sebagai rentetan Pauli mudah dengan susunan yang sepadan dengan yang digunakan oleh Qiskit:
def xt_observable(n_qubits, t_steps):
pauli_str = "".join(["I" * t_steps, "X", "I" * (n_qubits - t_steps - 1)])
pauli_str = pauli_str[::-1] # Reverse the string to match qiskit order
return SparsePauliOp(data=pauli_str, coeffs=1.0)
Dalam contoh 12 qubit kecil kita, pemboleh ukur kelihatan seperti ini:
# Build the observable for the kicked Ising model
small_observable = xt_observable(n_qubits=12, t_steps=6)
print(small_observable)
SparsePauliOp(['IIIIIXIIIIII'],
coeffs=[1.+0.j])
Qiskit Functions menggunakan PUB sebagai cara untuk mengumpul input. Dalam kes kita, mari pertimbangkan satu litar dan pemboleh ukur sebagai PUB kita:
# Collect the input PUBs, in this case composed of a
# single circuit and observable
pubs = [(small_circuit, [small_observable])]
Seterusnya, kita mendapat akses kepada fungsi TEM. Kita mula-mula menyediakan pengesahan yang diperlukan ke IBM Cloud dan memilih Backend daripada peranti yang tersedia. Token, Backend yang tersedia, dan nama sumber daya awan yang berkaitan (CRN) boleh diperoleh dengan masuk ke akaun anda di papan pemuka IBM Quantum Platform.
# Set IBM Quantum credentials and backend configuration
personal_token = os.environ.get(
"QISKIT_IBM_TOKEN", "<API-KEY>"
) # Replace with your personal token or set the environment variable
channel = "ibm_quantum_platform"
crn = "your_crn" # Replace with the Cloud Resource Name (CRN)
# Select the QPU backend
backend_name = "ibm_qpu_name" # Replace with your desired backend's name
Muatkan fungsi TEM daripada Katalog Qiskit Functions:
# Load the TEM function from the Qiskit Functions Catalog
catalog = QiskitFunctionsCatalog(
channel=channel,
token=personal_token,
instance=crn,
)
tem = catalog.load("algorithmiq/tem")
Kita kini boleh menjalankan eksperimen pada litar Ising ditendang dengan mitigasi ralat yang disediakan oleh TEM. Menggunakan tetapan lalai, TEM boleh dijalankan dengan cara mudah dengan jangkaan runtime QPU sekitar 2.5 minit, bergantung pada QPU:
tem_job = tem.run(pubs=pubs, backend_name=backend_name)
Dengan pilihan lalai, fungsi TEM menjalankan tiga kerja pada komputer kuantum: pembelajaran hingar, mitigasi bacaan, dan persampelan litar. Bilangan shots yang digunakan oleh setiap satu boleh diubah dalam pilihan yang dihantar ke fungsi. Secara lalai, parameter ini ditetapkan untuk mencapai ketepatan 0.05 dalam nilai jangkaan yang dimitigasi. Kamu boleh menyemak status kerja anda di papan pemuka IBM Quantum Platform atau dengan:
print(tem_job.status())
QUEUED
Apabila statusnya DONE, kita boleh menyemak keputusan mentah dan yang dimitigasi. tem_evs yang ditakrifkan di bawah ialah nilai jangkaan pemboleh ukur yang diminta, dalam kes ini hanya satu pemboleh ukur, , dan tem_std ialah sisihan piawai yang berkaitan.
# Get the results of the TEM job
tem_results = tem_job.result()[
0
] # Get the first and only result from the job
tem_evs = tem_results.data.evs[0]
tem_std = tem_results.data.stds[0]
print(f"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}")
TEM Result: 1.031 ± 0.046
Kita juga boleh menyemak berapa banyak runtime kuantum yang digunakan untuk setiap panggilan di IBM Quantum Platform, atau dengan memeriksa metadata keputusan daripada kod Python.
# Get the TEM job runtime
tem_runtime = tem_job.result().metadata["resource_usage"][
"RUNNING: EXECUTING_QPU"
]["QPU_TIME"]
print(f"TEM Runtime: {tem_runtime} seconds")
TEM Runtime: 155.0 seconds
Menyesuaikan parameter TEM dan pilihan lanjutan
Fungsi TEM menyediakan beberapa pilihan lanjutan untuk menyesuaikan aliran kerja mitigasi ralat anda. Pilihan ini membolehkan anda mengawal ketepatan, bilangan shots, strategi pembelajaran hingar, dan parameter lain untuk lebih sesuai dengan keperluan eksperimen dan sumber daya kuantum yang tersedia.
Pilihan lanjutan yang biasa ialah:
precision: Menentukan ketepatan sasaran untuk nilai jangkaan yang dimitigasi.default_shots: Sebagai gantiprecision, anda boleh menentukan bilangan shots yang digunakan dalam kerja pengukuran.tem_max_bond_dimension: Dimensi ikatan maksimum yang digunakan dalam rangkaian tensor.tem_compression_cutoff: Nilai potongan yang digunakan untuk rangkaian tensor.- Pilihan pembelajaran hingar: Mengkonfigurasi kaedah pencirian hingar, seperti bilangan ulangan atau litar penentukuran tertentu.
private: Memastikan privasi litar dan keputusan eksperimen untuk anda dan melumpuhkan muat turun berbilang keputusan kerja.
Rujuk dokumentasi TEM atau katalog Qiskit Functions untuk senarai lengkap pilihan yang disokong dan perihalannya. Kamu boleh melaraskan parameter ini untuk mengimbangi masa runtime, penggunaan sumber daya, dan ketepatan keputusan. Kamu boleh menghantar pilihan ini sebagai andas kepada argumen options apabila menjalankan fungsi TEM:
options = {
"default_shots": 10_000,
"tem_max_bond_dimension": 512,
"tem_compression_cutoff": 1e-16,
# This option helps optimizing the measurement
# stage since the observable is strongly biased
# toward the X operator for all the qubits.
"compute_shadows_bias_from_observable": True,
# set to True to keep experiment results private,
# recommended for confidential circuits
"private": False,
}
Pilihan tersuai juga boleh dihantar kepada pembelajaran hingar. Definisi yang digunakan mengikut yang terdapat dalam Qiskit Runtime NoiseLearnerOptions:
nl_options = {
"num_randomizations": 32,
"max_layers_to_learn": 2,
"shots_per_randomization": 128,
"layer_pair_depths": [0, 1, 2, 4, 16, 32],
}
# add noise learning options to the overall options
options |= nl_options
Jalankan semula eksperimen dengan pilihan tersuai ini yang ditetapkan untuk litar kita. Masa runtime yang dijangka ialah kira-kira empat minit QPU.
tem_job_custom = tem.run(
pubs=pubs, backend_name=backend_name, options=options
)
Jika kerja tidak ditetapkan sebagai peribadi, kita boleh mendapatkan semula keputusan kemudian. Untuk melakukan itu, simpan ID kerja yang dicetak di sini dan gunakan tem_job_custom = catalog.get_job_by_id("your-job-id").
job_id = tem_job_custom.job_id
print(f"Job ID: {job_id}")
Job ID: 1ba10094-a541-457a-9287-dbd49306d12d
results_custom = tem_job_custom.result()
tem_evs = results_custom[0].data.evs[0]
tem_std = results_custom[0].data.stds[0]
print(f"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}")
TEM Result: 0.956 ± 0.018
Kita kini boleh memeriksa keputusan dan metadata untuk mendapatkan pandangan tentang eksperimen:
metadata_custom = results_custom[0].metadata
unmitigated_evs = metadata_custom["evs_non_mitigated"][0]
unmitigated_stds = metadata_custom["stds_non_mitigated"][0]
print(f"Unmitigated Result: {unmitigated_evs:.3f} ± {unmitigated_stds:.3f}")
# Exact result for the kicked Ising model from the reference paper
exact_evs = np.cos(2 * h) ** t_steps
print("Exact Result:", exact_evs)
Unmitigated Result: 0.894 ± 0.015
Exact Result: 1.0
# Plot comparing the different expectation values
plt.bar(
["Unmitigated", "TEM"],
[unmitigated_evs, tem_evs],
yerr=[unmitigated_stds, tem_std],
color=["grey", "c"],
)
plt.hlines(y=exact_evs, xmin=-0.5, xmax=1.5, colors="r", linestyles="dashed")
plt.ylabel("Expectation Value")
plt.ylim(0, 1.1)
plt.show()
Akhirnya, kita boleh menyemak kesan pilihan tersuai pada runtime QPU dan klasik:
# Get the metadata of the TEM job
job_metadata = results_custom.metadata
# Get the runtime of the TEM job
qpu_runtime = job_metadata["resource_usage"]["RUNNING: EXECUTING_QPU"][
"QPU_TIME"
]
classical_runtime = (
job_metadata["resource_usage"]["RUNNING: OPTIMIZING_FOR_HARDWARE"][
"CPU_TIME"
]
+ job_metadata["resource_usage"]["RUNNING: POST_PROCESSING"]["CPU_TIME"]
)
print(f"QPU Runtime: {qpu_runtime} seconds")
print(f"Classical Runtime: {classical_runtime} seconds")
QPU Runtime: 342.0 seconds
Classical Runtime: 107.632604 seconds
Meningkatkan skala TEM ke litar besar
Litar besar secara prinsipnya boleh dijalankan dengan fungsi TEM. Walau bagaimanapun, penting untuk menyedari had sumber daya klasik, kerana TEM dilaksanakan pada pengendali IBM Cloud dengan masa runtime yang berpotensi panjang. Untuk litar yang sangat besar, hubungi pasukan sokongan TEM di qiskit_ibm@algorithmiq.fi.
Di sini kita menjalankan contoh dengan litar yang lebih besar bersaiz utiliti 30 qubit, dengan mengoptimumkan parameter TEM untuk kelajuan berbanding ketepatan.
# Kicked Ising model parameters
n_qubits = 30
t_steps = 15
h = 0.0
# Load the circuit for the kicked Ising model
circuit = load("ki_30q.qasm")
# Build the observable for the kicked Ising model
observable = xt_observable(n_qubits=n_qubits, t_steps=t_steps)
# Collect the input PUBs, in this case composed of a
# single circuit and observable
pubs = [(circuit, [observable])]
Mari tentukan beberapa pilihan berorientasikan prestasi:
options = {
"num_randomizations": 32,
"max_layers_to_learn": 2,
"shots_per_randomization": 128,
"layer_pair_depths": [0, 1, 2, 4, 16, 32, 64],
"default_shots": 5_000,
"tem_max_bond_dimension": 128,
"tem_compression_cutoff": 1e-10,
"compute_shadows_bias_from_observable": True,
"private": False,
}
Akhirnya, jalankan eksperimen, dapatkan keputusan, dan visualisasikan. Ini akan mengambil masa kira-kira 3.5 minit QPU.
tem_job_large = tem.run(pubs=pubs, backend_name=backend_name, options=options)
job_id = tem_job_large.job_id
print(f"Job ID: {job_id}")
Job ID: 9f3f190f-f4b0-4dcb-bb83-5f71f37d0d77
results_large = tem_job_large.result()
tem_evs = results_large[0].data.evs[0]
tem_std = results_large[0].data.stds[0]
print(f"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}")
# Get the metadata of the TEM job
job_metadata = tem_job_large.result().metadata
# Get the runtime of the TEM job
qpu_runtime = job_metadata["resource_usage"]["RUNNING: EXECUTING_QPU"][
"QPU_TIME"
]
classical_runtime = (
job_metadata["resource_usage"]["RUNNING: OPTIMIZING_FOR_HARDWARE"][
"CPU_TIME"
]
+ job_metadata["resource_usage"]["RUNNING: POST_PROCESSING"]["CPU_TIME"]
)
print(f"QPU Runtime: {qpu_runtime} seconds")
print(f"Classical Runtime: {classical_runtime} seconds")
TEM Result: 0.794 ± 0.026
QPU Runtime: 203.0 seconds
Classical Runtime: 251.71805499999996 seconds
# Plot comparing the different expectation values
metadata_large = results_large[0].metadata
unmitigated_evs = metadata_large["evs_non_mitigated"][0]
unmitigated_stds = metadata_large["stds_non_mitigated"][0]
exact_evs = np.cos(2 * h) ** t_steps
plt.bar(
["Unmitigated", "TEM"],
[unmitigated_evs, tem_evs],
yerr=[unmitigated_stds, tem_std],
color=["grey", "c"],
)
plt.hlines(y=exact_evs, xmin=-0.5, xmax=1.5, colors="r", linestyles="dashed")
plt.ylabel("Expectation Value")
plt.ylim(0, 1.1)
plt.show()