HaloAHS: Jalankan Simulasi Hamiltonian Analog pertama Anda - Amazon Braket

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

HaloAHS: Jalankan Simulasi Hamiltonian Analog pertama Anda

Bagian ini memberikan informasi tentang menjalankan Simulasi Hamiltonian Analog pertama Anda.

Rantai spin yang berinteraksi

Untuk contoh kanonik dari sistem banyak partikel yang berinteraksi, mari kita pertimbangkan cincin delapan putaran (yang masing-masing dapat berada dalam keadaan “naik” dan “bawah”). Meskipun kecil, sistem model ini sudah menunjukkan beberapa fenomena menarik dari bahan magnetik yang terjadi secara alami. Dalam contoh ini, kami akan menunjukkan bagaimana menyiapkan apa yang disebut urutan anti-feromagnetik, di mana putaran berturut-turut mengarah ke arah yang berlawanan.

Diagram menghubungkan 8 simpul lingkaran yang berisi panah terbalik ke atas dan ke bawah.

Pengaturan

Kita akan menggunakan satu atom netral untuk mewakili setiap putaran, dan status putaran “atas” dan “bawah” akan dikodekan dalam keadaan Rydberg yang tereksitasi dan keadaan dasar atom, masing-masing. Pertama, kami membuat pengaturan 2-d. Kita dapat memprogram cincin putaran di atas dengan kode berikut.

Prasyarat: Anda perlu memasang pip Braket. SDK (Jika Anda menggunakan instance notebook yang dihosting Braket, ini sudah SDK diinstal sebelumnya dengan notebook.) Untuk mereproduksi plot, Anda juga perlu menginstal matplotlib secara terpisah dengan perintah shell. pip install matplotlib

import numpy as np import matplotlib.pyplot as plt # required for plotting from braket.ahs.atom_arrangement import AtomArrangement a = 5.7e-6 # nearest-neighbor separation (in meters) register = AtomArrangement() register.add(np.array([0.5, 0.5 + 1/np.sqrt(2)]) * a) register.add(np.array([0.5 + 1/np.sqrt(2), 0.5]) * a) register.add(np.array([0.5 + 1/np.sqrt(2), - 0.5]) * a) register.add(np.array([0.5, - 0.5 - 1/np.sqrt(2)]) * a) register.add(np.array([-0.5, - 0.5 - 1/np.sqrt(2)]) * a) register.add(np.array([-0.5 - 1/np.sqrt(2), - 0.5]) * a) register.add(np.array([-0.5 - 1/np.sqrt(2), 0.5]) * a) register.add(np.array([-0.5, 0.5 + 1/np.sqrt(2)]) * a)

yang juga bisa kita rencanakan dengan

fig, ax = plt.subplots(1, 1, figsize=(7,7)) xs, ys = [register.coordinate_list(dim) for dim in (0, 1)] ax.plot(xs, ys, 'r.', ms=15) for idx, (x, y) in enumerate(zip(xs, ys)): ax.text(x, y, f" {idx}", fontsize=12) plt.show() # this will show the plot below in an ipython or jupyter session
Plot sebar menunjukkan poin yang didistribusikan di seluruh nilai positif dan negatif pada kedua sumbu.

Interaksi

Untuk mempersiapkan fase anti-feromagnetik, kita perlu menginduksi interaksi antara putaran tetangga. Kami menggunakan interaksi van der Waals untuk ini, yang secara native diimplementasikan oleh perangkat atom netral (seperti Aquila perangkat dari QuEra). Menggunakan spin-representasi, istilah Hamiltonian untuk interaksi ini dapat dinyatakan sebagai jumlah atas semua pasangan spin (j, k).

Persamaan interaksi Hamilton yang menunjukkan interaksi ini dinyatakan sebagai jumlah atas semua pasangan spin (j, k).

Di sini, nj=↑ j ⟨↑ adalah j operator yang mengambil nilai 1 hanya jika spin j berada dalam keadaan “naik”, dan 0 sebaliknya. Kekuatannya adalah V j,k =C6/(dj,k​) 6, dimana C 6 adalah koefisien tetap, dan d j,k adalah jarak Euclidean antara spin j dan k. Efek langsung dari istilah interaksi ini adalah bahwa setiap keadaan di mana spin j dan spin k “naik” memiliki energi yang meningkat (dengan jumlah Vj,k). Dengan hati-hati merancang sisa AHS program, interaksi ini akan mencegah putaran tetangga dari keduanya berada dalam keadaan “naik”, efek yang umumnya dikenal sebagai “blokade Rydberg.”

