メインコンテンツへスキップ
このプロジェクトはベータ版です。バグを見つけましたか?GitHub Issueを開く。質問やアイデアがありますか?Discussionsで質問する — フィードバックをお待ちしています!
このページの翻訳品質はいかがですか?

127量子ビットのキックト・イジング模型をシミュレーションする

このガイドでは、pauli-propパッケージを使って、ヘビーヘックス格子上の127量子ビット・キックト・イジング模型の時間発展を古典的にシミュレーションし、単一サイトの磁化⟨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次トロッター分解は、2020ステップのトロッターステップにわたる量子回路UUとして実装されます。結合定数JJはJ=−π2J=-\frac{\pi}{2}に固定されるため、hmod  π2=0h\mod\frac{\pi}{2}=0となるときは常にUUはCliffordになります。

ワークフロー:

  • トロッター化したイジング模型を実装する量子回路を作成します

    • hhをClifford点0.00.0とπ2\frac{\pi}{2}の間で変化させます
  • 格子の中央のサイト(量子ビット6262)を選び、各回路について2020ステップのトロッターステップ後の磁化を推定します

  • hhがあるClifford点から別のClifford点へ移動するにつれて、磁化が1.01.0から0.00.0へ減衰していく様子を観察します

回路を作成する​

まず、qiskit-ibm-runtimeのFakeSherbrookeを使って、127量子ビットのEagle QPUのカップリングマップのエッジ・インデックスを取得します。エッジ・インデックスが得られたら、シミュレーションしたいhhの各値に対するトロッター回路を作成します。これらの回路は、20ステップのトロッターステップと5420個のゲートを使って、ハミルトニアンの1次トロッター化を実装します。

# 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伝播で時間発展をシミュレーションする​

次に、測定したいオブザーバブル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を簡単に推定できます。

frame='h'を設定して、オブザーバブルをハイゼンベルク描像(U†OUU^{\dagger}OU)で発展させることを指定します。シュレーディンガー発展(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から離れるにつれて、次の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