メインコンテンツへスキップ

Qiskit Aer プリミティブによるスタビライザー回路の効率的なシミュレーション

Package versions

このページのコードは、以下の要件を使用して開発されました。 これらのバージョン以降を使用することをお勧めします。

qiskit[all]~=2.3.0
qiskit-aer~=0.17

このページでは、Qiskit Aer プリミティブを使用して、Pauli ノイズの影響を受けるものを含むスタビライザー回路を効率的にシミュレートする方法を説明します。

スタビライザー回路(Clifford 回路とも呼ばれます)は、古典的に効率よくシミュレートできる重要な制限付き量子回路のクラスです。スタビライザー回路を定義する方法はいくつかありますが、そのひとつは、以下の Gate のみで構成される量子回路であるというものです。

Hadamard と S を使うことで、角度が集合 {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} に含まれる任意の Pauli 回転 Gate(RxR_xRyR_yRzR_z)を(グローバル位相を除いて)構成できるため、これらの Gate も定義に含めることができます。

スタビライザー回路は量子誤り訂正の研究において重要です。また、古典的にシミュレート可能であるという特性は、量子コンピューターの出力の検証にも役立ちます。たとえば、100 Qubit を使う量子回路を量子コンピューター上で実行したいとします。量子コンピューターが正しく動作しているかどうかはどのように確認すればよいでしょうか?100 Qubit の量子回路は、ブルートフォースの古典シミュレーションの範囲を超えています。回路をスタビライザー回路になるように修正することで、目的の回路と類似した構造を持ちながら古典コンピューターでシミュレートできる回路を量子コンピューター上で実行できます。スタビライザー回路での量子コンピューターの出力を確認することで、非スタビライザー回路においても正しく動作しているという確信を得られます。この考え方の実践例については、フォールトトレランス前の量子コンピューティングの有用性の証拠 を参照してください。

Qiskit Aer プリミティブによる完全・ノイズありシミュレーション では、Qiskit Aer を使って汎用量子回路の完全シミュレーションおよびノイズありシミュレーションを行う方法を説明しています。その記事で使用されているサンプル Circuit、efficient_su2 を使って構築した 8 Qubit の Circuit を考えてみましょう。

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2

n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")

Output of the previous code cell

Qiskit Aer を使ってこの Circuit を簡単にシミュレートできました。しかし、Qubit 数を 500 に設定するとどうなるでしょうか。

n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large

量子回路のシミュレーションコストは Qubit 数に対して指数関数的に増加するため、このような大規模な回路は Qiskit Aer のような高性能シミュレーターでも一般に処理能力を超えてしまいます。汎用量子回路の古典シミュレーションは、Qubit 数がおおよそ 50 〜 100 を超えると実行不可能になります。ただし、efficient_su2 Circuit は RyR_y および RzR_z Gate の角度によってパラメータ化されていることに注目してください。これらの角度がすべて集合 {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} に含まれる場合、回路はスタビライザー回路となり、効率的にシミュレートできます!

次のセルでは、スタビライザー回路シミュレーターを Backend とする Sampler プリミティブを使って Circuit を実行します。Circuit がスタビライザー回路であることが保証されるよう、ランダムに選択したパラメーターを使用します。

import numpy as np
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import SamplerV2 as Sampler

measured_circuit = circuit.copy()
measured_circuit.measure_all()

rng = np.random.default_rng(1234)
params = rng.choice(
[0, np.pi / 2, np.pi, 3 * np.pi / 2],
size=circuit.num_parameters,
)

# Initialize a Sampler backed by the stabilizer circuit simulator
exact_sampler = Sampler(
options=dict(backend_options=dict(method="stabilizer"))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(
1, AerSimulator(method="stabilizer")
)
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params)
job = exact_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()

スタビライザー回路シミュレーターはノイズありシミュレーションもサポートしていますが、制限されたノイズモデルのクラスのみ対応しています。具体的には、量子ノイズは Pauli error チャネルで特徴付けられる必要があります。脱分極エラー はこのカテゴリに該当するため、シミュレートできます。また、読み出しエラー などの古典ノイズチャネルもシミュレートできます。

次のコードセルは前と同じシミュレーションを実行しますが、今回は各 CX Gate に 2% の脱分極エラーを追加し、測定された各ビットを 5% の確率で反転させる読み出しエラーを指定したノイズモデルを使用します。

from qiskit_aer.noise import NoiseModel, depolarizing_error, ReadoutError

noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
bit_flip_prob = 0.05
noise_model.add_all_qubit_quantum_error(
depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noise_model.add_all_qubit_readout_error(
ReadoutError(
[
[1 - bit_flip_prob, bit_flip_prob],
[bit_flip_prob, 1 - bit_flip_prob],
]
)
)

noisy_sampler = Sampler(
options=dict(
backend_options=dict(method="stabilizer", noise_model=noise_model)
)
)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()

次に、スタビライザーシミュレーターを Backend とする Estimator プリミティブを使用して、オブザーバブル ZZZZZ \cdots Z の期待値を計算します。スタビライザー回路の特殊な構造により、結果は 0 になる可能性が非常に高いです。

from qiskit.quantum_info import SparsePauliOp
from qiskit_aer.primitives import EstimatorV2 as Estimator

observable = SparsePauliOp("Z" * n_qubits)

exact_estimator = Estimator(
options=dict(backend_options=dict(method="stabilizer")),
)
isa_circuit = pass_manager.run(circuit)
pub = (isa_circuit, observable, params)
job = exact_estimator.run([pub])
result = job.result()
pub_result = result[0]
exact_value = float(pub_result.data.evs)
exact_value
0.0

次のステップ

推奨事項