量子流体の実装
/icons/hr.icon
エンコード
二次元上の流体では、以下のように9方向のベクトルを用意する必要があるため、マス目の数を$ mとしたときは$ 9m個のベクトルが必要。(静止、上、右上、右、右下、下、左下、左、左上)
https://scrapbox.io/files/68b68cc96ad07e6e4bca5d33.png
また、量子ビット数を$ nとしたとき、量子状態の数は$ 2^n個である。
そのため、理論上は量子ビット数は$ \lceil \log_2 9m \rceil個が必要。
ただし、エンコードの計算都合を考えると、8方向+静止1で分けて$ \lceil \log_2 8m \rceil$ + \lceil \log_2 m \rceilが良さそう。
さらに、マス目$ (x,y)で取り出しやすい形式にするため、$ |x\rangle|y\rangle|v\rangle($ vは8方向)としたい。なので、横のマス目数を$ w縦のマス目数を$ hとしたとき、
8方向
$ \lceil \log_2 w \rceil$ + \lceil log_2 h \rceil$ +log_2 8$ \tag{1}
静止1
$ \lceil \log_2 m \rceil \tag{2}
だけ量子ビットが必要。
また、8方向の回路と、静止1の回路について、確率1で正規化しなければいけないので、古典ビットに倍率を保持しておく必要がある。
今回は、8方向の解釈を以下のようにする。
https://scrapbox.io/files/68b694a3e8e2113ca7e525f3.png
/icons/hr.icon
回路実装
概要
シンプルな2x2の格子を考える。
https://scrapbox.io/files/68b68de7e8d04409cc0de577.png
ここで、$ (1),(2)より
$ \lceil \log_22 \rceil + \lceil \log_22 \rceil +3 =5
$ \lceil \log_2{4} \rceil = 2
$ 5+2=7
7量子ビット必要である。
また、状態の初期化演算を$ U_{init}、移流項を$ U_{swap}として、以下のような回路になる。
https://scrapbox.io/files/68b6902acfd5bf5b7b979f54.png
$ U_{init}については、各ライブラリの初期化関数を活用できるため、割愛。詳細はAQCEなど参照。 $ U_{swap}については、いくつか考え方がある。
端点到着後の挙動
平面トーラス
1つ目は、平面トーラスである。画面の端まで行った場合、反対側に戻る。
$ |x\rangle |y\rangle内のSwapで完結するので、これが1番簡単そう。
https://scrapbox.io/files/68b691cca8c948afc75f3394.png
反射
2つ目は、反射である。画面の端まで行ったら、ベクトルを反射させる。
向きも変わるので、$ |x\rangle |y\rangle |v\rangleでのSwapが必要となり、処理の実装(回路的な意味で)が平面トーラスより少し面倒。ロジック自体の複雑さは、ただのスワップなので同等。
https://scrapbox.io/files/68b692e2a8c948afc75f4235.png
無限放出
3つ目は、無限放出である。画面の端まで行ったら、値は失われる。
Swapは$ |x\rangle |y\rangle内で済むが、値の損失を考慮して確率を正規化し直す作業が必要なため、おそらく1番実装が難しい。
もしくは虚無ビットを作るか?そこに確率を流し込む。なんかいけそう。
https://scrapbox.io/files/68b6934e7869f4d85674e442.png
移流項の実装
今回は、平面トーラスで実装する。
たとえば、上方向のベクトルのみで考えたとする。
https://scrapbox.io/files/68b695e18bead631918c3fb6.png
すると、
〜〜〜〜〜
$ |0\rangle |0\rangle |000\rangleは端点に到達しているため、反対側の$ |0\rangle |1\rangle |000\rangleへ移動。
$ |0\rangle |1\rangle |000\rangleは1マス上に移動し、$ |0\rangle |0\rangle |000\rangleへ移動。
$ |0\rangle |0\rangle |000\rangle $ \larr \text{Swap} \rarr $ |0\rangle |1\rangle |000\rangle
方向が変わらないということは、$ |v\rangle (=|000\rangle)に影響はないため、$ |x\rangle|y\rangleに対しSwapを作成し、
$ |0\rangle |0\rangle = \left( \begin{matrix} 1\\0\\0\\0 \end{matrix} \right)
$ |0\rangle |1\rangle = \left( \begin{matrix} 0\\1\\0\\0 \end{matrix} \right)
$ U_{swap(0,0),(0,1)} = \left( \begin{matrix} 0&1&0&0\\ 1&0&0&0\\ 0&0&1&0\\ 0&0&0&1 \end{matrix} \right)
〜〜〜〜〜
$ |1\rangle |0\rangle |000\rangleは端点に到達しているため、反対側の$ |1\rangle |1\rangle |000\rangleへ移動。
$ |1\rangle |1\rangle |000\rangleは1マス上に移動し、$ |1\rangle |0\rangle |000\rangleへ移動。
$ |1\rangle |0\rangle |000\rangle $ \larr \text{Swap} \rarr $ |1\rangle |1\rangle |000\rangle
$ |1\rangle |0\rangle = \left( \begin{matrix} 0\\0\\1\\0 \end{matrix} \right)
$ |1\rangle |1\rangle = \left( \begin{matrix} 0\\0\\0\\1 \end{matrix} \right)
$ U_{swap(1,0),(1,1)} = \left( \begin{matrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&0&1\\ 0&0&1&0 \end{matrix} \right)
〜〜〜〜〜
もしこれが3つなら、
$ |0\rangle |00\rangle |000\rangle $ \larr \text{Swap} \rarr $ |0\rangle |01\rangle |000\rangle
$ |0\rangle |01\rangle |000\rangle $ \larr \text{Swap} \rarr $ |0\rangle |10\rangle |000\rangle
で移動が完了。4つ以上でも、同様にSwapを増やしていけばいいだけ。
〜〜〜〜〜
他の7方向も、同様に実装可能。
結果、
???これおかしいかも???
どっちも-2すると、たとえば上方向で一番右の列が取れない気がする。
斜めって実はめんどくさくないか?対角以外繋がってる気がする
(-1,0,1)(-1,0,1)の組み合わせを考えなくてはいけないのでは?
$ U_{swap} = \sum_{v=0}^{7} \sum_{y=0}^{h-2} \sum_{x=0}^{w-2} U_{swap(x, y), (x,(y+1))}
($ \%は剰余を示す)