これは トポロジカル符号の実装実験 の記事です。
はじめに
前回の記事では、二次元カラー符号(2D color code)[参考1]の基本構造と、符号距離 $d=3$ に対応する Steane 符号を用いた実装を確認しました。特に、4.8.8 カラー符号においては Clifford ゲートをトランスバーサルに実装できることを整理しました。
カラー符号では、符号距離を大きくすることで、より多くの物理量子ビット誤りを訂正できます。その一方で、物理量子ビット数やスタビライザー生成元の数が増えるため、論理状態を準備するエンコード回路も複雑になります。具体的な回路は一意ではなく、同じ符号空間を準備する場合でも、ゲート数、回路深さ、量子ビットの並べ方、CNOT の向きなどは回路の取り方によって変わります。そのため、符号距離の大きいカラー符号では、実際に扱いやすい形でエンコード回路を構成することが一つの課題になります。
$d=3$ のカラー符号は Steane 符号としてよく知られており、こちらの記事でも解説しています。しかし、符号距離を $d=5$ 以上に拡張した符号については、具体的なエンコード回路などの実装まで含めて解説している記事は見当たりませんでした。
そこで本記事では、Steane 符号から一歩進んで、符号距離 $d=5$ の 4.8.8 カラー符号のエンコード回路を実際にシミュレータ上で実装し、期待される論理状態が得られるかを確認します。
カラー符号と符号距離
まず、今回扱うカラー符号の構造を確認しておきます。カラー符号は、格子の頂点に物理量子ビットを配置し、格子の面に対応する演算子をスタビライザー生成元として定義する符号です。
図1に、符号距離 $d=3, 5, 7$ に対応する 4.8.8 格子の例を示します。各頂点は物理量子ビットを表します。また、各面 $f$ に対して、そこに含まれる頂点上のパウリ演算子を掛け合わせた面演算子を定義します。
図1. 符号距離dに対応する 4.8.8 格子
具体的には、各面 $f$ に対して、$X$ 型と $Z$ 型の二種類の面演算子
$$
g_f^X := \prod_{v \in f} X_v
\tag{1}
$$
$$
g_f^Z := \prod_{v \in f} Z_v
\tag{2}
$$
を定義します。ここで、$v$ は面 $f$ の頂点、$X_v,Z_v$ は頂点 $v$ に置かれた物理量子ビットに作用するパウリ演算子です。つまり、一つの面 $f$ から、$X$ 型生成元 $g_f^X$ と $Z$ 型生成元 $g_f^Z$ が一つずつ定まります。このようにして得られる面演算子全体が、カラー符号のスタビライザー生成元になります。これらをまとめて $g_1,g_2,\dots,g_r$ と書くと、符号空間 $C$ は
$$
C={|\psi\rangle \mid g_i|\psi\rangle=|\psi\rangle,\ i=1,\dots,r}
\tag{3}
$$
で与えられます。したがって、符号空間 $C$ に属する状態は、図1のすべての面に対応する生成元について $+1$ 固有状態になっています。
量子誤り訂正符号は、しばしば $[[n,k,d]]$ という記法で表されます。ここで、$n$ は物理量子ビット数、$k$ は符号化される論理量子ビット数、$d$ は符号距離を表します。符号距離 $d$ の符号では、$t=\left\lfloor \frac{d-1}{2} \right\rfloor$ 個までの物理量子ビット誤りを訂正できます。例えば、$d=3$ では 1 量子ビット誤りまで、$d=5$ では 2 量子ビット誤りまで訂正できます。
本記事で扱う $[[17,1,5]]$ 符号は、17 個の物理量子ビットを用いて 1 個の論理量子ビットを符号化する、符号距離 5 のカラー符号ということになります。前回扱った Steane 符号、すなわち $[[7,1,3]]$ 符号から符号距離を一段階大きくした例として見ることができます。
エンコードの考え方
スタビライザー符号において、論理状態をエンコードする方法は大きく分けて二つあります。一つは、スタビライザー生成元を測定し、測定結果に基づいて符号空間へ射影する方法です。もう一つは、測定を用いず、ユニタリ操作によって入力状態を符号空間内の論理状態へ写す方法です。以下では便宜上、前者を「射影測定によるエンコード」、後者を「ユニタリ操作によるエンコード」と呼ぶことにします。
どちらの方法を選ぶかは、符号の種類だけでなく、実験やシミュレーションで何を調べたいか、また使用するデバイスの性質にも依存します。
射影測定によるエンコード
この方法では、初期状態に対して生成元を測定し、測定結果に対応する固有空間へ状態を射影します。ただし、任意の入力状態をそのまま論理状態へエンコードすることは難しく、実際には $|0_L\rangle$ や $|+_L\rangle$ のような特定の論理状態の準備に用いられることが多いです。任意の状態を論理状態として準備したい場合には、state injection1 などの手法を組み合わせて考える必要があります。
ここでは、論理ゼロ状態 $|0_L\rangle$ の準備を考えます。物理量子ビットを $|0\rangle^{\otimes n}$ に初期化したあと、各生成元の $+1$ 固有空間へ射影すると、形式的には
$$
|0_L\rangle
\propto
\left(
\prod_{i=1}^{r}
\frac{I+g_i}{2}
\right)
|0\rangle^{\otimes n}
\tag{4}
$$
と書けます。ここでは規格化定数を省略しています。
実際には、すべての測定結果が $+1$ になるとは限りません。というのも、射影演算子はユニタリではないからです。ある生成元 $g_i$ の測定結果が $-1$ だった場合、状態は $g_i$ の $-1$ 固有空間へ射影されています。この場合、$g_i$ と反可換な演算子を作用させて、状態を $+1$ 側に戻すか、測定結果を記録して後で古典的に補正をします。したがって、射影測定によるエンコードでは、生成元を測定するだけでなく、得られた測定結果をどのように扱うかも手順に含まれます2。
この方法は、スタビライザー測定を高速かつ高忠実度に実行できる場合に有効です。特に、誤り訂正サイクルを繰り返し実行する量子計算機では、スタビライザー測定はもともと必要な操作です。そのため、状態準備を測定とシンドローム処理の枠組みに組み込むことができます。
また、ハードウェアの接続性に制約がある場合にも有効な選択肢になります。たとえば超伝導量子ビットでは、量子ビットはチップ上に配置され、多くの場合、近接した量子ビット間の結合を介して 2 量子ビットゲートを実装します。このような制約のもとでは、遠距離ゲートを多用するエンコード回路を作るよりも、局所的なスタビライザー測定だけで扱える符号が有利になります。
一方で、測定には時間がかかります。また、測定結果そのものが誤る場合もあります。さらに、測定結果に応じて後の操作を変える必要がある場合、古典制御の遅延も問題になります。そのため、測定が遅いデバイス、測定誤りが大きいデバイス、または測定結果をすぐに次の操作へ反映しにくいデバイスでは、測定ベースの方法は実装上の負担が大きくなることがあります。
ユニタリ操作によるエンコード
ユニタリ操作によるエンコードは、測定を用いずに論理状態を準備する方法です。入力する 1 量子ビット状態を
$$
|\phi\rangle=\alpha|0\rangle+\beta|1\rangle
\tag{5}
$$
とし、残りの物理量子ビットを $|0\rangle$ に初期化したとします。このとき、適切なユニタリ操作 $U_{\mathrm{enc}}$ を構成することで、
$$
U_{\mathrm{enc}}\left(|\phi\rangle\otimes |0\rangle^{\otimes(n-1)}\right)=\alpha|0_L\rangle+\beta|1_L\rangle
\tag{6}
$$
となるように、任意の 1 量子ビット状態を符号空間の論理状態へ写すことができます。スタビライザー符号では、このような $U_{\mathrm{enc}}$ を生成元から構成できることが知られています[参考2]。
この方法では、測定結果による分岐がありません。一度 $U_{\mathrm{enc}}$ を実現するゲート列を定めれば、同じ操作を実行することで論理状態を準備できます。そのため、シミュレーションで扱いやすく、小規模な符号の動作確認や、論理状態を明示的に準備したい場合に適しています。
また、実機実装では、測定が遅い場合や、測定結果に応じたリアルタイム制御を避けたい場合に有効です。特に、イオントラップや中性原子のように、量子ビット間の接続性を比較的柔軟に使えるハードウェアでは、ユニタリ操作によるエンコードが選択肢になります。
一方で、$U_{\mathrm{enc}}$ を実現するゲート列が深くなると、ゲート誤りの影響を受けやすくなります。特に、途中で発生した誤りが CNOT などの 2 量子ビットゲートを通じて複数の量子ビットへ広がる点には注意が必要です。また、必要な量子ビット同士を直接相互作用させられない場合、SWAP などの追加操作が必要になり、さらにゲート列が深くなります。
[[17,1,5]] 符号のエンコード
それでは、$[[17,1,5]]$ 符号のエンコードを具体的に実装します。
図2に、$[[17,1,5]]$ 符号の量子ビットの配置を示します。各頂点には物理量子ビットが対応しており、量子ビットには $q_0,q_1,\dots,q_{16}$ のインデックスを割り当てています。
図2. [[17,1,5]]符号の量子ビットの配置
入力する 1 量子ビット状態を
$$
|\phi\rangle=\alpha|0\rangle+\beta|1\rangle
\tag{7}
$$
とし、残りの 16 個の物理量子ビットを $|0\rangle$ に初期化します。本記事では、入力状態を $q_1$ に準備します。このとき、適切なユニタリ操作 $U_{\mathrm{enc}}$ によって
$$
U_{\mathrm{enc}}\left(|\phi\rangle_{q_1}\otimes|0\rangle^{\otimes 16}\right)=\alpha|0_L\rangle+\beta|1_L\rangle
\tag{8}
$$
となるように、入力状態を論理状態へ写します。
実装
今回は、$[[17,1,5]]$ 符号のエンコードを具体的に確認するため、図2の量子ビット配置と生成元の条件をもとに、$U_{\mathrm{enc}}$ を自分で構成しました。構成にあたり、なるべくゲート数が少なくなるようにしています。ゲート数が増えると、実機ではゲート誤りの影響を受けやすくなります。また、シミュレーションでもゲート列が深くなるほど計算量が増えます。そのため、同じ論理状態を準備する場合には、不要なゲートを取り除いた浅い回路の方が扱いやすくなります。
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit.quantum_info import Statevector, Pauli
from qiskit.visualization import plot_histogram
import matplotlib.pyplot as plt
import numpy as np
# %matplotlib inline
# [[17,1,5]]符号における論理状態の符号化
# データ量子ビットはq1
circ = QuantumCircuit(17)
circ.h(0)
circ.h(4)
circ.h(6)
circ.h(7)
circ.h(8)
circ.h(12)
circ.h(15)
circ.h(16)
circ.cx(1, 2)
circ.cx(0, 3)
circ.cx(0, 1)
circ.cx(6, 14)
circ.cx(6, 2)
circ.cx(6, 3)
circ.cx(8, 13)
circ.cx(15, 10)
circ.cx(15, 11)
circ.cx(15, 14)
circ.cx(16, 15)
circ.cx(2, 5)
circ.cx(5, 9)
circ.cx(7, 6)
circ.cx(16, 7)
circ.cx(6, 10)
circ.cx(7, 11)
circ.cx(4, 0)
circ.cx(0, 2)
circ.cx(8, 4)
circ.cx(4, 5)
circ.cx(12, 8)
circ.cx(8, 9)
circ.cx(9, 13)
# エンコード回路を変数に保存
encoder = circ.to_instruction(label='encoder')
decoder = circ.inverse().to_instruction(label='decoder')
circ.draw("mpl")
エンコード後の状態の確認
エンコード後の状態がどのような状態になっているかを見ておきます。このエンコード回路では、8 個の Hadamard ゲートによって、$|0_L\rangle$ は $2^8=256$ 個の計算基底の重ね合わせになります。同様に、$|1_L\rangle$ も $2^8=256$ 個の計算基底の重ね合わせになります。
# 状態ベクトル取得
state = Statevector.from_instruction(circ)
# 各基底状態の確率
probs = state.probabilities_dict()
# 基底の数
print(len(probs))
[out]
256
具体的に、エンコードによって得られた状態が $[[17,1,5]]$ 符号の符号空間に入っていること、すなわちスタビライズ状態であることを確認します。
スタビライザー符号では、符号空間はすべての生成元の $+1$ 固有空間として定義されます。したがって、エンコード後の状態 $|\psi_{\mathrm{enc}}\rangle$ が符号空間に属していれば、各生成元 $g_i$ に対して $g_i|\psi_{\mathrm{enc}}\rangle=|\psi_{\mathrm{enc}}\rangle$ が成り立ちます。このことは、期待値を計算することで確認できます。すべて生成元について $\langle \psi_{\mathrm{enc}}|g_i|\psi_{\mathrm{enc}}\rangle=1$ となっていれば、$|\psi_{\mathrm{enc}}\rangle$ はスタビライズされていることが分かります。
今回のエンコード回路は Hadamard ゲートと CNOT ゲートのみからなる Clifford 回路です。そのため、Qiskit の StabilizerState を用いて、状態をスタビライザー形式のまま扱うことができます。
$[[17,1,5]]$ 符号の生成元を Pauli 文字列として定義します。
stabilizers = {
"g_1": Pauli("IIIIIIIIIIIIIXXXX"),
"g_2": Pauli("IIIIIIIIIIIXXIXIX"),
"g_3": Pauli("IIIIIIIXXIIXXIIII"),
"g_4": Pauli("IIIIIXXIIXXIIIIII"),
"g_5": Pauli("IIIXXIIXXIIIIIIII"),
"g_6": Pauli("IXXIIXXIIIIIIIIII"),
"g_7": Pauli("XXIIIXIIIXIIIIIII"),
"g_8": Pauli("IIXXIIXXIIXXIXXII"),
"g_9": Pauli("IIIIIIIIIIIIIZZZZ"),
"g_10": Pauli("IIIIIIIIIIIZZIZIZ"),
"g_11": Pauli("IIIIIIIZZIIZZIIII"),
"g_12": Pauli("IIIIIZZIIZZIIIIII"),
"g_13": Pauli("IIIZZIIZZIIIIIIII"),
"g_14": Pauli("IZZIIZZIIIIIIIIII"),
"g_15": Pauli("ZZIIIZIIIZIIIIIII"),
"g_16": Pauli("IIZZIIZZIIZZIZZII"),
}
状態 $|\psi_{\mathrm{enc}}\rangle$ に対して各生成元の期待値を計算します。具体的には、$q_1$ に $|0\rangle$ を入力した場合と、$q_1$ に $|1\rangle$ を入力した場合のそれぞれについて、各生成元の期待値を計算します。どちらの場合もすべての期待値が $1$ であれば、得られた $|0_L\rangle$ と $|1_L\rangle$ は同じ符号空間に属していることが確認できます。
- $|0\rangle$ を入力した場合
from qiskit.quantum_info import StabilizerState
state = StabilizerState(circ)
for name, S in stabilizers.items():
val = state.expectation_value(S)
print(f"<{name}> = {val}")
[out]
<g_1> = 1
<g_2> = 1
<g_3> = 1
<g_4> = 1
<g_5> = 1
<g_6> = 1
<g_7> = 1
<g_8> = 1
<g_9> = 1
<g_10> = 1
<g_11> = 1
<g_12> = 1
<g_13> = 1
<g_14> = 1
<g_15> = 1
<g_16> = 1
- $|1\rangle$ を入力した場合
circ1 = QuantumCircuit(17)
# 入力状態 |1> を q[1] に準備する
circ1.x(1)
# エンコード回路を適用する
circ1.append(encoder.copy(), range(17))
state1 = StabilizerState(circ1)
for name, S in stabilizers.items():
val = state1.expectation_value(S)
print(f"<{name}> = {val}")
[out]
<g_1> = 1
<g_2> = 1
<g_3> = 1
<g_4> = 1
<g_5> = 1
<g_6> = 1
<g_7> = 1
<g_8> = 1
<g_9> = 1
<g_10> = 1
<g_11> = 1
<g_12> = 1
<g_13> = 1
<g_14> = 1
<g_15> = 1
<g_16> = 1
いずれの場合においても、すべての生成元で期待値が $\langle \psi_{\mathrm{enc}}|g_i|\psi_{\mathrm{enc}}\rangle=1$ となっています。エンコード回路 $U_{\mathrm{enc}}$ によって $[[17,1,5]]$ 符号の生成元でスタビライズされる論理状態を作ることができています。
論理状態のフィデリティ
ここで一つ気になる点があります。前節では、エンコード回路 $U_{\mathrm{enc}}$ によってスタビライズ状態を作ることは確認できました。しかし、それだけで「入力した任意の状態が、期待通りの論理状態としてエンコードされている」と言い切ってよいのでしょうか。
例えば、入力状態が $|\phi\rangle=\alpha|0\rangle+\beta|1\rangle$ であるとき、エンコード後の状態として期待されるのは $\alpha|0_L\rangle+\beta|1_L\rangle$ です。つまり、$|0\rangle$ と $|1\rangle$ がそれぞれ $|0_L\rangle$ と $|1_L\rangle$ に写されるだけでなく、重ね合わせの係数 $\alpha,\beta$ も論理基底上で正しく保たれている必要があります。
そこで、実際に得られた状態と期待される論理状態を直接比較します。まず、$|0\rangle$ を入力して得られる状態を $|0_L\rangle$、$|1\rangle$ を入力して得られる状態を $|1_L\rangle$ とします。次に、同じ $U_{\mathrm{enc}}$ を重ね合わせ状態 $|\phi\rangle$ に作用させ、得られる状態を
$$
|\psi_{\mathrm{enc}}\rangle=U_{\mathrm{enc}}
\left(
|\phi\rangle\otimes |0\rangle^{\otimes 16}
\right)
\tag{9}
$$
とします。期待される論理状態は
$$
|\psi_{\mathrm{target}}\rangle=\alpha|0_L\rangle+\beta|1_L\rangle
\tag{10}
$$
です。実際に得られた状態 $|\psi_{\mathrm{enc}}\rangle$ と、期待される状態 $|\psi_{\mathrm{target}}\rangle$ のフィデリティ
$$
F=
|\langle \psi_{\mathrm{target}}|\psi_{\mathrm{enc}}\rangle|^2
\tag{11}
$$
を計算します。理想的には $F=1$ となります。
ここでは、StabilizerState ではなく Statevector を用います。StabilizerState はスタビライザー状態、すなわち Clifford 操作で生成できる状態を扱うための形式です。一方、任意に選んだ係数 $\alpha,\beta$ を持つ入力状態は一般にはその条件を満たさないので、扱えない場合があります。そこで、ここでは Statevector を用いて、実際に得られた状態 $|\psi_{\mathrm{enc}}\rangle$ と期待される論理状態 $|\psi_{\mathrm{target}}\rangle$ を直接比較します。
from qiskit.quantum_info import state_fidelity
n_qubits = 17
input_qubit = 1
# 入力状態 |phi> = alpha|0> + beta|1> の係数を指定
vec = np.array([1, np.sqrt(2)], dtype=complex)
vec = vec / np.linalg.norm(vec)
alpha, beta = vec
# |0_L> を作る
circ0 = QuantumCircuit(n_qubits)
circ0.append(encoder.copy(), range(n_qubits))
state0_L = Statevector.from_instruction(circ0)
# |1_L> を作る
circ1 = QuantumCircuit(n_qubits)
circ1.x(input_qubit)
circ1.append(encoder.copy(), range(n_qubits))
state1_L = Statevector.from_instruction(circ1)
# 入力状態 |phi> を q_1 に準備してエンコード
circ_phi = QuantumCircuit(n_qubits)
circ_phi.initialize([alpha, beta], input_qubit)
circ_phi.append(encoder.copy(), range(n_qubits))
state_enc = Statevector.from_instruction(circ_phi)
# 期待される論理状態 |psi_target> を作成
state_target = Statevector(alpha * state0_L.data + beta * state1_L.data)
# フィデリティを計算
fidelity = state_fidelity(state_enc, state_target)
print(f"Fidelity = {fidelity:.4f}")
[out]
Fidelity = 1.0000
出力されたフィデリティは F=1.0000 となりました。したがって、今回選んだ入力状態に対して、実際に得られた状態 $|\psi_{\mathrm{enc}}\rangle$ は、期待される論理状態 $|\psi_{\mathrm{target}}\rangle$ と一致していることが分かります。つまり、$U_{\mathrm{enc}}$ は、入力状態の重ね合わせ係数を保ったまま、対応する論理状態へ正しく写していることが確認できました。
論理ゲートの実装
最後に、エンコードした論理状態に対して、論理ゲートをトランスバーサルに実装できることを確認します。前回記事で見たように、二次元カラー符号では論理パウリ演算子や Clifford ゲートをトランスバーサルに実装できます。
ここではエラーは起こらないものとして、$U_{\mathrm{enc}}$の逆操作(つまり${U_{\mathrm{enc}}^{\dagger}}$)によって復号を行います。
論理 X ゲート
まず、論理 $X$ ゲートを確認します。
circ = QuantumCircuit(17)
circ.append(encoder.copy(), range(17))
for i in range(17):
circ.x(i)
circ.append(decoder.copy(), range(17))
# Z基底測定
circ.measure_all()
# circ.draw("mpl")
# シミュレータでの実行
n_shots = 10000 # シミュレーターでのサンプリング回数
backend_sim = AerSimulator() # シミュレーターの用意
result = backend_sim.run(transpile(circ.decompose()), shots=n_shots).result()
counts = result.get_counts(0)
plot_histogram(counts)
$q_1$ に入力した $|0\rangle$ に対して、復号後は $q_1$ のみが $1$、その他の量子ビットはすべて $0$ になっています。期待通り論理 $X$ ゲートが作用していることが確認できました。
論理 S ゲート
次に、論理 $S$ ゲートを確認します。$S$ ゲートは一量子ビットに対して
$$
S|0\rangle=|0\rangle
\tag{12}
$$
$$
S|1\rangle=e^{i\pi/2}|1\rangle
\tag{13}
$$
と作用します。
4.8.8 格子のカラー符号では、符号距離 $d$ によって、トランスバーサルな $S$ 操作が論理 $S$ として働くか、論理 $S^\dagger$ として働くかが変わるので注意が必要です。今回は $d=5$ であり、$d\equiv 1 \pmod{4}$ なので、
$$
S_L = S^{\otimes n}
\tag{14}
$$
として論理 $S$ ゲートを実装できます。
位相は通常の測定では直接確認できないため、ここでは Statevector を用いて数値的に確認します。$|1_L\rangle$のみ位相が変化することを確認するため、$
|+\rangle = \frac{|0\rangle + |1\rangle}{\sqrt{2}}
$ を入力状態として与えます。
import matplotlib.cm as cm
# 量子回路の作成
circ = QuantumCircuit(17)
# |+> を入力
circ.h(1)
circ.append(encoder.copy(), range(17))
for i in range(17):
circ.s(i)
circ.append(decoder.copy(), range(17))
# 量子状態の取得
state = Statevector.from_instruction(circ)
amps = np.abs(state.data)
phases = np.mod(np.angle(state.data), 2*np.pi)
# 非ゼロ成分のみ抽出
mask = amps > 1e-12
amps = amps[mask]
phases = phases[mask]
indices = np.nonzero(mask)[0]
# プロット
basis = [f"{i:0{circ.num_qubits}b}" for i in indices]
norm = plt.Normalize(0, 2*np.pi)
colors = cm.hsv(norm(phases))
fig, ax = plt.subplots(figsize=(10, 5))
ax.bar(basis, amps, color=colors)
ax.set(
ylim=(0, 1),
xlabel="Basis State",
ylabel="Amplitude",
title=r"${S_L} |+\rangle$"
)
cbar = fig.colorbar(cm.ScalarMappable(norm=norm, cmap="hsv"), ax=ax)
cbar.set_label("Phase")
cbar.set_ticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])
cbar.set_ticklabels(['0', r'$\pi/2$', r'$\pi$', r'$3\pi/2$', r'$2\pi$'])
plt.show()
復号後の結果から、$|1_L\rangle$ に対応する状態に対して位相が $e^{i\pi/2}$ だけかかっていることが確認できます。したがって、全ての物理量子ビットに $S$ ゲートを作用させることで、期待通り論理 $S$ ゲートを実装できました。
このように、$[[17,1,5]]$ 符号でも、 Clifford ゲートをトランスバーサルに実装できることが確認できました。
まとめ
今回は、符号距離 $d=5$ のカラー符号である $[[17,1,5]]$ 符号について、論理状態のエンコードを実装しました。任意の1量子ビット状態をエンコードできることや、論理 $X$ ゲートや論理 $S$ ゲートが期待通りに作用することをシミュレータ上で確認できました。
ただし、本記事で扱ったエンコードについては、理想的な論理状態を準備するためのものです。実機上で誤り耐性を考える場合には、エンコード中のゲート誤りや、測定誤り、復号処理なども含めて考える必要があります。
本記事が、Steane 符号から一歩進んで、符号距離を拡張したカラー符号を実装するための参考になれば幸いです。
参考文献
- Bombin, H. and Martin-Delgado, M. A.: Topological quantum distillation, Phys. Rev. Lett., Vol. 97, No. 18, 180501 (2006)
- Cleve, R. and Gottesman, D.: Efficient Computations of Encodings for Quantum Error Correction, Physical Review A, Vol. 56, pp. 76–82 (1997)


