<jupyter_start><jupyter_text>Quantum State Tomography* **Last Updated:** Feb 20, 2019* **Requires:** qiskit-terra 0.7<jupyter_code># Needed for functions
import numpy as np
import time

# Import Qiskit classes
import qiskit 
from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister, Aer
from qiskit.quantum_info import state_fidelity
from qiskit.providers.aer import noise

# Tomography functions
import sys, os
sys.path.append(os.path.abspath(os.path.join('..')))
import qiskit.ignis.verification.tomography as tomo
import qiskit.ignis.error_mitigation.measurement as mc<jupyter_output><empty_output><jupyter_text>2-Qubit state tomography Example<jupyter_code># Create a state preparation circuit
q2 = QuantumRegister(2)
bell = QuantumCircuit(q2)
bell.h(q2[0])
bell.cx(q2[0], q2[1])
print(bell.qasm())

job = qiskit.execute(bell, Aer.get_backend('statevector_simulator'))
psi_bell = job.result().get_statevector(bell)
print(psi_bell)
# Generate circuits and run on simulator
t = time.time()
qst_bell = tomo.state_tomography_circuits(bell, q2)
job = qiskit.execute(qst_bell, Aer.get_backend('qasm_simulator'), shots=5000)
print('Time taken:', time.time() - t)

# Extract tomography data so that countns are indexed by measurement configuration
# Note that the None labels are because this is state tomography instead of process tomography
# Process tomography would have the preparation state labels there

tomo_counts_bell = tomo.tomography_data(job.result(), qst_bell)
tomo_counts_bell
# Generate fitter data and reconstruct density matrix
probs_bell, basis_matrix_bell, weights_bell = tomo.fitter_data(tomo_counts_bell)
rho_bell = tomo.state_cvx_fit(probs_bell, basis_matrix_bell, weights_bell)
F_bell = state_fidelity(psi_bell, rho_bell)
print('Fit Fidelity =', F_bell)<jupyter_output>Fit Fidelity = 0.9999419228568267<jupyter_text>Repeat the Example with Measurement Noise<jupyter_code>#Add measurement noise
noise_model = noise.NoiseModel()
for qi in range(2):
    read_err = noise.errors.readout_error.ReadoutError([[0.75, 0.25],[0.1,0.9]])
    noise_model.add_readout_error(read_err,[qi])
    
#generate the calibration circuits
meas_calibs, state_labels = mc.measurement_calibration(qr=q2)

backend = Aer.get_backend('qasm_simulator')
qobj_cal = qiskit.compile(meas_calibs, backend=backend, shots=15000)
qobj_tomo = qiskit.compile(qst_bell, backend=backend, shots=15000)

job_cal = backend.run(qobj_cal, noise_model=noise_model)
job_tomo = backend.run(qobj_tomo, noise_model=noise_model)

MeasCal = mc.MeasurementFitter(job_cal.result(),state_labels)
tomo_counts_bell = tomo.tomography_data(job_tomo.result(), qst_bell)

# Generate fitter data and reconstruct density matrix
probs_bell, basis_matrix_bell, weights_bell = tomo.fitter_data(tomo_counts_bell)

#no correction
rho_bell = tomo.state_cvx_fit(probs_bell, basis_matrix_bell, weights_bell)
F_bell = state_fidelity(psi_bell, rho_bell)
print('Fit Fidelity (no correction) =', F_bell)

