Skip to main content
IBM Quantum Platform

Qiskit Aerプリミティブを用いた安定化回路の効率的なシミュレーション

  • このページのコードは、以下の要件に基づいて開発された。 これらのバージョンまたは新しいバージョンの使用をお勧めします。

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

このページでは、Qiskit Aerプリミティブを使って、パウリノイズを含むスタビライザー回路を効率的にシミュレーションする方法を紹介します。

安定化回路はクリフォード回路とも呼ばれ、古典的に効率よくシミュレーションできる量子回路の重要な限定クラスである。 スタビライザー回路を定義するには、いくつかの等価な方法がある。 一つの定義として、スタビライザー回路とは、以下のゲートのみで構成される量子回路である:

ハダマードとSを用いて、任意のパウリ回転ゲート( RxR_x, RyR_yRzR_z )の集合 {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} (グローバル位相まで)に含まれる角度を持つ任意のパウリ回転ゲートを構成することができるので、これらのゲートも定義に含めることができる。

安定化回路は量子エラー訂正の研究にとって重要である。 古典的なシミュレーションが可能なため、量子コンピュータの出力を検証するのにも役立つ。 例えば、100量子ビットを使う量子回路を量子コンピューターで実行したいとする。 量子コンピューターが正しく動作していることをどうやって確認するのですか? 100量子ビットの量子回路は、ブルートフォース(総当り)の古典的シミュレーションの域を出ない。 スタビライザー回路になるように回路を修正すれば、量子コンピュータ上で、目的の回路と似た構造を持ちながら古典コンピュータ上でシミュレーションできる回路を実行できる。 スタビライザー回路で量子コンピュータの出力をチェックすることで、非スタビライザー回路でも量子コンピュータが正しく動作していることを確信できる。 この考え方が実際に使われている例については、「 フォールト・トレランス以前の量子コンピューティングの有用性の証拠 」を参照されたい。

Qiskit Aerプリミティブによる厳密でノイズの少ないシミュレーションではQiskit Aerを使用して一般的な量子回路の厳密でノイズの少ないシミュレーションを実行する方法を示しています。 その記事で使われた回路例、 efficient_su2を使った8量子ビット回路を考えてみよう:

from qiskit.circuit.library import efficient_su2

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

Output:

Output of the previous code cell

Qiskit Aerを使って、この回路を簡単にシミュレーションすることができた。 しかし、量子ビット数を500に設定したとしよう:

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

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

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

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

スタビライザー回路シミュレーターはノイズ・シミュレーションもサポートしているが、限られたクラスのノイズ・モデルに対してのみである。 具体的には、量子ノイズはパウリ誤差チャネルによって特徴付けられなければならない。 脱分極エラーもこのカテゴリーに入るので、シミュレートすることができる。 読み出し誤差のような古典的なノイズチャンネルもシミュレートできる。

次のコード・セルは、前回と同じシミュレーションを実行しますが、今回は、各CXゲートに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()

ここで、スタビライザー・シミュレータに裏付けされた 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

Output:

0.0

次のステップ

推奨事項
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。