

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

# AHS 您好：執行您的第一個類比 Hamiltonian 模擬
<a name="braket-get-started-hello-ahs"></a>

本節提供執行第一個類比 Hamiltonian 模擬的相關資訊。

**Topics**
+ [互動旋轉鏈](#braket-get-started-interacting-spin-chain)
+ [安排](#braket-get-started-arrangement)
+ [互動](#braket-get-started-interaction)
+ [駕駛欄位](#braket-get-started-driving-field)
+ [AHS 程式](#braket-get-started-ahs-program)
+ [在本機模擬器上執行](#braket-get-started-running-local-simulator)
+ [分析模擬器結果](#braket-get-started-analyzing-simulator-results)
+ [在 QuEra 的 Aquila QPU 上執行](#braket-get-started-running-aquila-qpu)
+ [分析 QPU 結果](#braket-get-started-analyzing-qpu-results)
+ [後續步驟](#braket-get-started-ahs-next)

## 互動旋轉鏈
<a name="braket-get-started-interacting-spin-chain"></a>

對於許多互動粒子系統的正式範例，讓我們考慮一個八次旋轉的環 （每個旋轉環可以是「向上」∣↑⟩ 和「向下」∣↓⟩ 狀態）。雖然很小，但此模型系統已展現一些自然產生的磁性材料的有趣現象。在此範例中，我們將示範如何準備所謂的抗鐵磁順序，其中連續旋轉指向相反方向。

![\[連接 8 個包含上下箭頭的圓形節點的圖表。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/AntiFerromagnetic.png)


## 安排
<a name="braket-get-started-arrangement"></a>

我們將使用一個中性原子來代表每次旋轉，而「向上」和「向下」旋轉狀態將分別以激磁的 Rydberg 狀態和原子的接地狀態進行編碼。首先，我們建立 2 天排列。我們可以使用下列程式碼來編寫上述旋轉環。

 **先決條件**：您需要 pip 安裝 [Braket SDK](https://github.com/aws/amazon-braket-sdk-python#installing-the-amazon-braket-python-sdk)。（如果您使用的是 Braket 託管筆記本執行個體，此 SDK 會預先安裝筆記本。) 若要重現圖，您也需要使用 shell 命令 單獨安裝 matplotlib`pip install matplotlib`。

```
from braket.ahs.atom_arrangement import AtomArrangement
import numpy as np
import matplotlib.pyplot as plt  # Required for plotting

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
```

![\[散佈圖顯示分散在兩個軸上正值和負值的點。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/PlotNeutralAtoms.png)


## 互動
<a name="braket-get-started-interaction"></a>

為了準備抗鐵磁階段，我們需要在鄰近旋轉之間觸發互動。我們對此使用 [van der Waals 互動](https://en.wikipedia.org/wiki/Van_der_Waals_force)，這是由中性原子裝置 （例如來自 Aquila的裝置QuEra) 原生實作。使用旋轉代表法，此互動的 Hamiltonian 詞彙可以用總和來表示所有旋轉對 (j，k)。

![\[漢密爾頓互動方程式顯示此互動，以所有旋轉對 (j，k) 的總和表示。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/HInteraction.png)


在這裡，nj =jj∣↑⟩⟨↑∣ 是運算子，只有在旋轉 j 處於「上升」狀態時，才會採用 1 的值，否則為 0。強度為 Vj,k=C6/(dj,k​)6，其中 6Cis 是固定係數，而 dis j,k是旋轉 j 和 k 之間的歐幾里得距離。此互動術語的立即效果是，旋轉 j 和旋轉 k 都是「向上」的任何狀態都具有更高的能量 （按 V 量）j,k。透過仔細設計 AHS 計畫的其餘部分，此互動將防止相鄰旋轉同時處於「上」狀態，這是一種通常稱為「Rydberg 封鎖」的效果。

## 駕駛欄位
<a name="braket-get-started-driving-field"></a>

在 AHS 程式開始時，所有旋轉 （預設） 都會以「向下」狀態開始，處於所謂的鐵磁階段。密切關注我們準備抗鐵磁階段的目標，我們指定了時間相依的一致駕駛欄位，可將旋轉從此狀態順暢地轉換為「上升」狀態的許多身體狀態。對應的 Hamiltonian 可以寫入為

![\[描述漢密爾頓磁碟機函數計算的數學方程式。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/HDrive.png)


其中 DLR(t)、φ(t)、Δ(t) 是時間相依的全域振幅 （也稱為 [Rabi 頻率](https://en.wikipedia.org/wiki/Rabi_frequency))、階段，以及影響所有旋轉的駕駛欄位的調整。此處的 S−,k=k​k∣↓⟩⟨↑∣and S\$1,k=(S−,k)†=k​k∣↑⟩⟨↓∣ 分別是旋轉 k 的降低和提高運算子，而 nk=kk∣↑��⟩⟨↑∣ 是與之前相同的運算子。駕駛欄位的 DLR 部分會一致地聯結所有旋轉的「向下」和「向上」狀態，而 Δ 部分則會控制「向上」狀態的能源獎勵。

若要程式設計從鐵磁階段順利轉換為抗鐵磁階段，請使用下列程式碼指定駕駛欄位。

```
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、delta 和 Omega。頂端子圖表顯示成長到剛好高於 6 rads/s，並保持 4 秒，直到下降至 0。中間子圖描述衍生產品的相關線性成長，而底部子圖則說明接近零的扁平線。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/DrivingTimeSeries.png)


## AHS 程式
<a name="braket-get-started-ahs-program"></a>

註冊、駕駛欄位 （以及隱含 van der Waals 互動） 組成了類比 Hamiltonian 模擬程式 `ahs_program`。

```
from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation

ahs_program = AnalogHamiltonianSimulation(
   register=register,
   hamiltonian=drive
)
```

## 在本機模擬器上執行
<a name="braket-get-started-running-local-simulator"></a>

由於此範例很小 （少於 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
```

## 分析模擬器結果
<a name="braket-get-started-analyzing-simulator-results"></a>

我們可以使用下列函數彙總鏡頭結果，以推斷每次旋轉的狀態 （可能是「d」表示「down」、「u」表示「up」或「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)
```

```
*[Output]*
{'dddddddd': 5, 'dddddddu': 12, 'ddddddud': 15, ...}
```

`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)
```

![\[長條圖顯示大量鏡頭，沒有相鄰的「向上」狀態組態。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/AHSCounts1.png)


![\[長條圖顯示一些相鄰「向上」狀態組態的鏡頭，其中 4 個狀態為 1.0 個鏡頭。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/AHSCounts2.png)


從圖中，我們可以讀取下列觀察，確認已成功準備抗鐵磁階段。

1. 一般而言，非封鎖狀態 （其中沒有兩個相鄰旋轉處於「上」狀態） 比至少有一個相鄰旋轉處於「上」狀態的狀態更常見。

1. 一般而言，除非組態遭到封鎖，否則具有更多 "up" 激發的狀態是有利的。

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

1. 第二個最常見的狀態是其中只有 3 個「向上」激發，連續分隔為 1、2、2。這顯示 van der Waals 互動也會影響 （雖然更小） 下一個最近鄰。

## 在 QuEra 的 Aquila QPU 上執行
<a name="braket-get-started-running-aquila-qpu"></a>

 **先決條件**：除了 pip 安裝 Braket [SDK](https://github.com/aws/amazon-braket-sdk-python#installing-the-amazon-braket-python-sdk) 之外，如果您是 Amazon Braket 的新手，請確定您已完成必要的[入門步驟](https://docs.aws.amazon.com/braket/latest/developerguide/braket-get-started.html)。

**注意**  
如果您使用的是 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 筆記本簡介](https://github.com/aws/amazon-braket-examples/blob/main/examples/analog_hamiltonian_simulation/01_Introduction_to_Aquila.ipynb)。) 我們可以呼叫 `discretize`方法來執行此操作。

```
discretized_ahs_program = ahs_program.discretize(aquila_qpu)
```

現在，我們可以在 Aquila QPU 上執行程式 （目前只執行 100 個鏡頭）。

**注意**  
在Aquila處理器上執行此程式會產生費用。Amazon Braket SDK 包含[成本追蹤器](https://aws.amazon.com/blogs/quantum-computing/managing-the-cost-of-your-experiments-in-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}")
```

```
*[Output]*
ARN: arn:aws:braket:us-east-1:123456789012:quantum-task/12345678-90ab-cdef-1234-567890abcdef
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]*
ARN: arn:aws:braket:us-east-1:123456789012:quantum-task/12345678-90ab-cdef-1234-567890abcdef
status: COMPLETED
```

一旦狀態為 COMPLETED （也可以從 Amazon Braket [主控台](https://us-east-1.console.aws.amazon.com/braket/home?region=us-east-1#/tasks)的量子任務頁面進行檢查），我們可以使用下列方式查詢結果：

```
result_aquila = task.result()
```

## 分析 QPU 結果
<a name="braket-get-started-analyzing-qpu-results"></a>

使用與之前相同的`get_counts`函數，我們可以計算計數：

```
counts_aquila = get_counts(result_aquila)
   print(counts_aquila)
```

```
*[Output]*
{'dddududd': 2, 'dudududu': 18, 'ddududud': 4, ...}
```

並使用 繪製它們`plot_counts`：

```
plot_counts(counts_aquila)
```

![\[長條圖顯示大量鏡頭，沒有相鄰的「向上」狀態組態。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/QPUPlotCounts1.png)


![\[長條圖顯示一些相鄰「向上」狀態組態的鏡頭，其中 4 個狀態為 1.0 個鏡頭。\]](http://docs.aws.amazon.com/zh_tw/braket/latest/developerguide/images/QPUPlotCounts2.png)


請注意，一小部分的鏡頭具有空的網站 （以 “e” 標記）。這是因為 Aquila QPU 的每個原子準備瑕疵為 1-2%。除此之外，由於鏡頭數量較少，結果與模擬在預期的統計波動內相符。

## 後續步驟
<a name="braket-get-started-ahs-next"></a>

恭喜您，您現在已使用本機 AHS 模擬器和 Aquila QPU 在 Amazon Braket 上執行第一個 AHS 工作負載。

若要進一步了解 Rydberg 物理、類比 Hamiltonian 模擬和Aquila裝置，請參閱我們的[筆記本範例](https://github.com/aws/amazon-braket-examples/tree/main/examples/analog_hamiltonian_simulation)。