기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
안녕하세요 AHS: 첫 번째 아날로그 해밀턴 시뮬레이션 실행
이 섹션에서는 첫 번째 아날로그 해밀턴 시뮬레이션을 실행하는 방법에 대한 정보를 제공합니다.
스핀 체인 상호 작용
상호 작용하는 파티클이 많은 시스템의 표준 예제의 경우 8회전의 링을 생각해 보겠습니다(각각이 “위” “”↑” 및 “아래” “""” 상태에 있을 수 있음). 작지만이 모델 시스템은 이미 자연적으로 발생하는 자기 재료의 몇 가지 흥미로운 현상을 보여줍니다. 이 예에서는 연속 회전이 반대 방향을 가리키는 소위 강자성 반강자성 순서를 준비하는 방법을 보여줍니다.
계약
중립 원자 하나를 사용하여 각 스핀에 대해 서게 되며, “위” 및 “아래” 스핀 상태는 각각 원자의 여기된 Rydberg 상태 및 지상 상태로 인코딩됩니다. 먼저 2일 배열을 생성합니다. 다음 코드를 사용하여 위의 스핀 링을 프로그래밍할 수 있습니다.
사전 조건: Braket SDKpip 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
상호 작용
강자성 방지 단계를 준비하려면 인접한 스핀 간의 상호 작용을 유도해야 합니다. 이를 위해 van der Waals 상호 작용을
여기서 nj =""""j""""j"는 spin j가 “up” 상태인 경우에만 1을, 그렇지 않은 경우에는 0을 취하는 연산자입니다. 강도는 Vj,k=C6/(dj,k)6이며, 여기서 C6는 고정 계수이고 dj,k는 스핀 j와 k 사이의 유클리드 거리입니다. 이 상호 작용 용어의 즉각적인 효과는 스핀 j와 스핀 k가 모두 “위”인 모든 상태가 에너지(V 양)를 높인다는 것입니다j,k. AHS 프로그램의 나머지 부분을 주의 깊게 설계하면 이웃 스핀이 모두 'Rydberg 차단'이라고 하는 효과인 '위' 상태가 되는 것을 방지할 수 있습니다.
주행 필드
AHS 프로그램 시작 시 모든 스핀(기본값)은 '다운' 상태로 시작되며, 강자성 단계가 됩니다. 강자성 방지 단계를 준비하는 목표를 주시하면서이 상태에서 스핀을 “상향” 상태가 선호되는 다신체 상태로 원활하게 전환하는 시간 의존적 코히어런트 주행 필드를 지정합니다. 해당 Hamiltonian은 로 작성할 수 있습니다.
여기서 Ω(t),"(t),Δ(t)는 모든 스핀에 균일하게 영향을 미치는 주행 필드의 시간 의존적인 전역 진폭(라비 주파수
강자성 단계에서 강자성 단계로의 원활한 전환을 프로그래밍하기 위해 다음 코드로 주행 필드를 지정합니다.
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
AHS 프로그램
레지스터, 주행 필드(및 암시적 반 데르 발스 상호 작용)는 아날로그 해밀턴 시뮬레이션 프로그램을 구성합니다ahs_program
.
from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation ahs_program = AnalogHamiltonianSimulation( register=register, hamiltonian=drive )
로컬 시뮬레이터에서 실행
이 예제는 작기 때문에(15회 회전 미만) AHS호환에서 실행하기 전에 Braket와 함께 제공되는 로컬 AHS 시뮬레이터에서 실행할 QPU수 있습니다SDK. 로컬 시뮬레이터는 Braket에서 무료로 사용할 수 있으므로 SDK코드를 올바르게 실행할 수 있도록 하는 것이 가장 좋습니다.
여기서는 로컬 시뮬레이터가 양자 상태의 시간 진화를 추적하고 최종 상태에서 샘플을 추출하므로 총 런타임을 약간만 늘리면서 샷 수를 높은 값(예: 1백만)으로 설정할 수 있습니다.
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)
플롯에서 다음 관측치를 읽고 강자성 방지 단계를 성공적으로 준비했는지 확인할 수 있습니다.
-
일반적으로 비차단 상태(두 개의 이웃 스핀이 “위” 상태에 있지 않음)는 하나 이상의 이웃 스핀 쌍이 둘 다 “위” 상태에 있는 상태보다 더 일반적입니다.
-
일반적으로 구성이 차단되지 않는 한 '위' 여자가 더 많은 상태가 선호됩니다.
-
가장 일반적인 상태는 실제로 완벽한 강자성 방지 상태
"dudududu"
및 입니다"udududud"
. -
두 번째로 가장 일반적인 상태는 1, 2, 2의 연속 분리와 함께 3개의 “위” 여기만 있는 상태입니다. 이는 van der Waals 상호 작용이 가장 가까운 이웃에도 영향을 미친다는 것을 보여줍니다(크게 작음).
QuEraAquila에서 실행 QPU
사전 조건: Braket를 설치하는 pip 외에도 Amazon Braket을 처음 사용하는 SDK
참고
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)
이제에서 프로그램을 실행할 수 있습니다(지금은 100회만 실행).Aquila QPU.
참고
에서이 프로그램 실행 Aquila 프로세서에 비용이 발생합니다. Amazon Braket에는 고객이 비용 한도를 설정하고 거의 실시간으로 비용을 추적할 수 있는 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
양자 작업이 실행되는 데 걸리는 시간이 크게 다르므로(가용 기간 및 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
상태가 되면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%로 인한 것입니다.Aquila QPU. 이 외에도 샷 수가 적기 때문에 결과는 예상 통계 변동 내에서 시뮬레이션과 일치합니다.
다음 단계
축하합니다. 이제 로컬 시뮬레이터와 AHS를 사용하여 Amazon Braket에서 첫 번째 AHS 워크로드를 실행했습니다.Aquila QPU.
Rydberg 물리, 아날로그 Hamiltonian 시뮬레이션 및에 대해 자세히 알아보려면 Aquila 디바이스의 경우 예제 노트북을 참조하세요