3-2. QiskitとIBM Q Experienceの使い方

IBM Q Experienceは2016年5月24日にIBM社が世界で初めてクラウド上に公開した量子コンピュータである[1]。この節では、IBM Q Experienceの使い方及びIBM社が開発している量子計算用フレームワークQiskitの使い方を学ぶ。

IBM Q Experienceの実行環境を用意する

アカウント登録

  1. まず、IBM Q ExperienceのWebページ[1] の右上のSign Inボタンをクリックしてアカウントを作る。

  2. メールアドレスとパスワードもしくは外部サービスのアカウントが要求されるが、Sign Inボタン下のSign Upをクリックする。

  3. 必要事項を記入し、Sign Upボタンをクリックする。

  4. 登録したメールアドレスにメールが送られるので、そのメール内のリンクをクリックする。すると別ウィンドウで登録完了の画面が出るので、次からはログイン可能になる。

APIの取得

これでIBM Q Experienceに登録できたので、次はIBM Q Experienceの実機(本物の量子コンピュータ)のアクセスに必要なIBM Q Experience APIの取得の仕方を学ぶ。

  1. ログイン後にWelcome to Experience!のポップアップが出るので右上の×印をクリックして閉じる。

  2. 画面右上のアイコン → “My Account”をクリックし、登録したアカウント情報を見る。

  3. 画面右上に“Account”, “Community”, “Advanced”のうち“Advanced”をクリックする。

  4. “API Token”の欄が“undefined”になっているので、“Regenerate”ボタンをクリックしてAPIを生成する。隣の“Copy this token”ボタンを押すとAPIをクリップボードに貼り付けられる。

ちなみに、IBM Q ExperienceのWebページ[1]上のGUIでドラッグ&ドロップで回路を生成し、実行することも可能である。

Qiskitの実行環境を用意する

Qiskitはpipを経由してインストールすることができる。PC内のコマンドライン(Windowsのコマンドプロンプト、Macのターミナル)にpip install qiskitと入力して実行すれば。Jupyter Notebookをお使いの方は、セル内に!pip install qiskitと入力すると使えるようになる。

Qiskitを使ってみる

QiskitはPythonフレームワークなので書く時の文法はPythonと同じである。その前に実機の使用に必要な情報をQconfig.pyにまとめて実行するファイルと同じディレクトリに保存する必要がある。Qconfig.pyの中身は以下の通りである。

[1]:
#'MY_API_TOKEN'にAPIをペーストする。
APItoken = 'MY_API_TOKEN'

config = {
    'url': 'https://quantumexperience.ng.bluemix.net/api',
    #IBM Q Networkユーザーは以下の情報も入力する。IBM Q Networkとは、IBMが量子コンピューティングの研究開発のために特別に結んだ協定で、
    #提携先に所属していれば20量子ビットの量子コンピュータが使える。ちなみに、アジアでは唯一慶應義塾大学(ibmq_20_tokyo)が選ばれている。
    #'hub': 'MY_HUB',
    #'group': 'MY_GROUP',
    #'project': 'MY_PROJECT'
}

if 'APItoken' not in locals():
  raise Exception("Please set up your access token. See Qconfig.py.")

ここでは、\(|\Psi^{+}\rangle=\frac{|00\rangle + |11\rangle}{\sqrt{2}}\)というBell状態ペアの生成のプログラムを例に学んでいく。

[1]:
#必要なモジュールのインポート
from qiskit import IBMQ, QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute, Aer
from qiskit.qasm import pi
from qiskit.tools.visualization import plot_histogram, circuit_drawer
import numpy as np
import Qconfig
[7]:
#自分のアカウントを保存する。これ以降はIBMQ.load_account()を入力すればいい。
IBMQ.save_account(Qconfig.APItoken)

#自分のアカウントで使用できるバックエンドを見る
IBMQ.backends()
[7]:
[<IBMQBackend('ibmqx4') from IBMQ()>,
 <IBMQBackend('ibmq_16_melbourne') from IBMQ()>,
 <IBMQBackend('ibmq_qasm_simulator') from IBMQ()>]

IBM Q Experienceの一般ユーザーは4量子ビットの実機‘ibmqx4’、16量子ビットの実機‘ibmqx16’、そして32量子ビットの量子シミュレータ‘ibmq_qasm_simulator’が使えることが分かった。以下のコマンドを打つと1番ジョブが投げやすい実機が分かる。

