import numpy as np
# Importing standard Qiskit libraries
from qiskit import QuantumCircuit, transpile, Aer, IBMQ,execute
from qiskit.tools.jupyter import *
from qiskit.visualization import *
from ibm_quantum_widgets import *

# Loading your IBM Quantum account(s)
provider = IBMQ.load_account()

# Criando um circuito de n qubits
n = 4
qc = QuantumCircuit(n)

#Desenhando o circuito
qc.draw()

backend = Aer.get_backend('statevector_simulator')
results = execute(qc, backend).result().get_statevector()
plot_bloch_multivector(qc)

import matplotlib.pyplot as plt
from IPython.display import display, Latex

n = 1
qc = QuantumCircuit(n)
print('Com probabilidade máxima (igual 1) o qubit se econtra no estado 0.')

backend = Aer.get_backend('statevector_simulator')
results = execute(qc,backend).result().get_counts()
display(plot_histogram(results, figsize = (2,2)))

state = execute(qc,backend).result().get_statevector()
plot_bloch_multivector(state)

# Colocando em superposição
qc = QuantumCircuit(n)
qc.h(0) 
display(qc.draw())

state = execute(qc,backend).result().get_statevector()
plot_bloch_multivector(state)


# print('--- O resultado abaixo mostra que temos um qubit em superposição.')
# print("--- Apesar termos 50% de chance de medir o estado 0 ou  1, só conseguimos extrair um bit \ 
#       de informação do sistema. O número de bits (clássicos) de informação extraídos \
#       do sistema será, no máximo, igual ao número qubits")
# print("--- O nosso resultado será 0 ou 1")

qc = QuantumCircuit(n,1)
qc.h(0)
qc.measure(0,0)


backend = Aer.get_backend('qasm_simulator')
results = execute(qc,backend, shots=10000).result().get_counts()
plot_histogram(results, figsize=(2,2))


n = 4

qc = QuantumCircuit(n)
qc.id(0) # nao faz nada no qubit 0
qc.x(1)  # flipa o qubit 1 --- 0->1
qc.h(2)  # coloca o qubit 2 em superposição: |0> = |0> + |1>
qc.x(3)  # flipa o qubit 3 --- |0> -> |1>
qc.h(3)  # coloca o qubit 3 em superposção: |1> = |0> - |1>
qc.draw()

print("--------- Mostra a posição de cada um dos qubits na esfera de Bloch ---------")
backend = Aer.get_backend('statevector_simulator')
results = execute(qc,backend).result().get_statevector()
plot_bloch_multivector(results)

n = 1
qc = QuantumCircuit(n,1)
qc.h(0)
qc.measure(0,0)
display(qc.draw())

# |0> ---> H ----->|0> + |1>

print('----------O resultado da medida de um qubit em superposição.---------\n')
shots = 10000
backend = Aer.get_backend('qasm_simulator')
results = execute(qc,backend, shots=shots).result().get_counts()
display(plot_histogram(results,figsize = (3,3)))

state0 = results['0']
state1 = results['1']

print(f'Ao rodar {shots} vezes experimento, o resultado 0 apareceu {state0} \
vezes e resultado 1 ocorreu {state1} vezes')

print("\n\n------ Visualização da medida do experimento rodando quatro vezes ------\n")
for i in range(4):
    results = execute(qc,backend, shots = 1).result().get_counts()
    display(plot_histogram(results, figsize=(2,2)))

# Run the code in this cell to see the widget
from qiskit_textbook.widgets import gate_demo
gate_demo(gates='pauli+h+rz')

n = 2
qc = QuantumCircuit(n)
qc.h(0)
qc.h(1)
# qc.measure(range(n), range(n))
display(qc.draw())

#|0> -> H -> |0> + |1>
#|00> -> H|0>*Id|0> = (|0> + |1>)(|0>) = (|00> + |10>) Estado nao emaranhado

backend = Aer.get_backend('statevector_simulator')
results = execute(qc,backend).result().get_counts()
plot_histogram(results, figsize = (3,3))



n = 2
qc = QuantumCircuit(n)
qc.h(0)
qc.cx(0,1)
# qc.measure(0,0)
# qc.measure(1,1)




qc.draw()

backend = Aer.get_backend('statevector_simulator')
results = execute(qc,backend).result().get_counts()
plot_histogram(results, figsize = (3,3))


#|0> -> H -> |0> + |1>
#|00> -> H|0>*Id|0> = (|0> + |1>)(|0>) = (|00> + |10>) aplicar CNOT (|00> + |11>) - Estado Emaranhado


