Quantum Programming 101: How to perform addition on quantum computers

0
626

Introduction

In this tutorial you will see how to implement the quantum equivalent of a Full Adder on IBMs quantum computers using quantum logic gates.

What is a Full Adder?

A Full Adder is a logic circuit used by classical computers to implement addition on up to 3 bits.

Source: circuitTHEORYSource: circuitTHEORY

The Full Adder circuit contains 3 inputs: A, B, and Cin (short for Carry in.as it carries in from the previous Full Adder since they can be stringed together)

There are also 2 outputs called Sum and Cout (Short for carry out as it carries out a bit to the Cin of the next adder)

Truth Table

2019-12-11 20_09_42-Window.png

Implementation

Circuit diagram of a quantum full adderCircuit diagram of a quantum full adder

To implement a Full Adder on a quantum computer we will need 4 qubits (ie 1 for each input and output of the Full Adder).

  • Q0: Qubit for input A

  • Q1: Qubit for Input B

  • Q2: Qubit for Input Cin

  • Q3: Qubit for Sum

  • Q4: Qubit for Cout

How it works

For calculating the Sum we simply apply a CNOT gate to Q3 (Sum) from all inputs. This means that if any one of the inputs are 1 then Q3 will be flipped to 1. If all inputs are 0 then Q3 will remain 0.

To calculate Cout (Q4) we apply Toffoli gates with Q4 as the target and the input combinations (Q0,Q1), (Q0,Q2), (Q1,Q2) as the control qubits.

Note: Because of the order of the gates we can never get the Sum and Cout to both equal 1 if only 2 of the inputs are 1.

Code

print(‘\n Quantum Full Adder’)
print(‘———————‘)
from qiskit import QuantumRegister
from qiskit import QuantumRegister, ClassicalRegister
from qiskit import QuantumCircuit, execute,IBMQ
IBMQ.enable_account(‘INSERT API TOKEN HERE’)
provider = IBMQ.get_provider(hub=’ibm-q’)

######## A ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[0])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])
########################################

backend = provider.get_backend(‘ibmq_qasm_simulator’)
job = execute(circuit, backend, shots=1)
print(‘\nExecuting…\n’)
print(‘\nA\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)

######## B ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[1])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])

######################################
job = execute(circuit, backend, shots=1)
print(‘\nB\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)

######## A + B ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[0])
circuit.x(q[1])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])
######################################

job = execute(circuit, backend, shots=1)
print(‘\nA + B\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)

######## Cin ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[2])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])
######################################

job = execute(circuit, backend, shots=1)
print(‘\nCin\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)

######## Cin + A ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[2])
circuit.x(q[0])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])
######################################

job = execute(circuit, backend, shots=1)
print(‘\nCin + A\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)

######## Cin + B ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[2])
circuit.x(q[1])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])
######################################

job = execute(circuit, backend, shots=1)
print(‘\nCin + B\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)

######## Cin + A + B ###########################
q = QuantumRegister(5,’q’)
c = ClassicalRegister(2,’c’)
circuit = QuantumCircuit(q,c)
circuit.x(q[2])
circuit.x(q[1])
circuit.x(q[0])
circuit.cx(q[0],q[3])
circuit.cx(q[1],q[3])
circuit.cx(q[2],q[3])
circuit.ccx(q[0],q[1],q[4])
circuit.ccx(q[0],q[2],q[4])
circuit.ccx(q[1],q[2],q[4])
circuit.measure(q[3],c[0])
circuit.measure(q[4],c[1])
######################################

job = execute(circuit, backend, shots=1)
print(‘\nCin + A + B\n’)
result = job.result()
counts = result.get_counts(circuit)
print(‘RESULT: ‘,counts,’\n’)
print(‘Press any key to close’)
input()

Once you run the code you will get the following output:

2019-12-11 19_53_58-Window.png
Want to learn about Quantum Programming? Head over to Quantum Computing UK: https://quantumcomputinguk.org/