Sampler
状態ベクトルのシミュレーションとは異なり、量子コンピュータを使って演算子の期待値を推定するためにはサンプリング測定が必要です。サンプリング測定では、量子回路の実行と量子ビットの測定が複数回繰り返し行われます。演算子の期待値の推定は、繰り返した測定の統計を使用して行われます。
回路のサンプリング測定を行うために、Samplerを使うことができます。ここではSamplerの定義を紹介し、どのように作成、実行が行えるかについて紹介します。
前提条件
このチュートリアルで使用するQURI Partsモジュール:
quri-parts-circuit, quri-parts-core, quri-parts-qulacs
インストールは以下のコマンドで行うことができます:
!pip install "quri-parts[qulacs]"
回路の準備
準備として、サンプルするための回路を作成します:
from math import pi
from quri_parts.circuit import QuantumCircuit
# A circuit with 4 qubits
circuit = QuantumCircuit(4)
circuit.add_X_gate(0)
circuit.add_H_gate(1)
circuit.add_Y_gate(2)
circuit.add_CNOT_gate(1, 2)
circuit.add_RX_gate(3, pi/4)
インターフェース
回路のサンプリング測定を行う場合、Samplerを使用することができます。QURI Partsでは、Samplerは指定された回路(パラメータなし)を指定された回数だけサンプリングし、カウント値を返す関数を表します。ideal Samplerの場合には、返却値は確率にショット数を掛けたものに対応します。
複数の回路によってサンプリングを行いたい場合、QURI Partsは複数の(回路やショット)ペアによってサンプルする関数ConcurrentSamplerも提供しています。
SamplerとConcurrentSamplerはどちらも以下の関数シグネチャを持つ抽象インターフェースです:
from typing import Callable, Iterable, Mapping, Union
from typing_extensions import TypeAlias
from quri_parts.circuit import NonParametricQuantumCircuit
#: MeasurementCounts represents count statistics of repeated measurements of a quantum
#: circuit. Keys are observed bit patterns encoded in integers and values are counts
#: of observation of the corresponding bit patterns.
MeasurementCounts: TypeAlias = Mapping[int, Union[int, float]]
#: Sampler represents a function that samples a specified (non-parametric) circuit by
#: a specified times and returns the count statistics. In the case of an ideal Sampler,
# the return value corresponds to probabilities multiplied by shot count.
Sampler: TypeAlias = Callable[[NonParametricQuantumCircuit, int], MeasurementCounts]
#: ConcurrentSampler represents a function that samples specified (non-parametric)
#: circuits concurrently.
ConcurrentSampler: TypeAlias = Callable[
[Iterable[tuple[NonParametricQuantumCircuit, int]]], Iterable[MeasurementCounts]
]
Samplerそのもの(quri_parts.core.samplingで定義)は抽象インターフェースであり、本当のサンプリングを行うために具体的なインスタンス必要です。Samplerインターフェースには複数の実装が存在し、いくつかのものは回路シミュレータを使用しており、他のものは実際の量子コンピュータを使用しています。
Samplerを作成し実行
Qulacsによる状態ベクトルのシミュレーションを使用したSamplerを作成し、サンプリングを行ってみましょう。
from quri_parts.qulacs.sampler import create_qulacs_vector_sampler
# Create the sampler
sampler = create_qulacs_vector_sampler()
sampling_result = sampler(circuit, shots=1000)
print(sampling_result)
# output
Counter({5: 423, 3: 419, 13: 90, 11: 68})
MeasurementCountsは実際はpythonのdictになっており、キーは観測されたビットのパターン、値は回数です。
使用可能なSamplerのリスト
QURI Partsの使用可能なSamplerのリストです。生成関数の引数として各々のシミュレータにオプションを設定することができます。
| モジュール | 生成関数 | ノイズ | 種類 |
|---|---|---|---|
| quri-parts-itensor | create_itensor_mps_sampler(Concurrent) | ✘ | MPS |
| quri-parts-qulacs | create_qulacs_vector_sampler(Concurrent) create_qulacs_vector_ideal_sampler create_qulacs_stochastic_state_vector_sampler(Concurrent) create_qulacs_density_matrix_sampler(Concurrent) create_qulacs_density_matrix_ideal_sampler create_qulacs_noisesimulator_sampler(Concurrent) | ✘ ✘ ✔ ✔ ✔ ✔ | Statevector Statevector Statevector Density matrix Density matrix NoiseSimulator |
| quri-parts-stim | create_stim_clifford_sampler(Concurrent) | ✘ | Clifford |
SamplingBackendと組み合わせてcreate_sampler_from_sampling_backend(link)でSamplerを作成することもできます。以下はQURI Partsで利用できるSamplingBackendの一覧です:
| モジュール | バックエンド | クラス |
|---|---|---|
| quri-parts-braket | AWS Braket | BraketSamplingBackend |
| quri-parts-qiskit | Qiskit | QiskitSamplingBackend QiskitRuntimeSamplingBackend |
さらに詳しい情報は、以下の量子コンピュータ実機を使用したサンプリングのチュートリアルを参照してください。