import qiskit
from qiskit import *
import math
import numpy as np

def qc_ezz(t):
    qc = QuantumCircuit(2, name = 'e^(-itZZ)')
    qc.cx(0, 1); qc.rz(2*t, 1); qc.cx(0, 1) 
    return qc
def qc_exx(t):
    qc = QuantumCircuit(2, name = 'e^(-itXX)')
    qc.h([0,1]); qc.cx(0, 1); qc.rz(2*t, 1); qc.cx(0, 1); qc.h([0,1])
    return qc
def qc_eyy(t):
    qc = QuantumCircuit(2, name = 'e^(-itYY)')
    qc.sdg([0,1]); qc.h([0,1]); qc.cx(0, 1); qc.rz(2*t, 1); qc.cx(0, 1); qc.h([0,1]); qc.s([0,1])
    return qc
def qc_Bj(t):
    qc = QuantumCircuit(3, name = 'B_j')
    qc_ezz_ = qc_ezz(t); qc_eyy_ = qc_eyy(t); qc_exx_ = qc_exx(t)
    qc.append(qc_ezz_, [1, 2]); qc.append(qc_eyy_, [1, 2]); qc.append(qc_exx_, [1, 2])
    qc.append(qc_ezz_, [0, 1]); qc.append(qc_eyy_, [0, 1]); qc.append(qc_exx_, [0, 1])
    return qc
qc_Bj_ = qc_Bj(math.pi/2); qc_Bj_.draw(output='mpl')

qc_Bj_.decompose().draw(output='mpl')

nshots = 8192
IBMQ.load_account()
provider = IBMQ.get_provider(hub='ibm-q-community', group='ibmquantumawards', project='open-science-22')
#provider = qiskit.IBMQ.get_provider(hub = 'ibm-q-research-2', group = 'federal-uni-sant-1', project = 'main')
device = provider.get_backend('ibmq_jakarta')
simulator = Aer.get_backend('qasm_simulator')
from qiskit.tools.monitor import job_monitor
from qiskit.ignis.verification.tomography import state_tomography_circuits, StateTomographyFitter
from qiskit.tools.monitor import backend_overview, backend_monitor
from qiskit.providers.aer import noise
from qiskit.providers.aer.noise import NoiseModel
from qiskit.ignis.mitigation.measurement import complete_meas_cal, CompleteMeasFitter

noise_model = NoiseModel.from_backend(device)
basis_gates = noise_model.basis_gates
coupling_map = device.configuration().coupling_map

ket0 = np.array([[1],[0]]); ket1 = np.array([[0],[1]]);
psi0 = np.kron(ket0, np.kron(ket1, ket1)) # initial state to be used for computing the fidelity
t = math.pi
for j in range(0, 10): # Trotter stepsm_info.
    # quantum circuit
    qc = QuantumCircuit(7)
    qc.x([5, 3]) # prepares the initial state
    qc_Bj_ = qc_Bj(t/(j+1))
    for k in range(0, j+1):
        qc.append(qc_Bj_, [5, 3, 1])
    qstc = state_tomography_circuits(qc, [5, 3, 1])
    # simulation
    job_sim = execute(qstc, backend = simulator, shots = nshots)
    qstf_sim = StateTomographyFitter(job_sim.result(), qstc)
    rho_sim = qstf_sim.fit(method = 'lstsq')
    F_sim = quantum_info.state_fidelity(psi0, rho_sim)
    # simulation with simulated noise
    job_exp = execute(qstc, backend = simulator, shots = nshots, noise_model = noise_model, 
                      basis_gates = basis_gates, coupling_map = coupling_map)
    qstf_exp = StateTomographyFitter(job_exp.result(), qstc)
    rho_exp = qstf_exp.fit(method = 'lstsq')
    F_exp = quantum_info.state_fidelity(psi0, rho_exp)
    print('No. passos=', j+1, ',F_sim=', F_sim, ',F_exp=', F_exp)

inha visto essa reprovação mas não me dei por conta que n# for error mitigation
qr = QuantumRegister(7)
qubit_list = [5,3,1] # the qubits on which we shall apply error mitigation
meas_calibs, state_labels = complete_meas_cal(qubit_list = qubit_list, qr = qr)
job_cal = execute(meas_calibs, backend = simulator, shots = nshots, noise_model = noise_model, 
                  basis_gates = basis_gates, coupling_map = coupling_map)
meas_fitter = CompleteMeasFitter(job_cal.result(), state_labels)

