from qiskit import QuantumCircuit, execute,QuantumCircuit, ClassicalRegister, QuantumRegister, Aer
from math import pi
import numpy as np
from qiskit.visualization import plot_bloch_multivector, plot_histogram
%matplotlib inline

qc = QuantumCircuit(3)
# Apply H-gate to each qubit:
for qubit in range(3):
    qc.h(qubit)
# See the circuit:
qc.draw('mpl')

# Let's see the result
def final_state(circuit):
    backend = Aer.get_backend('statevector_simulator')
    final_state = execute(circuit,backend).result().get_statevector()
    return final_state
fs=final_state(qc)
fs

# In Jupyter Notebooks we can display this nicely using Latex.
# If not using Jupyter Notebooks you may need to remove the 
# array_to_latex function and use print(final_state) instead.
from qiskit_textbook.tools import array_to_latex
array_to_latex(fs, pretext="\\text{Statevector} = ")

qchx = QuantumCircuit(2)
qchx.h(0)
qchx.x(1)
qchx.draw('mpl')

backend = Aer.get_backend('unitary_simulator')
unitary = execute(qchx,backend).result().get_unitary()

# In Jupyter Notebooks we can display this nicely using Latex.
# If not using Jupyter Notebooks you may need to remove the 
# array_to_latex function and use print(unitary) instead.
from qiskit_textbook.tools import array_to_latex
array_to_latex(unitary, pretext="\\text{Circuit = }\n")

qci = QuantumCircuit(2)
qci.x(1)
qci.draw('mpl')

# Simulate the unitary
backend = Aer.get_backend('unitary_simulator')
unitary = execute(qci,backend).result().get_unitary()
# Display the results:
array_to_latex(unitary, pretext="\\text{Circuit = } ")

qcn = QuantumCircuit(2)
# Apply CNOT
qcn.cx(0,1)
# See the circuit:
qcn.draw('mpl')

qch = QuantumCircuit(2)
# Apply H-gate to the first:
qch.h(0)
qch.draw('mpl')

# # Let's see the result:
# backend = Aer.get_backend('statevector_simulator')
# final_state = execute(qch,backend).result().get_statevector()


fs1 = final_state(qch)
fs1

# # Print the statevector neatly:
array_to_latex(fs1, pretext="\\text{Statevector = }")

qchn = QuantumCircuit(2)
# Apply H-gate to the first:
qchn.h(0)
# Apply a CNOT:
qchn.cx(0,1)
qchn.draw('mpl')

# Let's see the result:
fs2 = final_state(qchn)
# Print the statevector neatly:
array_to_latex(fs2, pretext="\\text{Statevector = }")

qcu = QuantumCircuit(2)
# Apply H-gate to the first:
qcu.h(0)
qcu.draw('mpl')

# Let's see the result:
backend = Aer.get_backend('unitary_simulator')
final_state = execute(qcu,backend).result().get_unitary()
# Print the statevector neatly:
array_to_latex(final_state, pretext="\\text{Circuit = }")

qcm = QuantumCircuit(2,2)
# Apply H-gate to the first:
qcm.h(0)
qcm.draw('mpl')

qcm.cx(0,1)
qcm.measure([0,1],[0,1])
qcm.draw('mpl')

# Let's see the result:
backend = Aer.get_backend('qasm_simulator')
results = execute(qcm,backend, shots=1000).result()
counts  = results.get_counts(qcm)
print(counts)

plot_histogram(counts)

import qiskit
qiskit.__qiskit_version__

