Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Halo AHS: Jalankan Simulasi Hamiltonian Analog pertama Anda
AHS
Simulasi Hamiltonian Analog
Perangkat kuantum yang mampu melakukan AHS akan menyetel parameternya (misalnya amplitudo dan detuning medan penggerak yang koheren) untuk mendekati evolusi waktu sistem kuantum di bawah Hamiltonian khusus. Paradigma AHS cocok untuk mensimulasikan sifat statis dan dinamis dari sistem kuantum dari banyak partikel yang berinteraksi. QPU yang dibuat khusus, seperti perangkat Aquila
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 “atas”). 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.](images/AntiFerromagnetic.png)
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 menginstal Braket SDK.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
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.](images/PlotNeutralAtoms.png)
Interaksi
Untuk mempersiapkan fase anti-feromagnetik, kita perlu menginduksi interaksi antara putaran tetangga. Kami menggunakan interaksi van der Waals
![Persamaan interaksi Hamilton yang menunjukkan interaksi ini dinyatakan sebagai jumlah atas semua pasangan spin (j, k).](images/HInteraction.png)
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 program AHS, interaksi ini akan mencegah putaran tetangga dari keduanya berada dalam keadaan “naik”, efek yang umumnya dikenal sebagai “blokade Rydberg.”
Bidang mengemudi
Pada awal program AHS, 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.](images/HDrive.png)
di mana Ω (t), φ (t), Δ (t) adalah amplitudo global yang bergantung pada waktu (alias frekuensi Rabi
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.](images/DrivingTimeSeries.png)
Program AHS
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 QPU yang kompatibel dengan AHS, kita dapat menjalankannya di simulator AHS lokal yang dilengkapi dengan Braket SDK. Karena simulator lokal tersedia secara gratis dengan Braket SDK, 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.](images/AHSCounts1.png)
![Bagan batang menunjukkan bidikan beberapa konfigurasi status “naik” tetangga, dengan status turun dari nilai tinggi ke rendah.](images/AHSCounts2.png)
Dari plot, kita dapat membaca pengamatan berikut verifikasi bahwa kita berhasil menyiapkan fase anti-feromagnetik.
-
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”.
-
Umumnya, status dengan lebih banyak eksitasi “naik” lebih disukai, kecuali konfigurasi diblokade.
-
Keadaan yang paling umum memang merupakan keadaan anti-feromagnetik yang sempurna dan.
"dudududu"
"udududud"
-
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
catatan
Jika Anda menggunakan instance notebook yang dihosting Braket, Braket SDK sudah diinstal sebelumnya dengan instance tersebut.
Dengan semua dependensi diinstal, kita dapat terhubung ke QPU. Aquila
from braket.aws import AwsDevice aquila_qpu = AwsDevice("arn:aws:braket:us-east-1::device/qpu/quera/Aquila")
Untuk membuat program AHS kami cocok untuk QuEra mesin, kami 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 Aquiladiscretize
metode.
discretized_ahs_program = ahs_program.discretize(aquila_qpu)
Sekarang kita dapat menjalankan program (hanya menjalankan 100 tembakan untuk saat ini) pada Aquila QPU.
catatan
Menjalankan program ini pada Aquila prosesor akan dikenakan biaya. Amazon Braket SDK menyertakan Cost Tracker
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 pemanfaatan QPU), ada baiknya untuk mencatat ARN tugas kuantum, 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 status SELESAI (yang juga dapat diperiksa dari halaman tugas kuantum konsol
result_aquila = task.result()
Menganalisis hasil QPU
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.](images/QPUPlotCounts.png)
Perhatikan bahwa sebagian kecil bidikan memiliki situs kosong (ditandai dengan “e”). Hal ini disebabkan oleh ketidaksempurnaan persiapan atom 1-2% per atom dari QPU. Aquila Selain itu, hasilnya cocok dengan simulasi dalam fluktuasi statistik yang diharapkan karena sejumlah kecil tembakan.
Selanjutnya
Selamat, Anda sekarang telah menjalankan beban kerja AHS pertama Anda di Amazon Braket menggunakan simulator AHS lokal dan QPU. Aquila