I found this code for Shor's algorithm but it always was failing at the end of the modular_exponentiation routine because the keyvalue of '00000' was not found in the dictionary on the call to b_measure = result.get_counts()[format(i, '0{}b'.format(n+1))[-(n+1):]]
Here is the original code in its entirety:
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, Aer, execute
Function to perform modular exponentiation
def modular_exponentiation(a, x, N):
"""Calculate a^x mod N"""
n = N.bit_length()
qr = QuantumRegister(n + 1)
cr = ClassicalRegister(n + 1)
circuit = QuantumCircuit(qr, cr)
for i in range(n):
circuit.initialize([1, 0], qr[i])
circuit.initialize([1, 0], qr[n])
for i in range(n):
if (x >> i) & 1:
circuit.cx(qr[n], qr[i])
for i in range(n):
circuit.x(qr[i])
for i in range(2 ** n):
b = bin(a * i % N)[2:].zfill(n)
for j in range(n):
if b[j] == '1':
circuit.cx(qr[j], qr[n])
circuit.barrier()
for j in range(n):
circuit.measure(qr[j], cr[j])
circuit.measure(qr[n], cr[n])
backend = Aer.get_backend('qasm_simulator')
result = execute(circuit, backend, shots=1).result()
b_measure = result.get_counts()[format(i, '0{}b'.format(n))]
for j in range(n):
if b_measure[j] == '1':
circuit.x(qr[j])
return circuit
Function to perform Shor's algorithm
def shor(N):
"""Find the factors of N using Shor's algorithm"""
n = N.bit_length()
M = 2 ** n
t = 0
while M ** (t / 2) < 2 * n ** 2:
t += 1
a = 2
for i in range(t):
a = pow(a, M // 2, N)
if a == 0:
return 0
if a == -1:
a = N - 1
period = None
while period is None:
circuit = modular_exponentiation(a, 2 ** t, N)
backend = Aer.get_backend('qasm_simulator')
result = execute(circuit, backend, shots=1).result()
for key, value in result.get_counts().items():
if value > 0:
x = int(key, 2)
period = x // 2 ** (n - t)
break
factor1 = pow(a, period // 2, N) - 1
factor2 = pow(a, period // 2, N) + 1
return (factor1, factor2)
Example usage
N = 15
factors = shor(N)
print("Factors of", N, "are", factors)
I am doing this to learn, so I am not quantum computing expert. I made changes to roughly the last ten lines of modular_exponentiation routine to eliminate the runtime errors as best as I could infer that it should work. My changed code for the end of modular_exponentiation routine is as follows. This runs, the results are consistent between runs, but the results are wrong. For example, I tried a known prime of 419. The program says the factors are (335, 337). I tried increasing the number of shots to 10, but this does not seem to have any effect on the results. Other values of N, such as composite numbers, also get results that are not correct.
Thanks in advance for any advice.
circuit.measure(qr[n], cr[n])
backend = Aer.get_backend('qasm_simulator')
result = execute(circuit, backend, shots=10).result()
#print("n = ", n)
tempkey = format(i, '0{}b'.format(n+1))[-(n+1):]
#print("two = ", tempkey)
if tempkey in result.get_counts():
b_measure = result.get_counts()[tempkey]
for j in range(n):
#print("b_measure, j = ", b_measure, j)
if tempkey[j] == '1':
#if b_measure[j] == '1':
circuit.x(qr[j])
else:
b_measure = 0
return circuit