Mengurangkan ralat Trotter bagi dinamik Hamiltonian dengan formula berbilang produk
Dalam notebook ini, anda akan belajar cara menggunakan Formula Berbilang Produk (MPF) untuk mencapai ralat Trotter yang lebih rendah pada observable kita berbanding ralat yang ditanggung oleh litar Trotter paling dalam yang sebenarnya akan kita jalankan. Anda akan melakukannya dengan melalui langkah-langkah corak Qiskit:
-
Langkah 1: Petakan ke masalah kuantum
-
Takrifkan Hamiltonian masalah kita
- Gunakan MPF untuk menjana litar evolusi masa yang di-Trotterkan
-
-
Langkah 2: Optimumkan masalah
- Di sini kita transpile litar kita untuk GenericBackendV2
-
Langkah 3: Jalankan eksperimen
- Gunakan StatevectorEstimator untuk memudahkan dalam notebook ini
-
Langkah 4: Bina semula keputusan
- Kira nilai jangkaan MPF
Langkah 1: Petakan ke masalah kuantum
1a: Menyediakan Hamiltonian kita
Kita menggunakan model Ising pada garisan 10 tapak:
di mana adalah kekuatan gandingan antara dua tapak dan adalah medan magnet luaran. Pakej qiskit_addon_utils menyediakan fungsi-fungsi boleh guna semula untuk pelbagai tujuan.
Modul qiskit_addon_utils.problem_generators nya menyediakan fungsi untuk menjana Hamiltonian seperti Heisenberg pada graf sambungan yang diberikan. Graf ini boleh jadi sama ada rustworkx.PyGraph atau CouplingMap yang memudahkan penggunaannya dalam aliran kerja berpusat-Qiskit.
Dalam bahagian berikut, kita cipta garisan mudah 10 qubit menggunakan kaedah CouplingMap.from_line.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_addon_mpf": "qiskit-addon-mpf", "qiskit_addon_utils": "qiskit-addon-utils", "rustworkx": "rustworkx", "scipy": "scipy"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit.transpiler import CouplingMap
# Generate some coupling map to use for this example
coupling_map = CouplingMap.from_line(10, bidirectional=False)
from rustworkx.visualization import graphviz_draw
graphviz_draw(coupling_map.graph, method="circo")
Seterusnya, kita jana SparsePauliOp pada sambungan yang diberikan dengan pemalar yang dikehendaki.
from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian
# 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(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 yang akan kita ukur adalah jumlah magnetisasi yang boleh kita bina dengan mudah seperti yang ditunjukkan di bawah:
from qiskit.quantum_info import SparsePauliOp
L = coupling_map.size()
observable = SparsePauliOp.from_sparse_list([("Z", [i], 1 / L / 2) for i in range(L)], num_qubits=L)
print(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])
1b: Formula Berbilang Produk
MPF mengurangkan ralat Trotter bagi dinamik Hamiltonian melalui gabungan berwajaran beberapa pelaksanaan litar.
Untuk lebih jelas, kita takrifkan MPF sebagai:
di mana adalah pekali pemberat kita, adalah matriks ketumpatan yang sepadan dengan keadaan tulen yang diperoleh dengan mengevolusi keadaan awal menggunakan formula produk, , melibatkan langkah Trotter, dan mengindeks bilangan formula produk yang membentuk MPF.
Perkara utama di sini ialah ralat Trotter yang tinggal adalah lebih kecil daripada ralat Trotter yang akan diperoleh dengan hanya menggunakan nilai terbesar!
Anda boleh melihat kegunaan MPF dari dua perspektif:
-
Untuk bajet langkah Trotter yang tetap yang boleh anda jalankan, anda boleh mendapatkan keputusan dengan ralat Trotter yang lebih kecil secara keseluruhan.
-
Untuk bilangan langkah Trotter yang menghasilkan litar dalam, anda boleh menggunakan MPF untuk mencari beberapa litar kedalaman lebih pendek untuk dijalankan yang menghasilkan ralat Trotter yang serupa.
Pengenalan kepada MPF statik
MPF statik ialah MPF yang nilai -nya TIDAK bergantung pada masa evolusi, .
Menentukan pekali MPF statik untuk set nilai yang diberikan adalah bersamaan dengan menyelesaikan sistem persamaan linear: , di mana adalah pekali yang kita minati, adalah matriks yang bergantung pada dan jenis PF yang kita gunakan (), dan adalah vektor kekangan. Untuk ringkas, kita tidak akan masuk lebih detail di sini dan sebaliknya merujuk anda ke dokumentasi LSE.
Kita boleh cari penyelesaian untuk secara analitik sebagai , lihat contohnya Carrera Vazquez et al., 2023 atau Zhuk et al., 2023. Namun, penyelesaian tepat ini boleh jadi "berkeadaan buruk" menghasilkan norma L1 yang sangat besar untuk pekali kita, , yang boleh membawa kepada prestasi MPF yang buruk. Sebaliknya, seseorang juga boleh mendapatkan penyelesaian anggaran yang meminimumkan norma L1 bagi dalam usaha mengoptimumkan tingkah laku MPF.
Dalam bahagian berikut, anda akan belajar cara melakukan semua ini.
Memilih
Pilihan adalah bergantung pada pengguna akhir. Pada dasarnya, sebarang nilai boleh dipilih tetapi ada yang akan membawa kepada amplifikasi hingar yang lebih besar pada peranti sebenar berbanding pilihan lain. Oleh itu, adalah penting untuk cuba mencari nilai yang "baik".
Di sini, kita akan pilih nilai tetap untuk . Nilai terkecil didorong oleh masa evolusi sasaran yang biasanya memberitahu kita untuk memenuhi tetapi secara empirikal kita tahu bahawa menetapkannya sama dengan biasanya berfungsi juga. Jika anda ingin tahu lebih lanjut tentang ini dan cara memilih nilai yang lain, rujuk panduan berkaitan: Cara memilih langkah Trotter untuk MPF.
time = 8.0
trotter_steps = (8, 12, 19)
Menyediakan LSE
Sekarang setelah kita memilih , kita mesti terlebih dahulu bina LSE, seperti yang dijelaskan di atas.
Matriks bukan sahaja bergantung pada tetapi juga pilihan formula produk (PF) kita -- khususnya peringkatnya.
Selain itu, seseorang boleh mengambil kira sama ada PF adalah simetri atau tidak (lihat Carrera Vazquez et al., 2023), dengan menetapkan symmetric=True.
Namun, ini tidak diperlukan seperti yang ditunjukkan oleh Zhuk et al., 2023.
Di sini, kita akan menggunakan formula Suzuki-Trotter peringkat kedua yang menghasilkan order=2 dan kita akan tetapkan symmetric=True.
from qiskit_addon_mpf.static import setup_static_lse
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.]))
Menyelesaikan untuk secara analitik
Seperti yang disebutkan sebelum ini, kita boleh cari secara analitik:
import numpy as np
coeffs_analytical = lse.solve()
print(coeffs_analytical)
[ 0.17239057 -1.19447005 2.02207947]
Mengoptimumkan untuk menggunakan model tepat
Sebagai alternatif kepada mengira , anda juga boleh menggunakan setup_exact_problem untuk membina contoh cvxpy.Problem yang menggunakan LSE sebagai kekangan dan penyelesaian optimalnya akan menghasilkan .
Dalam bahagian seterusnya, akan jelas kenapa antara muka ini wujud.
from qiskit_addon_mpf.costs import setup_exact_problem
model_exact, coeffs_exact = setup_exact_problem(lse)
model_exact.solve()
print(coeffs_exact.value)
[ 0.17239057 -1.19447005 2.02207947]
Sebagai petunjuk sama ada MPF yang dibina dengan pekali ini akan menghasilkan keputusan yang baik, kita boleh menggunakan norma L1 (lihat juga Carrera Vazquez et al., 2023).
print(np.linalg.norm(coeffs_exact.value, ord=1))
3.3889400921655914
Mengoptimumkan untuk menggunakan model anggaran
Mungkin berlaku bahawa norma L1 untuk set nilai yang dipilih dianggap terlalu tinggi. Jika itu berlaku dan anda tidak boleh memilih set nilai yang berbeza, anda boleh menggunakan penyelesaian anggaran untuk LSE sebagai ganti penyelesaian tepat.
Untuk melakukannya, cuma gunakan setup_sum_of_squares_problem untuk membina contoh cvxpy.Problem yang berbeza yang mengehadkan norma L1 kepada ambang yang dipilih sambil meminimumkan perbezaan dan .
from qiskit_addon_mpf.costs import setup_sum_of_squares_problem
model_approx, coeffs_approx = setup_sum_of_squares_problem(lse, max_l1_norm=3.0)
model_approx.solve()
print(coeffs_approx.value)
print(np.linalg.norm(coeffs_approx.value, ord=1))
[-0.40454257 0.57553173 0.8290123 ]
1.8090865903790838
Perhatikan, anda ada kebebasan penuh tentang cara menyelesaikan masalah pengoptimuman ini, bermakna anda boleh menukar penyelesai pengoptimuman, ambang penumpuannya, dan sebagainya. Lihat panduan berkaitan tentang Cara menggunakan model anggaran.
1c: Menyediakan litar Trotter
Pada ketika ini, kita dah jumpa pekali pengembangan kita, , dan yang tinggal ialah menjana litar kuantum yang di-Trotterkan. Sekali lagi, modul qiskit_addon_utils.problem_generators datang menyelamatkan untuk buat benda tu:
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
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)

