%run init.ipynb

!pip install -U qiskit==0.39.4

import qiskit
from qiskit import *
nshots = 8192
IBMQ.load_account()
provider = qiskit.IBMQ.get_provider(hub='ibm-q', group='open', project='main')
device = provider.get_backend('ibmq_quito')
simulator = Aer.get_backend('qasm_simulator')
from qiskit.tools.monitor import job_monitor

qr = QuantumRegister(1)
qc = QuantumCircuit(qr)
qc.h(qr[0])
qc.draw()

from qiskit_experiments.library import StateTomography # essa é com o novo qiskit 039

qcst = StateTomography(qc, measurement_qubits = [0])
data = qcst.run(simulator)
rho = data.block_for_results().analysis_results(0).value

from qiskit.visualization import array_to_latex
array_to_latex(rho)

d = rho.dims()[0]; print(rho.dims(), d)

rhoM = rho.to_operator().data; print(rhoM)

rhoM[0,0], abs(rhoM[0,0])

job_exp = qcst.run(device, shots=nshots)#.block_for_results()
print(job_exp.experiment_id)
job_exp.job_status()
sudo apt install jupyter-core

rho = job_exp.block_for_results().analysis_results(0).value
rhoM = rho.to_operator().data; print(rhoM)

for j in range(0,10):
    print("\r %d"%j,end=" ")

data = device.retrieve_job('03834ee2-0c74-45ff-b744-2cfa3d74f860')
rho = data.block_for_results().analysis_results(0).value
rhoM = rho.to_operator().data; print(rhoM)

!pip install -U qiskit==0.36.2

# como sempre, importa tudo do qiskit
from qiskit import *
import qiskit

qiskit.__qiskit_version__

# importa também funcoes para determinar os circuitos a serem tomografados e pra ajustar os dados
from qiskit.ignis.verification.tomography import state_tomography_circuits, StateTomographyFitter

# cria os circuitos, sem medidas
qr = QuantumRegister(1); qc = qiskit.QuantumCircuit(qr); 

# cria o circuito
qc.h(qr[0]);

# visualiza o circuito
qc.draw(output='mpl')

# Determina de qual circuito e de qual qubit fazer TEQ
qstc = state_tomography_circuits(qc, qr[0])

# No. de medidas pra estimar cada dist. de probabilidade
nshots = 8192

# testa/executa no simulador
job = qiskit.execute(qstc, Aer.get_backend('qasm_simulator'), shots=nshots)

# 'ajusta' os resultados conforme o esperado do circuit qst
qstf = StateTomographyFitter(job.result(), qstc)

# extrai o operador densidade tomografado
rho = qstf.fit(method='lstsq')

# note que o que retorna é um array do numpy
rho # funcionou mudando a versao do qiskit com o novo ambiente conda

import numpy as np
from matplotlib import pyplot as plt

# grafica a parte real de um estado de um qubit
def plot_rho1qb(rho):
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    result = [rho[0,0], rho[0,1], rho[1,0], rho[1,1]]
    result = np.array(result, dtype=float)
    fig = plt.figure(figsize=(4, 4), dpi=100)
    ax1 = fig.add_subplot(111, projection='3d')
    xlabels = np.array([r'$|0\rangle$', r'$|1\rangle$']); xpos = np.arange(xlabels.shape[0])
    ylabels = np.array([r'$|1\rangle$', r'$|0\rangle$']); ypos = np.arange(ylabels.shape[0])
    xposM, yposM = np.meshgrid(xpos, ypos, copy=False); zpos = result
    dx = 0.5; dy = 0.5; dz = zpos
    ax1.set_xlim(0, 1.5); ax1.set_ylim(0, 1.5); ax1.set_zlim(-1, 1)
    ax1.w_xaxis.set_ticks(xpos + dx/2.0); ax1.w_xaxis.set_ticklabels(xlabels)
    ax1.w_yaxis.set_ticks(ypos + dy/2.0); ax1.w_yaxis.set_ticklabels(ylabels)
    values = np.linspace(0.2, 1.0, xposM.ravel().shape[0]); colors = cm.rainbow(values)
    ax1.bar3d(xposM.ravel(), yposM.ravel(), dz*0, dx, dy, dz, color=colors)
    plt.show()

plot_rho1qb(rho.real), plot_rho1qb(rho.imag)

# carrega minha conta no IBMQ (o ID foi incluido no outro arquivo, nao precisa incluir aqui)
qiskit.IBMQ.load_account();

#provider = IBMQ.get_provider('ibm-q')
provider = IBMQ.get_provider(hub = 'ibm-q-research-2', group = 'federal-uni-sant-1', project = 'main')

# determina em qual backend vamos executar o circuito
device = provider.get_backend('ibmq_quito')

# para monitorar a execucao
from qiskit.tools.monitor import job_monitor

# executa os circuitos para TEQ no chip
job = qiskit.execute(qstc, backend = device, shots = nshots)

print(job.job_id()); job_monitor(job)

# 'ajusta' os resultados conforme o esperado do circuit qst
qstf = StateTomographyFitter(job.result(), qstc)

# extrai o operador densidade tomografado
rho = qstf.fit(method='lstsq'); rho

plot_rho1qb(rho.real), plot_rho1qb(rho.imag)

