IBMQ のお試し

量子コンピュータの基本的な使い方のメモです。まず, IBMQ は以下のサイトから利用できます。
IBM Q Experience
簡単な回路であれば, GUI で試してみるのが良いと思います。
ドラッグ&ドロップで簡単に使うことができます。ただし, 使用するバックエンド(ibmqx2, ibmqx4 など)によって回路が異なるため, 制御NOT (CNOT)を使用するときにどのノードにおけるかは制限があります。
f:id:puyokw:20180407170318j:plain
simulate を押せばシミュレーションが実行でき, run を押せば実機で実行できます。

(以下の記事のqiskit のversion はだいぶ古いので, そのうち書き直そうと思います。)
本格的に使いたい場合には, qiskit を使用するのが良さそうです。
GitHub - Qiskit/qiskit-terra: Terra provides the foundations for Qiskit. It allows the user to write quantum circuits easily, and takes care of the constraints of real hardware.
python からibmqを使用することができます。インストールは

pip install qiskit

で, できます。
実機で実行するには, api token が必要となります。
github のinstallation の項に従って, IBM Q Experience のアカウントを作成して, api token を発行します。
(ユーザー名の部分をクリックして, My Account を選択。Advanced の項目の中にAPI Token が存在するので, そこのRegenerate をクリックして作成。)

Qconfig.py として以下のようなコードを準備します。(API token は先程取得したものを記載します。)

APItoken = 'PUT_YOUR_API_TOKEN_HERE'

config = {
    'url': 'https://quantumexperience.ng.bluemix.net/api',

    # If you have access to IBM Q features, you also need to fill the "hub",
    # "group", and "project" details. Replace "None" on the lines below
    # with your details from Quantum Experience, quoting the strings, for
    # example: 'hub': 'my_hub'
    # You will also need to update the 'url' above, pointing it to your custom
    # URL for IBM Q.
    'hub': None,
    'group': None,
    'project': None
}

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

これで準備が完了です。

python からシミュレーションを実行する

以下では, 具体的に回路を作成して, 回路図の表示, シミュレーションの実行を行います。
f:id:puyokw:20180409035411j:plain
このようなtoy example を考えてみます。
回路自体は次のように書けます。

from qiskit import QuantumProgram
qp = QuantumProgram()

nq = 3  # number of qubits
q = qp.create_quantum_register("q", nq) # nq 量子ビット準備する
c = qp.create_classical_register("c", nq) # 測定用の領域を確保

circuits = ['testQ'] # 回路の名前を入力
testQ = qp.create_circuit(circuits[0], [q], [c]) # 回路の作成準備
# 1 列目
testQ.h(q[0]) # q0 にH を作用させる
testQ.h(q[1]) # q1 にH を作用させる
testQ.h(q[2]) # q2 にH を作用させる

# 2 列目
testQ.z(q[1]) # q1 にz を作用させる
testQ.cx(q[1],q[2]) # q1, q2 にcnotを作用させる

# 3 列目
testQ.h(q[2]) # q2 にH を作用させる

# 測定
testQ.measure(q[0], c[0]) # q0 を測定し, c0 に結果を格納
testQ.measure(q[1], c[1]) # q1 を測定し, c1 に結果を格納
testQ.measure(q[2], c[2]) # q2 を測定し, c2 に結果を格納

これをシミュレーションして, 結果をヒストグラムで表示します。

# 実行する
results = qp.execute(circuits, backend='local_qasm_simulator', shots=8192, seed=1) 
# 結果を図示する
from qiskit.tools.visualization import plot_histogram
plot_histogram(results.get_counts(circuits[0]))

f:id:puyokw:20180409035645p:plain
結果の状態(000や001など)では, 右側からq0, q1, q2 を示しています。この場合q2 は常に0 の状態です。

回路図を表示するのがやや面倒で, まずlatex_drawer を用いることで, tex ファイルに変換します。ここからは各自の環境に依存しますが, pdflatex を用いてpdf に変換して, さらにpdf2image もしくはpoppler のpdftocairo を用いて画像に変換して読み込みます。

import os 
from qiskit.tools.visualization import latex_drawer
from PIL import Image 
# ipython を使用する場合
# from IPython.display import Image 

filename='circuit'
tmpdir='tmp/'
if not os.path.exists(tmpdir):
    os.makedirs(tmpdir)

latex_drawer(testQ, tmpdir+filename+".tex", basis="h,z") # tex ファイルの作成
os.system("pdflatex -output-directory {} {}".format(tmpdir, filename+".tex")) # tex -> pdf 
os.system("pdftocairo -jpeg {}.pdf {}".format(tmpdir+filename, tmpdir+filename)) # pdf -> jpeg
img = Image.open(os.path.join('./'+tmpdir+filename+'-1.jpg'))
img.show()
#Image(filename=os.path.join(tmpdir+filename+'-1.jpg')) # ipython を使用する場合
#pdf2image.convert_from_path(tmpdir+filename+".pdf") # pdf2image が使える場合は, こちらでもOK 

上記のようなコードにより, 回路図が表示されます。
sympy のqasm を用いても回路図を表示できます。まず, 回路のコードを表示します。

QASM_source = qp.get_qasm('testQ')
print(QASM_source)
#OPENQASM 2.0;
#include "qelib1.inc";
#qreg q[3];
#creg c[3];
#h q[0];
#h q[1];
#h q[2];
#z q[1];
#cx q[1],q[2];
#h q[2];
#measure q[0] -> c[0];
#measure q[1] -> c[1];
#measure q[2] -> c[2];

次に, plot するために文字列を変換していきます。

from sympy.physics.quantum.qasm import Qasm

STR=str(QASM_source).replace(';','').replace('[','').replace(']','').replace('cx','cnot').split('\n')[4:-1]
SSTR=[]
for s in STR:
    s_tmp=s.split(' ')
    if s_tmp[0]=='measure':
        s_tmp=s_tmp[:-2]
    s_tmp2=s_tmp[0]
    if len(s_tmp)>1:
        s_tmp2+=' '
        s_tmp2+=','.join(s_tmp[1::])
    SSTR.append(s_tmp2)

SSTR=["qubit "+"q"+str(i) for i in range(nq)]+SSTR
print(SSTR)
# ['qubit q0', 'qubit q1', 'qubit q2', 'h q0', 'h q1', 'h q2', 'z q1', 'cnot q1,q2', 'h q2', 'measure q0', 'measure q1', 'measure q2'] 

これを用いて図示します。

import matplotlib.pyplot as plt
qprog1=Qasm()
for i in range(len(SSTR)):
    qprog1.add(SSTR[i])

qprog1.plot()
plt.show()

f:id:puyokw:20180409040419p:plain

他にも, 実機で実行する場合などのチュートリアルが以下に書かれています。
GitHub - Qiskit/qiskit-tutorials: A collection of Jupyter notebooks from the community and qiskit developers showing how to use Qiskit

python から実機を使用する

python から実機での実行がまだ上手く行っていないので, そのあたりをもう少し調べていこうと思います。