blueqat news
量子コンピュータ関連銘柄 更新: 10/12 14:30(日本時間)
%は前日比・グラフは直近10営業日の推移 — 株価とニュースの突き合わせ / 業界の関係図
生成AIで始める量子ソフトウェア

【AIで量子アプリ】第2回 離れた2枚のコインが必ず同じ面になるアプリ

要約

連載の第2回です。量子ビットを2個使い、離れた2枚のコインが投げるたびに必ず同じ面になるアプリを作ります。追加するコードは1文字だけ。できあがったものを東京の実機にも投げたところ、1,000回中111回は2枚が違う面になりました。シミュレータと実機の差をそのまま載せています。

この連載でやること――アプリのコードは生成AIに書かせます。そして作ったものを、シミュレータではなく本物の量子コンピュータで動かします。

シミュレータというのは、量子コンピュータの振る舞いを普通のパソコンで計算して真似したものです。理想的な答えが返ってきます。いっぽう本物の機械は、まだ誤りが多く、答えがずれます。そのずれた数字を、そのまま載せます。難しい数式は使いません。

前回は量子ビットを1個だけ使って、表か裏が出るアプリを作りました。今回は2個にします。

作るのは、離れた場所にある2枚のコインが、投げるたびに必ず同じ面になるアプリです。片方が表ならもう片方も表、片方が裏ならもう片方も裏。これが毎回そろいます。

作るもの

画面の左右に2枚のコインを置きます。ボタンを1回押すと、2枚同時に投げます。

第2回で作ったアプリ。6回投げて、6回とも2枚が同じ面になりました
第2回で作ったアプリ。6回投げて、6回とも2枚が同じ面になりました

写真は実際に6回押したところです。右下に「6 回投げて、一致 6 回」と出ています。

変えるのは1文字だけ

前回のバックエンドと見比べてください。変わったのは回路の行だけです。

@app.route("/api/toss")
def toss():
    result = Circuit().h[0].cx[0, 1].m[:].run(shots=1)
    bits = list(result.keys())[0]          # "00" か "11"
    face = ["表" if b == "0" else "裏" for b in bits]
    return jsonify({"left": face[0], "right": face[1], "same": face[0] == face[1]})

.cx[0, 1] が増えました。CXゲートといいます。「0番目が1なら、1番目をひっくり返す」という操作です。

順番に見ます。まず .h[0] で0番目を重ね合わせにします。ここまでは前回と同じで、0番目は表とも裏とも決まっていません。

次に .cx[0, 1] を掛けます。0番目が決まっていないので、1番目も「0番目と同じ」という関係だけが決まって、それ自体は決まりません。この状態を量子もつれと呼びます。

最後に .m[:] で両方を測ります。[:] は全部、という意味です。ここで初めて2つとも決まり、しかも必ず同じ値になります。返ってくるのは {'00': 1} か {'11': 1} だけで、01 や 10 は出ません。

フロントエンド

左右に並べて、まとめて書き換えるだけです。

<div class="pair">
  <div class="coin"><div class="who">東京</div><div class="face" id="l">—</div></div>
  <div class="coin"><div class="who">ニューヨーク</div><div class="face" id="r">—</div></div>
</div>
<button onclick="toss()">2 枚まとめて投げる</button>
<script>
let n = 0, same = 0;
async function toss() {
  const r = await fetch('/api/toss').then(x => x.json());
  l.textContent = r.left; document.getElementById('r').textContent = r.right;
  n++; if (r.same) same++;
  document.getElementById('log').textContent = `${n} 回投げて、一致 ${same} 回`;
}
</script>

一致した回数を数えているのは、本当に毎回そろうことを画面で確かめられるようにするためです。

何がすごいのか

「同じ値を2つ返しているだけでは?」と思われるかもしれません。実際、このアプリと同じ見た目のものは、乱数を1回引いて両方に入れれば作れます。

違うのは、投げる前に答えが決まっていない点です。乱数を1回引く方法では、両方に入れた時点で答えが決まっています。もつれのほうは、測るまでどちらの面かが決まっていません。それでも、測ったときには必ずそろいます。

この「決まっていないのにそろう」が、普通のプログラムでは作れない部分です。量子暗号や量子テレポーテーションと呼ばれるものは、どれもここを土台にしています。

気をつけること

もつれた2枚は必ずそろいますが、片方を見て「もう片方を表にしよう」と決めることはできません。出る面はこちらでは選べないからです。

ですから、これを使って情報を瞬時に送ることはできません。よく誤解されるところなので、書き添えておきます。

実機でも投げてみました

ここまではシミュレータです。手元のパソコンが量子の振る舞いを計算で真似しています。

同じコードを、東京にある本物の量子コンピュータに投げました。OQC Toshiko Tokyo-1 という32量子ビットの機械です。1,000回ぶん実行しました。コードは1行も変えていません。

結果です。

出た目回数
004282枚とも表
114612枚とも裏
0163本来出ないはず
1048本来出ないはず

一致したのは889回、88.9%でした。つまり111回、およそ9回に1回は2枚が違う面になっています。

シミュレータでは一度も起きなかったことです。前回の量子コインもそうでしたが、実機には必ずずれがあります。

念のため書き添えると、これは失敗ではありません。89%は正しく一致していますし、本来出ないはずの目は11の461回に対して63回と48回で、正しい側が7倍以上あります。もつれは確かに作れています。

次回

なぜ11%もずれるのか。理由は1つではありません。次回はそこを分解します。

そして、この11%が測れたこと自体に意味があります。シミュレータでは絶対に出ない数字だからです。

動かないときは blueqat の版を確かめてください。2.0.4 では run(shots=1) を run(shots=1, backend="numpy") に変えると動きます(2.1.3 以降は変えないでください)。詳しくは第1回に書きました。

続きはメールでも受け取れます

新着記事のまとめを、毎日・週1回・月1回から選んでお届けします。 対談と教えて先生の続きも読めるようになります。登録も閲覧も無料です。

ログインしてメール配信を設定