Rigetti のお試し

IBMQ 以外にも量子プログラミングができるプラットフォームとして Rigetti Forest があります。
Rigetti
Rigetti Forest のシミュレータは, メールアドレスを登録することで使用できます。実機での実行するためには, アカウントのアップグレードが必要なため, ここではシミュレーションの方を試します。python のpyquil を使用します。
GitHub - rigetticomputing/pyquil: A Python library for quantum programming using Quil.

pip install pyquil

でインストールできます。

メールアドレスを登録すると, key とuser_id が貰えますので, それを以下のような内容の .pyquil_config ファイルを作成します。

[Rigetti Forest]
key: <Rigetti Forest API key>
user_id: <Rigetti User ID>

Installation and Getting Started — pyQuil 1.8.0 documentation
の注意書きにあるように, Linux では /users/username に, Mac では /Users/Username に, Windows では C:\Users\Username にこのファイルを配置します。

以下では, 回路の作成, 回路の図示を行います。

from pyquil.quil import Program
from pyquil.api import QVMConnection
from pyquil.gates import *
qvm = QVMConnection()
p1=Program()
p1.inst(H(0),
        CNOT(0,1),
        H(1),
        MEASURE(0,0),
        MEASURE(1,1)) # 回路を作成
print(p1)
# 出力
#H 0
#CNOT 0 1
#H 1
#MEASURE 0 [0]
#MEASURE 1 [1]

pyquil では柔軟に回路を作成することができます。

p1.inst(H(0),
        CNOT(0,1),
        H(1),
        MEASURE(0,0),
        MEASURE(1,1)) 
の部分は
p1.inst(H(0))
p1.inst(CNOT(0,1))
p1.inst(H(1))
p1.inst(MEASURE(0,0))
p1.inst(MEASURE(1,1)) 
と書いても同じです。

また複数の回路を結合することもできます。

q1=Program()
q1.inst(Z(0),I(0))
q1.inst(X(1))
print(q1)
# 出力
# Z 0
# I 0
# X 1
# q1 の後にp1 を結合する
q1.inst(p1)
print(q1)
# 出力結果
# Z 0
# I 0
# X 1
# H 0
# CNOT 0 1
# H 1
# MEASURE 0 [0]
# MEASURE 1 [1]

シミュレーションの実行は次のようにして行います。

result=qvm.run(p1, [0,1], 10)
print(result) 
# [[1, 0], [0, 1], [1, 0], [0, 0], [0, 0], [0, 1], [1, 0], [0, 0], [1, 0], [0, 1]]

試行回数を増やした版で再度実験して集計します。

result=qvm.run(p1, [0,1], 8000)
# 各サブリストの中をまとめる
L=[]
for sublist in result:
    L.append(''.join([str(l) for l in sublist]))

# pandas を用いて集計する
import pandas as pd 
import matplotlib.pyplot as plt
df=pd.DataFrame({"state": L})
df['state'].value_counts().plot.bar()
plt.show()

f:id:puyokw:20180408040019p:plain

from pyquil.latex.latex_generation import to_latex 
tmpdir='tmp/'
filename='circuit1'
dc=to_latex(q1.inst()) # q1 の回路をtex 形式に変換
with open(tmpdir+filename+'.tex','w') as f:
    f.write(dc) 

回路をtex 形式に変換するまではpyquil でできますが, そこからpdflatex を用いてpdf に変換します。それをさらにjpeg などに変換して読み込みます。

import os
os.system("pdflatex -output-directory {} {}".format(tmpdir, filename+".tex"))
os.system("pdftocairo -jpeg {}.pdf {}".format(tmpdir+filename, tmpdir+filename))

from PIL import Image 
img = Image.open(os.path.join('./'+tmpdir+filename+'-1.jpg'))
img.show()

f:id:puyokw:20180408035143j:plain
他にもsympy のqasm を利用することでも回路図を表示することもできます。

from sympy.physics.quantum.qasm import Qasm
from sympy.physics.quantum.gate import IdentityGate
import matplotlib.pyplot as plt

# Qasm では, identity gate が含まれていないため, 継承して追加します
class QasmEx(Qasm):
    def identity(self, arg):
        self.circuit.append(IdentityGate(self.index(arg)))

# 回路を図示
def VisualizeCircuit(circuit):
    STR=str(circuit).split('\n')[:-1]
    SSTR=[]
    for s in STR:
        s_tmp=s.split(' ')
        if s_tmp[0]=='MEASURE':
            s_tmp=s_tmp[:-1]
        s_tmp2=s_tmp[0]
        if len(s_tmp)>1:
            s_tmp2+=' '
            s_tmp2+=','.join(list(map(lambda x: 'q'+x,s_tmp[1::])))
        SSTR.append(s_tmp2)
    SSTR=list(map(lambda x: x.replace("MEASURE","measure").replace("I","identity"),SSTR))
    SSTR=["qubit "+"q"+str(i) for i in range(2)]+SSTR
    qprog1=QasmEx()
    for i in range(len(SSTR)):
        qprog1.add(SSTR[i])
    qprog1.plot()

VisualizeCircuit(q1.inst())
plt.show()

f:id:puyokw:20180409023857p:plain

pyquil の印象としては, 回路を書くのは便利そうな感じがしました。