PEC(確率的誤りキャンセル法)の使い方#
前前節で紹介した外挿法は、ハードウェアでの実行性に優れているものの、ノイズのバイアスに関する理論保証がない、という問題を抱えていました。 ここでは、ノイズチャネル\(\mathcal{E}\)に関する表式が得られているとの仮定のもとで、不偏推定を可能にする量子エラー抑制の手法である、 確率的誤りキャンセル法 (Probabilistic Error Cancellation, 以下PEC) を紹介します。
\(\newcommand{\ket}[1]{| #1 \rangle}\) \(\newcommand{\bra}[1]{\langle #1 |}\) \(\newcommand{\braket}[2]{\langle #1 | #2 \rangle}\)
# notebookを実行する前に、以下のライブラリをインストールしてください。
# mitiqは量子エラー抑制用のライブラリです。
#
# !pip install mitiq ply cirq
PECでは、エラーに対応するノイズチャネル\(\mathcal{E}\)の逆演算\(\mathcal{E}^{-1}\)を、物理的な量子チャネルの線形和として実現します。
ここで、\(\{\mathcal{B}_k\}\)はノイズなく実行できる量子操作の集合で、\(\{q_k\}\)はその符号付き重みに対応しています。
import mitiq
mitiq.SUPPORTED_PROGRAM_TYPES.keys()
frontend = "qiskit"
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[2], line 1
----> 1 import mitiq
2 mitiq.SUPPORTED_PROGRAM_TYPES.keys()
3 frontend = "qiskit"
ModuleNotFoundError: No module named 'mitiq'
問題設定#
1量子ビットの深さ2の量子回路を定義します。
from qiskit import QuantumCircuit
import numpy as np
circuit = QuantumCircuit(1)
circuit.h(0)
circuit.ry(np.pi/8, 0)
print(circuit)
from cirq import DensityMatrixSimulator, depolarize
from mitiq.interface import convert_to_mitiq
noise_rate = 0.3
mitiq_circuit, _ = convert_to_mitiq(circuit)
noisy_circuit = mitiq_circuit.with_noise(depolarize(p=noise_rate))
print(noisy_circuit)
#q_0: ───H───D(0.3)[<virtual>]───Ry(0.125π)───D(0.3)[<virtual>]───
実行器の定義とノイズ付き期待値計算#
import cirq
import numpy as np
def estimate_Z_noisy(circuit, noise_level=0.3):
"""Returns Tr[ρ Z] where ρ is the state prepared by the circuit
executed with depolarizing noise.
"""
# Replace with code based on your frontend and backend.
mitiq_circuit, _ = convert_to_mitiq(circuit)
# We add a simple noise model to simulate a noisy backend.
noisy_circuit = mitiq_circuit.with_noise(depolarize(p=noise_level))
rho = DensityMatrixSimulator().simulate(noisy_circuit).final_density_matrix
return rho[0, 0].real - rho[1, 1].real
noisy_value = estimate_Z_noisy(circuit, noise_level = noise_rate)
ideal_value = estimate_Z_noisy(circuit, noise_level=0.0)
print(f"誤差(補正なし): {abs(ideal_value - noisy_value):.5f}")
#誤差(補正なし): 0.24492
擬確率表現の生成とPECの適用#
ノイズチャネルは脱分局ノイズで、以下のように与えられています。
これに対して、逆写像を計算すると、以下のように与えられることがわかります。
例えば、 \(p=0.3\)とおくと、
であり、\(\gamma = \sum_k|q_k| = 1.5 + 3 * (1/6) = 2\)であることから、物理量の推定を実行する際には\(\gamma^{N_g}=4\)倍された値を用いる。 例えばパウリ演算子の期待値推定を行う際には、 測定によって\(0, 1\)が得られた場合、推定値を\(\pm4\)に割り当てる。
from mitiq.pec.representations.depolarizing import represent_operations_in_circuit_with_local_depolarizing_noise
#reps_ideal = represent_operations_in_circuit_with_local_depolarizing_noise(circuit, 0)
reps_noisy = represent_operations_in_circuit_with_local_depolarizing_noise(circuit, noise_rate)
print(f"ゲートのノイズ除去のための擬確率表現:")
print(reps_noisy[0])
print(reps_noisy[1])
#q_0: ───Ry(0.125π)─── = 1.500*(q_0: ───Ry(0.125π)───)-0.167*(q_0: ───Ry(0.125π)───X───)-0.167*(q_0: ───Ry(0.125π)───Y───)-0.167*(q_0: ───Ry(0.125π)───Z───)
#q_0: ───H─── = 1.500*(q_0: ───H───)-0.167*(q_0: ───H───X───)-0.167*(q_0: ───H───Y───)-0.167*(q_0: ───H───Z───)
from mitiq import pec
sampled_circuits = pec.construct_circuits(circuit, representations=reps_noisy, num_samples = 300)
print(f"Number of sample circuits: {len(sampled_circuits)}")
for i in range(4):
print(f"\n{i}番目の量子回路: ")
print(sampled_circuits[i])
from mitiq import pec
noisy_value = estimate_Z_noisy(circuit, noise_level = noise_rate)
print(f"誤差(PECなし): {abs(ideal_value - noisy_value):.5f}")
for num_shots in [10, 100, 1000]:
pec_value = pec.execute_with_pec(circuit, estimate_Z_noisy, representations=reps_noisy, num_samples = num_shots)
print(f"\n測定回数 = {num_shots}")
print(f"誤差(PECあり): {abs(ideal_value - pec_value):.5f}")
#誤差(PECなし): 0.24492
#測定回数 = 10
#誤差(PECあり): 0.05817
#測定回数 = 100
#誤差(PECあり): 0.02780
#測定回数 = 1000
#誤差(PECあり): 0.01612