您好 AHS:運行您的第一個模擬哈密頓模擬 - Amazon Braket

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

您好 AHS:運行您的第一個模擬哈密頓模擬

AHS

擬哈密頓模擬(AHS)是量子計算的一種範式,與量子電路不同:而不是一系列門,每個門一次僅作用於幾個量子比特,而是由所討論的哈密頓時間和空間相關參數來定義。一個系統的哈密頓計算了它的能量水平和外力的影響,共同控制了其狀態的時間演變。對於 N 量子比特系統,哈密爾頓可以由複數的 2 N X2 N N 平方矩陣來表示。

能夠執行 AHS 的量子設備將調整其參數(例如相干驅動場的振幅和除諧),以密切近似定制哈密頓定制下量子系統的時間演變。AHS 範式適用於模擬許多交互作用粒子的量子系統的靜態和動態特性。依據特定目的建置的 QPU,例如 Aquila 裝置,QuEra可以模擬系統的時間變化,而這些尺寸在傳統硬體上是不可行的。

互動式旋轉鏈

對於許多相互作用粒子系統的標準示例,讓我們考慮一圈八次旋轉(每個旋轉都可以在「向上」∣ ↑和「向下」∣ ↓狀態)。雖然很小,這個模型系統已經展現出了一些天然存在的磁性材料的有趣現象。在此示例中,我們將展示如何準備所謂的反鐵磁順序,其中連續旋轉指向相反的方向。

圖連接包含反向上和向下箭頭 8 圓節點。

安排

我們將使用一個中性原子來代表每次旋轉,「向上」和「向下」旋轉狀態將分別編碼為 Rydberg 狀態和原子的接地狀態。首先,我們創建 2-d 排列。我們可以使用以下代碼編程上述旋轉環。

先決條件:您需要點安裝布拉基特 SDK。(如果您使用的是 Braket 託管的筆記本實例,則此 SDK 已預先安裝在筆記本中。) 要重現繪圖,您還需要使用 shell 命令單獨安裝 matplotlib。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)

我們也可以繪製

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
散點圖顯示分佈在兩個軸上的正值和負值上的點。

互動

為了準備防鐵磁相,我們需要誘導相鄰旋轉之間的相互作用。我們為此使用范德華互動,該交互作用是由中性原子設備(例如來QuEra自的設備)本身實現的Aquila。使用旋轉表示法,此相互作用的哈密頓術語可以表示為所有自旋對(j,k)的總和。

哈密頓交互方程式將此相互作用顯示為所有自旋對(j,k)的總和。

在這裡,nj=∣ ↑ jj ∣ 是一個運算符,只有當旋轉 j 處於「向上」狀態時才接受值 1,否則為 0。強度為 V j,k = C6/(dj,k​6,其中 C 6 是固定係數,d j,k 是旋轉 j 和 k 之間的歐幾里得距離。這個相互作用術語的直接效果是,旋轉 j 和旋轉 k 都「向上」的任何狀態都會提高能量(由量 Vj,k)。通過仔細設計 AHS 程序的其餘部分,這種交互將防止相鄰旋轉都處於「向上」狀態,這種效果通常稱為「Rydberg 封鎖」。

駕駛領域

在 AHS 程序的開始時,所有旋轉(默認情況下)都以「向下」狀態開始,它們處於所謂的鐵磁相。密切關注我們準備防鐵磁相的目標,我們指定了一個依賴於時間的相干驅動場,該領域可以將旋轉從此狀態平穩地轉換為多體狀態,其中「向上」狀態是首選的。相應的哈密頓軸可以寫成

描述哈密頓驅動函數計算的數學方程式。

其中 Ω(t),(t),Δ(t)是均勻影響所有旋轉的時間依賴性,全球幅度(又名拉比頻率),相位和解調。這裡 S −,k =∣ ↓ k​ ↑ ∣ k 和 S +,k = (S−,k) =∣ ↑ k​k ∣ 分別是旋轉 k 的降低和提高運算子,n k =∣ ↑ ↑ ∣ 和以前相同的操作員。k k驅動場的 Ω 部分連貫地結合所有旋轉的「向下」和「上」狀態,而 Δ 部分則控制「向上」狀態的能量獎勵。

為了編程從鐵磁相到抗鐵磁相的平滑過渡,我們使用以下代碼指定驅動場。

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 )

我們可以使用以下腳本可視化驅動場的時間序列。

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
隨著時間的推移顯示 phi,三角洲和歐米茄的三個圖表。頂部子圖顯示增長到剛剛高於 6 個 Rads/s,其中停留 4 秒,直到它回落到 0。中間子圖描繪了導數的相關線性增長,底部子圖說明了接近零的平線。

