%matplotlib inline
from qiskit import *

# The following code is for nicer display of the matrices
from IPython.display import display, Markdown

def format_float(x):
    if x % 1 == 0:
        return int(x)
    else:
        return x

def format_imaginary(z):
    if abs(z.imag) < 1e-15:
        return "{}".format(format_float(z.real))
    elif abs(z.real) < 1e-15:
        if z.imag == 1:
            return "i"
        elif z.imag == -1:
            return "-i"
        return "{}i".format(format_float(z.imag))
    if z.imag > 0:
        return "{} + {}i".format(z.real, abs(z.imag))
    else:
        return "{} - {}i".format(z.real, abs(z.imag))

def display_matrix(gate, gate_name="U"):
    a00 = format_imaginary(gate[0][0])
    a01 = format_imaginary(gate[0][1])
    a10 = format_imaginary(gate[1][0])
    a11 = format_imaginary(gate[1][1])
    ans = r"${} = \begin{{bmatrix}} {} & {} \\ {} & {}\end{{bmatrix}}$".format(gate_name,a00, a01, a10, a11)
    return Markdown(ans)

simulator = Aer.get_backend("unitary_simulator")

circuit = QuantumCircuit(1)
circuit.draw(output="mpl")

job = execute(circuit, backend=simulator)
result = job.result()
unitary = result.get_unitary()
print(unitary)

circuit = QuantumCircuit(1)
circuit.x(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary, "X")
)

circuit = QuantumCircuit(1)
circuit.x(0)
circuit.h(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary)
)

circuit = QuantumCircuit(1)
circuit.h(0)
circuit.z(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary)
)

circuit = QuantumCircuit(1)
circuit.z(0)
circuit.h(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary)
)

circuit = QuantumCircuit(1)
circuit.y(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary, "Y")
)

circuit = QuantumCircuit(1)
circuit.y(0)
circuit.y(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary, "U")
)

circuit = QuantumCircuit(1)
circuit.s(0)
circuit.s(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary, "U")
)

circuit = QuantumCircuit(1)
circuit.s(0)
circuit.sdg(0)  # sdg = s dagger
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary, "U")
)

circuit = QuantumCircuit(1)
circuit.s(0)
#circuit.sdg(0)
circuit.s(0)
circuit.s(0)
circuit.s(0)
circuit.draw(output="mpl")

unitary = execute(circuit, backend=simulator).result().get_unitary()
display(
    display_matrix(unitary, "U")
)