<jupyter_start><jupyter_text>Process tomographyQuantum process tomography involves - preparing a state - executing a process - measuring in a basis The process is kept fixed, while the experimental settings ((prep, measure) tuples) are varied. You first choose a suitable set of input states and measurement operators, and then run every `itertools.product` combinations of settings.For input states, we choose the SIC basis comprised of four states, and wee measure in the Pauli basis. The scalling w.r.t. number of qubits is therefore $4^n 3^n$, which is very exponential. If you use the $\pm$ eigenstates of the pauli operators, it scales as $6^n 3^n$.<jupyter_code>import numpy as np
from pyquil import Program, get_qc
from pyquil.gates import *<jupyter_output><empty_output><jupyter_text>Construct a processWhich is represented as a pyQuil `Program`<jupyter_code>qubits = [0]
process = Program(RX(np.pi, qubits[0]))
print(process)<jupyter_output><empty_output><jupyter_text>Construct a `TomographyExperiment` for process tomographyThe `I` basis measurements are redundant, and can be grouped with other terms (see below).<jupyter_code>from forest_benchmarking.tomography import generate_process_tomography_experiment
experiment = generate_process_tomography_experiment(process, qubits)
print(experiment)<jupyter_output><empty_output><jupyter_text>PyQuil will run the tomography programs<jupyter_code>from pyquil.operator_estimation import measure_observables

qc = get_qc('2q-pyqvm')
# Over-write full quilc compilation with a much more simple
# version that *only* substitutes gates to Rigetti-native gates.
# We don't want to accidentally compile away our tomography circuit
# or map to different qubits.
from forest_benchmarking.compilation import basic_compile
qc.compiler.quil_to_native_quil = basic_compile

results = list(measure_observables(qc=qc, tomo_experiment=experiment, n_shots=100_000))
results<jupyter_output><empty_output><jupyter_text>PGDB Estimate<jupyter_code>from forest_benchmarking.tomography import pgdb_process_estimate
process_choi_est = pgdb_process_estimate(results, qubits)
np.real_if_close(np.round(process_choi_est, 2))
from forest_benchmarking.superop_conversion import kraus2choi
from pyquil.gate_matrices import X as X_matrix
process_choi_ideal = kraus2choi(X_matrix)
np.real_if_close(np.round(process_choi_ideal))<jupyter_output><empty_output><jupyter_text>Plot Pauli Transfer Matrix of Estimate<jupyter_code>import matplotlib.pyplot as plt
from forest_benchmarking.superop_conversion import choi2pauli_liouville
from forest_benchmarking.tomography import plot_pauli_transfer_matrix

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12,5))
plot_pauli_transfer_matrix(choi2pauli_liouville(process_choi_ideal), ax1, title='Ideal')
plot_pauli_transfer_matrix(choi2pauli_liouville(process_choi_est), ax2, title='Estimate')
plt.tight_layout()<jupyter_output><empty_output><jupyter_text>Two qubit example - CNOT<jupyter_code>qubits = [0, 1]
process = Program(CNOT(qubits[0], qubits[1]))
experiment = generate_process_tomography_experiment(process, qubits)
print(experiment)
results = list(measure_observables(qc=qc, tomo_experiment=experiment, n_shots=100_000))
results[:10]
def _print_big_matrix(mat):
    for row in mat:
        for elem in row:
            elem = np.real_if_close(np.round(elem, 2))
            if elem != 0:
                print(f'{elem:.1f}', end=' ')
            else:
                print(' . ', end=' ')
        print()
process_choi_est = pgdb_process_estimate(results, qubits)
_print_big_matrix(process_choi_est)
from pyquil.gate_matrices import CNOT as CNOT_matrix
process_choi_ideal = kraus2choi(CNOT_matrix)
_print_big_matrix(process_choi_ideal)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12,5))
plot_pauli_transfer_matrix(choi2pauli_liouville(process_choi_ideal), ax1, title='Ideal')
plot_pauli_transfer_matrix(choi2pauli_liouville(process_choi_est), ax2, title='Estimate')
plt.tight_layout()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08575727181544635, 'fraction_numerical': 0.013791374122367101, 'mean_word_length': 7.25879917184265, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, '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': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '50824', 'license': 'Apache-2.0', 'n_tokens_mistral': 1387, 'n_tokens_neox': 1304, 'n_words': 316, 'path': 'examples/tomography_process.ipynb', 'repo_name': 'msohaibalam/forest-benchmarking', 'size': '3988'}