ket0 = np.array([[1],[0]]); ket1 = np.array([[0],[1]]); #ket0, ket1
psi0 = np.kron(ket0, np.kron(ket1, ket1)) # initial state to be used for computing the fidelity
t = math.pi
for j in range(0, 10): # Trotter steps
    # quantum circuit
    qc = QuantumCircuit(7)
    qc.x([5, 3]) # prepares the initial state
    qc_Bj_ = qc_Bj(t/(j+1))
    for k in range(0, j+1):
        qc.append(qc_Bj_, [5, 3, 1])
    qstc = state_tomography_circuits(qc, [5, 3, 1])
    # simulation
    job_sim = execute(qstc, backend = simulator, shots = nshots)
    qstf_sim = StateTomographyFitter(job_sim.result(), qstc)
    rho_sim = qstf_sim.fit(method = 'lstsq')
    F_sim = quantum_info.state_fidelity(psi0, rho_sim)
    # simulation with simulated noise and error mitigation
    job_exp = execute(qstc, backend = simulator, shots = nshots, noise_model = noise_model, 
                      basis_gates = basis_gates, coupling_map = coupling_map)
    mitigated_results = meas_fitter.filter.apply(job_exp.result())
    qstf_exp = StateTomographyFitter(mitigated_results, qstc)
    rho_exp = qstf_exp.fit(method = 'lstsq')
    F_exp = quantum_info.state_fidelity(psi0, rho_exp)
    print('No. passos=', j+1, ',F_sim=', F_sim, ',F_exp=', F_exp)

def qc_Bj_zz(t, th, ph):
    qc = QuantumCircuit(3, name = 'B_j_zz')
    qc_ezz_ = qc_ezz(t); qc_eyy_ = qc_eyy(t); qc_exx_ = qc_exx(t)
    qc.rz(2*th, [1,2])
    qc.append(qc_ezz_, [1, 2]); qc.append(qc_eyy_, [1, 2]); qc.append(qc_exx_, [1, 2])
    qc.rz(-2*th, [1,2])
    qc.rz(2*ph, [0,1])
    qc.append(qc_ezz_, [0, 1]); qc.append(qc_eyy_, [0, 1]); qc.append(qc_exx_, [0, 1])
    qc.rz(-2*ph, [0,1])
    return qc
qc_Bj_zz_ = qc_Bj_zz(math.pi, math.pi/3, math.pi/4); qc_Bj_zz_.draw(output='mpl')

ket0 = np.array([[1],[0]]); ket1 = np.array([[0],[1]]); #ket0, ket1
psi0 = np.kron(ket0, np.kron(ket1, ket1)) # initial state to be used for computing the fidelity
t = math.pi
j = 6; print('N. of Trotter steps = ', j+1)
th_max = 2*math.pi; dth = th_max/16; th = np.arange(0, th_max+dth, dth); dim_th = th.shape[0] 
ph_max = 2*math.pi; dph = ph_max/16; ph = np.arange(0, ph_max+dph, dph); dim_ph = ph.shape[0]
for m in range(0, dim_th):
    for n in range(0, dim_ph):
        # quantum circuit
        qc = QuantumCircuit(7)
        qc.x([5, 3]) # prepares the initial state
        qc_Bj_zz_ = qc_Bj_zz(t/(j+1), th[m], ph[n])
        for k in range(0, j+1):
            qc.append(qc_Bj_zz_, [5, 3, 1])
        qstc = state_tomography_circuits(qc, [5, 3, 1])
        # simulation
        job_sim = execute(qstc, backend = simulator, shots = nshots)
        qstf_sim = StateTomographyFitter(job_sim.result(), qstc)
        rho_sim = qstf_sim.fit(method = 'lstsq')
        F_sim = quantum_info.state_fidelity(psi0, rho_sim)
        # simulation with simulated noise and error mitigation
        job_exp = execute(qstc, backend = simulator, shots = nshots, noise_model = noise_model, 
                          basis_gates = basis_gates, coupling_map = coupling_map)
        mitigated_results = meas_fitter.filter.apply(job_exp.result())
        qstf_exp = StateTomographyFitter(mitigated_results, qstc)
        rho_exp = qstf_exp.fit(method = 'lstsq')
        F_exp = quantum_info.state_fidelity(psi0, rho_exp)
        print('th=', th[m], ', ph=', ph[n], ', F_sim=', F_sim, ', F_exp=', F_exp)

def qc_Bj_zx(t, th, ph):
    qc = QuantumCircuit(3, name = 'B_j_zz')
    qc_ezz_ = qc_ezz(t); qc_eyy_ = qc_eyy(t); qc_exx_ = qc_exx(t)
    qc.rx(2*th, [1,2])
    qc.append(qc_ezz_, [1, 2]); qc.append(qc_eyy_, [1, 2]); qc.append(qc_exx_, [1, 2])
    qc.rx(-2*th, [1,2])
    qc.rz(2*ph, [0,1])
    qc.append(qc_ezz_, [0, 1]); qc.append(qc_eyy_, [0, 1]); qc.append(qc_exx_, [0, 1])
    qc.rz(-2*ph, [0,1])
    return qc
qc_Bj_zx_ = qc_Bj_zx(math.pi, math.pi/3, math.pi/4); qc_Bj_zx_.draw(output='mpl')