#correct data
probs_bell = MeasCal.calibrate(probs_bell, method=1)
rho_bell = tomo.state_cvx_fit(probs_bell, basis_matrix_bell, weights_bell)
F_bell = state_fidelity(psi_bell, rho_bell)
print('Fit Fidelity (w/ correction) =', F_bell)<jupyter_output>Fit Fidelity (no correction) = 0.5722696020964947
Fit Fidelity (w/ correction) = 0.9912583476271389<jupyter_text>Generating and fitting random statesWe now test the functions on state generated by a circuit consiting of a layer of random single qubit unitaries u3<jupyter_code>def random_u3_tomo(nq, shots):
    
    def rand_angles():
        return tuple(2 * np.pi * np.random.random(3) - np.pi)
    q = QuantumRegister(nq)
    circ = QuantumCircuit(q)
    for j in range(nq):
        circ.u3(*rand_angles(), q[j])
    job = qiskit.execute(circ, Aer.get_backend('statevector_simulator'))
    psi_rand = job.result().get_statevector(circ)
    
    qst_circs = tomo.state_tomography_circuits(circ, q)
    job = qiskit.execute(qst_circs, Aer.get_backend('qasm_simulator'),
                         shots=shots)
    tomo_counts = tomo.tomography_data(job.result(), qst_circs)
    probs, basis_matrix, weights = tomo.fitter_data(tomo_counts, beta=0.5)
    
    rho_cvx = tomo.state_cvx_fit(probs, basis_matrix, weights)
    rho_mle = tomo.state_mle_fit(probs, basis_matrix, weights)
    
    print('F fit (CVX) =', state_fidelity(psi_rand, rho_cvx))
    print('F fit (MLE) =', state_fidelity(psi_rand, rho_mle))
for j in range(5):
    print('Random single-qubit unitaries: set {}'.format(j))
    random_u3_tomo(3, 5000)<jupyter_output>Random single-qubit unitaries: set 0
F fit (CVX) = 0.996372003713741
F fit (MLE) = 0.9924743894012955
Random single-qubit unitaries: set 1
F fit (CVX) = 0.9998028756769166
F fit (MLE) = 0.9970505822524109
Random single-qubit unitaries: set 2
F fit (CVX) = 0.9929243725666841
F fit (MLE) = 0.9915540566134604
Random single-qubit unitaries: set 3
F fit (CVX) = 0.997715191175975
F fit (MLE) = 0.9951079774538191
Random single-qubit unitaries: set 4
F fit (CVX) = 0.9983143670333272
F fit (MLE) = 0.9988766200849537<jupyter_text>5-Qubit Bell State<jupyter_code># Create a state preparation circuit
q5 = QuantumRegister(5)
bell5 = QuantumCircuit(q5)
bell5.h(q5[0])
for j in range(4):
    bell5.cx(q5[j], q5[j + 1])

# Get ideal output state
job = qiskit.execute(bell5, Aer.get_backend('statevector_simulator'))
psi_bell5 = job.result().get_statevector(bell5)

# Generate circuits and run on simulator
t = time.time()
qst_bell5 = tomo.state_tomography_circuits(bell5, q5)
job = qiskit.execute(qst_bell5, Aer.get_backend('qasm_simulator'), shots=5000)

# Extract tomography data so that countns are indexed by measurement configuration
tomo_counts_bell5 = tomo.tomography_data(job.result(), qst_bell5)
probs_bell5, basis_matrix_bell5, weights_bell5 = tomo.fitter_data(tomo_counts_bell5)
print('Time taken:', time.time() - t)
t = time.time()
rho_mle_bell5 = tomo.state_mle_fit(probs_bell5, basis_matrix_bell5, weights_bell5)
print('MLE Reconstruction')
print('Time taken:', time.time() - t)
print('Fit Fidelity:', state_fidelity(psi_bell5, rho_mle_bell5))
t = time.time()
rho_sdp_bell5 = tomo.state_cvx_fit(probs_bell5, basis_matrix_bell5, weights_bell5, solver='CVXOPT')
print('SDP Reconstruction')
print('Time taken:', time.time() - t)
print('Fidelity:', state_fidelity(psi_bell5, rho_sdp_bell5))<jupyter_output>SDP Reconstruction
Time taken: 42.37651491165161
Fidelity: 0.9999138790152728
{'fraction_non_alphanumeric': 0.10844873191224522, 'fraction_numerical': 0.05585809864633577, 'mean_word_length': 6.279728199320498, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '418019', 'license': 'Apache-2.0', 'n_tokens_mistral': 2636, 'n_tokens_neox': 2375, 'n_words': 512, 'path': 'examples/state-tomography.ipynb', 'repo_name': 'ajavadia/qiskit-ignis', 'size': '6427'}