Bidang mengemudi

Pada awal AHS program, semua putaran (secara default) dimulai dalam keadaan “turun”, mereka berada dalam apa yang disebut fase feromagnetik. Mengawasi tujuan kami untuk mempersiapkan fase anti-feromagnetik, kami menentukan medan penggerak koheren yang bergantung pada waktu yang dengan lancar mentransisikan putaran dari keadaan ini ke keadaan banyak tubuh di mana keadaan “naik” lebih disukai. Hamiltonian yang sesuai dapat ditulis sebagai

Persamaan matematika yang menggambarkan perhitungan fungsi drive Hamiltonian.

di mana Ω (t), φ (t), Δ (t) adalah amplitudo global yang bergantung pada waktu (alias frekuensi Rabi), fase, dan detuning medan penggerak yang mempengaruhi semua putaran secara seragam. Di sini S −,k =↓ k​ ⟨↑ ↑ k and S +,k =( S−,k) =↑ k​ ⟨↓ k adalah operator penurun dan peningkatan spin k, masing-masing, dan n k =↑ ⟨↑ adalah operator yang sama seperti sebelumnya. k k Bagian Ω dari medan mengemudi secara koheren menggabungkan status “turun” dan “naik” dari semua putaran secara bersamaan, sedangkan bagian Δ mengontrol hadiah energi untuk keadaan “naik”.

Untuk memprogram transisi yang mulus dari fase feromagnetik ke fase anti-feromagnetik, kami menentukan bidang penggerak dengan kode berikut.

from braket.timings.time_series import TimeSeries from braket.ahs.driving_field import DrivingField # smooth transition from "down" to "up" state time_max = 4e-6 # seconds time_ramp = 1e-7 # seconds omega_max = 6300000.0 # rad / sec delta_start = -5 * omega_max delta_end = 5 * omega_max omega = TimeSeries() omega.put(0.0, 0.0) omega.put(time_ramp, omega_max) omega.put(time_max - time_ramp, omega_max) omega.put(time_max, 0.0) delta = TimeSeries() delta.put(0.0, delta_start) delta.put(time_ramp, delta_start) delta.put(time_max - time_ramp, delta_end) delta.put(time_max, delta_end) phi = TimeSeries().put(0.0, 0.0).put(time_max, 0.0) drive = DrivingField( amplitude=omega, phase=phi, detuning=delta )

Kita dapat memvisualisasikan deret waktu bidang mengemudi dengan skrip berikut.

fig, axes = plt.subplots(3, 1, figsize=(12, 7), sharex=True) ax = axes[0] time_series = drive.amplitude.time_series ax.plot(time_series.times(), time_series.values(), '.-'); ax.grid() ax.set_ylabel('Omega [rad/s]') ax = axes[1] time_series = drive.detuning.time_series ax.plot(time_series.times(), time_series.values(), '.-'); ax.grid() ax.set_ylabel('Delta [rad/s]') ax = axes[2] time_series = drive.phase.time_series # Note: time series of phase is understood as a piecewise constant function ax.step(time_series.times(), time_series.values(), '.-', where='post'); ax.set_ylabel('phi [rad]') ax.grid() ax.set_xlabel('time [s]') plt.show() # this will show the plot below in an ipython or jupyter session
Tiga grafik yang menunjukkan phi, delta, dan omega dari waktu ke waktu. Subplot teratas menunjukkan pertumbuhan tepat di atas 6 rads/s di mana ia tetap selama 4 detik hingga turun kembali ke 0. Subplot tengah menggambarkan pertumbuhan linier terkait turunan, dan subplot bawah menggambarkan garis datar mendekati nol.

AHSprogram

Register, bidang mengemudi, (dan interaksi van der Waals implisit) membentuk program Simulasi Hamiltonian Analog. ahs_program

from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation ahs_program = AnalogHamiltonianSimulation( register=register, hamiltonian=drive )

Berjalan di simulator lokal

Karena contoh ini kecil (kurang dari 15 putaran), sebelum menjalankannya pada AHS -kompatibelQPU, kita dapat menjalankannya di AHS simulator lokal yang disertakan dengan SDK Braket. Karena simulator lokal tersedia secara gratis dengan BraketSDK, ini adalah praktik terbaik untuk memastikan bahwa kode kami dapat dijalankan dengan benar.