inha visto essa reprovação mas não me dei por conta que nket0 = np.array([[1],[0]]); ket1 = np.array([[0],[1]]); #ket0, ket1
psi0 = np.kron(ket0, np.kron(ket1, ket1)) # initial state to be used for computing the fidelity
t = math.pi
j = 6; print('N. of Trotter steps = ', j+1)
th_max = 2*math.pi; dth = th_max/16; th = np.arange(0, th_max+dth, dth); dim_th = th.shape[0] 
ph_max = 2*math.pi; dph = ph_max/16; ph = np.arange(0, ph_max+dph, dph); dim_ph = ph.shape[0]
for m in range(0, dim_th):
    for n in range(0, dim_ph):
        # quantum circuit
        qc = QuantumCircuit(7)
        qc.x([5, 3]) # prepares the initial state
        qc_Bj_zx_ = qc_Bj_zx(t/(j+1), th[m], ph[n])
        for k in range(0, j+1):
            qc.append(qc_Bj_zx_, [5, 3, 1])
        qstc = state_tomography_circuits(qc, [5, 3, 1])
        # simulation
        job_sim = execute(qstc, backend = simulator, shots = nshots)
        qstf_sim = StateTomographyFitter(job_sim.result(), qstc)
        rho_sim = qstf_sim.fit(method = 'lstsq')
        F_sim = quantum_info.state_fidelity(psi0, rho_sim)
        # simulation with simulated noise and error mitigation
        job_exp = execute(qstc, backend = simulator, shots = nshots, noise_model = noise_model, 
                          basis_gates = basis_gates, coupling_map = coupling_map)
        mitigated_results = meas_fitter.filter.apply(job_exp.result())
        qstf_exp = StateTomographyFitter(mitigated_results, qstc)
        rho_exp = qstf_exp.fit(method = 'lstsq')
        F_exp = quantum_info.state_fidelity(psi0, rho_exp)
        print('th=', th[m], ', ph=', ph[n], ', F_sim=', F_sim, ', F_exp=', F_exp)

def qc_Bj_yx(t, th, ph):
    qc = QuantumCircuit(3, name = 'B_j_zz')
    qc_ezz_ = qc_ezz(t); qc_eyy_ = qc_eyy(t); qc_exx_ = qc_exx(t)
    qc.rx(2*th, [1,2])
    qc.append(qc_ezz_, [1, 2]); qc.append(qc_eyy_, [1, 2]); qc.append(qc_exx_, [1, 2])
    qc.rx(-2*th, [1,2])
    qc.barrier()
    qc.ry(2*ph, [0,1])
    qc.append(qc_ezz_, [0, 1]); qc.append(qc_eyy_, [0, 1]); qc.append(qc_exx_, [0, 1])
    qc.ry(-2*ph, [0,1])
    return qc
qc_Bj_yx_ = qc_Bj_yx(math.pi, math.pi/3, math.pi/4); qc_Bj_yx_.draw(output='mpl')

https://arxiv.org/abs/2204.07816ket0 = np.array([[1],[0]]); ket1 = np.array([[0],[1]]); #ket0, ket1
psi0 = np.kron(ket0, np.kron(ket1, ket1)) # initial state to be used for computing the fidelity
t = math.pi
j = 6; print('N. of Trotter steps = ', j+1)
th_max = 2*math.pi; dth = th_max/16; th = np.arange(0, th_max+dth, dth); dim_th = th.shape[0] 
ph_max = 2*math.pi; dph = ph_max/16; ph = np.arange(0, ph_max+dph, dph); dim_ph = ph.shape[0]
for m in range(0, dim_th):
    for n in range(0, dim_ph):
        # quantum circuit
        qc = QuantumCircuit(7)
        qc.x([5, 3]) # prepares the initial state
        qc_Bj_yx_ = qc_Bj_yx(t/(j+1), th[m], ph[n])
        for k in range(0, j+1):
            qc.append(qc_Bj_yx_, [5, 3, 1])
        qstc = state_tomography_circuits(qc, [5, 3, 1])
        # simulation
        job_sim = execute(qstc, backend = simulator, shots = nshots)
        qstf_sim = StateTomographyFitter(job_sim.result(), qstc)
        rho_sim = qstf_sim.fit(method = 'lstsq')
        F_sim = quantum_info.state_fidelity(psi0, rho_sim)
        # simulation with simulated noise and error mitigation0.34
        job_exp = execute(qstc, backend = simulator, shots = nshots, noise_model = noise_model, 
                          basis_gates = basis_gates, coupling_map = coupling_map)
        mitigated_results = meas_fitter.filter.apply(job_exp.result())
        qstf_exp = StateTomographyFitter(mitigated_results, qstc)
        rho_exp = qstf_exp.fit(method = 'lstsq')
        F_exp = quantum_info.state_fidelity(psi0, rho_exp)
        print('th=', th[m], ', ph=', ph[n], ', F_sim=', F_sim, ', F_exp=', F_exp)

noise_model = NoiseModel.from_backend(device)
basis_gates = noise_model.basis_gates
coupling_map = device.configuration().coupling_map

basis_gates

print(coupling_map)

553/3

