import numpy as np
#from qiskit import *
from qiskit import QuantumCircuit, execute, Aer, IBMQ

from qiskit.visualization import plot_histogram, plot_gate_map, plot_circuit_layout
from qiskit.tools.monitor import job_monitor

import matplotlib.pyplot as plt
%matplotlib inline


IBMQ.load_account()
provider = IBMQ.get_provider(group='open')

ghz = QuantumCircuit(5,5)
ghz.h(0)
for idx in range(1,5):
    ghz.cx(0,idx)
ghz.barrier(range(5))
ghz.measure(range(5), range(5))
ghz.draw(output='mpl')


from qiskit import transpile
import inspect
inspect.signature(transpile)

provider = IBMQ.get_provider(group='open')
provider.backends(simulator=False)

backend = provider.get_backend('ibmqx2')
backend.configuration().basis_gates

qc = QuantumCircuit(2,1)
qc.h(0)
qc.x(1)
qc.cu1(np.pi/4, 0, 1)  
# cu1 is controlled u1 just like CNOT is controlled NOT
qc.h(0)
qc.measure([0], [0])
qc.draw(output='mpl')

qc_basis = qc.decompose()
qc_basis.draw(output='mpl')

print(qc.depth(), ',', qc_basis.depth())

swap_circ = QuantumCircuit(2)
display ( swap_circ.draw(output='mpl') )
swap_circ.swap(0, 1)
display  ( swap_circ.decompose().draw(output='mpl') )

ccx_circ = QuantumCircuit(3)
ccx_circ.ccx(0, 1, 2)
ccx_circ.decompose().draw(output='mpl')

backend = provider.get_backend('ibmq_16_melbourne')
plot_gate_map(backend, plot_directed=True)

new_circ_lv0 = transpile(ghz, backend=backend, optimization_level=0)
plot_circuit_layout(new_circ_lv0, backend )

backend = provider.get_backend('ibmq_16_melbourne')
new_circ_lv3 = transpile(ghz, backend=backend, optimization_level=3)

print('Depth:', new_circ_lv3.depth())
plot_circuit_layout(new_circ_lv3, backend)

#job1 = execute(new_circ_lv3, backend)
#job_monitor(job1)

# Virtual -> physical
#    0    ->    11
#    1    ->    12
#    2    ->    10
#    3    ->    2
#    4    ->    4

good_ghz = transpile(ghz, backend, initial_layout=[11,12,10,2,4])
print('Depth:', good_ghz.depth())
plot_circuit_layout(good_ghz, backend)

