Skip to main content
IBM Quantum Platform

クイック・スタート

このガイドでは、この qiskit-addon-pna パッケージの最小限の動作例を紹介します。 我々は、伝播型騒音吸収(PNA)を用いて、騒音低減のための観測量を構築する。 ある回路とパウリ・リンドブラッド雑音モデルが与えられた場合、PNAは観測量を逆雑音チャネルを通じて古典的に伝播させる。 ノイズの混入したQPU上で結果として得られる観測量について測定を行うことで、学習されたゲートノイズを軽減することができる。

NoiseLearnerV3directed execution model 」を用いて現実的なワークフローを構築し、量子ハードウェア上で実行する方法(ノイズモデルの学習を含む)については、 IBM Quantum Platform のPNAチュートリアルをご覧ください。


1. PNA用の入力データを準備する

PNAは、回路、ノイズモデル、および観測変数を入力として受け取ります。 ここでは、 1D 鎖上で、10キュービットのトロッター化横磁場イジングモデルを構築する。 各エンタングルメントゲートに対して、ランダムな2-ローカル・パウリ・リンドブラッドノイズモデルを生成し、そのゲートの直前にQiskit Aer PauliLindbladError の命令として埋め込みます。 測定対象として、 weight-4 のパウリ-Z観測量を選択する。

import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp, pauli_basis
from qiskit_aer.noise import PauliLindbladError


def random_pauli_lindblad_noise(generators, seed, noise_scale=2e-3):
    rates = np.random.default_rng(seed).random(len(generators)) * noise_scale
    return PauliLindbladError(generators, rates)


def ising_circuit(
    num_qubits,
    layers,
    edge_noise=None,
    *,
    num_steps=3,
    rx_angle=np.pi / 8,
    rzz_angle=-np.pi / 2,
):
    """Trotterized transverse-field Ising model; edge_noise=None gives the noiseless circuit."""
    qc = QuantumCircuit(num_qubits)
    for _ in range(num_steps):
        qc.rx(rx_angle, range(num_qubits))
        for layer in layers:
            for edge in layer:
                if edge_noise is not None:
                    qc.append(
                        edge_noise[edge], edge
                    )  # inject synthetic gate noise
                qc.rzz(rzz_angle, *edge)
    return qc


num_qubits = 10

# Two entangling layers per Trotter step: even and odd bonds of a 1D chain
layers = [
    [(i, i + 1) for i in range(0, num_qubits - 1, 2)],
    [(i, i + 1) for i in range(1, num_qubits - 1, 2)],
]
edges = [edge for layer in layers for edge in layer]

# Random 2-local Pauli-Lindblad noise, one instance per entangling gate
two_qubit_paulis = SparsePauliOp(
    [p for p in pauli_basis(2) if np.sum(p.x + p.z)]
).paulis
edge_noise = {
    edge: random_pauli_lindblad_noise(two_qubit_paulis, seed=1234 + j)
    for j, edge in enumerate(edges)
}

noisy_circuit = ising_circuit(num_qubits, layers, edge_noise)

# A single weight-4 observable: <Z3 Z4 Z5 Z6>
observable = SparsePauliOp.from_sparse_list(
    [("ZZZZ", [3, 4, 5, 6], 1.0)], num_qubits=num_qubits
)

noisy_circuit.draw("mpl", fold=-1, scale=0.6)

Output:

Output of the previous code cell

2. ノイズ低減用観測量を生成する

generate_noise_mitigating_observable は、 逆ノイズチャネルの各パウリ生成子を回路の末端まで順方向に伝播させます。 その後、観測値は逆ノイズチャネルを通じてバックプロパゲーションされ、新しい観測値 O~\tilde{O} が返されます。計算コストに影響を与える3つの主要なパラメータは以下の通りです:

  • max_err_terms: 前方伝播の際に、各アンチノイズ生成器に保持される項の数。
  • max_obs_terms: O~\tilde{O} に保持される項の数。
  • atol: この閾値より係数の絶対値が小さい項は除外される。

atolこのクリフォード回路に近い小さな回路については、項の制限を高く設定し、適度な値を用いることで、 O~\tilde{O} が小さく保たれ、そのすべての項を測定できるようになります。

multiprocessing注:この関数は を使用 Python します。 スクリプトとして実行する場合は、 if name == "main": guard 内で呼び出してください。

from qiskit_addon_pna import generate_noise_mitigating_observable

mitigating_observable = generate_noise_mitigating_observable(
    noisy_circuit,
    observable,
    max_err_terms=100_000,
    max_obs_terms=100_000,
    atol=1e-5,
    num_processes=4,
)

print(f"Original observable:         {len(observable)} term")
print(f"Noise-mitigating observable: {len(mitigating_observable)} terms")

Output:

Original observable:         1 term
Noise-mitigating observable: 207 terms

3. ノイズ低減観測量を測定することで、ゲートエラーを低減する

ここでは、この新しい観測量によって、実験に影響を及ぼしていたゲートノイズが効果的に低減されていることがわかる。

import matplotlib.pyplot as plt
from qiskit_aer.primitives import EstimatorV2

noiseless_circuit = ising_circuit(num_qubits, layers)

# density_matrix method at zero precision -> exact expectation values (no shot noise)
estimator = EstimatorV2(
    options={
        "backend_options": {"method": "density_matrix"},
        "default_precision": 0.0,
    }
)

ideal, noisy, mitigated = (
    result.data.evs
    for result in estimator.run(
        [
            (noiseless_circuit, observable),
            (noisy_circuit, observable),
            (noisy_circuit, mitigating_observable),
        ]
    ).result()
)

print(f"Ideal (noiseless):   {ideal:.4f}")
print(f"Noisy (unmitigated): {noisy:.4f}")
print(f"Mitigated (PNA):     {mitigated:.4f}")

fig, ax = plt.subplots()
ax.bar(
    ["Noisy", "Mitigated"],
    [noisy, mitigated],
    width=0.6,
    color=["#b0b0b0", "#4c4c4c"],
)
ax.axhline(ideal, color="green", linestyle="--", label="Ideal (noiseless)")
ax.set_ylabel(r"$\langle Z_3 Z_4 Z_5 Z_6 \rangle$")
ax.legend()
plt.show()

Output:

Ideal (noiseless):   0.8073
Noisy (unmitigated): 0.6431
Mitigated (PNA):     0.8071
Output of the previous code cell
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。