Skip to main content
IBM Quantum Platform

Qiskit Aerプリミティブを用いた正確かつノイズを含むシミュレーション

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

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

Qiskit SDK プリミティブを用いた厳密シミュレーションでは、 Qiskitに付属する参照プリミティブを使用して量子回路の厳密シミュレーションを行う方法を示しています。 現在存在する量子プロセッサにはエラーやノイズが生じるため、厳密なシミュレーションの結果は、実際のハードウェア上で回路を実行した際に期待される結果を必ずしも反映するとは限りません。 Qiskit のリファレンスプリミティブではノイズのモデリングはサポートされていませんが、 Qiskit Aer には、ノイズのモデリングをサポートするプリミティブの実装が含まれています。 Qiskit Aerは、リファレンスプリミティブの代わりに使用することで、より高いパフォーマンスと豊富な機能を実現できる高性能な量子回路シミュレータです。 これは Qiskitエコシステムの一部です。 本記事では、Qiskit Aerのプリミティブを用いた、正確なシミュレーションおよびノイズを含むシミュレーションの手法について解説します。

ノート
  • qiskit-aer v0.14 またはそれ以降が必要。
  • Qiskit Aerのプリミティブはプリミティブインターフェースを実装していますが、 IBM Quantum のプリミティブと同じオプションは提供していません。 たとえば、レジリエンスレベルは、Qiskit Aerのプリミティブでは利用できません。
  • Aerがサポートするシミュレーション方法のオプションの詳細については、 AerSimulator のドキュメントを参照してください。

厳密でノイズの少ないシミュレーションを探求するために、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

この回路には、 RyR_yRzR_z ゲートの回転角度を表すパラメータが含まれている。 この回路をシミュレーションする場合、これらのパラメータに明示的な値を指定する必要がある。 次のセルでは、これらのパラメータにいくつかの値を指定し、 Qiskit AerのEstimatorプリミティブを使って、観測値 ZZZZZ \cdots Z の正確な期待値を計算する。

from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import EstimatorV2 as Estimator

observable = SparsePauliOp("Z" * n_qubits)
params = [0.1] * circuit.num_parameters

exact_estimator = Estimator()
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
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.8870140234256602

それでは、すべてのCXゲートに2%の脱分極誤差を含むノイズモデルを初期化しましょう。 実際には、回路を実行する際、2量子ビットゲート(ここではCXゲート)に起因するエラーが、主なエラーの原因となります。 Qiskit Aer でのノイズモデルの構築に関する概要については、 「ノイズモデルの構築 」を参照してください。

次のセルでは、このノイズモデルを組み込んだ推定器を構築し、それを使って観測可能値の期待値を計算する。

from qiskit_aer.noise import NoiseModel, depolarizing_error

noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
noise_model.add_all_qubit_quantum_error(
    depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)

noisy_estimator = Estimator(
    options=dict(backend_options=dict(noise_model=noise_model))
)
job = noisy_estimator.run([pub])
result = job.result()
pub_result = result[0]
noisy_value = float(pub_result.data.evs)
noisy_value

Output:

0.7247404214143528

ご覧のように、ノイズがある場合の期待値は正しい値からかなり離れている。 実際には、ノイズの影響に対抗するために様々なエラー軽減テクニックを採用することができるが、これらのテクニックについての議論はこの記事の範囲外である。

ノイズが最終的な結果にどのような影響を与えるか、非常に大まかな感覚を得るために、各CXゲートに2%の脱分極誤差を加えるノイズモデルを考えてみよう。 確率 pp を持つ脱分極エラーは、密度行列 ρ\rho に対して次のような作用を持つ量子チャンネル EE として定義される:

E(ρ)=(1p)ρ+pI2nE(\rho) = (1 - p) \rho + p\frac{I}{2^n}

ここで、 nn は量子ビット数で、この場合は2である。 すなわち、確率 pp、状態は完全に混合された状態に置き換えられ、確率 1p1 - p、状態は保存される。 mm 脱分極チャネルを適用した後、状態が保存される確率は (1p)m(1 - p)^m となる。したがって、シミュレーションの最後に正しい状態が保持される確率は、回路のCXゲートの数に応じて指数関数的に下がると予想される。

回路内のCXゲートの数を数え、 (1p)m(1 - p)^m を計算しよう。 count_ops 。ゲート名とカウント数を対応付ける辞書を取得し、CXゲートのエントリーを取り出す。

cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count

Output:

0.6542558123199923

この65%という値は、最終的な状態が正しい確率の大まかな推定値を示している。 シミュレーションの初期状態を考慮していないため、これは保守的な見積もりである。

次のコードセルは、Qiskit AerのSamplerプリミティブを使用して、ノイズの多い回路からサンプリングする方法を示しています。 Samplerプリミティブで実行する前に、回路に測定値を追加する必要がある。

from qiskit_aer.primitives import SamplerV2 as Sampler

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

noisy_sampler = Sampler(
    options=dict(backend_options=dict(noise_model=noise_model))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params, 100)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
pub_result.data.meas.get_counts()

Output:

{'00000000': 60,
 '00001111': 1,
 '11000000': 3,
 '10100000': 3,
 '10001111': 1,
 '00010000': 1,
 '00001010': 1,
 '00111100': 1,
 '01000000': 6,
 '10000000': 5,
 '00110000': 1,
 '00011000': 2,
 '01100000': 2,
 '00000110': 2,
 '11000100': 1,
 '10000110': 1,
 '01010000': 2,
 '00011110': 1,
 '00010100': 2,
 '01011010': 1,
 '00000010': 1,
 '00001100': 1,
 '11100000': 1}

次のステップ

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