@yuichirominato 2019.02.09更新 219views

[shor] Adder circuit with decimal number on blueqat SDK


Introduction

We usually using binary number to calculate on quantum circuit. We now try convert decimal number to calculate basic adder circuit.

Generalization

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

carry

Let’s prepare carry and carry_reverse and sum circuit first.

from blueqat import Circuit

def carry(a):
    return Circuit().ccx[a+1,a+2,a+3].cx[a+1,a+2].ccx[a,a+2,a+3]

def carry_reverse(a):
    return Circuit().ccx[a,a+2,a+3].cx[a+1,a+2].ccx[a+1,a+2,a+3]

def sum(a):
    return Circuit().cx[a+1,a+2].cx[a,a+2] 

Using like this.

(carry(0)+carry(3)+Circuit().cx[4,5]+sum(3)+carry_reverse(0)+sum(0)).m[:].run(shots=100)

Counter({'0000000': 100})

This is adder of 1bit

x = carry(0)+carry(3)+Circuit().cx[4,5]+sum(3)+carry_reverse(0)+sum(0)

(Circuit().x[1,4]+x).m[:].run(shots=100)                              

Counter({'0110110': 100})

This is adder of 1+2=3. Using X gate for input of number.

Decimal to Binary

def tobinary(A):
    return bin(A)[2:] 

tobinary(10)                                                                                    
'1010'

Alignment of bits

Get the number of length of bits and make alignment of bits.

def digits(a,b): 
     aa = tobinary(a)  
     bb = tobinary(b)  
     alen = len(aa)  
     blen = len(bb)  
     maxlen = max(alen,blen) 
     if alen>blen: 
         bb = bb.zfill(alen) 
     elif blen>alen: 
         aa = aa.zfill(blen) 
  
     str = '' 
     for i in range(maxlen): 
         str += '0' + aa[maxlen-i-1] + bb[maxlen-i-1] 
     str += '0' 
     return str

digits(2,2)                                                                                     
'0000110'

Convert binary input to Xgate operation

def tox(a): 
     cir = Circuit(len(a)) 
     for i in range(len(a)): 
         if a[i] == "1": 
             cir += Circuit().x[i] 
     return cir

tox("101").m[:].run(shots=100)                                                                  
Counter({'101': 100})

It works.

#5 and 2
tox(digits(5,2)).m[:].run(shots=100) 

Counter({'0100010100': 100})

#70 and 90
tox(digits(70,90)).m[:].run(shots=1) 
Counter({'0000110100010010000110': 1})

By using this function you can convert decimal number to binary and prepare the data using X gate.

Binary to Decimal

We have to prepare this function for the result of adder circuit.

def todecimal(A):
    return int(str(A),2) 

todecimal(10) 
2

And we need function to get only the result of adder from the array of bits including a and c besides b.

#select only b from array of 0000101
def getb(result): 
     str = result[-1] 
     digi = int((len(result)-1)/3) 
     for i in range(digi): 
         str += result[-2-i*3] 
     return todecimal(str)

Generalization

Let’s make the main circuit using prepared circuits.

def plus(a,b): 
     qubits = len(digits(a,b)) 
     cir1 = tox(digits(a,b)) 
     digi = int((len(digits(a,b))-1)/3) 

     cir2 = Circuit(qubits)     
     for i in range(digi): 
         cir2 += carry(i*3) 

     cir3 = Circuit(qubits).cx[-3,-2] + sum((digi-1)*3) 
  
     cir4 = Circuit(qubits) 
     for i in range(digi-1): 
         cir4 += carry_reverse((digi-i-2)*3) 
         cir4 += sum((digi-i-2)*3)
  
     result = (cir1 + cir2 + cir3 + cir4).m[:].run(shots=1) 
     return getb(result.most_common()[0][0])

It’s done!

Let’s try

Just try to calculate

plus(2,2)
4

plus(13,15)
28

plus(70,90)
160

It works and you can actually calculate adder of decimal number using quantum circuit (simulator).

from blueqat import Circuit

#Carry circuit
def carry(a):
    return Circuit().ccx[a+1,a+2,a+3].cx[a+1,a+2].ccx[a,a+2,a+3]

#Reverse of carry circuit
def carry_reverse(a):
    return Circuit().ccx[a,a+2,a+3].cx[a+1,a+2].ccx[a+1,a+2,a+3]

#Sum of bits
def sum(a):
    return Circuit().cx[a+1,a+2].cx[a,a+2] 

#Decimal to binary number
def tobinary(A):
    return bin(A)[2:] 

#Prepare bits in array 
def digits(a,b): 
     aa = tobinary(a)  
     bb = tobinary(b)  
     alen = len(aa)  
     blen = len(bb)  
     maxlen = max(alen,blen) 
     if alen>blen: 
         bb = bb.zfill(alen) 
     elif blen>alen: 
         aa = aa.zfill(blen) 
  
     str = '' 
     for i in range(maxlen): 
         str += '0' + aa[maxlen-i-1] + bb[maxlen-i-1] 
     str += '0' 
     return str

#Convert binary input to X gate circuit
def tox(a): 
     cir = Circuit(len(a)) 
     for i in range(len(a)): 
         if a[i] == "1": 
             cir += Circuit().x[i] 
     return cir

#Binary number to decimal number for the result
def todecimal(A):
    return int(str(A),2) 

#Get only the result from the array of all bits
def getb(result): 
     str = result[-1] 
     digi = int((len(result)-1)/3) 
     for i in range(digi): 
         str += result[-2-i*3] 
     return todecimal(str)

#the main circuit
def plus(a,b): 
     qubits = len(digits(a,b)) 
     cir1 = tox(digits(a,b)) 
     digi = int((len(digits(a,b))-1)/3) 

     cir2 = Circuit(qubits)     
     for i in range(digi): 
         cir2 += carry(i*3) 

     cir3 = Circuit(qubits).cx[-3,-2] + sum((digi-1)*3) 
  
     cir4 = Circuit(qubits) 
     for i in range(digi-1): 
         cir4 += carry_reverse((digi-i-2)*3) 
         cir4 += sum((digi-i-2)*3)
  
     result = (cir1 + cir2 + cir3 + cir4).m[:].run(shots=1) 
     return getb(result.most_common()[0][0])

Discussion

If you like super mario maker or mine craft, you feel easy to the quantum computer.


Back To Top