QISKit 手引き

ちょっとIBM Qを触ってみたので、QISKitについてまとめておきます。

**2017年11月時点の記事であり、最新の内容ではありません。**

# 導入

* IBM Qについて
   - 量子ゲート式の量子コンピュータ 
   - IBM quantumexperienceのアカウントを作成することで無料で利用可能
   - [公式サイト](https://www.research.ibm.com/ibm-q/)
   - [IBM沼田さんによる解説記事](https://www.ibm.com/developerworks/jp/cloud/library/cl-quantum-computing/index.html) にあるようにGUIで量子回路を設計してSimulator or 実機で計算が可能
   - 2017年11月現在, 主に利用できるのは5 qubitのibmqx4, Qiitaにも解説記事はいくつかある 
     - [量子コンピュータで１＋１を計算する](https://qiita.com/kjtnk/items/8385052a50e3154d1022): シミュレータで00,01同士の足し算をした記事
     - [量子コンピュータ（実機）で量子フーリエ変換する](https://qiita.com/converghub/items/7bcf8abd03d724349437): ibmqx2を用いた量子フーリエ変換をした記事
   - 量子ゲートについてはちゃんと行列表記のある[英語wiki](https://en.wikipedia.org/wiki/Quantum_gate)が今のところ個人的にわかりやすい

* QISKit
   - IBM Researchと研究者によって与えられている、IBM Qにジョブ投げするためのKit
   - [Github](https://github.com/QISKit)にチュートリアル用のJupyter, Python SDK, Swift SDK,  JavaScript SDK, Python API, またユーザガイドやopenqasmのガイド等が存在
   - ~~なぜか[公式](https://www.qiskit.org/)が英語と日本語に対応しており、~~Python SDKでは[マニュアル](https://qiskit.org/documentation/)を読めば簡単に実装可能
     - また公式の開発速度が結構な速度なので、公式の解説が最も頼りになります
     - 日本語対応は終了している模様です(2019年追記)
   - [量子コンピュータで1+1を計算する[実装編]](https://qiita.com/hiroyuki827/items/77b9922ed8acba96df31): Python SDKの実装例の記事

QISKitにでてきたOpenQASMとは何か, APIとSDKの違いは何かについては以下では記述します。

# OpenQASM

* OpenQASM: 量子アセンブリ言語(quantum assembly language (QASM)) 
* OpenQASMは量子回路を記述するための言語です
* IBM QのComposer画面から、OpenQASMを用いて回路設計が可能です
  - 手順: 
    "Switch to Qasm Editor"をクリックすると、
      <img width="750" alt="スクリーンショット 2017-11-26 18.54.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/107161/7b3c3b91-00b7-754a-da36-fd6b0129c067.png">
    QASMで回路を設計できるようになります
      <img width="750" alt="スクリーンショット 2017-11-26 18.54.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/107161/6dd7fcd1-8a7e-8522-4f2a-0cb6246ed1b2.png">
* QISKitのSDK, APIは内部でOpenQASMを記述しています
* Cross et al. (2017) [Open Quantum Assembly Language](https://arxiv.org/abs/1707.03429)で詳細が記述されています

# SDK

例えば1+1のシミュレータ計算は下記のように計算できますが、

```py
from qiskit import QuantumProgram
import json

def read_api():
	f_api = open("../api_token.json", "r")
	api_dic = json.load(f_api)
	QX_TOKEN = api_dic["api"]
	QX_URL = "https://quantumexperience.ng.bluemix.net/api"
	return(QX_TOKEN, QX_URL)

class Q_Circuit():
	_Name = "summation"
	_Num_qr = 4
	_Num_cr = 4

def summation():
	qp = QuantumProgram()
	token, url = read_api()
	qp.set_api(token, url)

	#Qbitの設定
	qr = qp.create_quantum_register("qr", Q_Circuit._Num_qr)
	cr = qp.create_classical_register("cr", Q_Circuit._Num_cr)
	qc = qp.create_circuit(Q_Circuit._Name, [qr], [cr])

	#回路部分		
	qc.h(qr[0])
	qc.h(qr[1])
	qc.ccx(qr[0], qr[1], qr[2])
	qc.cx(qr[0], qr[3])
	qc.cx(qr[1], qr[3])

	qc.measure(qr, cr)
	print(qp.get_qasm(Q_Circuit._Name))		#QASMコードの取得
	result = qp.execute([Q_Circuit._Name], shots=1024)		#計算の実行
	print(result.get_data(Q_Circuit._Name))

if __name__ == '__main__':
	summation()
```

`print(qp.get_qasm(Q_Circuit._Name)) ` で取得できるように、またqiskitの中身( [_quantumcircuit.py](https://github.com/QISKit/qiskit-sdk-py/blob/master/qiskit/_quantumcircuit.py), [_quantumregister.py](https://github.com/QISKit/qiskit-sdk-py/blob/master/qiskit/_quantumregister.py) )を見ればわかるように、内部ではOPENQASMが使われています。
(executeはデフォルトがbackend="local_qasm_simulator")

# API

APIはより直接的に、OpenQASMそのものを記述してIBM Qに送ります([参考コード](https://www.infoq.com/news/2017/03/ibm-qiskit-quantum-computing))。
1+1の場合、先程のOPENQASMを利用して、シミュレータで、

```py
from IBMQuantumExperience import IBMQuantumExperience
import json

def read_api():
	f_api = open("../api_token.json", "r")
	api_dic = json.load(f_api)
	QX_TOKEN = api_dic["api"]
	QX_URL = "https://quantumexperience.ng.bluemix.net/api"
	return(QX_TOKEN, QX_URL)

def Qasm_Code():
	qasm = """//OPENQASM 2.0
OPENQASM 2.0;
include "qelib1.inc";
qreg q[4];
creg c[4];
h q[0];
h q[1];
ccx q[0],q[1],q[2];
cx q[0],q[3];
cx q[1],q[3];
measure q[3] -> c[0];
measure q[2] -> c[1];
measure q[1] -> c[2];
measure q[0] -> c[3];
"""
	return(qasm)

def main():
	token, url = read_api()
	IBMQ = IBMQuantumExperience(token)
	qasm = Qasm_Code()
	result = IBMQ.run_experiment(qasm, shots= 1024,name='api_test', timeout=60)
	print(result.values() )

if __name__ == '__main__':
	main()
```
とすることで計算を実行できます。(run_experimentのデフォルトがbackend='simulator',
 [IBMQuantumExperience.py](https://github.com/QISKit/qiskit-api-py/blob/master/IBMQuantumExperience/IBMQuantumExperience.py))
ibmqx4に計算を投げる場合はrun_experimentをbackend="ibmqx4"と指定します。
(上記の回路設計ではibmqx4では計算が走らないので、適宜qasmを変える必要があります)

API経由で投げた計算は、IBM QのComposerページのQuantum Scoresに結果が溜まってしまうのが注意点です。