|
| 1 | +''' |
| 2 | + Shor's Algorithm |
| 3 | +
|
| 4 | + Shor's algorithm is a quantum computer algorithm for integer factorization. |
| 5 | + Informally, it solves the following problem: Given an integer N, find its |
| 6 | + prime factors. It was invented in 1994 by the American mathematician Peter Shor. |
| 7 | +
|
| 8 | + Source: https://www.wikiwand.com/en/Shor%27s_algorithm |
| 9 | +
|
| 10 | + Factorization problem can reduce to period finding problem. Consider the sequence |
| 11 | + of the powers of two |
| 12 | +
|
| 13 | + 1, 2, 4, 8, 16, 32, 64, 128, ... |
| 14 | +
|
| 15 | + Now, let's look at the same sequence 'mod 15': |
| 16 | +
|
| 17 | + 1, 2, 4, 8, 1, 2, 4, 8, ... |
| 18 | +
|
| 19 | + This is a modulo sequence that repeats every four numbers, that is, a periodic modulo |
| 20 | + sequence with a period of four. Reduction of factorization of N to the problem of |
| 21 | + finding the period of an integer 1 < x < N depends on the following result from number theory: |
| 22 | +
|
| 23 | + The function F(a) = x^a mod N is a periodic function, where x is an integer coprime |
| 24 | + to N and a >= 0. |
| 25 | +
|
| 26 | + Source: https://github.com/Qiskit/qiskit-community-tutorials/blob/b9266a4f9c1f6b3f4cf5117d9c443f9f1c3518cb/algorithms/shor_algorithm.ipynb |
| 27 | +
|
| 28 | +''' |
| 29 | +import math |
| 30 | + |
| 31 | +from qiskit import IBMQ, BasicAer |
| 32 | +from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, execute |
| 33 | + |
| 34 | +# We'll build circuit for a^x mod 15 for a = 2 |
| 35 | +qr = QuantumRegister(5) |
| 36 | +cr = ClassicalRegister(5) |
| 37 | + |
| 38 | +circuit = QuantumCircuit(qr, cr) |
| 39 | + |
| 40 | +# Initialize q[0] to |1> |
| 41 | +circuit.x(qr[0]) |
| 42 | + |
| 43 | +# Apply a**4 mod 15 |
| 44 | +circuit.h(qr[4]) |
| 45 | +circuit.h(qr[4]) |
| 46 | +circuit.measure(qr[4], cr[0]) |
| 47 | +circuit.reset(qr[4]) |
| 48 | + |
| 49 | +# Apply a**2 mod 15 |
| 50 | +circuit.h(qr[4]) |
| 51 | +circuit.cx(qr[4], qr[2]) |
| 52 | +circuit.cx(qr[4], qr[0]) |
| 53 | +circuit.u1(math.pi/2., qr[4]).c_if(cr, 1) |
| 54 | +circuit.u1(math.pi/2., qr[4]).c_if(cr, 1) |
| 55 | +circuit.h(qr[4]) |
| 56 | +circuit.measure(qr[4], cr[1]) |
| 57 | +circuit.reset(qr[4]) |
| 58 | + |
| 59 | +# Apply a mod 15 |
| 60 | +circuit.h(qr[4]) |
| 61 | +circuit.cswap(qr[4], qr[3], qr[2]) |
| 62 | +circuit.cswap(qr[4], qr[2], qr[1]) |
| 63 | +circuit.cswap(qr[4], qr[1], qr[0]) |
| 64 | +circuit.u1(3.*math.pi/4., qr[4]).c_if(cr, 3) |
| 65 | +circuit.u1(math.pi/2., qr[4]).c_if(cr, 2) |
| 66 | +circuit.u1(math.pi/4., qr[4]).c_if(cr, 1) |
| 67 | +circuit.h(qr[4]) |
| 68 | +circuit.measure(qr[4], cr[2]) |
| 69 | + |
| 70 | +# Run our circuit with local simulator |
| 71 | +backend = BasicAer.get_backend('qasm_simulator') |
| 72 | +shots = 1024 |
| 73 | +results = execute(circuit, backend=backend, shots=shots).result() |
| 74 | +answer = results.get_counts() |
| 75 | +print(answer) |
| 76 | +# We see the measurements yield x = 0, 2, 4 and 6 with equal(ish) probability. |
| 77 | +# Using the continued fraction expansion for x/2^3, we note that only x = 2 and |
| 78 | +# 6 give the correct period r = 4, and thus the factors p = gcd(a^{r/2}+1,15) = 3 |
| 79 | +# and q = gcd(a^{r/2}-1,15) = 5. |
0 commit comments