Di sini, kita dapat mengatur jumlah bidikan ke nilai tinggi (katakanlah, 1 juta) karena simulator lokal melacak evolusi waktu status kuantum dan mengambil sampel dari keadaan akhir; karenanya, meningkatkan jumlah bidikan, sambil meningkatkan total runtime hanya sedikit.

from braket.devices import LocalSimulator device = LocalSimulator("braket_ahs") result_simulator = device.run( ahs_program, shots=1_000_000 ).result() # takes about 5 seconds

Menganalisis hasil simulator

Kami dapat menggabungkan hasil bidikan dengan fungsi berikut yang menyimpulkan status setiap putaran (yang mungkin “d” untuk “bawah”, “u” untuk “naik”, atau “e” untuk situs kosong), dan menghitung berapa kali setiap konfigurasi terjadi di seluruh bidikan.

from collections import Counter def get_counts(result): """Aggregate state counts from AHS shot results A count of strings (of length = # of spins) are returned, where each character denotes the state of a spin (site): e: empty site u: up state spin d: down state spin Args: result (braket.tasks.analog_hamiltonian_simulation_quantum_task_result.AnalogHamiltonianSimulationQuantumTaskResult) Returns dict: number of times each state configuration is measured """ state_counts = Counter() states = ['e', 'u', 'd'] for shot in result.measurements: pre = shot.pre_sequence post = shot.post_sequence state_idx = np.array(pre) * (1 + np.array(post)) state = "".join(map(lambda s_idx: states[s_idx], state_idx)) state_counts.update((state,)) return dict(state_counts) counts_simulator = get_counts(result_simulator) # takes about 5 seconds print(counts_simulator)
{'udududud': 330944, 'dudududu': 329576, 'dududdud': 38033, ...}

Berikut counts adalah kamus yang menghitung berapa kali setiap konfigurasi status diamati di seluruh bidikan. Kami juga dapat memvisualisasikannya dengan kode berikut.

from collections import Counter def has_neighboring_up_states(state): if 'uu' in state: return True if state[0] == 'u' and state[-1] == 'u': return True return False def number_of_up_states(state): return Counter(state)['u'] def plot_counts(counts): non_blockaded = [] blockaded = [] for state, count in counts.items(): if not has_neighboring_up_states(state): collection = non_blockaded else: collection = blockaded collection.append((state, count, number_of_up_states(state))) blockaded.sort(key=lambda _: _[1], reverse=True) non_blockaded.sort(key=lambda _: _[1], reverse=True) for configurations, name in zip((non_blockaded, blockaded), ('no neighboring "up" states', 'some neighboring "up" states')): plt.figure(figsize=(14, 3)) plt.bar(range(len(configurations)), [item[1] for item in configurations]) plt.xticks(range(len(configurations))) plt.gca().set_xticklabels([item[0] for item in configurations], rotation=90) plt.ylabel('shots') plt.grid(axis='y') plt.title(f'{name} configurations') plt.show() plot_counts(counts_simulator)
Bagan batang menunjukkan sejumlah besar bidikan tanpa konfigurasi status “naik” tetangga.
Bagan batang menunjukkan bidikan beberapa konfigurasi status “naik” tetangga, dengan status turun dari nilai tinggi ke rendah.

Dari plot, kita dapat membaca pengamatan berikut verifikasi bahwa kita berhasil menyiapkan fase anti-feromagnetik.

  1. Umumnya, negara bagian yang tidak diblokade (di mana tidak ada dua putaran tetangga yang berada dalam keadaan “naik”) lebih umum daripada negara bagian di mana setidaknya satu pasang putaran tetangga keduanya berada dalam keadaan “naik”.

  2. Umumnya, status dengan lebih banyak eksitasi “naik” lebih disukai, kecuali konfigurasi diblokade.

  3. Keadaan yang paling umum memang merupakan keadaan anti-feromagnetik yang sempurna dan. "dudududu" "udududud"

  4. Keadaan paling umum kedua adalah keadaan di mana hanya ada 3 eksitasi “naik” dengan pemisahan berturut-turut 1, 2, 2. Ini menunjukkan bahwa interaksi van der Waals memiliki pengaruh (meskipun jauh lebih kecil) pada tetangga terdekat berikutnya juga.

Berjalan di QuEra Aquila QPU

