Skip to content

Commit 8628f23

Browse files
Cleanup RB module (#762)
* - remove backend and raw data dependency from RB * fix #727 Co-authored-by: Christopher J. Wood <[email protected]>
1 parent 3e04191 commit 8628f23

File tree

14 files changed

+868
-371
lines changed

14 files changed

+868
-371
lines changed

docs/tutorials/randomized_benchmarking.rst

Lines changed: 105 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Randomized Benchmarking
44
A randomized benchmarking (RB) experiment consists of the generation of
55
random Clifford circuits on the given qubits such that the unitary
66
computed by the circuits is the identity. After running the circuits,
7-
the number of shots resulting in an error (i.e. an output different than
7+
the number of shots resulting in an error (i.e. an output different than
88
the ground state) are counted, and from this data one can infer error
99
estimates for the quantum device, by calculating the Error Per Clifford.
1010
See `Qiskit
@@ -15,8 +15,7 @@ for an explanation on the RB method, which is based on Ref. [1, 2].
1515

1616
import numpy as np
1717
from qiskit_experiments.library import StandardRB, InterleavedRB
18-
from qiskit_experiments.framework import ParallelExperiment
19-
from qiskit_experiments.library.randomized_benchmarking import RBUtils
18+
from qiskit_experiments.framework import ParallelExperiment, BatchExperiment
2019
import qiskit.circuit.library as circuits
2120

2221
# For simulation
@@ -47,7 +46,7 @@ in order to generate the RB circuits and run them on a backend:
4746
sequences are constructed by appending additional Clifford samples to
4847
shorter sequences. The default is ``False``
4948

50-
The analysis results of the RB Experiment includes:
49+
The analysis results of the RB Experiment may include:
5150

5251
- ``EPC``: The estimated Error Per Clifford
5352

@@ -60,6 +59,40 @@ The analysis results of the RB Experiment includes:
6059
Running a 1-qubit RB experiment
6160
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6261

62+
Standard RB experiment will provide you gate errors for every basis gates
63+
constituting averaged Clifford gate. Note that you can only obtain a single EPC value :math:`\cal E`
64+
from a single RB experiment. As such, computing the error values for multiple gates :math:`\{g_i\}`
65+
requires some assumption of contribution of each gate to the total depolarizing error.
66+
This is so called ``gate_error_ratio`` option you can find in analysis options.
67+
68+
Provided that we have :math:`n_i` gates with independent error :math:`e_i` per Clifford,
69+
the total EPC is estimated by the composition of error from every basis gate,
70+
71+
.. math::
72+
73+
{\cal E} = 1 - \prod_{i} (1 - e_i)^{n_i} \sim \sum_{i} n_i e_i + O(e^2),
74+
75+
where :math:`e_i \ll 1` and the higher order terms can be ignored.
76+
77+
We cannot distinguish :math:`e_i` with a single EPC value :math:`\cal E` as explained,
78+
however by defining an error ratio :math:`r_i` with respect to
79+
some standard value :math:`e_0`, we can compute EPG :math:`e_i` for each basis gate.
80+
81+
.. math::
82+
83+
{\cal E} \sim e_0 \sum_{i} n_i r_i
84+
85+
The EPG of :math:`i` th basis gate will be
86+
87+
.. math::
88+
89+
e_i \sim r_i e_0 = \dfrac{r_i{\cal E}}{\sum_{i} n_i r_i}.
90+
91+
Because EPGs are computed based on this simple assumption,
92+
this is not necessary representing the true gate error on the hardware.
93+
If you have multiple kinds of basis gates with unclear error ratio :math:`r_i`,
94+
interleaved RB experiment will always give you accurate error value :math:`e_i`.
95+
6396
.. jupyter-execute::
6497

6598
lengths = np.arange(1, 800, 200)
@@ -73,6 +106,7 @@ Running a 1-qubit RB experiment
73106
results1 = expdata1.analysis_results()
74107

75108
# View result data
109+
print("Gate error ratio: %s" % expdata1.experiment.analysis.options.gate_error_ratio)
76110
display(expdata1.figure(0))
77111
for result in results1:
78112
print(result)
@@ -82,55 +116,92 @@ Running a 1-qubit RB experiment
82116
Running a 2-qubit RB experiment
83117
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84118

85-
Running a 1-qubit RB experiment and a 2-qubit RB experiment, in order to
86-
calculate the gate error (EPG) of the ``cx`` gate:
119+
In the same way we can compute EPC for two-qubit RB experiment.
120+
However, the EPC value obtained by the experiment indicates a depolarization
121+
which is a composition of underlying error channels for 2Q gates and 1Q gates in each qubit.
122+
Usually 1Q gate contribution is small enough to ignore, but in case this
123+
contribution is significant comparing to the 2Q gate error,
124+
we can decompose the contribution of 1Q gates [3].
125+
126+
.. math::
127+
128+
\alpha_{2Q,C} = \frac{1}{5} \left( \alpha_0^{N_1/2} + \alpha_1^{N_1/2} +
129+
3 \alpha_0^{N_1/2} \alpha_1^{N_1/2} \right) \alpha_{01}^{N_2},
130+
131+
where :math:`\alpha_i` is the single qubit depolarizing parameter of channel :math:`i`,
132+
and :math:`\alpha_{01}` is the two qubit depolarizing parameter of interest.
133+
:math:`N_1` and :math:`N_2` are total count of single and two qubit gates, respectively.
134+
135+
Note that the single qubit gate sequence in the channel :math:`i` may consist of
136+
multiple kinds of basis gates :math:`\{g_{ij}\}` with different EPG :math:`e_{ij}`.
137+
Therefore the :math:`\alpha_i^{N_1/2}` should be computed from EPGs,
138+
rather than directly using the :math:`\alpha_i`, which is usually a composition of
139+
depolarizing maps of every single qubit gate.
140+
As such, EPGs should be measured in the separate single-qubit RBs in advance.
141+
142+
.. math::
143+
144+
\alpha_i^{N_1/2} = \alpha_{i0}^{n_{i0}} \cdot \alpha_{i1}^{n_{i1}} \cdot ...,
145+
146+
where :math:`\alpha_{ij}^{n_{ij}}` indicates a depolarization due to
147+
a particular basis gate :math:`j` in the channel :math:`i`.
148+
Here we assume EPG :math:`e_{ij}` corresponds to the depolarizing probability
149+
of the map of :math:`g_{ij}`, and thus we can express :math:`\alpha_{ij}` with EPG.
150+
151+
.. math::
152+
153+
e_{ij} = \frac{2^n - 1}{2^n} (1 - \alpha_{ij}) = \frac{1 - \alpha_{ij}}{2},
154+
155+
for the single qubit channel :math:`n=1`. Accordingly,
156+
157+
.. math::
158+
159+
\alpha_i^{N_1/2} = \prod_{j} (1 - 2 e_{ij})^{n_{ij}},
160+
161+
as a composition of depolarization from every primitive gates per qubit.
162+
This correction will give you two EPC values as a result of the two-qubit RB experiment.
163+
The corrected EPC must be closer to the outcome of of interleaved RB.
164+
The EPGs of two-qubit RB are analyzed with the corrected EPC if available.
87165

88166
.. jupyter-execute::
89167

90-
lengths = np.arange(1, 200, 30)
168+
lengths_2_qubit = np.arange(1, 200, 30)
169+
lengths_1_qubit = np.arange(1, 800, 200)
91170
num_samples = 10
92171
seed = 1010
93-
qubits = (1,4)
94-
172+
qubits = (1, 4)
173+
95174
# Run a 1-qubit RB expriment on qubits 1, 4 to determine the error-per-gate of 1-qubit gates
96-
expdata_1q = {}
97-
epg_1q = []
98-
lengths_1_qubit = np.arange(1, 800, 200)
99-
for qubit in qubits:
100-
exp = StandardRB([qubit], lengths_1_qubit, num_samples=num_samples, seed=seed)
101-
expdata = exp.run(backend).block_for_results()
102-
expdata_1q[qubit] = expdata
103-
epg_1q += expdata.analysis_results()
175+
single_exps = BatchExperiment(
176+
[
177+
StandardRB([qubit], lengths_1_qubit, num_samples=num_samples, seed=seed)
178+
for qubit in qubits
179+
],
180+
flatten_results=True,
181+
)
182+
expdata_1q = single_exps.run(backend).block_for_results()
183+
104184

105185
.. jupyter-execute::
106186

107187
# Run an RB experiment on qubits 1, 4
108-
exp2 = StandardRB(qubits, lengths, num_samples=num_samples, seed=seed)
188+
exp_2q = StandardRB(qubits, lengths_2_qubit, num_samples=num_samples, seed=seed)
109189

110190
# Use the EPG data of the 1-qubit runs to ensure correct 2-qubit EPG computation
111-
exp2.analysis.set_options(epg_1_qubit=epg_1q)
191+
exp_2q.analysis.set_options(epg_1_qubit=expdata_1q.analysis_results())
112192

113193
# Run the 2-qubit experiment
114-
expdata2 = exp2.run(backend).block_for_results()
115-
116-
# View result data
117-
results2 = expdata2.analysis_results()
118-
119-
.. jupyter-execute::
194+
expdata_2q = exp_2q.run(backend).block_for_results()
120195

121196
# View result data
122-
display(expdata2.figure(0))
123-
for result in results2:
197+
print("Gate error ratio: %s" % expdata_2q.experiment.analysis.options.gate_error_ratio)
198+
display(expdata_2q.figure(0))
199+
for result in expdata_2q.analysis_results():
124200
print(result)
125201

126-
.. jupyter-execute::
127202

128-
# Compare the computed EPG of the cx gate with the backend's recorded cx gate error:
129-
expected_epg = RBUtils.get_error_dict_from_backend(backend, qubits)[(qubits, 'cx')]
130-
exp2_epg = expdata2.analysis_results("EPG_cx").value
131-
132-
print("Backend's reported EPG of the cx gate:", expected_epg)
133-
print("Experiment computed EPG of the cx gate:", exp2_epg)
203+
Note that ``EPC_corrected`` value is smaller than one of raw ``EPC``, which indicates
204+
contribution of depolarization from single-qubit error channels.
134205

135206

136207
Displaying the RB circuits
@@ -253,12 +324,6 @@ different qubits (see Ref. [5])
253324
par_exp = ParallelExperiment(exps)
254325
par_expdata = par_exp.run(backend).block_for_results()
255326
par_results = par_expdata.analysis_results()
256-
257-
# View result data
258-
for result in par_results:
259-
print(result)
260-
print("\nextra:")
261-
print(result.extra)
262327

263328

264329
Viewing sub experiment data

qiskit_experiments/curve_analysis/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
guess.constant_sinusoidal_offset
9191
guess.constant_spectral_offset
9292
guess.exp_decay
93+
guess.rb_decay
9394
guess.full_width_half_max
9495
guess.frequency
9596
guess.max_height

0 commit comments

Comments
 (0)