# ! pip install qiskit
# ! pip install numpy

from qiskit import QuantumCircuit, Aer, execute
from qiskit.visualization import plot_bloch_multivector, plot_histogram
from qiskit.quantum_info import Statevector
import numpy as np

ground_state  = np.array([1, 0])
excited_state = np.array([0, 1])

# Making an arbitary state
alpha = 2+ 4j
beta = -2
normalization_factor = np.sqrt(abs(alpha**2)+ abs(beta**2))
arbitrary_state = np.array([alpha, beta]) / normalization_factor

print("ground_state=", ground_state)
print("excited_state=", excited_state)
print("Arbitary_state=", arbitrary_state)

plot_bloch_multivector(ground_state)

plot_bloch_multivector(excited_state)

plot_bloch_multivector(arbitrary_state)

# Defining the matrices
I_matrix = np.identity(2)
Pauli_x = np.array([[0, 1], [1, 0]])
Pauli_y = np.array([[0, -1j], [1j, 0]])
Pauli_z = np.array([[1, 0], [0, 1]])
Hadamard_transform = np.sqrt(1/2) * np.array([[1, 1], [1, -1]])


print("\n Identity Matrix \n" , I_matrix )
print("\n Pauli X \n" , Pauli_x )
print("\n Pauli Y \n" , Pauli_y )
print("\n Pauli Z \n" , Pauli_z )
print("\n Hadamard Transform \n" , Hadamard_transform )

plus_state = np.dot(Hadamard_transform, ground_state)
plot_bloch_multivector(plus_state)

# Defining the Quantum Circuit with a Quantum Register of size 1
quantum_circuit = QuantumCircuit(1) 

# Applyign the hadamrad gate to the first Qubit
quantum_circuit.h(0)  

# Measuring the Circuit
#quantum_circuit.measure(0,0)

# DRwaing the quantum circuit
quantum_circuit.draw('mpl')

initial_state = Statevector.from_label('0')
plot_bloch_multivector(initial_state)

evolved_state = initial_state.evolve(quantum_circuit)
plot_bloch_multivector(evolved_state)

backend=Aer.get_backend('qasm_simulator')
counts = execute(quantum_circuit,backend, shots = 10).result().get_counts()
plot_histogram(counts)

