Photonqatで光量子計算 (量子テレポーテーション)

$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
$$

# はじめに
どうやら2020年は量子コンピュータの実用元年的なことが某所で言われているようで。
またQuantum Nativeという言葉も耳にする機会がじわじわ増えていたり。
「西暦2020年を境に世界は量子コンピュータの実用化へ舵を切った。」とでも書くとどこかのSF小説の書き出しみたいですね(素人感)。

私も去年はStrawberry Fieldsおじさんとしていくらか記事を発信させて頂いており、2020年も光量子計算推しでいく予定なのですが、今後は新たな連続量光量子計算ライブラリ「Photonqat」を紹介させて頂こうと思います。



大分毛色が違いますが一応このライブラリ、あのMDR社の「qat」シリーズ3号機となっています。
https://github.com/Blueqat/Photonqat

ただぶっちゃけ連続量光量子計算はいまいち流行ってないと思ってて、理由は

- 二準位系($\ket{0}, \ket{1}$)量子計算の方が理論が整備されていて役に立ちそうなアルゴリズムが多く提案されている
- 光量子計算(連続量)は第二量子化を前提としていてとっつき辛い
- 実機については超伝導やイオントラップと比較し大分遅れる

あたりかなと思っています。
これだけ見ると何も良いところが無く見えますが期待できる点もあり、

- [連続量を扱うアルゴリズム](http://arxiv.org/abs/1902.00409)や、[連続量の性質によって可能な誤り耐性符号](https://www.jps.or.jp/books/gakkaishi/2019/10/74-10researches3.pdf)が可能
- 光を使う特性上、ネットワーク化と相性が良い。[先日発表された別チップ間の量子テレポーテーションは光子を使用しています。](https://www.nature.com/articles/s41567-019-0727-x)
- 常温常圧で動作可能

という利点があります。
ある種ポテンシャル枠なので、ライブラリに欲しくなる、求められる機能がはっきりしていくのもこれからだと思っています。
だからこそ今のうちからソースコードレベルの挙動を熟知しておく事や、今後の発展に柔軟に対応していきたいというモチベーションから、私はPhotonqatを作り始めました。

まずはインストールから！

```
pip install photonqat
```

# 量子テレポーテーション
手始めに、以前[こちら](https://qiita.com/ryuNagai/items/e4e3e64786dde32bb43e)で紹介した量子テレポーテーションをPhotonqatでやってみましょう。
細かい解説は[上記記事](https://qiita.com/ryuNagai/items/e4e3e64786dde32bb43e)、もしくは[Xanaduのドキュメント](https://strawberryfields.readthedocs.io/en/latest/algorithms/teleportation.html)を参照ください。

## Photonqat

```python
import photonqat as pq
import numpy as np
import matplotlib.pyplot as plt

G = pq.Gaussian(3)

# original state
x_origin = 1
p_origin = 0.5

# squeezeng level
r = 2

# prepare the state to teleport
G.D(0, x_origin + p_origin * 1j) # Displacement
print('Mode 0: Original state =', G.mean(0))

G.S(1, -r) # Squeezing
G.S(2, r) # Squeezing
G.BS(1, 2, np.pi/4) # 50:50 beam splitter
G.BS(0, 1, np.pi/4) # 50:50 beam splitter
x0 = G.MeasX(0) # Measuring x
p1 = G.MeasP(1) # Measuring p
G.D(2, x0 + p1 * 1j) # conditionary displace mode 2

# state of mode 0 was teleported to mode2!
print('Mode 2: teleported state', G.mean(2))

W, x, p = G.Wigner(2) # plot
```

```python
Mode 0: Original state = [1.41421356 0.70710678]
Mode 2: teleported state = [1.4778595 0.6458722]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243619/b0821aa3-b6b3-6456-1549-a056ad284780.png)

## Strawberry Fields

```python
# initialize engine and program objects
eng = sf.Engine(backend="gaussian")
teleportation = sf.Program(3)

# original state
x_origin = 1
p_origin = 0.5

# squeezeng level
r = 2

with teleportation.context as q:
    sf.hbar = 1
    psi, alice, bob = q[0], q[1], q[2]

    # state to be teleported:
    Coherent(x_origin + p_origin * 1j) | psi

    Squeezed(-2) | alice
    Squeezed(2) | bob
    BSgate(pi/4, 0) | (alice, bob)
    BSgate(pi/4, 0) | (psi, alice)
    MeasureX | psi
    MeasureP | alice

    # Bob conditionally displaces his mode
    # based on Alice's measurement result
    Xgate(scale(psi, sqrt(2))) | bob
    Zgate(scale(alice, sqrt(2))) | bob

results = eng.run(teleportation)
# state of mode 0 was teleported to mode2!
print('Mode 2: teleported state', results.state.means()[2:6:3])

x = np.arange(-5, 5, 0.1)
p = np.arange(-5, 5, 0.1)
W = results.state.wigner(2, x, p)
X, P = np.meshgrid(x, p)
plt.contourf(X, P, W) # plot
```

```python
Mode 2: teleported state = [1.43704015 0.92828879]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243619/4a516641-fcf1-228c-d9f7-96e40755ec6b.png)


ここでやっている事は両ライブラリとも全く同じです。

Strawberry Fieldsはちょっと書き方が独特に思えて("|"で区切るとか)、これは人によって感覚が異なるかもしれませんが私は若干わずらわしいです。

Photonqatは今の所どシンプルです。
回路の途中で量子状態を覗き見ることさえも普通にできてしまう自由度の高さです。
(これはさすがに今後どうにかしようと思っています)
ただ多くの人に使いやすい、わかりやすいライブラリであるべきとは考えています。

# まとめ
色々とまだまだこれからと思いますがよろしくお願いします。

※追記
光量子計算でこんなアルゴリズム、アプリケーション候補があったよ！
とか
こんな機能あると良いんじゃない？
とかネタをシェア頂けると、とても嬉しいです。