AHS 計劃

寄存器,驅動場(以及隱含的范德華交互作用)構成了模擬哈密頓仿真程序。ahs_program

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

在本地模擬器上運行

由於此示例很小(小於 15 次旋轉),因此在與 AHS 兼容的 QPU 上運行之前,我們可以在 Braket SDK 附帶的本地 AHS 模擬器上運行它。由於 Braket SDK 可免費使用本地模擬器,因此這是確保我們的代碼可以正確執行的最佳實踐。

在這裡,我們可以將拍攝數量設置為高值(例如 100 萬),因為本地模擬器跟踪量子狀態的時間演變並從最終狀態中抽取樣本;因此,增加拍攝數量,同時僅略微增加總運行時間。

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

分析模擬器結果

我們可以使用以下函數聚合拍攝結果,該函數推斷每次旋轉的狀態(可能是「d」表示「向下」,「u」表示「向上」,或「e」表示空站點),並計算每個配置在鏡頭中發生的次數。

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, ...}

counts是一個字典,用於計算每個狀態配置在鏡頭中觀察到的次數。我們也可以用下面的代碼可視化它們。

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)
長條圖顯示大量沒有相鄰「向上」狀態配置的鏡頭。
橫條圖顯示一些相鄰「向上」狀態配置的鏡頭,狀態從高到低值降序。

從圖中,我們可以閱讀以下觀察結果驗證,我們成功地準備了抗鐵磁相。

  1. 通常,非阻塞狀態(其中沒有兩個相鄰旋轉處於「向上」狀態)比至少一對相鄰旋轉都處於「向上」狀態的州更為常見。

  2. 通常,除非配置被阻止,否則有更多「向上」激振的狀態會受到青睞。

  3. 最常見的狀態確實是完美的抗鐵磁狀態和. "dudududu" "udududud"

  4. 第二個最常見的狀態是那些只有 3 個「向上」激振,連續分離為 1,2,2。這表明凡德華互動也會對下一個最近的鄰居產生影響(儘管要小得多)。

跑上 QuEra的阿奎拉 QPU

先決條件:除了安裝 Braket SDK 的 pip 外,如果您是 Amazon Braket 的新手,請確認您已完成必要的入門步驟。

注意

如果您使用的是 Braket 託管的筆記本執行個體,Braket SDK 會預先安裝在執行個體中。

安裝所有依賴關係後,我們可以連接到 Aquila QPU。

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

為了使我們的 AHS 程序適用於QuEra機器,我們需要對所有值進行四捨五入以符合 Aquila QPU 允許的精度級別。(這些要求由名稱中帶有「解析度」的設備參數控制。 我們可以通過在筆記本aquila_qpu.properties.dict()中執行看到它們。 有關 Aquila 功能和要求的更多詳細信息,請參閱 Aquila 筆記本簡介。) 我們可以通過調用discretize方法來做到這一點。

discretized_ahs_program = ahs_program.discretize(aquila_qpu)

現在,我們可以在 Aquila QPU 上運行該程序(現在只運行 100 鏡頭)。

注意

在Aquila處理器上執行此程式將產生費用。Amazon Braket 開發套件包含成本追蹤器,可讓客戶設定成本限制,並以近乎即時的方式追蹤成本。

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

由於量子任務可能需要多長時間的差異很大(取決於可用性窗口和 QPU 利用率),記下量子任務 ARN 是一個好主意,因此我們可以在稍後使用下面的代碼片段檢查其狀態。

# 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

狀態完成後 (也可以從 Amazon Braket 主控台的量子任務頁面檢查),我們可以使用以下方式查詢結果:

result_aquila = task.result()

分析 QPU 結果

使用與以前相同的get_counts函數,我們可以計算計數:

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

並用以下方式繪製它們plot_counts

plot_counts(counts_aquila)
條形圖顯示有和沒有相鄰「向上」狀態的鏡頭速率。

請注意,一小部分鏡頭有空的網站(標有「e」)。這是由於 1— 2% 每個原子製劑缺陷的 QPU. Aquila 除此之外,由於拍攝次數少,結果與預期的統計波動範圍內的模擬匹配。

下一頁

恭喜您,您現在已經使用本地 AHS 模擬器和 QPU 在 Amazon Braket 上運行了第一個 AHS 工作負載。Aquila

要了解有關 Rydberg 物理,模擬哈密頓仿真和Aquila設備的更多信息,請參閱我們的示例筆記本。