#
# Copyright 2021 Quantum Benchmark Inc.
#
"""
K-body Noise Reconstruction (KNR)
=================================
"""
#%%
# This example illustrates how to generate k-body noise reconstruction (:tqdoc:`KNR`\)
# circuits and use them to estimate the probability distribution of stochastic Pauli
# errors afflicting the cycle being benchmarked. While this example uses a
# :doc:`simulator<../../guides/run/simulator>` to execute the circuits, the same
# procedure can be followed for hardware applications.
import trueq as tq
import trueq.simulation as tqs
# Define the cycle to benchmark using KNR.
cycle = tq.Cycle({label: tq.Gate.id for label in range(4)})
# Generate KNR circuits to benchmark the cycle, targeting only single body interactions,
# and 30 circuits for each length in [4, 32, 64].
circuits = tq.make_knr(cycle, n_random_cycles=[4, 32, 64], n_circuits=30, n_bodies=1)
# Initialize a simulator with stochastic Pauli noise, with worse noise on qubit 3.
sim = tq.Simulator()
sim.add_stochastic_pauli(px=0.005, py=0.005)
sim.add_stochastic_pauli(pz=0.01, match=tqs.LabelMatch(3))
# Run the circuits on the simulator to populate the results.
sim.run(circuits)
#%%
# Display a table of KNR estimates:
circuits.fit()
#%%
# Plot the results:
circuits.plot.knr_heatmap()
#%%
# From above, you can see that the largest single-qubit error is a :math:`Z` error on
# qubit ``3``, whose probability is approximately twice as large as the next leading
# single-qubit error. The probability of a :math:`Z` error on any other qubit is very
# low since we would have to have both an :math:`X` and a :math:`Y` error acting on
# that qubit for a :math:`Z` error to arise. This is exactly as expected given the
# noise defined by the simulator in this example.
#
# In the example above KNR was ran on only single body terms, below we run KNR on two
# body terms, for more details see :tqdoc:`KNR`\.
# Generate KNR circuits to benchmark the cycle, but now targeting both single and two
# body interactions, with 30 circuits for each length in [4, 12, 32].
circuits = tq.make_knr(cycle, [4, 12, 32], n_circuits=30, n_bodies=2)
# Run the circuits on the simulator to populate the results.
sim.run(circuits)
# Plot the results:
circuits.plot.knr_heatmap()
#%%
# As before, the Pauli error with the highest probability is a :math:`Z` error on qubit
# ``3`` and the other most-likely errors are weight 1. This is as expected based on our
# simple simulator model used in this example.