【Python】量子コンピュータのゲート演算をBlueqatでゼロからやってみよう

先日参加した勉強会にて、量子コンピュータの基本を学んだので、その知識をシェアします。

勉強会資料リンク：[Blueqat SDKハンズオン](https://www.slideshare.net/mdrft/blueqat-sdk),　[今後の量子コンピュータの展望〜機械学習への活用〜](https://www.slideshare.net/mdrft/190319)
#目次
・量子コンピュータの基本を学ぶ
・量子コンピューティングを体感できるSDK「Blueqat」の環境構築
・基本操作を学ぶ（ゲート演算）
#量子コンピューターとは？
量子コンピュータとは、量子力学的原理を用いて開発されるコンピュータです。
現代の一般的なコンピュータは**トランジスタ**を用いて、ビットが0/1(ON・OFF)の状態を保持し計算を行なっています。
一方、量子コンピュータは0/1(ON・OFF)の状態を表現することに加えて、**状態の重ね合わせ**を表現することができます。状態の重ね合わせでは、量子ビットが0/1のどちらかの状態を保持しているのではなく、どちらの状態も保持しています。
量子コンピュータが「状態の重ね合わせ」を実現することによって、**組合せ最適化問題**等の特定の計算を従来のコンピュータに比べ、超高速で実行できるのです。
現在では、GoogleやIBM、日本ではMDRといった企業が量子コンピュータの開発を進め、**化学分子のシミュレーション**などへの応用が試みられています。

【よくあるQ&A】
・量子コンピュータは既存のコンピュータの全ての計算を高速化できる、完全上位互換のマシンなのか？
ー**NO**。量子コンピュータは組合せ最適化問題等の**特定の分野の計算を高速化できるマシン**です。したがって、従来のコンピュータが完全に量子コンピュータに置き換わるわけではありません。

・量子コンピュータを利用するためには量子力学の知識が必要なのか？
ー**NO**。プログラマの立場であれば、解きたい問題である最適化問題等について理解している必要があります。したがって、**線形代数の知識**があれば問題のルールは理解でき、量子コンピュータを用いて解決することができます。
#量子コンピュータの構造方式2パターン
量子コンピュータを実現するモデルには現在2種類あります。
**量子ゲート方式**、**量子アニーリング方式**です。

量子ゲート方式は特定の問題を汎用的かつ高速に処理する、完全な量子コンピュータを実現できるモデルです。この方式を採用したマシンとして、IBMが開発した世界初の商用量子コンピュータである**IBM Q System One**が有名です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/296645/141ff852-ff2a-b646-8b77-ae11936846a8.png)
世界初（IBM調べ）の汎用近似量子コンピューティングシステム「IBM Q System One」 

量子アニーリング方式は**組合せ最適化問題を解くことのみに特化**したモデルであり、正確には量子コンピュータではありません。組合せ最適化問題を量子コンピュータの原理で高速に処理することを、より早く実現させるために考案されたものです。その詳細な原理についてはYahoo!デベロッパーネットワークに記事があります。

