File size: 3,691 Bytes
6efeab4
2859889
 
6efeab4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# -*- coding: utf-8 -*-
pip install qiskit
pip install qiskit-aer
"""
multiply.py: Multiply two numbers using repeated fourier 
               transform based addition.
"""

from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister
from qiskit import Aer, execute
from math import pi

def createInputState(qc, reg, n, pie):
    """
    Computes the quantum Fourier transform of reg, one qubit at
    a time.
    Apply one Hadamard gate to the nth qubit of the quantum register reg, and 
    then apply repeated phase rotations with parameters being pi divided by 
    increasing powers of two.
    """
    qc.h(reg[n])
    for i in range(0, n):
        qc.cp(pie / float(2**(i + 1)), reg[n - (i + 1)], reg[n])


def evolveQFTState(qc, reg_a, reg_b, n, pie, factor):
    """  
    Evolves the state |F(ψ(reg_a))> to |F(ψ(reg_a+reg_b))> using the quantum 
    Fourier transform conditioned on the qubits of the reg_b.
    Apply repeated phase rotations with parameters being pi divided by 
    increasing powers of two.
    """
    l = len(reg_b)
    for i in range(0, n + 1):
        if (n - i) > l - 1:
            pass
        else:
            qc.cp(factor*pie / float(2**(i)), reg_b[n - i], reg_a[n])


def inverseQFT(qc, reg, n, pie):
    """
    Performs the inverse quantum Fourier transform on a register reg.
    Apply repeated phase rotations with parameters being pi divided by 
    decreasing powers of two, and then apply a Hadamard gate to the nth qubit
    of the register reg.
    """
    for i in range(0, n):
        qc.cp(-1 * pie / float(2**(n - i)), reg[i], reg[n])
    qc.h(reg[n])


def add(reg_a, reg_b, circ, factor):
    """
    Add two quantum registers reg_a and reg_b, and store the result in 
    reg_a.
    """
    pie = pi
    n = len(reg_a) - 1

    # Compute the Fourier transform of register a
    for i in range(0, n + 1):
        createInputState(circ, reg_a, n - i, pie)
    # Add the two numbers by evolving the Fourier transform F(ψ(reg_a))>
    # to |F(ψ(reg_a+reg_b))>
    for i in range(0, n + 1):
        evolveQFTState(circ, reg_a, reg_b, n - i, pie, factor)
    # Compute the inverse Fourier transform of register a
    for i in range(0, n + 1):
        inverseQFT(circ, reg_a, i, pie)


# Take two numbers as user input in binary form
multiplicand_in = input("Enter the multiplicand.")
l1 = len(multiplicand_in)
multiplier_in = input("Enter the multiplier.")
l2 = len(multiplier_in)
# Make sure multiplicand_in holds the larger number
if l2 > l1:
    multiplier_in, multiplicand_in = multiplicand_in, multiplier_in
    l2, l1 = l1, l2

multiplicand = QuantumRegister(l1)
multiplier = QuantumRegister(l2)
accumulator = QuantumRegister(l1 + l2)
cl = ClassicalRegister(l1 + l2)
d = QuantumRegister(1)

circ = QuantumCircuit(accumulator, multiplier, multiplicand,
    d, cl, name="qc")

circ.x(d)
# Store bit strings in quantum registers
for i in range(l1):
    if multiplicand_in[i] == '1':
        circ.x(multiplicand[l1 - i - 1])

for i in range(l2):
    if multiplier_in[i] == '1':
        circ.x(multiplier[l1 - i - 1])

multiplier_str = '1'
# Perform repeated addition until the multiplier
# is zero
while(int(multiplier_str) != 0):
    add(accumulator, multiplicand, circ, 1)
    add(multiplier, d, circ, -1)
    for i in range(len(multiplier)):
        circ.measure(multiplier[i], cl[i])
    result = execute(circ, backend=Aer.get_backend('qasm_simulator'),
                    shots=2).result().get_counts(circ.name)
    multiplier_str = list(result.keys())[0]

circ.measure(accumulator, cl)
result = execute(circ, backend=Aer.get_backend('qasm_simulator'),
            shots=2).result().get_counts(circ.name)

print(result)