주 콘텐츠로 건너뛰기
이 프로젝트는 베타 단계입니다. 버그를 발견하셨나요? GitHub 이슈 만들기. 질문이나 아이디어가 있으신가요? Discussions에서 질문하기 — 피드백을 기다립니다!
이 페이지의 번역 품질은 어떻습니까?

127 큐비트 kicked-Ising 모델 시뮬레이션

이 가이드에서는 pauli-prop 패키지를 사용하여 heavy-hex 격자 위의 127 큐비트 kicked-Ising 모델의 시간 동역학을 고전적으로 시뮬레이션하고, 단일 사이트 자화 ⟨Z62⟩\langle Z_{62} \rangle를 근사합니다. 고려하는 해밀토니안은 다음과 같습니다.

H=−J∑⟨i,j⟩ZiZj+h∑iXiH = -J\sum\limits_{\langle i,j \rangle} Z_iZ_j + h\sum\limits_iX_i

여기서 J>0J>0는 최근접 스핀 i<ji<j 사이의 결합을 나타내고, hh는 전역 횡자기장입니다. 시간 발전 연산자의 1차 Trotter 분해는 2020개의 Trotter 단계에 걸친 양자 회로 UU로 구현됩니다. 결합 상수 JJ는 J=−π2J=-\frac{\pi}{2}로 고정하며, 따라서 hmod  π2=0h\mod\frac{\pi}{2}=0일 때마다 UU는 Clifford가 됩니다.

워크플로:

  • Trotter화된 Ising 모델을 구현하는 양자 회로 만들기

    • Clifford 점 0.00.0과 π2\frac{\pi}{2} 사이에서 hh 변화시키기
  • 격자 중앙의 사이트(큐비트 6262)를 선택하고, 각 회로에 대해 2020개의 Trotter 단계 후 자화를 추정하기

  • hh가 한 Clifford 점에서 다른 Clifford 점으로 이동함에 따라 자화가 1.01.0에서 0.00.0으로 감소하는 것을 관찰하기

회로 만들기​

먼저 qiskit-ibm-runtime의 FakeSherbrooke를 사용하여 127 큐비트 Eagle QPU의 커플링 맵에 대한 에지 인덱스를 가져옵니다. 에지 인덱스를 얻은 후에는 시뮬레이션하려는 여러 hh 값에 대한 Trotter 회로를 만듭니다. 이 회로들은 20개의 Trotter 단계와 5420개의 게이트를 사용하여 해밀토니안의 1차 Trotter화를 구현합니다.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "pauli_prop": "pauli-prop", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

# Get the edges in the device coupling map
backend = FakeSherbrooke()
edges = backend.coupling_map.get_edges()

# Num Trotter steps
num_steps = 20

# Create Trotter circuits with varying global fields
hs = [i * np.pi / 32 for i in range(17)]
circuits = []
for h in hs:
circuit = QuantumCircuit(backend.num_qubits)
for _ in range(num_steps):
circuit.rx(h, [i for i in range(backend.num_qubits)])
for edge in edges:
circuit.rzz(-np.pi / 2, edge[0], edge[1])
circuits.append(circuit)

Pauli propagation으로 시간 동역학 시뮬레이션하기​

다음으로 측정하려는 관측량 OO를 지정합니다. 여기서는 ⟨Z62⟩\langle Z_{62} \rangle를 추정합니다.

Clifford 점 사이의 자화를 연구하기 위해 OO를 회로 UU의 시작 부분까지 근사적으로 전파하여 새로운 관측량 O′≈U†OUO^\prime \approx U^{\dagger}OU를 얻습니다.

전파 중에 발전된 관측량의 항 개수는 게이트 수에 대해 지수적으로 증가하므로, 보통 증가할 수 있는 크기를 제한해야 합니다. 여기서는 O′O^\prime의 항 개수를 10510^5로 제한하고, 계수가 10−510^{-5}보다 작은 항은 잘라냅니다. 항을 잘라내면 약간의 오차가 발생합니다. O′O^\prime를 얻으면 O′O^\prime의 대각 항(모든 큐비트에서 I 또는 Z로만 이루어진 항)의 계수를 합하여 기댓값 ⟨0∣U†OU∣0⟩=⟨0∣O′∣0⟩\langle0|U^{\dagger}OU|0\rangle = \langle0|O^\prime|0\rangle를 쉽게 추정할 수 있습니다.

관측량을 Heisenberg 틀(U†OUU^{\dagger}OU)에서 발전시키겠다고 지정하기 위해 frame='h'를 설정합니다. Schrödinger 발전(UOU†UOU^{\dagger})에는 frame=s를 사용하세요.

import time

from pauli_prop import propagate_through_circuit
from qiskit.quantum_info import Pauli, SparsePauliOp

# Z_62 observable
id_pauli = Pauli("I" * backend.num_qubits)
observable = SparsePauliOp(id_pauli.dot(Pauli("Z"), [62]))

# Estimate the single-site magnetization for varying magnetic fields
times = []
approx_evs = []
for circuit in circuits:
st = time.perf_counter()
propagated_obs = propagate_through_circuit(
observable, circuit, 100_000, 1e-5, frame="h"
)[0]
times.append(time.perf_counter() - st)
approx_evs.append(
float(
propagated_obs.coeffs[~propagated_obs.paulis.x.any(axis=1)].sum()
)
)
print(f"Finished {len(circuits)} simulations in {sum(times):.0f}s")
Finished 17 simulations in 494s

시각화​

마지막으로 hh의 함수로 자화를 그래프로 그립니다. h=0h=0일 때 회로는 계산 기저의 초기 상태에 영향을 주지 않으며, ⟨0∣O∣0⟩=1.0\langle0|O|0\rangle = 1.0임을 압니다. hh가 00에서 멀어질수록 자화는 hh가 다음 Clifford 각도 π2\frac{\pi}{2}에 도달할 때까지 단조롭게 감소하며, 자화는 00으로 수렴합니다.

import matplotlib.pyplot as plt

plt.xlabel(r"$R_x$ angle $\theta_h$")
plt.ylabel(r"$\langle Z_{62} \rangle$")
plt.plot(hs, approx_evs, marker="o")
[<matplotlib.lines.Line2D at 0x123f68b00>]

Output of the previous code cell