[量子アニーリングがチョットワカルようになる記事](https://techblog.yahoo.co.jp/advent-calendar-2018/quantum-annealing/)

この方式を採用したマシンとして、カナダに本部を置くD-Wave Systemsが開発したD-Waveが有名です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/296645/82b4d265-5e20-e004-0395-270e1a9c5b4e.png)
D-Wave 2000Q 量子コンピューター
#量子コンピュータシミュレーションOSS「Blueqat」とは？
誰でも簡単に量子コンピュータの恩恵が受けられるようにとOSS化されたSDK。
[株式会社MDR](https://mdrft.com/)が開発した国産のOSSです。
Blueqatの名前の由来は日本産ということで、ドラえもん＝青い猫＝bluecatからきているそうです。
量子ゲートと量子アニーリングの両方の計算を行うことができます。
Q&Aは公式ワークスペースにてできるとのことです。

Githubリンク：[README](https://github.com/Blueqat/Blueqat/blob/master/README.rst)
公式コミュニティ：[Slack ワークスペース Blueqat](https://blueqat.slack.com/join/shared_invite/enQtNDA3NjU0MjM2NjEyLWU1MjJlNTM5NGNkNjk1NmYzYjU5NDliOTc5M2QwNDc1YmMyNzYzYjY3YmE2NGUxMTI1OTEyYTUwOWEyNmY4MWY)
#Blueqatの環境構築
**本記事での環境**
言語:Python3
OS:Mac

**Blueqatのインストール**

```bash
$pip install blueqat
$pip install numpy #既にインストール済みの方は不要
$pip install scipy #既にインストール済みの方は不要
```
#ゲート演算をやってみる
先ほど。量子コンピュータは0/1(ON・OFF)の状態を表現することに加えて、**状態の重ね合わせ**を表現することができると記述しました。
Blueqatを使って実際に「量子重ね合わせ」を体験してみましょう。

**【量子重ね合わせ】**

```python
from blueqat import Circuit
Circuit().h[0].m[:].run(shots=100)
```
実行結果は
**Counter({'1': 52, '0': 48})**
となりました。これは100回の試行(shots=100)のうち、1が52回、0が48回あったという意味です。

もう一度このコードを実行してみましょう。実行結果は
**Counter({'0': 57, '1': 43})**
となりました。これは100回の試行(shots=100)のうち、1が57回、0が43回だったという意味です。

0と1の数が変わっています。みなさんが実行された結果も実行のたびに変わったと思います。これが「**量子重ね合わせ**」の状態です。
この状態では各ノードが**不安定**な状態にあり、1と0のどちらの値を保持するかがランダムに決まっています。これが量子コンピュータの特色であり、この性質を用いることで特定の問題を従来のコンピュータよりも高速で実行することができるのです。

**【ゲート演算によって量子ビットの状態を変化させる】**

**量子ビットの状態変化を表した図**　(勉強会資料より)
<img width="327" alt="スクリーンショット 2019-03-22 15.51.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/296645/0feab628-94b2-f0c3-2021-e7e214ba4682.png">
ゲート演算と、量子ビットの動きの対応を理解するためには上の図が非常に便利です。

**Blueqatによるゲート処理の流れ**　(勉強会資料より)
<img width="564" alt="スクリーンショット 2019-03-22 16.19.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/296645/03b198f1-7141-b7e6-e702-c785a9e2e6b2.png">
Blueqatでは初期化→ゲート演算→測定の流れでコードを書きます。

**【実際にゲート演算を試してみる】**

**-hゲート処理-**
0→量子重ね合わせ、1→量子重ね合わせの状態に変化させることができます。
.h[0]で0(初期状態)からhゲート演算を行います。
.m[:]で状態の測定を行います。
shots=100で100回試行を繰り返します。

**0→量子重ね合わせ**

```python
Circuit().h[0].m[:].run(shots=100)
```

**1→量子重ね合わせ**

```python
Circuit().h[1].m[:].run(shots=100)
```

**-xゲート演算-**
従来のコンピュータのnot演算に該当します。
.x[0]で0(初期状態)からxゲート演算を行います。

**0→1**

```python
Circuit().x[0].m[:].run(shots=100)
```
実行結果
**Counter({'1': 100})**
すべての試行の量子ビットが1になりました。

**0→1→0**

```python
Circuit().x[0].x[0].m[:].run(shots=100)
```

実行結果
**Counter({'0': 100})**
すべての試行の量子ビットが0になりました。

**-zゲート演算-**
zゲート演算は**＋⇄ー**の変化です。**位相反転演算子**とも呼びます。
0に対しては何も変化させず、1に対しては、状態に対しては位相のみ反転を行います。
今回は**1量子ビットに対して演算を行なっている**ため、演算結果は0/1の2種類の状態のみを持ち、位相の反転を行うzゲート演算をすることには特に意味がありません。

#参考文献
[量子コンピュータとは](http://lyman.q.t.u-tokyo.ac.jp/Member/Tanakei/study/study00_qcom.htm)
[量子情報科学序論 IBM Qを動かして学ぶ量子コンピュータ](http://lyncs.hateblo.jp/entry/2017/12/16/000103#%E3%83%91%E3%82%A6%E3%83%AAZ)
[量子コンピュータって実際のところ何？　NECもアニーリングに注力](https://monoist.atmarkit.co.jp/mn/articles/1901/21/news036.html)

参考にさせていただきました。ありがとうございました。