common.title

Overview
Service overview
Terms of service

Privacy policy

Contact

Sign in
Sign up
common.title

量子コンピュータSDKのBlueqatで使える全量子ゲート早見表

Yuichiro Minato

2021/01/14 12:47

#blueqat

はじめに

量子コンピュータの演算を行うためには、ゲートを使います。量子ゲートと呼ばれる演算が基本になりますが、この一覧を見て見ます。

ゲートセット

早速見て見ます。

    "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,

これをみる感じでは、使いやすそうです。使い方を見て見ます。

回路を作る

回路は簡単にできます。

from blueqat import Circuit Circuit().h[0].m[:].run(shots=1)
Counter({'1': 1})

のようにすることで、

Counter({'1': 1})

答えが戻ってきます。基本的には、

Circuit()

で回路を作り、そこにゲートを適用しますが、

.h[0]

このようにチェーンでつなぎ、[]にゲートを適用したい量子ビットの通し番号を入れます。番号は0からスタートします。一つづつゲートを適用するとどうなるか見て見ます。

Iゲート

単位行列なので何も起きません。何もしないので0から始まった量子ビットは0のままです。

Circuit().i[0].run() #array([1.+0.j, 0.+0.j])
array([1.+0.j, 0.+0.j])

X,Y,Zゲート

こちらは基本のゲートです。パウリゲートと総称されます。ブロッホ球での軸の回転に相当します。サンプリング実行すると分かりづらいので、状態ベクトルを見て見ます。

Circuit().x[0].run() #array([0.+0.j, 1.+0.j])
array([0.+0.j, 1.+0.j])
Circuit().y[0].run() #array([0.-0.j, 1.+0.j])
array([0.-0.j, 0.+1.j])
Circuit().z[0].run() #array([ 1.+0.j, -0.+0.j])
array([ 1.+0.j, -0.+0.j])

Hゲート

量子重ね合わせを実現する大事なゲートです。アダマールゲートと呼びます。

Circuit().h[0].run() #array([0.70710678+0.j, 0.70710678+0.j])
array([0.70710678+0.j, 0.70710678+0.j])

Tゲート、Sゲートと、その逆回転

TゲートとSゲートはRZゲートのうちで、回転角が45度と90度に固定されたものです。回転ゲートはアダマールゲートを適用してから見た方がわかりやすいので、見て見ます。

Tゲートは、

Circuit().h[0].t[0].run() #array([0.70710678+0.j , 0.5 +0.5j])
array([0.70710678+0.j , 0.5       +0.5j])
#これと同じです 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ダガーゲートです。

Circuit().h[0].tdg[0].run() #array([0.70710678+0.j , 0.5 -0.5j])
array([0.70710678+0.j , 0.5       -0.5j])
#これと同じです 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ゲートは回転角が異なります。

Circuit().h[0].s[0].run() #array([0.70710678+0.j , 0. +0.70710678j])
array([0.70710678+0.j        , 0.        +0.70710678j])
#これと同じです 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ダガーゲートです。

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])
#これと同じです 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箇所あり、最初がコントロールビット、次がターゲットビットです。

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])
#コントロールビット側を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])
#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ゲート

CZゲートはコントロールビットが1の時にターゲットビットにZゲートを適用します。

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])
#コントロールビット側を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])

RX,RY,RZ,Phaseゲート

こちらはそれぞれの軸周りでの任意回転です。量子ビットの指定の前に角度の指定が必要になります。RZとPhaseは同じです。

Circuit().rx(math.pi/4)[0].run() #array([0.92387953+0.j , 0. -0.38268343j])
array([0.92387953+0.j        , 0.        -0.38268343j])
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])
#分かりづらいので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])
#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])

CRX,CRY,CRZゲート

こちらは軸周りの任意回転ゲートを制御ゲート化したものです。コントロールビットとターゲットビットの指定が必要になります。

#コントロールビットが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])
Circuit().x[0].crx(math.pi/4)[0,1].run()
array([0.        +0.j        , 0.92387953+0.j        ,

       0.        +0.j        , 0.        -0.38268343j])
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])
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])
#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,U2,U3ゲート

角度を指定して実行できるゲートです。指定できる角度の数によってゲートセットが異なります。

U1(lambda)
U2(phi,lambda)
U3(theta,phi,lambda)
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])
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])
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])

CU1,CU2,CU3ゲート

これらは上記のU1,U2,U3ゲートを制御ゲート化したものです。使い方は他のゲートと同じです。

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        ])
#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 ])
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])
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])

Swapゲート

こちらは2つの量子ビットの値を入れ替えます。簡単です。量子ビットの指定は2つあります。

Circuit().x[0].swap[0,1].m[:].run(shots=1) #Counter({'01': 1})
Counter({'01': 1})

CCX,Toffoliゲート

CCXとToffoliは同じゲートですが、コントロールビットが2つあります。両方が1の時だけ、ターゲットビットにXゲートを適用します。指定はコントロールビットを2つ指定し、ターゲットビットを指定します。

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])
#全く同じです 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かに計算結果が決まります。

Circuit().h[0].m[:].run(shots=100) #Counter({'1': 50, '0': 50})
Counter({'0': 53, '1': 47})
Circuit().h[0].measure[:].run(shots=100) #Counter({'0': 44, '1': 56})
Counter({'0': 53, '1': 47})

最後に

ゲートセットは基本的なものは網羅されてこの一覧を使えばいくらでも作れます。以上です。

© 2024, blueqat Inc. All rights reserved