[6]:
from qiskit.providers.ibmq import least_busy
large_enough_devices = IBMQ.backends(filters=lambda x: x.configuration().n_qubits > 3 \
                                                    and not x.configuration().simulator)
backend = least_busy(large_enough_devices)
print("The best backend is " + backend.name())
The best backend is ibmq_16_melbourne

ibmq_16_melbourneが1番忙しくないことが分かったので、今回はそれを実機として使う。次にシミュレータ、実機の順で結果を見ていく。

[4]:
#量子レジスタqを生成する。
q = QuantumRegister(2)

#古典レジスタcを生成する
c = ClassicalRegister(2)

#量子レジスタqと古典レジスタc間で量子回路を生成する。
qc = QuantumCircuit(q, c)

#1番目の量子ビットにHゲートをかける。
qc.h(q[0])

#1-2番目の量子ビットにCNOTゲートをかける。(1番目の量子ビットが制御量子ビット、2番目の量子ビットがコントロール量子ビット)
qc.cx(q[0],q[1])

#1番目の量子ビットの測定値を1番目の古典ビットに、2番目の量子ビットの測定値を2番目の古典ビットに渡す。
qc.measure(q[0], c[0])
qc.measure(q[1], c[1])


backends = ['qasm_simulator','ibmq_16_melbourne']

#シミュレータを使う時は下をコメントアウトする。
backend_sim = Aer.get_backend(backends[0])

#実機を使う時は下の行をコメントアウトする。
#backend_sim = IBMQ.get_backend(backends[1])

#量子回路qcを指定したバックエンド(backend_sim)で4096回実行する。
result = execute(qc, backend_sim, shots=4096).result()

#結果を出力する。
print(result.get_counts(qc))

#結果のヒストグラムを描画する。
plot_histogram(result.get_counts(qc))
{'00': 1952, '11': 2144}
[4]:
../_images/notebooks_3.2_Qiskit_IBMQ_11_1.png

生成した状態は\(\frac{|00\rangle + |11\rangle}{\sqrt{2}}\)だから、式の通り\(|00\rangle\)\(|11\rangle\)が得られる確率は共に50%に近いことが分かる。次に実機の結果を見てみよう。但し、実機での実験は結果を得るのに非常に時間がかかるので注意が必要だ。

[7]:
#量子レジスタqを生成する。
q = QuantumRegister(2)

#古典レジスタcを生成する
c = ClassicalRegister(2)

#量子レジスタqと古典レジスタc間で量子回路を生成する。
qc = QuantumCircuit(q, c)

#1番目の量子ビットにHゲートをかける。
qc.h(q[0])

#1-2番目の量子ビットにCNOTゲートをかける。(1番目の量子ビットが制御量子ビット、2番目の量子ビットがコントロール量子ビット)
qc.cx(q[0],q[1])

#1番目の量子ビットの測定値を1番目の古典ビットに、2番目の量子ビットの測定値を2番目の古典ビットに渡す。
qc.measure(q[0], c[0])
qc.measure(q[1], c[1])


backends = ['qasm_simulator','ibmq_16_melbourne']

#シミュレータを使う時は下をコメントアウトする。
#backend_sim = Aer.get_backend(backends[0])

#実機を使う時は下の行をコメントアウトする。
backend_sim = IBMQ.get_backend(backends[1])

#量子回路qcを指定したバックエンド(backend_sim)で4096回実行する。
result = execute(qc, backend_sim, shots=4096).result()

#結果を出力する。
print(result.get_counts(qc))

#結果のヒストグラムを描画する。
plot_histogram(result.get_counts(qc))
{'01': 189, '10': 199, '00': 2181, '11': 1527}
[7]:
../_images/notebooks_3.2_Qiskit_IBMQ_13_1.png

実機による結果を見てみると、理論上は得られない\(|01\rangle\)\(|10\rangle\)が得られていることが分かる。これは演算過程で生じたエラーによるものである。この結果は、今の量子コンピュータがNISQデバイス(中規模でノイズの発生を許す量子コンピュータ)と呼ばれることを分かりやすく示している。

参考文献

[1] https://quantumexperience.ng.bluemix.net/qx/experience [online] (参照日時 2019-02-13)