%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# Importing standard Qiskit libraries 
from qiskit import QuantumCircuit, execute
from qiskit.providers.aer import QasmSimulator
from qiskit.visualization import *
from qiskit.quantum_info import *

q1_sv = Statevector.from_label('+') # Available basis states are 0, 1, +, -, l, r
print(q1_sv.data)

q1_sv.is_valid()

print(q1_sv.probabilities_dict())
print(sum(q1_sv.probabilities()))

outcome, new_sv = q1_sv.measure() # This returns two values
print(f'The outcome of measurement was {outcome}')
print(f'The collapsed statevector after measurement is {new_sv.data}')

outcome2, new2_sv = new_sv.measure() # This returns two values
print('Measured collapsed statevector')
print(f'The outcome of measurement was {outcome2}')
print(f'The collapsed statevector after measurement is {new2_sv.data}')

q1_sv = Statevector.from_label('+')
measured_values = [int(q1_sv.measure()[0]) for _ in range(1000)]
print(f'Number of 0 measured: {measured_values.count(0)}, Number of 1 measured: {measured_values.count(1)}')

q1_sv = Statevector.from_label('+') # Available basis states are 0, 1, +, -, l, r
plot_bloch_multivector(q1_sv)

op1 = Operator.from_label('X') # I, X, Y, Z, S, T, H
print(op1.data)
op1.is_unitary()

op1_adj = op1.adjoint()
print(op1_adj.data)

res = op1*op1_adj
print(res.data)

q2_sv_0 = Statevector.from_label('+')
plot_bloch_multivector(q2_sv_0)

op1 = Operator.from_label('Z')
q2_sv_1 = q2_sv_0.evolve(op1)
plot_bloch_multivector(q2_sv_1)

op2 = Operator.from_label('Z')
q2_sv_2 = q2_sv_1.evolve(op2.adjoint())
plot_bloch_multivector(q2_sv_2)

print(q2_sv_0 == q2_sv_2)

qc = QuantumCircuit(1)
qc.h(0)
qc.z(0)
qc.draw(output='mpl')

visualize_transition(qc, trace=True)

qc = QuantumCircuit(1)
qc.h(0)
qc.z(0)
qc.measure_all()
qc.draw(output='mpl')

job = execute(qc, backend=QasmSimulator(), shots=1024)
plot_histogram(job.result().get_counts())

job.result().get_counts()