Prasyarat: Selain pip menginstal Braket SDK, jika Anda baru mengenal Amazon Braket, pastikan Anda telah menyelesaikan langkah-langkah Memulai yang diperlukan.

catatan

Jika Anda menggunakan instance notebook yang dihosting Braket, Braket sudah SDK diinstal sebelumnya dengan instance.

Dengan semua dependensi diinstal, kita dapat terhubung ke Aquila QPU.

from braket.aws import AwsDevice aquila_qpu = AwsDevice("arn:aws:braket:us-east-1::device/qpu/quera/Aquila")

Untuk membuat AHS program kami cocok untuk QuEra mesin, kita perlu membulatkan semua nilai untuk memenuhi tingkat presisi yang diizinkan oleh Aquila QPU. (Persyaratan ini diatur oleh parameter perangkat dengan “Resolusi” dalam namanya. Kita bisa melihatnya dengan mengeksekusi aquila_qpu.properties.dict() di notebook. Untuk detail lebih lanjut tentang kemampuan dan persyaratan Aquila, lihat buku catatan Pengantar Aquila.) Kita bisa melakukan ini dengan memanggil discretize metode.

discretized_ahs_program = ahs_program.discretize(aquila_qpu)

Sekarang kita dapat menjalankan program (hanya menjalankan 100 tembakan untuk saat ini) di Aquila QPU.

catatan

Menjalankan program ini di Aquila Prosesor akan dikenakan biaya. Amazon Braket SDK mencakup Pelacak Biaya yang memungkinkan pelanggan untuk menetapkan batas biaya serta melacak biaya mereka dalam waktu dekat.

task = aquila_qpu.run(discretized_ahs_program, shots=100) metadata = task.metadata() task_arn = metadata['quantumTaskArn'] task_status = metadata['status'] print(f"ARN: {task_arn}") print(f"status: {task_status}")
task ARN: arn:aws:braket:us-east-1:123456789012:quantum-task/12345678-90ab-cdef-1234-567890abcdef task status: CREATED

Karena varians yang besar tentang berapa lama tugas kuantum dapat dijalankan (tergantung pada jendela ketersediaan dan QPU pemanfaatan), ada baiknya untuk mencatat tugas kuantumARN, sehingga kami dapat memeriksa statusnya di lain waktu dengan cuplikan kode berikut.

# Optionally, in a new python session from braket.aws import AwsQuantumTask SAVED_TASK_ARN = "arn:aws:braket:us-east-1:123456789012:quantum-task/12345678-90ab-cdef-1234-567890abcdef" task = AwsQuantumTask(arn=SAVED_TASK_ARN) metadata = task.metadata() task_arn = metadata['quantumTaskArn'] task_status = metadata['status'] print(f"ARN: {task_arn}") print(f"status: {task_status}")
*[Output]* task ARN: arn:aws:braket:us-east-1:123456789012:quantum-task/12345678-90ab-cdef-1234-567890abcdef task status: COMPLETED

Setelah statusnya COMPLETED (yang juga dapat diperiksa dari halaman tugas kuantum konsol Amazon Braket), kami dapat menanyakan hasilnya dengan:

result_aquila = task.result()

Menganalisis QPU hasil

Menggunakan get_counts fungsi yang sama seperti sebelumnya, kita dapat menghitung hitungan:

counts_aquila = get_counts(result_aquila) print(counts_aquila)
*[Output]* {'udududud': 24, 'dudududu': 17, 'dududdud': 3, ...}

dan plot mereka denganplot_counts:

plot_counts(counts_aquila)
Bagan batang menunjukkan tingkat pemotretan dengan dan tanpa status “naik” tetangga.

Perhatikan bahwa sebagian kecil bidikan memiliki situs kosong (ditandai dengan “e”). Hal ini disebabkan oleh ketidaksempurnaan persiapan 1— 2% per atom dari Aquila QPU. Selain itu, hasilnya cocok dengan simulasi dalam fluktuasi statistik yang diharapkan karena sejumlah kecil tembakan.

Langkah selanjutnya

Selamat, Anda sekarang telah menjalankan AHS beban kerja pertama Anda di Amazon Braket menggunakan simulator lokal dan AHS Aquila QPU.

Untuk mempelajari lebih lanjut tentang fisika Rydberg, Simulasi Hamiltonian Analog dan Aquila perangkat, lihat contoh notebook kami.