from IPython.display import IFrame
IFrame("https://www.youtube.com/embed/hOlOY7NyMfs?start=75&end=126",560,315)

# Example of Brute force period finding algorithm
def find_period_classical(x, N):
    n = 1
    t = x
    while t != 1:
        t *= x
        t %= N
        n += 1
    return n

N = 4
qrQFT = QuantumRegister(N,'qftr')
QFT = QuantumCircuit(qrQFT)

for i in range(N):
    QFT.h(qrQFT[i])
    for k in range(i+1,N):
        l = k-i+1
        QFT.cu1(2*math.pi/(2**l),qrQFT[k],qrQFT[i])

QFT.draw(output='mpl')

import logging
logger = logging.getLogger()
logger.setLevel(logging.CRITICAL)

from qiskit import IBMQ
IBMQ.load_account()

import qiskit
qiskit.__version__

qiskit.__qiskit_version__

from qiskit.aqua.algorithms.quantum_algorithm import QuantumAlgorithm
from qiskit.aqua.algorithms import Shor
from qiskit import Aer
from qiskit.tools.visualization import plot_histogram
backend = Aer.get_backend("qasm_simulator")

logger.setLevel(logging.CRITICAL)

shor = Shor(15,11)
result = shor.run(backend)

result

circuit = shor.construct_circuit(measurement=True)

print(qiskit.aqua.utils.summarize_circuits(circuit))

circuit.draw()

cloud_backend = IBMQ.get_provider(group='open').get_backend('ibmq_qasm_simulator')
cloud_backend

execution = qiskit.execute(circuit,cloud_backend)

plot_histogram(execution.result().get_counts())

print('i(M/r)= 10000000=', int('10000000',2), ' M=', pow(2,8), ' r/i=', pow(2,8)/int('10000000',2), ' (i=1)')

logger.setLevel(logging.DEBUG)

counts = execution.result().get_counts()

for output_desired in list(counts.keys()):
    # Get the x_value from the final state qubits
    success = shor._get_factors(output_desired, int(2 * shor._n))
    if success:
        logger.info('Found factors {} from measurement {}.\n'.format(
            shor._ret['results'][output_desired], output_desired
        ))
    else:
        logger.info('Cannot find factors from measurement {} because {}\n'.format(
            output_desired, shor._ret['results'][output_desired]
        ))

logger.setLevel(logging.CRITICAL)

shor = Shor(15,7)
result = shor.run(backend)

result

circuit = shor.construct_circuit(measurement=True)

print(qiskit.aqua.utils.summarize_circuits(circuit))

circuit.draw()

execution = qiskit.execute(circuit,backend)

plot_histogram(execution.result().get_counts())

print('i(M/r)= 01000000=', int('01000000',2), ' M=', pow(2,8), ' r/i=', pow(2,8)/int('01000000',2), ' (i=1)')
print('i(M/r)= 10000000=', int('10000000',2), ' M=', pow(2,8), ' r/i=', pow(2,8)/int('10000000',2), ' (i=2)')
print('i(M/r)= 11000000=', int('11000000',2), ' M=', pow(2,8), ' r/i=', pow(2,8)/int('11000000',2), ' (i=3)')

logger.setLevel(logging.DEBUG)

counts = execution.result().get_counts()

for output_desired in list(counts.keys()):
    # Get the x_value from the final state qubits
    success = shor._get_factors(output_desired, int(2 * shor._n))
    if success:
        logger.info('Found factors {} from measurement {}.\n'.format(
            shor._ret['results'][output_desired], output_desired
        ))
    else:
        logger.info('Cannot find factors from measurement {} because {}\n'.format(
            output_desired, shor._ret['results'][output_desired]
        ))

