Memulai dengan Approximate quantum compilation dengan tensor networks (AQC-Tensor)
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-aer~=0.17
qiskit-addon-utils~=0.3.0
qiskit-addon-aqc-tensor[aer,quimb-jax]~=0.2.0; sys.platform != 'darwin'
scipy~=1.16.3
Panduan ini menunjukkan contoh kerja sederhana untuk memulai dengan AQC-Tensor. Dalam contoh ini, kamu akan mengambil circuit Trotter yang mensimulasikan evolusi model Ising medan transversal dan menggunakan metode AQC-Tensor untuk mengurangi kedalaman circuit yang dihasilkan. Selain itu, contoh ini memerlukan paket qiskit-addon-utils untuk generator masalah, qiskit-aer untuk simulasi tensor-network, dan scipy untuk optimasi parameter.
Untuk memulai, ingat bahwa Hamiltonian model Ising medan transversal memiliki bentuk
di mana kita akan mengasumsikan kondisi batas periodik yang menyiratkan bahwa untuk kita mendapatkan dan adalah kekuatan kopling antara dua situs dan adalah kekuatan medan magnet eksternal.
Potongan kode berikut akan menghasilkan Hamiltonian dari rantai Ising 10 situs dengan kondisi batas periodik.
# Added by doQumentation β required packages for this notebook
!pip install -q qiskit qiskit-addon-aqc-tensor qiskit-addon-utils qiskit-aer scipy
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import (
generate_time_evolution_circuit,
)
from qiskit_addon_aqc_tensor import generate_ansatz_from_circuit
from qiskit_addon_aqc_tensor.simulation import tensornetwork_from_circuit
from qiskit_addon_aqc_tensor.simulation import compute_overlap
from qiskit_addon_aqc_tensor.objective import MaximizeStateFidelity
from qiskit_aer import AerSimulator
from scipy.optimize import OptimizeResult, minimize
# Generate some coupling map to use for this example
coupling_map = CouplingMap.from_heavy_hex(3, bidirectional=False)
# Choose a 10-qubit circle on this coupling map
reduced_coupling_map = coupling_map.reduce(
[0, 13, 1, 14, 10, 16, 4, 15, 3, 9]
)
# Get a qubit operator describing the Ising field model
hamiltonian = generate_xyz_hamiltonian(
reduced_coupling_map,
coupling_constants=(0.0, 0.0, 1.0),
ext_magnetic_field=(0.4, 0.0, 0.0),
)
Pisahkan evolusi waktu menjadi dua bagian untuk eksekusi klasik dan kuantumβ
Tujuan keseluruhan dari contoh ini adalah mensimulasikan evolusi waktu dari Hamiltonian model. Kita lakukan hal itu di sini dengan evolusi Trotter, yang akan dibagi menjadi dua bagian.
- Bagian awal yang dapat disimulasikan menggunakan matrix product states (MPS). Inilah yang akan 'dikompilasi' menggunakan AQC-Tensor.
- Bagian selanjutnya yang akan dieksekusi pada perangkat keras kuantum.
Kita akan memilih untuk mengevolusi sistem hingga waktu dan menggunakan AQC-Tensor untuk mengompresi evolusi waktu hingga waktu , kemudian mengevolusi menggunakan langkah Trotter biasa hingga .
Dari sini kita akan menghasilkan dua circuit, satu yang akan dikompres menggunakan AQC-Tensor dan satu yang akan dieksekusi pada QPU. Untuk circuit pertama, karena ini akan disimulasikan secara klasik menggunakan matrix product states, kita akan menggunakan jumlah lapisan yang banyak untuk meminimalkan kesalahan Trotter. Sementara itu circuit kedua yang mensimulasikan evolusi waktu dari ke akan menggunakan jauh lebih sedikit lapisan untuk meminimalkan kedalaman.
# Generate circuit to be compressed
aqc_evolution_time = 4.0
aqc_target_num_trotter_steps = 45
aqc_target_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),
time=aqc_evolution_time,
)
# Generate circuit to execute on hardware
subsequent_evolution_time = 1.0
subsequent_num_trotter_steps = 5
subsequent_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=subsequent_num_trotter_steps),
time=subsequent_evolution_time,
)
Untuk tujuan perbandingan, kita juga akan menghasilkan circuit ketiga. Satu yang berevolusi hingga , tetapi yang memiliki jumlah lapisan yang sama dengan circuit kedua yang berevolusi dari ke . Inilah circuit yang akan kita eksekusi jika kita tidak menggunakan teknik AQC-Tensor. Kita sebut ini sebagai circuit perbandingan untuk saat ini.
aqc_comparison_num_trotter_steps = int(
subsequent_num_trotter_steps
/ subsequent_evolution_time
* aqc_evolution_time
)
aqc_comparison_num_trotter_steps
comparison_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_comparison_num_trotter_steps),
time=aqc_evolution_time,
)
Hasilkan ansatz dan buat simulasi MPSβ
Selanjutnya kita akan menghasilkan ansatz yang akan kita optimalkan. Ia akan berevolusi ke waktu evolusi yang sama dengan circuit pertama kita (dari ke ), tetapi dengan lebih sedikit langkah Trotter.
Setelah circuit dihasilkan, kita kemudian meneruskannya ke fungsi generate_ansatz_from_circuit() dari AQC-Tensor yang menganalisis konektivitas dua-Qubit dan mengembalikan dua hal. Pertama adalah circuit ansatz yang dihasilkan dengan konektivitas dua-Qubit yang sama, dan kedua adalah sekumpulan parameter yang, ketika dimasukkan ke ansatz, menghasilkan circuit input.
aqc_ansatz_num_trotter_steps = 5
aqc_good_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),
time=aqc_evolution_time,
)
aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(
aqc_good_circuit, qubits_initially_zero=True
)
aqc_ansatz.draw("mpl", fold=-1)
Selanjutnya kita akan membangun representasi MPS dari state yang akan diaproksimasi oleh AQC. Kita juga akan menghitung fidelitas antara state yang disiapkan oleh circuit perbandingan vs circuit yang menghasilkan state target (yang menggunakan lebih banyak langkah Trotter).
# Generate MPS simulator settings and obtain the MPS representation of the target state
simulator_settings = AerSimulator(
method="matrix_product_state",
matrix_product_state_max_bond_dimension=100,
)
aqc_target_mps = tensornetwork_from_circuit(
aqc_target_circuit, simulator_settings
)
# Compute the fidelity between the MPS representation of the target state and the state produced by the comparison circuit
comparison_mps = tensornetwork_from_circuit(
comparison_circuit, simulator_settings
)
comparison_fidelity = (
abs(compute_overlap(comparison_mps, aqc_target_mps)) ** 2
)
print(f"Comparison fidelity: {comparison_fidelity}")
Comparison fidelity: 0.9997111919739693
Optimalkan parameter ansatz menggunakan MPSβ
Terakhir, kita akan mengoptimalkan circuit ansatz agar menghasilkan state target dengan fidelitas yang lebih tinggi dari comparison_fidelity kita. Fungsi biaya yang akan diminimalkan adalah MaximizeStateFidelity dan akan dioptimalkan menggunakan optimizer L-BFGS dari scipy.
objective = MaximizeStateFidelity(
aqc_target_mps, aqc_ansatz, simulator_settings
)
stopping_point = 1 - comparison_fidelity
def callback(intermediate_result: OptimizeResult):
print(f"Intermediate result: Fidelity {1 - intermediate_result.fun:.8}")
if intermediate_result.fun < stopping_point:
# Good enough for now
raise StopIteration
result = minimize(
objective,
aqc_initial_parameters,
method="L-BFGS-B",
jac=True,
options={"maxiter": 100},
callback=callback,
)
if (
result.status
not in (
0,
1,
99,
)
): # 0 => success; 1 => max iterations reached; 99 => early termination via StopIteration
raise RuntimeError(
f"Optimization failed: {result.message} (status={result.status})"
)
print(f"Done after {result.nit} iterations.")
aqc_final_parameters = result.x
Intermediate result: Fidelity 0.95084365
Intermediate result: Fidelity 0.98409893
Intermediate result: Fidelity 0.99142033
Intermediate result: Fidelity 0.99521405
Intermediate result: Fidelity 0.99566673
Intermediate result: Fidelity 0.99650054
Intermediate result: Fidelity 0.99683487
Intermediate result: Fidelity 0.99720426
Intermediate result: Fidelity 0.99761726
Intermediate result: Fidelity 0.99809073
Intermediate result: Fidelity 0.99838244
Intermediate result: Fidelity 0.99861841
Intermediate result: Fidelity 0.99874617
Intermediate result: Fidelity 0.99892696
Intermediate result: Fidelity 0.99908129
Intermediate result: Fidelity 0.99917737
Intermediate result: Fidelity 0.99925456
Intermediate result: Fidelity 0.99933134
Intermediate result: Fidelity 0.99947173
Intermediate result: Fidelity 0.99956469
Intermediate result: Fidelity 0.99964488
Intermediate result: Fidelity 0.99967419
Intermediate result: Fidelity 0.99968821
Intermediate result: Fidelity 0.9997448
Done after 24 iterations.
Pada titik ini kita memiliki sekumpulan parameter yang menghasilkan state target dengan fidelitas lebih tinggi dari yang akan dihasilkan circuit perbandingan tanpa menggunakan AQC. Dengan parameter optimal ini, circuit yang telah dikompres sekarang memiliki kesalahan Trotter yang lebih kecil dan kedalaman yang lebih kecil dibanding circuit aslinya.
Sebagai langkah terakhir, potongan kode berikut membangun circuit evolusi waktu lengkap yang bisa diteruskan ke pipeline Transpiler dan dieksekusi pada perangkat keras kuantum.
final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)
final_circuit.compose(subsequent_circuit, inplace=True)
final_circuit.draw("mpl", fold=-1)
Langkah selanjutnyaβ
- Coba tutorial Approximate quantum compilation untuk circuit evolusi waktu.