@yuichirominato 2019.01.24更新 321views

【加算】量子ゲート回路を用いた多ビットのゲート加算器


はじめに

量子コンピュータには高速性と汎用性があります。現在の量子コンピュータは少ない量子ビットを活用するために、汎用性は後回しにして高速性の検討をしています。しかし将来的なことを考えて汎用性も考えてみます。

加算器

まずは最新のBlueqatを使って足し算をやってみたいと思います。今回は工夫をして、|a,b> => |a,a+b>というように量子ビットを節約して加算を行なってみます。作る回路はまずは1ビットでやってみます。

0+0=0,1+0=1,0+1=1,1+1=2

を実装してみます。

入力a,入力b,入力c=0,出力a,出力a+b,出力桁上がりcとして、この順番で、

000000
010010
100110
110101

となればokです。回路は、コントロールゲート*の記号でターゲットゲートがXとなってcxとccx(トフォリ)を表現して

a --*--*-- a 
b --*--X-- a+b
c --X----- c

Blueqatコードとしては、ccxとcxをつかい、

from blueqat import Circuit

a = Circuit().ccx[0,1,2].cx[0,1].m[:] #足し算回路

#000の入力
(Circuit() + a).run(shots=100)
                                      
Counter({'000': 100}) #出力も000

#100の入力
(Circuit().x[0] + a).run(shots=100)                                   
Counter({'110': 100}) #出力は110

#010の入力
(Circuit().x[1] + a).run(shots=100)                                   
Counter({'010': 100}) #出力は010

#110の入力
(Circuit().x[0,1] + a).run(shots=100)                                 
Counter({'101': 100}) #出力は101

できました。これが、上から、

0+0=0
1+0=1
0+1=1
1+1=2

となりました。

一般化

大きくしてみます。1995年の有名な論文がありますので参考にします。

Quantum Networks for Elementary Arithmetic Operations
V. Vedral, A. Barenco, A. Ekert
(Submitted on 16 Nov 1995)
https://arxiv.org/abs/quant-ph/9511018

https://arxiv.org/abs/quant-ph/9511018

これが一般化された加算器です。図中のCarryとSumはこうなります。

https://arxiv.org/abs/quant-ph/9511018

a+bを実現しますが、$a_0*2^0+a_1*2^1+a_2*2^2,…+b_0*2^0+b_1*2^1+b_2*2^2,… = $のようにビットを使って計算をします。ビット数節約のために、bの値が上書きされて、a+bとなって出てきます。

1量子ビット同士の足し算

a+bを考えますが、aもbも1量子ビットの場合の一般化は、4量子ビットを使って下記のようになります。*はコントロールビットを表します。a0とb0に数字を入れると、b0が上書きされて、|c0,a0,b0,b1> ==> |c0,a0,a0+b0,b1>となってでてきます。b2は桁上がりです。

c0 --?--------*--------*-- c0
a0 --?--*--*--|--*--*--|-- a0
b0 --?--*--X--*--X--X--X-- a0+b0
b1 --?--X-----X----------- b1

コードで書くと、

from blueqat import Circuit

a = Circuit().ccx[1,2,3].cx[1,2].ccx[0,2,3].cx[1,2].cx[1,2].cx[0,2].m[:]
(Circuit() + a).run(shots=100)

Counter({'0000': 100})

最初の?に何も入れないで実行すると、0000 -> 0000となります。これはあってます。0+0=0

(Circuit().x[1] + a).run(shots=100)

Counter({'0110': 100})

これもあってます、0100 -> 0110となって答えが01となっています。

(Circuit().x[2] + a).run(shots=100)

Counter({'0010': 100})

これもあっています。0010 -> 0010となり、0+1 = 01となります。

(Circuit().x[1,2] + a).run(shots=100)

Counter({'0101': 100})

これもあっています。0110 -> 0101となり、1+1 = 10となり、桁上がりに成功しています。

2量子ビット同士の足し算

次に2量子ビット使ってみます。今度は7量子ビット使います。

c0 --?------*-------------*-------*- c0
a0 --?--*-*-|-------------|-*-*-*-|- a0
b0 --?--*-X-*-------------*-X-*-X-X- a0+b0
c1 --?--X---X-----*-----*-X---X----- c1
a1 --?--------*-*-|-*-*-|----------- a1
b1 --?--------*-X-*-X-X-X----------- a1+b1
b2 --?--------X---X----------------- b2

コードは、

a = Circuit().ccx[1,2,3].cx[1,2].ccx[0,2,3].ccx[4,5,6].cx[4,5].ccx[3,5,6].cx[4,5].cx[4,5].cx[3,5].ccx[0,2,3].cx[1,2].ccx[1,2,3].cx[1,2].cx[0,2].m[:]

(Circuit()+a).run(shots=100)

Counter({'0000000': 100})

00+00=000

次に、例えば、3+3 = ?をすると、

(Circuit().x[1,2,4,5]+a).run(shots=100)

Counter({'0100111': 100})

11+11 = 110これにより3+3=6

これは全加算器が一般化されているので、どんどん上に拡張していくことで大きな数を実装することができます。

ちなみに回路を逆に組むことで減算ができます。

減算

いまの2ビット回路を組んで、4-2をしてみます。これは先ほどの回路を逆にするだけです。

コードは、

a = Circuit().cx[0,2].cx[1,2].ccx[1,2,3].cx[1,2].ccx[0,2,3].cx[3,5].cx[4,5].cx[4,5].ccx[3,5,6].cx[4,5].ccx[4,5,6].ccx[0,2,3].cx[1,2].ccx[1,2,3].m[:]

(Circuit().x[4,5,6]+a).run(shots=100)

Counter({'0000101': 100})

こうなりました。a1=1となり、4-2=2となりました。b2の桁上がりは逆算できないようでしたのでこれは自分で0にしないといけないかもしれません。

Hゲート使う

まずHゲートを使ってみます。足し算が重ね合わせを使うので答えがどれが出るかわかりません。

a = Circuit().ccx[1,2,3].cx[1,2].ccx[0,2,3].ccx[4,5,6].cx[4,5].ccx[3,5,6].cx[4,5].cx[4,5].cx[3,5].ccx[0,2,3].cx[1,2].ccx[1,2,3].cx[1,2].cx[0,2].m[:]

(Circuit().h[1,2,4,5]+a).run(shots=100)

Counter({'0100101': 8,
         '0100111': 6,
         '0000101': 7,
         '0010110': 7,
         '0110010': 10,
         '0010000': 8,
         '0000000': 6,
         '0000010': 5,
         '0000110': 6,
         '0010010': 7,
         '0110101': 8,
         '0100001': 5,
         '0100010': 5,
         '0110110': 7,
         '0110000': 3,
         '0010101': 2})

このように重ね合わせを使ってたくさんの足し算をすることができました。答えは100回計算してばらつきを見ました。

まとめ

簡単に加算をみてみました。これを使ってモジュロ演算もできます。次回はモジュロ演算も見てみたいと思います。また、2進数表示のままだったので、次回は10進数に直してみやすくしておきます。以上です。

Recommended


CONTACT

info@mdrft.com

ブログトップへ Wikiへ移動

量子コンピュータ一般

量子ゲートアルゴリズム

量子アニーリング一般

量子アニーリングアルゴリズム

BlueqatSDKの使い方