from qiskit import QuantumCircuit, Aer
from qiskit.visualization import plot_state_qsphere, plot_bloch_multivector
import math

def plot_bloch_sphere(qc, title, initial):
    backend = Aer.get_backend('statevector_simulator')
    result = backend.run(qc).result()
    sv = result.get_statevector()
    return plot_bloch_multivector(sv, title=title+' Gate: initial |'+initial+'>')

def plot_qsphere_with_phase(qc):
    backend = Aer.get_backend('statevector_simulator')
    result = backend.run(qc).result()
    sv = result.get_statevector()
    return plot_state_qsphere(sv, show_state_phases=True)

qc = QuantumCircuit(1)
qc.x(0)
plot_bloch_sphere(qc, 'X', '0')

qc = QuantumCircuit(1)
qc.y(0)
plot_bloch_sphere(qc, 'Y', '0')

qc = QuantumCircuit(1)
qc.initialize([0, 1], 0)
qc.y(0)
plot_bloch_sphere(qc, 'Y', '1')

qc = QuantumCircuit(1)
qc.z(0)
plot_bloch_sphere(qc, 'Z', '0')

qc = QuantumCircuit(1)
qc.initialize([0, 1], 0)
qc.z(0)
plot_bloch_sphere(qc, 'Z', '1')

plot_qsphere_with_phase(qc)

qc = QuantumCircuit(1)
qc.h(0)
plot_bloch_sphere(qc, 'Hadamard', '0')

qc = QuantumCircuit(1)
qc.initialize([1/math.sqrt(2), 1/math.sqrt(2)])
qc.rz(math.pi/4,  0)
plot_bloch_sphere(qc, 'Rz', '+')

plot_qsphere_with_phase(qc)

qc = QuantumCircuit(1)
qc.initialize([1/math.sqrt(2), 1/math.sqrt(2)])
qc.s(0)
plot_bloch_sphere(qc, 'S', '+')

plot_qsphere_with_phase(qc)

qc = QuantumCircuit(1)
qc.initialize([1/math.sqrt(2), 1/math.sqrt(2)])
qc.t(0)
plot_bloch_sphere(qc, 'S', '+')

plot_qsphere_with_phase(qc)




from qiskit.quantum_info import Operator

XX = Operator([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
XX

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
bellOp = Operator(qc)
bellOp

qc = QuantumCircuit(2)
qc.append(bellOp, [0, 1])
qc.draw('mpl')

from qiskit.quantum_info.operators import Pauli

A = Operator(Pauli(label='X'))
B = Operator(Pauli(label='Z'))
A.tensor(B)

A.compose(B)

A+B

