勉強のきっかけ
このところ休日返上で働いていましたが、急ぎの仕事にめどがついたので、1日だけ休みを取り、前から気になっていた量子コンピューターについて勉強してみました。
もちろん、今回も ChatGPT を質問攻めにして助けてもらいながら理解を深めました。人間の先生なら「おまえ、しつこいぞ」と怒られるレベルですが、AI は決して怒りません(笑)
ようやく量子計算のしくみがつかめてきたので、Prologで実験的なコードを書いてみました。せっかくなので、その記録を共有したいと思います。
量子の世界のデータ構造
量子コンピュータでは、複素数が主役です。
1ビットを表すためには、通常の 0 または 1 ではなく、それぞれの状態が持つ振幅(複素数)が必要です。
たとえば、1ビットなら [c(R1,I1), c(R2,I2)] のように2つの複素数、2ビットなら 4つの複素数で状態を表します。
Prologでは複素数を c(R,I) という形で表しました:
c(実部, 虚部)
たとえば、[c(1,0), c(0,0), c(0,0), c(0,0)] は、2ビットの初期状態 |00⟩ に対応します。
計算の心臓部:ユニタリ行列との積
量子コンピューターの計算の基本は、「状態ベクトルにユニタリ行列をかけること」です。これは線形代数で習った行列とベクトルの積ですが、要素が複素数になっている点が違います。
Prologでは次のように行列をリストのリストで表しました:
cnot([[c(1,0), c(0,0), c(0,0), c(0,0)],
[c(0,0), c(1,0), c(0,0), c(0,0)],
[c(0,0), c(0,0), c(0,0), c(1,0)],
[c(0,0), c(0,0), c(1,0), c(0,0)]]).
これは有名なCNOTゲートを表しています。
状態ベクトルとこの行列の積を計算するために、mprod(U, V, W) という述語を定義しました。U がユニタリ行列、V が状態ベクトル、W に結果が返ります。
初期化:Hadamardゲート
量子状態を初期化するために、Hadamard行列を使います。これは各状態に「すべての可能性を等確率で割り当てる」ためのゲートです。
以下は2ビット版のHadamard行列:
hadamard([[c(0.7071,0), c(0.0,0), c(0.7071,0), c(0.0,0)],
[c(0.0,0), c(0.7071,0), c(0.0,0), c(0.7071,0)],
[c(0.7071,0), c(0.0,0), c(-0.7071,0), c(0.0,0)],
[c(0.0,0), c(0.7071,0), c(0.0,0), c(-0.7071,0)]]).
デバッグツールとしての「干渉」計算
量子状態の振幅と位相を確認するために、**干渉(interference)の総和を計算し、それを極座標(振幅・位相)**に変換してみました。
Prologのコードでいうと:
interference(V, Z) :-
interference1(V, Z1),
polar(Z1, Z).
polar(c(R, I), p(A, S)) :-
A is sqrt(R^2 + I^2),
S is acos(R / A).
結果が p(1.4142, 0.0) であれば、振幅の合計が √2 で位相が 0、つまり成功していることになります。
実験結果
以下のような実験コードを書きました:
test1(V) :-
state(S),
hadamard(H),
mprod(H, S, R),
cnot(C),
mprod(C, R, V).
これを実行すると:
?- test1(X).
X = [c(0.7071,0.0), c(0.0,0.0), c(0.0,0.0), c(0.7071,0.0)].
それぞれの振幅の2乗を確率とみなして計算します:
?- probability(X, P).
P = [0.5, 0.0, 0.0, 0.5].
つまり:
基底状態 確率
00⟩
50%
01⟩
0%
10⟩
0%
11⟩
50%
これは制御ビットが 1 のときのみ対象ビットが反転した結果であり、CNOT の動作通りです。
まとめ
Prologで量子コンピューターのシミュレーションを始めてみました。最初は正直まったく分かりませんでしたが、丁寧に質問を重ねるうちに、ようやく少しずつ理解できるようになってきました。
記事の最後にこの名言を引用しておきたいと思います:
これは一人の人間にとっては小さな一歩だが、人類にとっては大きな飛躍である。
— ニール・アームストロング
実験コード
GitHubにコードを公開しています。興味のある方はぜひ試してみてください。
→ https://github.com/sasagawa888/nprolog/blob/master/tests/quantum.pl