量子コンピューター・シミュレーター
JavaScriptで小さな量子回路を書き、ブラウザー内で直接シミュレーションして、回路図、確率、状態ベクトルを確認できます。また、加算などの計算を高水準で記述し、実際の可逆量子回路へ自動変換される様子も観察できます。
ノイズモデル
本物の量子コンピューターは完全には計算できません。量子ビットは非常に敏感で、熱、電磁場、隣接量子ビットなど環境との望ましくない相互作用によって情報の一部を失います(デコヒーレンス)。ゲート操作にも誤差があり、最後の読み出しにも失敗が起こります。このシミュレーターは初期状態では理想的に計算しますが、ここで代表的な誤差モデルを有効にし、結果への影響を直接観察できます。
quantum.add、quantum.subtract、quantum.multiply、quantum.divide、quantum.randomを使って計算を記述します。Ctrl+Enterでシミュレーションを開始します。詳しくは「ドキュメント」ボタンを開いてください。
このコードは上のプログラムコードから自動生成され、直接シミュレーションされました。ここで手動編集して再実行できます。
生成された回路が手動編集されました。そのため図のレジスター区分は非表示です。上のプログラムコードを再実行すると変更が上書きされます。
最大4,000文字。利用可能なQuantumCircuitメソッド:x、y、z、h、s、sdg、t、tdg、rx、ry、rz、cnot、cz、ccnot(別名:toffoli)、swap、measureAll、run。Ctrl+Enterでシミュレーションを開始します。
回路図
ステップ表示では、選択したゲート直後の確率と状態ベクトルを正確に示します。下のshot結果は常に回路全体へ適用されます。
OpenQASM 2.0
OpenQASM 2.0は量子回路で広く使われる交換形式で、Qiskitなどが読み込めます。ビット順に注意してください。このシミュレーターではq0が最上位(左)ですが、Qiskitではq[0]が最下位なので、測定ビット列は左右反転して表示されます。
確率
各ビット列を測定する確率を状態ベクトルから厳密に計算します。読み方向:q0は左端の最上位ビットです。
Bloch球
各量子ビットの状態をBloch球内の矢印で示します。北極=|0⟩、南極=|1⟩、赤道=等しい重みの重ね合わせです。矢印が球の半径より明らかに短い場合、その量子ビットは単独の純粋状態を持たず、他の量子ビットともつれています。ノイズでも矢印は短くなります。有効なノイズモデルではコヒーレンスが失われ、矢印が内側へ縮みます。ここでのノイズ付き球はノイズ軌道を平均した近似です。上のステップ表示ではゲートごとに矢印が動きます(ノイズなしの場合のみ)。
shot結果
シミュレーション測定で各ビット列が実際に出現した回数です。結果が複数ある場合、回数は厳密な確率の周辺で無作為にばらつきます。
状態ベクトル
確率の背後にある複素振幅です。振幅の絶対値の2乗(実部²+虚部²)が、その状態の確率です。
| 状態 | 実部 | 虚部 |
|---|
基礎:どのように動くのか
プログラムから物理量子ビットまで
本物の量子コンピューターはチップだけではありません。古典制御回路が回路を精密なパルスへ変換します。イオントラップ方式などでは、冷却、再ポンプ、量子ビット操作、読み出し用レーザーを光学系で整形し、遮蔽された真空容器へ導きます。そこで量子ビット状態を変更・測定し、結果を古典コンピューターへ返します。
量子ビットと基底状態
古典ビットは0か1です。量子ビットは2つの基底状態 |0⟩ と |1⟩の重ね合わせにもなれます。複数量子ビットの基底状態はビット列で表し、例えば2量子ビットの |10⟩ では、このシミュレーターの q0 は常に左端の最上位ビットです。
重ね合わせ
重ね合わせ状態の量子ビットは複数の基底状態の成分を同時に持ちます。成分は複素振幅で表され、振幅の絶対値の2乗が測定時に対応する状態を得る確率になります。
Bloch球
1量子ビットの状態は球内の矢印として表せます。北極は |0⟩、南極は |1⟩、赤道上は等しい重みの重ね合わせで、位相が赤道上の向きを決めます。回転ゲート rx、 ry、 rz は各軸の周りに矢印を回し、SやTなどの位相ゲートはZ軸周りに回します。量子ビットがもつれると矢印は中心へ縮み、単独の純粋状態を持たないことを視覚化できます。
測定とshots
measureAll() はすべての量子ビットを一度に測定し、回路を終了します。1回の測定では無作為な結果を1つだけ得るため、 run({ shots })で概念上shots回測定し、確率分布をヒストグラムとして表します。厳密な確率はshotの無作為性とは別に状態ベクトルから直接計算します。
Hadamardゲート
Hadamardゲート h(q) は、確定状態|0⟩ または |1⟩の量子ビットを、 |0⟩ と |1⟩ が等しい重みを持つ重ね合わせへ変えます。測定するとおよそ50%ずつになります。
位相ゲート:SとT
位相ゲート s(q) と t(q) は単独の量子ビットの測定確率を変えず、 |1⟩ 振幅の位相だけをSは90度、Tは45度回転します。重ね合わせと組み合わせると効果が現れ、2つのHadamardの間では位相により振幅が強め合うか打ち消し合います。dagger版の sdg(q) と tdg(q) は逆方向へ回してSとTを取り消します。Tを2回でS、Sを2回でZになります。
CNOTと条件付き量子もつれ
CNOTゲート cnot(control, target) は、制御量子ビットが |1⟩のときだけ標的を反転します。制御量子ビットがあらかじめ重ね合わせなら、Bell状態のような量子もつれを作れます。制御量子ビットが確定した基底状態なら、もつれを作らず条件付きビット反転だけを行います。CNOTが必ずもつれを作るわけではありません。
CZ:CNOTの対称な仲間
CZゲート cz(a, b) は、両方の量子ビットが |1⟩のときだけ振幅の符号を反転します。CNOTと違い制御と標的の区別がなく、両量子ビットへ同じように作用するため、図では接続された2つの点として描きます。標的の前後へHadamardを置くとCZからCNOTへ変換できます。CZはGrover探索など多くのアルゴリズムの中心的構成要素です。
GHZ状態:3量子ビットのもつれ
Greenberger、Horne、Zeilingerに由来するGHZ状態は、Bell状態を3量子ビットへ拡張します。1つのHadamardと2つのCNOTですべてをもつれさせると、測定結果は |000⟩ または |111⟩ だけとなり、混合したビット列は現れません。各量子ビットは単独の状態を持たず、情報は共有相関だけにあります。
Deutschアルゴリズム:最小の量子的優位性
Deutschアルゴリズムは、未知のoracleを1回だけ評価して、古典コンピューターなら2回必要な問い、つまり関数が定数か均等かに答えます。入力を重ね合わせ状態でoracleへ通すと、干渉により答えが入力量子ビットへ明確に符号化されます。このphase kickbackの原理は、ほぼすべての量子アルゴリズムの中心にあります。
Grover探索:振幅の増幅
Grover探索は、古典的方法より少ない問い合わせで未整列集合から印を付けた要素を探します。oracleが位相反転で対象状態を印付けし、ここではCZを使用します。その後、diffusion演算子が他の振幅を犠牲にして対象振幅を増幅します。2量子ビットなら1回の反復で対象を100%の確率で測定できます。
可逆加算:quantum.add()から回路へ
上のプログラムコードは quantum.add({ a, b }) を、古典加算を完全に可逆に再現するX、CNOT、CCNOT(Toffoli)ゲート回路へ変換します。情報を捨てないため、各ゲートを正確に取り消せます。CCNOTccnot(c1, c2, target)は両方の制御量子ビットが |1⟩ のときだけ標的を反転し、桁上がり付き全加算器を含む任意の古典回路を可逆に構成できます。入力AとBはXゲートで確定した基底状態として初期化されます。回路全体が重ね合わせではなく確定状態だけを通るため、最後の測定では古典的に正しい和を100%の確率で1つだけ得ます。そのため、量子シミュレーションであっても quantum.add() は、確率が100%未満の複数の状態ではなく、決定論的な結果を返します。
減算:加算を逆向きに実行
量子回路の各ゲートは正確に逆変換できるため、加算回路全体を逆向きに実行すると減算になります。 quantum.subtract({ a, b }) は加算器のゲートを逆順で使い、a-bを計算します。これは可逆計算の基本原理で、計算段階が情報を破壊せず、すべてを取り消せます。この版では負の結果を避けるためa ≥ bが必要です。
乗算:quantum.multiply()
乗算も加算と同じ可逆構成要素から作ります。筆算と同様に、因数bの立っているビットに応じて、因数aを位置をずらしながら複数回加算します。各部分加算は同じ可逆ripple-carry加算器で、桁上がりが次の積ビットへ流れます。結果レジスターは積に応じて大きくなるため、ここでは因数を3ビット(0~7)に制限し、因数、積、桁上がり量子ビットを10量子ビット以内に収めます。
除算:quantum.divide()
除算も可逆的な構成要素だけを使います: quantum.divide({ a, b }) は、余りレジスターから除数をずらしながら可逆に減算する筆算の除算を行い、結果として商 と 余りを返します(a = quotient · b + remainder)。被除数、除数、商 および 借り量子ビットを10量子ビット以内に収めるため、 bits(a) + bits(b) + bits(a÷b) + 1 ≤ 10 が必要で、0除算を避けるため除数 b は1以上です。入力が予算に収まらない場合は計算せず、エディターに報告します。
真性乱数:quantum.random()
古典コンピューターの乱数は決定論的アルゴリズムによる疑似乱数です。量子コンピューターでは quantum.random({ bits }) が各ビットをHadamardで50/50の重ね合わせにし、測定時に根本的に予測不能な値を得られます。本物の量子ハードウェアでは物理的な真性乱数ですが、このシミュレーターはブラウザーの疑似乱数で模倣します。
シミュレーターと本物の量子ハードウェア
このシミュレーターはブラウザー上の古典的な浮動小数点演算で状態を厳密に計算します。最大10量子ビットの非常に小さな回路だけを扱うため可能です。本物の量子コンピューターは物理量子ビットを使い、デコヒーレンスやノイズによる誤差があります。古典的に実用上シミュレーションできないほど大きな回路で初めて優位性が現れます。このツールは学習用であり、本物の量子プロセッサーではありません。