from qiskit import *
import numpy as np
import sys 
sys.path.append("..")

qiskit.__qiskit_version__

from Modules.kitaev_qpe import KQPE

U = np.array([[1, 0],
              [0, np.exp(2*np.pi*1j*(1/3))]])

kqpe = KQPE(unitary=U, precision=16)
kq_circ = kqpe.get_circuit(show=True, save_circ=True,
                           circ_name="KQPE_circ_1qubit.JPG")

q = QuantumCircuit(5, 6)
q.x(3)
q.append(kq_circ, qargs=[1, 2, 3])
q.draw('mpl')

phase = kqpe.get_phase(backend=Aer.get_backend(
    'qasm_simulator'), QC=q, ancilla=[1, 2], clbits=[0, 1], show=True)

print("Phase of the unitary is :", phase)

q = QuantumCircuit(2, name='Unitary')
q.cp(2*np.pi*(1/7), 0, 1)
q.draw('mpl')

unitary = q

kqpe = KQPE(unitary, precision=12)
kq_circ = kqpe.get_circuit(show=True)

q = QuantumCircuit(5, 2)
q.x([2, 3])
q.append(kq_circ, qargs=[0, 1, 2, 3])
q.draw('mpl')

sim = Aer.get_backend('qasm_simulator')

phase = kqpe.get_phase(backend=sim, QC=q, ancilla=[
                       0, 1], clbits=[0, 1], show=True)

print("Phase returned is :", phase)

q = QuantumCircuit(2, name='Phase Unitary')
q.cp(2*np.pi*(1/7), 0, 1)
display(q.draw('mpl'))
unitary = q

precision = [i for i in range(8, 18)]
precision

estimates, errors = [], []
for prec in precision:
    kqpe = KQPE(unitary, precision=prec)
    kq_circ = kqpe.get_circuit(show=False)

    # making circuit
    q = QuantumCircuit(5, 2)
    q.x([2, 3])
    q.append(kq_circ, qargs=[0, 1, 2, 3])

    # getting the phase
    phase = kqpe.get_phase(backend=sim, QC=q, ancilla=[
                           0, 1], clbits=[0, 1], show=False)
    estimates.append(phase[0])
    errors.append(abs(1/7-phase[0]))

import matplotlib.pyplot as plt
plt.title("Phase Estimation for $ \phi $ = 1/7", fontsize=16)
plt.xlabel("Precision for estimation")
plt.ylabel("Estimates for Error and Phase")
plt.plot([7, 18], [1/7, 1/7], color='black', label='Actual', linewidth=2)
plt.plot(precision, estimates, marker='o', color='magenta',
         alpha=0.6, label='Phase Estimate')
plt.plot(precision, errors, marker='s', color='cyan',
         alpha=0.6, label="Error estimate")
plt.grid()
plt.legend()
plt.savefig("Kitaev Multiqubit Estimation Plot.JPG", dpi=200)



