最初に必要なライブラリを準備し、blueqatを最新にします。
pip install --no-deps -U git+https://github.com/jcmgray/quimb.git@develop autoray blueqat
Collecting git+https://github.com/jcmgray/quimb.git@develop
Cloning https://github.com/jcmgray/quimb.git (to revision develop) to /tmp/pip-req-build-dipu73lx
Running command git clone -q https://github.com/jcmgray/quimb.git /tmp/pip-req-build-dipu73lx
Requirement already satisfied: autoray in /opt/conda/lib/python3.8/site-packages (0.3.1)
Requirement already satisfied: blueqat in /opt/conda/lib/python3.8/site-packages (1.0.0)
Note: you may need to restart the kernel to use updated packages.
今回はグラフ問題でmaxcutの時間発展をしてみます。横磁場イジングの量子断熱時間発展では、Hを最初にすべての量子ビットに適用し、重ね合わせ状態を準備し、グラフの接続をRZZでつなぎます。そして、その後RXを再度すべての量子ビットにかけます。適用する角度はQAOAでは最適化するのですが、今回は手動でランダムな値をかけてみます。
量子ビット数は70にしてみます。
##time
from blueqat import Circuit
import numpy as np
N = 70
#グラフ描画用に頂点を保存する配列
arr = []
全部の量子ビットにHゲートをかけます。
circ = Circuit(N).h[:]
次に接続を作ります。今回はRZZを連続して適用すると不具合が見つかったので、代わりにCX-RZ-CXを適用します。角度はとりあえずランダムにします。
for i in range(N-2):
for j in range(i+1, N):
if np.random.rand() > 0.95:
#RZZに不具合があったのでCX-RZ-CXしています。。。(22.5.7現在)
circ.cx[i, j]
circ.rz(np.random.rand()*2*np.pi)[j]
circ.cx[i, j]
arr.append((i, j))
最後にRXもかけます。ここも本来は最適化しますが、今回は例題なので適当にかけてみます。
circ.rx(np.random.rand()*2*np.pi)[:]
Circuit(70).h[:].cx[0, 5].rz(1.4783308985155572)[5].cx[0, 5].cx[0, 41].rz(2.09016159556391)[41].cx[0, 41].cx[1, 14].rz(2.4468516963805405)[14].cx[1, 14].cx[1, 22].rz(0.05072188271940544)[22].cx[1, 22].cx[1, 23].rz(2.399660268854264)[23].cx[1, 23].cx[1, 42].rz(4.944964051040579)[42].cx[1, 42].cx[1, 49].rz(1.4680766047574283)[49].cx[1, 49].cx[2, 11].rz(2.702063777584034)[11].cx[2, 11].cx[2, 25].rz(4.724846967372007)[25].cx[2, 25].cx[2, 39].rz(3.2985036557899625)[39].cx[2, 39].cx[2, 42].rz(5.370488824570627)[42].cx[2, 42].cx[3, 37].rz(5.622882767932398)[37].cx[3, 37].cx[3, 65].rz(0.7758601153994636)[65].cx[3, 65].cx[4, 31].rz(0.9366710861119513)[31].cx[4, 31].cx[4, 61].rz(2.4630321222913856)[61].cx[4, 61].cx[5, 25].rz(5.993815958052451)[25].cx[5, 25].cx[5, 61].rz(2.1845067256528514)[61].cx[5, 61].cx[6, 8].rz(3.3816070930159254)[8].cx[6, 8].cx[6, 28].rz(1.6461380166511634)[28].cx[6, 28].cx[6, 41].rz(2.5582086512343056)[41].cx[6, 41].cx[6, 59].rz(4.055343522478827)[59].cx[6, 59].cx[7, 13].rz(1.914577301556198)[13].cx[7, 13].cx[8, 13].rz(0.10031980079588114)[13].cx[8, 13].cx[8, 25].rz(1.107950659874152)[25].cx[8, 25].cx[8, 49].rz(3.72857304602888)[49].cx[8, 49].cx[9, 43].rz(2.6870170534246745)[43].cx[9, 43].cx[9, 51].rz(2.664040393677384)[51].cx[9, 51].cx[10, 16].rz(5.807152526602204)[16].cx[10, 16].cx[10, 22].rz(5.95676958499741)[22].cx[10, 22].cx[10, 50].rz(1.332603578840916)[50].cx[10, 50].cx[10, 54].rz(3.4078416461299583)[54].cx[10, 54].cx[10, 65].rz(3.320898202614074)[65].cx[10, 65].cx[11, 34].rz(1.7579943804003877)[34].cx[11, 34].cx[12, 27].rz(1.8207430506799036)[27].cx[12, 27].cx[12, 31].rz(4.725803074338074)[31].cx[12, 31].cx[12, 35].rz(5.09585056713146)[35].cx[12, 35].cx[12, 62].rz(0.8177263112902984)[62].cx[12, 62].cx[13, 46].rz(5.553278505146352)[46].cx[13, 46].cx[14, 41].rz(3.6810457511571153)[41].cx[14, 41].cx[14, 54].rz(3.4985848872548355)[54].cx[14, 54].cx[14, 61].rz(1.7944018131588326)[61].cx[14, 61].cx[15, 45].rz(1.5789378578239315)[45].cx[15, 45].cx[15, 54].rz(2.498555367601998)[54].cx[15, 54].cx[16, 65].rz(5.132485816486401)[65].cx[16, 65].cx[17, 23].rz(2.8892257916796797)[23].cx[17, 23].cx[17, 28].rz(4.014520183397256)[28].cx[17, 28].cx[18, 30].rz(5.991977076368043)[30].cx[18, 30].cx[18, 44].rz(0.20680422206351207)[44].cx[18, 44].cx[18, 47].rz(5.186832301950854)[47].cx[18, 47].cx[18, 68].rz(0.9595522791415491)[68].cx[18, 68].cx[18, 69].rz(3.5703119648024337)[69].cx[18, 69].cx[19, 31].rz(2.655621103385435)[31].cx[19, 31].cx[19, 59].rz(6.0055386885308595)[59].cx[19, 59].cx[20, 22].rz(5.649750417023133)[22].cx[20, 22].cx[20, 25].rz(6.219622223318173)[25].cx[20, 25].cx[20, 43].rz(2.3972439243997377)[43].cx[20, 43].cx[20, 54].rz(1.12782025768315)[54].cx[20, 54].cx[21, 61].rz(0.3006670958065202)[61].cx[21, 61].cx[21, 64].rz(2.3224112458572166)[64].cx[21, 64].cx[22, 40].rz(0.8454473067796482)[40].cx[22, 40].cx[23, 50].rz(4.949246718017649)[50].cx[23, 50].cx[23, 54].rz(6.130693458605812)[54].cx[23, 54].cx[23, 58].rz(0.3582729727548934)[58].cx[23, 58].cx[24, 30].rz(5.197802616632302)[30].cx[24, 30].cx[24, 47].rz(4.423907648067997)[47].cx[24, 47].cx[24, 68].rz(1.4126979522458798)[68].cx[24, 68].cx[25, 30].rz(3.9438717497588396)[30].cx[25, 30].cx[25, 46].rz(2.978888965888831)[46].cx[25, 46].cx[25, 47].rz(0.7062392008738569)[47].cx[25, 47].cx[25, 55].rz(5.396514182619574)[55].cx[25, 55].cx[25, 68].rz(3.376587486477514)[68].cx[25, 68].cx[27, 28].rz(4.336475549262691)[28].cx[27, 28].cx[28, 59].rz(0.16574619039521887)[59].cx[28, 59].cx[29, 38].rz(5.672407731380425)[38].cx[29, 38].cx[29, 39].rz(1.2631099942931125)[39].cx[29, 39].cx[29, 69].rz(5.653014514257939)[69].cx[29, 69].cx[30, 32].rz(4.985788141021371)[32].cx[30, 32].cx[30, 42].rz(4.57061604788749)[42].cx[30, 42].cx[30, 69].rz(2.935994484922813)[69].cx[30, 69].cx[31, 45].rz(3.187158807107849)[45].cx[31, 45].cx[31, 56].rz(0.17279844547077994)[56].cx[31, 56].cx[32, 43].rz(2.052003471551316)[43].cx[32, 43].cx[32, 50].rz(3.5021806213335247)[50].cx[32, 50].cx[33, 34].rz(3.2873782512719067)[34].cx[33, 34].cx[33, 55].rz(0.12955002189920609)[55].cx[33, 55].cx[35, 36].rz(2.6601962242833315)[36].cx[35, 36].cx[35, 41].rz(4.186731616136539)[41].cx[35, 41].cx[35, 51].rz(6.163001362556825)[51].cx[35, 51].cx[35, 54].rz(0.6095116450593432)[54].cx[35, 54].cx[35, 66].rz(3.6525679909886506)[66].cx[35, 66].cx[37, 59].rz(2.866954143781386)[59].cx[37, 59].cx[38, 53].rz(4.126303737783139)[53].cx[38, 53].cx[38, 67].rz(2.5944404069562657)[67].cx[38, 67].cx[39, 62].rz(3.333615649107265)[62].cx[39, 62].cx[40, 41].rz(5.256251593102868)[41].cx[40, 41].cx[40, 43].rz(6.034442251187846)[43].cx[40, 43].cx[40, 48].rz(1.766751946038789)[48].cx[40, 48].cx[40, 51].rz(4.171417750944293)[51].cx[40, 51].cx[40, 53].rz(2.361201045734315)[53].cx[40, 53].cx[40, 65].rz(2.654445202277427)[65].cx[40, 65].cx[41, 48].rz(3.2663131909462724)[48].cx[41, 48].cx[42, 47].rz(5.134118961415472)[47].cx[42, 47].cx[42, 52].rz(2.010677466309603)[52].cx[42, 52].cx[42, 56].rz(4.235225313290344)[56].cx[42, 56].cx[42, 64].rz(1.2314307535763735)[64].cx[42, 64].cx[43, 55].rz(1.5331592339660807)[55].cx[43, 55].cx[44, 48].rz(4.494054914627234)[48].cx[44, 48].cx[45, 54].rz(1.4191820596287352)[54].cx[45, 54].cx[45, 62].rz(5.931766960534691)[62].cx[45, 62].cx[47, 58].rz(2.1776029320854824)[58].cx[47, 58].cx[47, 59].rz(1.2691193495232)[59].cx[47, 59].cx[48, 61].rz(3.7425418940570814)[61].cx[48, 61].cx[49, 56].rz(4.007850358430091)[56].cx[49, 56].cx[50, 59].rz(2.9269777796863847)[59].cx[50, 59].cx[51, 52].rz(3.3567546202228464)[52].cx[51, 52].cx[53, 59].rz(4.490197242609587)[59].cx[53, 59].cx[54, 63].rz(5.004049233397418)[63].cx[54, 63].cx[54, 65].rz(5.214510942773282)[65].cx[54, 65].cx[56, 61].rz(5.83630652912451)[61].cx[56, 61].cx[59, 65].rz(1.5654754907017365)[65].cx[59, 65].cx[61, 63].rz(1.8738081548033072)[63].cx[61, 63].cx[62, 68].rz(3.8264413672433144)[68].cx[62, 68].rx(0.26899259077746723)[:]
これで回路ができました。まずグラフを描画してみます。
import networkx as nx
import matplotlib.pyplot as plt
#ノード数
plt.figure(figsize=(15,15))
G = nx.Graph()
G.add_edges_from(arr)
nx.draw_networkx(G, node_size=100, labels={})
plt.show()
<Figure size 1080x1080 with 1 Axes>
そしてマシンの性能によってかなり時間がかかりますが、実行してサンプルを取ってみます。
circ.run(backend="quimb")
Counter({'0010111111110111010011010001001010100000110011100000100110011110100001': 1})
実行するとサンプルが取れました。以前の10量子ビット前後のQAAに比べると格段にサイズが大きいです。計算時間もかかりますが、普通にシミュレーションしたらとても計算が終わらないような問題です。今後はこのような量子コンピュータでの計算をどのように高速化して効率化して社会問題や量子の問題に適用していくのかをたっぷり探索したいですね。以上です。