Langkah 2: Optimumkan masalah
Biasanya, ini adalah langkah dalam corak di mana anda mengoptimumkan litar untuk pelaksanaan pada perkakasan. Di sini, oleh sebab kita hanya menggunakan simulator tanpa hingar, kita cuma transpile litar kita untuk GenericBackendV2.
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit.transpiler import generate_preset_pass_manager
backend = GenericBackendV2(num_qubits=10)
transpiler = generate_preset_pass_manager(optimization_level=2, backend=backend)
transpiled_circuits = [transpiler.run(circ) for circ in circuits]
Langkah 3: Jalankan eksperimen kuantum
Seperti yang dijelaskan pada awal tadi, kita akan langkau langkah pengoptimuman 2 kerana kita cuma akan mengira nilai jangkaan observable sasaran kita menggunakan simulator bebas-hingar, iaitu StatevectorEstimator.
from qiskit.primitives import StatevectorEstimator
estimator = StatevectorEstimator()
job = estimator.run([(circ, observable) for circ in transpiled_circuits])
result = job.result()
Langkah 4: Bina semula keputusan
Pertama, kita ekstrak nilai jangkaan individu yang diperoleh untuk setiap litar Trotter:
evs = [res.data.evs for res in result]
print(evs)
[array(0.23799162), array(0.35754312), array(0.38649906)]
Seterusnya, kita gabungkan semula nilai-nilai itu dengan pekali MPF kita untuk menghasilkan nilai jangkaan keseluruhan MPF. Di bawah, kita buat begitu untuk setiap cara berbeza yang kita gunakan untuk mengira .
print("Analytical solution:", evs @ coeffs_analytical)
print("Exact model solution:", evs @ coeffs_exact.value)
print("Approx. model solution:", evs @ coeffs_approx.value)
Analytical solution: 0.3954847855980006
Exact model solution: 0.39548478559800204
Approx. model solution: 0.42991214253489807
Akhirnya, untuk masalah kecil ini kita boleh kira nilai rujukan tepat menggunakan scipy.linalg.expm seperti berikut:
from scipy.linalg import expm
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(exact_obs.real)
0.40060242487899755
Kita boleh nampak dengan jelas bahawa MPF telah mengurangkan ralat Trotter berbanding yang diperoleh dengan PF individu paling dalam dengan . Namun, kita juga nampak bahawa model anggaran tidak sempurna kerana ia sebenarnya menghasilkan nilai jangkaan yang lebih buruk daripada penyelesaian tepat. Ini menunjukkan kepentingan menggunakan kriteria penumpuan yang ketat pada model anggaran seperti yang akan anda pelajari dalam panduan Cara menggunakan model anggaran.