Nobisuke
Dekisugi
RAG
Privacy policy
2021/01/14 12:47
量子コンピュータの演算を行うためには、ゲートを使います。量子ゲートと呼ばれる演算が基本になりますが、この一覧を見て見ます。
早速見て見ます。
"i": gate.IGate,
"x": gate.XGate,
"y": gate.YGate,
"z": gate.ZGate,
"h": gate.HGate,
"t": gate.TGate,
"s": gate.SGate,
"cz": gate.CZGate,
"cx": gate.CXGate,
"cnot": gate.CXGate,
"rx": gate.RXGate,
"ry": gate.RYGate,
"rz": gate.RZGate,
"phase": gate.RZGate,
"crx": gate.CRXGate,
"cry": gate.CRYGate,
"crz": gate.CRZGate,
"cphase": gate.CU1Gate,
"u1": gate.U1Gate,
"u2": gate.U2Gate,
"u3": gate.U3Gate,
"cu1": gate.CU1Gate,
"cu2": gate.CU2Gate,
"cu3": gate.CU3Gate,
"swap": gate.SwapGate,
"ccx": gate.ToffoliGate,
"toffoli": gate.ToffoliGate,
"t": gate.TGate,
"tdg": gate.TDagGate,
"s": gate.SGate,
"sdg": gate.SDagGate,
"measure": gate.Measurement,
"m": gate.Measurement,
これをみる感じでは、使いやすそうです。使い方を見て見ます。
回路は簡単にできます。
Copy from blueqat import Circuit Circuit().h[0].m[:].run(shots=1)
Counter({'1': 1})
のようにすることで、
Counter({'1': 1})
答えが戻ってきます。基本的には、
Circuit()
で回路を作り、そこにゲートを適用しますが、
.h[0]
このようにチェーンでつなぎ、[]にゲートを適用したい量子ビットの通し番号を入れます。番号は0からスタートします。一つづつゲートを適用するとどうなるか見て見ます。
単位行列なので何も起きません。何もしないので0から始まった量子ビットは0のままです。
Copy Circuit().i[0].run() #array([1.+0.j, 0.+0.j])
array([1.+0.j, 0.+0.j])
こちらは基本のゲートです。パウリゲートと総称されます。ブロッホ球での軸の回転に相当します。サンプリング実行すると分かりづらいので、状態ベクトルを見て見ます。
Copy Circuit().x[0].run() #array([0.+0.j, 1.+0.j])
array([0.+0.j, 1.+0.j])
Copy Circuit().y[0].run() #array([0.-0.j, 1.+0.j])
array([0.-0.j, 0.+1.j])
Copy Circuit().z[0].run() #array([ 1.+0.j, -0.+0.j])
array([ 1.+0.j, -0.+0.j])
量子重ね合わせを実現する大事なゲートです。アダマールゲートと呼びます。
Copy Circuit().h[0].run() #array([0.70710678+0.j, 0.70710678+0.j])
array([0.70710678+0.j, 0.70710678+0.j])
TゲートとSゲートはRZゲートのうちで、回転角が45度と90度に固定されたものです。回転ゲートはアダマールゲートを適用してから見た方がわかりやすいので、見て見ます。
Tゲートは、
Copy Circuit().h[0].t[0].run() #array([0.70710678+0.j , 0.5 +0.5j])
array([0.70710678+0.j , 0.5 +0.5j])
Copy #これと同じです import math Circuit().h[0].rz(math.pi/4)[0].run() #array([0.70710678+0.j , 0.5 +0.5j])
array([0.65328148-0.27059805j, 0.65328148+0.27059805j])
Tゲートの逆回転がTダガーゲートです。
Copy Circuit().h[0].tdg[0].run() #array([0.70710678+0.j , 0.5 -0.5j])
array([0.70710678+0.j , 0.5 -0.5j])
Copy #これと同じです Circuit().h[0].rz(-math.pi/4)[0].run() #array([0.70710678+0.j , 0.5 -0.5j])
array([0.65328148+0.27059805j, 0.65328148-0.27059805j])
Sゲートは回転角が異なります。
Copy Circuit().h[0].s[0].run() #array([0.70710678+0.j , 0. +0.70710678j])
array([0.70710678+0.j , 0. +0.70710678j])
Copy #これと同じです Circuit().h[0].rz(math.pi/2)[0].run() #array([7.07106781e-01+0.j , 4.32978028e-17+0.70710678j])
array([0.5-0.5j, 0.5+0.5j])
Sゲートの逆回転がSダガーゲートです。
Copy Circuit().h[0].sdg[0].run() #array([7.07106781e-01+0.j , 4.32978028e-17-0.70710678j])
array([7.07106781e-01+0.j , 4.32978028e-17-0.70710678j])
Copy #これと同じです Circuit().h[0].rz(-math.pi/2)[0].run() #array([7.07106781e-01+0.j , 4.32978028e-17-0.70710678j])
array([0.5+0.5j, 0.5-0.5j])
CX、CNOTゲート こちらは、条件付きのゲートと呼ばれ、コントロールビットとターゲットビットがあります。コントロールビット側が1の時にXゲートを適用します。ビットの指定は2箇所あり、最初がコントロールビット、次がターゲットビットです。
Copy Circuit().cx[0,1].run() #array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
Copy #コントロールビット側を1にして見ます。 Circuit().x[0].cx[0,1].run() #array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
Copy #cnotでも全く同じです。 Circuit().x[0].cnot[0,1].run() #array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
CZゲートはコントロールビットが1の時にターゲットビットにZゲートを適用します。
Copy Circuit().cz[0,1].run() #array([ 1.+0.j, 0.+0.j, 0.+0.j, -0.+0.j])
array([ 1.+0.j, 0.+0.j, 0.+0.j, -0.+0.j])
Copy #コントロールビット側を1にして見ます。 Circuit().x[0].cz[0,1].run() #array([ 0.+0.j, 1.+0.j, 0.+0.j, -0.+0.j])
array([ 0.+0.j, 1.+0.j, 0.+0.j, -0.+0.j])
こちらはそれぞれの軸周りでの任意回転です。量子ビットの指定の前に角度の指定が必要になります。RZとPhaseは同じです。
Copy Circuit().rx(math.pi/4)[0].run() #array([0.92387953+0.j , 0. -0.38268343j])
array([0.92387953+0.j , 0. -0.38268343j])
Copy Circuit().ry(math.pi/4)[0].run() #array([0.92387953+0.j, 0.38268343+0.j])
array([0.92387953+0.j, 0.38268343+0.j])
Copy #分かりづらいのでHかけてからやります Circuit().h[0].rz(math.pi/4)[0].run() #array([0.70710678+0.j , 0.5 +0.5j])
array([0.65328148-0.27059805j, 0.65328148+0.27059805j])
Copy #RZと同じ Circuit().h[0].phase(math.pi/4)[0].run() #array([0.70710678+0.j , 0.5 +0.5j])
array([0.70710678+0.j , 0.5 +0.5j])
こちらは軸周りの任意回転ゲートを制御ゲート化したものです。コントロールビットとターゲットビットの指定が必要になります。
Copy #コントロールビットが0だと何も起きません。 Circuit().crx(math.pi/4)[0,1].run() #array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
Copy Circuit().x[0].crx(math.pi/4)[0,1].run()
array([0. +0.j , 0.92387953+0.j ,
0. +0.j , 0. -0.38268343j])
Copy Circuit().x[0].cry(math.pi/4)[0,1].run() #array([0. +0.j, 0.92387953+0.j, 0. +0.j, 0.38268343+0.j])
array([0. +0.j, 0.92387953+0.j, 0. +0.j, 0.38268343+0.j])
Copy Circuit().x[0].h[1].crz(math.pi/4)[0,1].run() #array([0. +0.j , 0.70710678+0.j , 0. +0.j , 0.5 +0.5j])
array([0. +0.j , 0.65328148-0.27059805j,
0. +0.j , 0.65328148+0.27059805j])
Copy #CRZと同じ Circuit().x[0].h[1].cphase(math.pi/4)[0,1].run() #array([0. +0.j , 0.70710678+0.j , 0. +0.j , 0.5 +0.5j])
array([0. +0.j , 0.70710678+0.j , 0. +0.j , 0.5 +0.5j])
角度を指定して実行できるゲートです。指定できる角度の数によってゲートセットが異なります。
U1(lambda)
U2(phi,lambda)
U3(theta,phi,lambda)
Copy Circuit().h[0].u1(0.1)[0].run() #array([0.70710678+0.j , 0.70357419+0.07059289j])
array([0.70622308-0.03534061j, 0.70622308+0.03534061j])
Copy Circuit().h[0].u2(0.1,0.2)[0].run() #array([ 0.09983342+0.j , -0.09933467+0.99003329j])
array([-0.00498959-0.09970865j, 0.99376067+0.04972948j])
Copy Circuit().h[0].u3(0.1,0.2,0.3)[0].run() #array([0.672542 +0.j , 0.64895946+0.35572302j])
array([0.64897187-0.17648868j, 0.71956476+0.17295609j])
これらは上記のU1,U2,U3ゲートを制御ゲート化したものです。使い方は他のゲートと同じです。
Copy Circuit().h[1].cu1(0.1)[0,1].run() #array([0.70710678+0.j, 0. +0.j, 0.70710678+0.j, 0. +0.j])
array([0.70688582-0.01767583j, 0. +0.j ,
0.70688582-0.01767583j, 0. +0.j ])
Copy #0番目を1にしてから、 Circuit().x[0].h[1].cu1(0.1)[0,1].run()
array([0. +0.j , 0.70688582-0.01767583j,
0. +0.j , 0.70511898+0.0529833j ])
Copy Circuit().x[0].h[1].cu2(0.1,0.2)[0,1].run()
array([ 0. +0.j , -0.00498959-0.09970865j,
0. +0.j , 0.99376067+0.04972948j])
Copy Circuit().x[0].h[1].cu3(0.1,0.2,0.3)[0,1].run()
array([0. +0.j , 0.64897187-0.17648868j,
0. +0.j , 0.71956476+0.17295609j])
こちらは2つの量子ビットの値を入れ替えます。簡単です。量子ビットの指定は2つあります。
Copy Circuit().x[0].swap[0,1].m[:].run(shots=1) #Counter({'01': 1})
Counter({'01': 1})
CCXとToffoliは同じゲートですが、コントロールビットが2つあります。両方が1の時だけ、ターゲットビットにXゲートを適用します。指定はコントロールビットを2つ指定し、ターゲットビットを指定します。
Copy Circuit().x[:2].ccx[0,1,2].run() #array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
Copy #全く同じです Circuit().x[:2].toffoli[0,1,2].run() #array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
測定ゲートは測定をします。測定をすると0か1かに計算結果が決まります。
Copy Circuit().h[0].m[:].run(shots=100) #Counter({'1': 50, '0': 50})
Counter({'0': 53, '1': 47})
Copy Circuit().h[0].measure[:].run(shots=100) #Counter({'0': 44, '1': 56})
Counter({'0': 53, '1': 47})
ゲートセットは基本的なものは網羅されてこの一覧を使えばいくらでも作れます。以上です。
© 2024, blueqat Inc. All rights reserved