Skip to content
This repository was archived by the owner on Aug 21, 2023. It is now read-only.

Commit de7ca35

Browse files
dcmckayibmjaygambetta
authored andcommitted
Move ignis files to tutorials (#551)
1 parent e32d94e commit de7ca35

File tree

7 files changed

+3548
-0
lines changed

7 files changed

+3548
-0
lines changed

community/ignis/RB_overview.ipynb

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Randomized Benchmarking Overview\n",
8+
"\n",
9+
"### Contributors\n",
10+
"\n",
11+
"Shelly Garion$^{1}$, Yael Ben-Haim$^{2}$ and David McKay$^{2}$\n",
12+
"\n",
13+
"1. IBM Research Haifa, Haifa University Campus, Mount Carmel Haifa, Israel\n",
14+
"2. IBM T.J. Watson Research Center, Yorktown Heights, NY, USA\n",
15+
"\n",
16+
"### References\n",
17+
"\n",
18+
"1. Easwar Magesan, J. M. Gambetta, and Joseph Emerson, Robust randomized benchmarking of quantum processes,\n",
19+
"https://arxiv.org/pdf/1009.3639\n",
20+
"\n",
21+
"2. Easwar Magesan,, Jay M. Gambetta, and Joseph Emerson, Characterizing Quantum Gates via Randomized Benchmarking,\n",
22+
"https://arxiv.org/pdf/1109.6887\n",
23+
"\n",
24+
"3. A. D. C'orcoles, Jay M. Gambetta, Jerry M. Chow, John A. Smolin, Matthew Ware, J. D. Strand, B. L. T. Plourde, and M. Steffen, Supplementary material for ''Process verification of two-qubit quantum gates by randomized benchmarking'', https://arxiv.org/pdf/1210.7011\n",
25+
"\n",
26+
"4. Jay M. Gambetta, A. D. C´orcoles, S. T. Merkel, B. R. Johnson, John A. Smolin, Jerry M. Chow,\n",
27+
"Colm A. Ryan, Chad Rigetti, S. Poletto, Thomas A. Ohki, Mark B. Ketchen, and M. Steffen,\n",
28+
"Characterization of addressability by simultaneous randomized benchmarking, https://arxiv.org/pdf/1204.6308\n",
29+
"\n",
30+
"5. David C. McKay, Sarah Sheldon, John A. Smolin, Jerry M. Chow, and Jay M. Gambetta, Three Qubit Randomized Benchmarking,\n",
31+
"https://arxiv.org/pdf/1712.06550"
32+
]
33+
},
34+
{
35+
"cell_type": "markdown",
36+
"metadata": {},
37+
"source": [
38+
"## Intorduction\n",
39+
"\n",
40+
"One of the main challenges in building a quantum information processor is the non-scalability of completely\n",
41+
"characterizing the noise affecting a quantum system via process tomography. In addition, process tomography is sensitive to noise in the pre- and post rotation gates plus the measurements (SPAM errors). Gateset tomography can take these errors into account, but the scaling is even worse. A complete characterization\n",
42+
"of the noise is useful because it allows for the determination of good error-correction schemes, and thus\n",
43+
"the possibility of reliable transmission of quantum information.\n",
44+
"\n",
45+
"Since complete process tomography is infeasible for large systems, there is growing interest in scalable\n",
46+
"methods for partially characterizing the noise affecting a quantum system. A scalable (in the number $n$ of qubits comprising the system) and robust algorithm for benchmarking the full set of Clifford gates by a single parameter using randomization techniques was presented in [1]. The concept of using randomization methods for benchmarking quantum gates is commonly called **Randomized Benchmarking\n",
47+
"(RB)**."
48+
]
49+
},
50+
{
51+
"cell_type": "markdown",
52+
"metadata": {},
53+
"source": [
54+
"## The Randomized Benchmarking Protocol\n",
55+
"\n",
56+
"A RB protocol consists of the following steps:\n",
57+
"\n",
58+
"(We should first import the relevant qiskit classes for the demonstration)."
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": 5,
64+
"metadata": {},
65+
"outputs": [],
66+
"source": [
67+
"#Import general libraries (needed for functions)\n",
68+
"import numpy as np\n",
69+
"import matplotlib.pyplot as plt\n",
70+
"from IPython import display\n",
71+
"\n",
72+
"#Import Qiskit classes classes\n",
73+
"import qiskit\n",
74+
"from qiskit.providers.aer.noise import NoiseModel\n",
75+
"from qiskit.providers.aer.noise.errors.standard_errors import depolarizing_error, thermal_relaxation_error\n",
76+
"\n",
77+
"#Import the RB Functions\n",
78+
"import qiskit.ignis.verification.randomized_benchmarking as rb"
79+
]
80+
},
81+
{
82+
"cell_type": "markdown",
83+
"metadata": {},
84+
"source": [
85+
"### Step 1: Generate RB sequences\n",
86+
"\n",
87+
"The RB sequences consist of random Clifford elements chosen uniformly from the Clifford group on $n$-qubits, \n",
88+
"including a computed reversal element,\n",
89+
"that should return the qubits to the initial state.\n",
90+
"\n",
91+
"More precisely, for each length $m$, we choose $K_m$ RB sequences. \n",
92+
"Each such sequence contains $m$ random elements $C_{i_j}$ chosen uniformly from the Clifford group on $n$-qubits, and the $m+1$ element is defined as follows: $C_{i_{m+1}} = (C_{i_1}\\cdot ... \\cdot C_{i_m})^{-1}$.\n",
93+
"\n",
94+
"For example, we generate below several sequences of 2-qubit Clifford circuits."
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": 9,
100+
"metadata": {},
101+
"outputs": [],
102+
"source": [
103+
"#Generate RB circuits (2Q RB)\n",
104+
"\n",
105+
"#number of qubits\n",
106+
"nQ=2 \n",
107+
"rb_opts = {}\n",
108+
"#Number of Cliffords in the sequence\n",
109+
"rb_opts['length_vector'] = [1, 10, 20, 50, 75, 100, 125]\n",
110+
"#Number of seeds (random sequences)\n",
111+
"rb_opts['nseeds'] = 5 \n",
112+
"#Default pattern\n",
113+
"rb_opts['rb_pattern'] = [[0,1]]\n",
114+
"\n",
115+
"rb_circs, xdata = rb.randomized_benchmarking_seq(**rb_opts)"
116+
]
117+
},
118+
{
119+
"cell_type": "markdown",
120+
"metadata": {},
121+
"source": [
122+
"As an example, we print the circuit corresponding to the first RB sequence"
123+
]
124+
},
125+
{
126+
"cell_type": "code",
127+
"execution_count": 11,
128+
"metadata": {},
129+
"outputs": [
130+
{
131+
"name": "stdout",
132+
"output_type": "stream",
133+
"text": [
134+
" ┌───┐┌─────┐┌───┐ ┌───┐┌───┐┌───┐ ░ ┌───┐┌─────┐»\n",
135+
"qr_0: |0>┤ H ├┤ Sdg ├┤ H ├──■───────────────────┤ H ├┤ S ├┤ X ├─░─┤ X ├┤ Sdg ├»\n",
136+
" └───┘└─────┘└───┘┌─┴─┐┌─────┐┌───┐┌───┐└───┘└───┘└───┘ ░ └───┘└─────┘»\n",
137+
"qr_1: |0>─────────────────┤ X ├┤ Sdg ├┤ H ├┤ X ├────────────────░─────────────»\n",
138+
" └───┘└─────┘└───┘└───┘ ░ »\n",
139+
" cr_0: 0 ═════════════════════════════════════════════════════════════════════»\n",
140+
" »\n",
141+
" cr_1: 0 ═════════════════════════════════════════════════════════════════════»\n",
142+
" »\n",
143+
"« ┌───┐ ┌───┐┌───┐┌───┐┌─┐\n",
144+
"«qr_0: ┤ H ├─────────────────■─────┤ H ├┤ S ├┤ H ├┤M├\n",
145+
"« └───┘┌───┐┌───┐┌───┐┌─┴─┐┌─┐└───┘└───┘└───┘└╥┘\n",
146+
"«qr_1: ─────┤ X ├┤ H ├┤ S ├┤ X ├┤M├────────────────╫─\n",
147+
"« └───┘└───┘└───┘└───┘└╥┘ ║ \n",
148+
"«cr_0: ══════════════════════════╬═════════════════╩═\n",
149+
"« ║ \n",
150+
"«cr_1: ══════════════════════════╩═══════════════════\n",
151+
"« \n"
152+
]
153+
}
154+
],
155+
"source": [
156+
"print(rb_circs[0][0])"
157+
]
158+
},
159+
{
160+
"cell_type": "markdown",
161+
"metadata": {},
162+
"source": [
163+
"One can verify that the Unitary representing each RB circuit should be the identity (with a global phase). \n",
164+
"We simulate this using Aer unitary simulator."
165+
]
166+
},
167+
{
168+
"cell_type": "code",
169+
"execution_count": 10,
170+
"metadata": {},
171+
"outputs": [],
172+
"source": [
173+
"#Create a new circuit without the measurement\n",
174+
"qc = qiskit.QuantumCircuit(*rb_circs[0][-1].qregs,*rb_circs[0][-1].cregs)\n",
175+
"for i in rb_circs[0][-1][0:-nQ]:\n",
176+
" qc._attach(i)"
177+
]
178+
},
179+
{
180+
"cell_type": "code",
181+
"execution_count": 12,
182+
"metadata": {},
183+
"outputs": [],
184+
"source": [
185+
"#Create a new circuit without the measurement\n",
186+
"qc = qiskit.QuantumCircuit(*rb_circs[0][-1].qregs,*rb_circs[0][-1].cregs)\n",
187+
"for i in rb_circs[0][-1][0:-nQ]:\n",
188+
" qc._attach(i)"
189+
]
190+
},
191+
{
192+
"cell_type": "code",
193+
"execution_count": 13,
194+
"metadata": {},
195+
"outputs": [
196+
{
197+
"name": "stdout",
198+
"output_type": "stream",
199+
"text": [
200+
"[[-0.707-0.707j 0. +0.j 0. +0.j 0. +0.j ]\n",
201+
" [ 0. -0.j -0.707-0.707j -0. +0.j 0. +0.j ]\n",
202+
" [ 0. +0.j 0. +0.j -0.707-0.707j 0. +0.j ]\n",
203+
" [ 0. -0.j 0. +0.j 0. +0.j -0.707-0.707j]]\n"
204+
]
205+
}
206+
],
207+
"source": [
208+
"#The Unitary is an identity (with a global phase)\n",
209+
"backend = qiskit.Aer.get_backend('unitary_simulator')\n",
210+
"basis_gates = ['u1','u2','u3','cx'] # use U,CX for now\n",
211+
"basis_gates_str = ','.join(basis_gates)\n",
212+
"job = qiskit.execute(qc, backend=backend, basis_gates=basis_gates_str)\n",
213+
"print(np.around(job.result().get_unitary(),3))"
214+
]
215+
},
216+
{
217+
"cell_type": "markdown",
218+
"metadata": {},
219+
"source": [
220+
"### Step 2: Execute the RB sequences (with some noise)\n",
221+
"\n",
222+
"We can execute the RB sequences either using Qiskit Aer Simulator (with some noise model) or using IBMQ provider, and obtain a list of results.\n",
223+
"\n",
224+
"By assumption each operation $C_{i_j}$ is allowed to have some error, represnted by $\\Lambda_{i_j,j}$, and each sequence can be modeled by the operation:\n",
225+
"$$\\textit{S}_{\\textbf{i}_\\textbf{m}} = \\bigcirc_{j=1}^{m+1} (\\Lambda_{i_j,j} \\circ C_{i_j})$$\n",
226+
"where ${\\textbf{i}_\\textbf{m}} = (i_1,...,i_m)$ and $i_{m+1}$ is uniquely determined by ${\\textbf{i}_\\textbf{m}}$."
227+
]
228+
},
229+
{
230+
"cell_type": "code",
231+
"execution_count": 14,
232+
"metadata": {},
233+
"outputs": [],
234+
"source": [
235+
"# Run on a noisy simulator\n",
236+
"noise_model = NoiseModel()\n",
237+
"noise_model.add_all_qubit_quantum_error(depolarizing_error(0.002, 1), ['u1', 'u2', 'u3'])\n",
238+
"noise_model.add_all_qubit_quantum_error(depolarizing_error(0.002, 2), 'cx')\n",
239+
"\n",
240+
"backend = qiskit.Aer.get_backend('qasm_simulator')\n",
241+
"basis_gates = 'u1,u2,u3,cx'\n",
242+
"result_list = []"
243+
]
244+
},
245+
{
246+
"cell_type": "markdown",
247+
"metadata": {},
248+
"source": [
249+
"### Step 3: Get statistics about the survival probabilities\n",
250+
"\n",
251+
"For each of the $K_m$ sequences the survival probability $Tr[E_\\psi \\textit{S}_{\\textbf{i}_\\textbf{m}}(\\rho_\\psi)]$\n",
252+
"is measured. \n",
253+
"Here $\\rho_\\psi$ is the initial state taking into account preparation errors and $E_\\psi$ is the\n",
254+
"POVM element that takes into account measurement errors.\n",
255+
"In the ideal (noise-free) case $\\rho_\\psi = E_\\psi = |\\psi \\rangle \\langle \\psi|$. \n",
256+
"\n",
257+
"In practice one can measure the probability to go back to the exact initial state, i.e. all the qubits in the ground state ($|00...0\\rangle$) or just the probability for one of the qubits to return back to the ground state. Measuring the qubits independently can be more convenient if a correlated measurement scheme is not possible. Both measurements will fit to the same decay parameter according to the properties of the twirl. "
258+
]
259+
},
260+
{
261+
"cell_type": "markdown",
262+
"metadata": {},
263+
"source": [
264+
"### Step 4: Find the averaged sequence fidelity\n",
265+
"\n",
266+
"Average over the $K_m$ random realizations to find the averaged sequence **fidelity**,\n",
267+
"$$F_{seq}(m,\\psi) = Tr[E_\\psi \\textit{S}_{K_m}(\\rho_\\psi)]$$\n",
268+
"where \n",
269+
"$$\\textit{S}_{K_m} = \\frac{1}{K_m} \\sum_{\\textbf{i}_\\textbf{m}} \\textit{S}_{\\textbf{i}_\\textbf{m}}$$"
270+
]
271+
},
272+
{
273+
"cell_type": "markdown",
274+
"metadata": {},
275+
"source": [
276+
"### Step 5: Fit the results\n",
277+
"\n",
278+
"Repeat Steps 1 through 4 for different values of $m$ and fit the\n",
279+
"Fit the results for the averaged sequence delity to the model:\n",
280+
"$$ \\textit{F}_g(m,|\\psi \\rangle ) = A_0 p^m +B_0$$\n",
281+
"where $A_0$ and $B_0$ absorb state preparation and measurement errors as well as an edge effect from the\n",
282+
"error on the final gate.\n",
283+
"\n",
284+
"$p$ determines the average error-rate $r$, which is also called **Error per Clifford (EPC)** \n",
285+
"according to the relation $$ r = 1-p-\\frac{1-p}{2^n} = \\frac{2^n-1}{2^n}(1-p)$$"
286+
]
287+
},
288+
{
289+
"cell_type": "code",
290+
"execution_count": 16,
291+
"metadata": {},
292+
"outputs": [
293+
{
294+
"name": "stdout",
295+
"output_type": "stream",
296+
"text": [
297+
"After seed 0, EPC 0.011154\n",
298+
"After seed 1, EPC 0.011494\n",
299+
"After seed 2, EPC 0.010545\n",
300+
"After seed 3, EPC 0.011478\n",
301+
"After seed 4, EPC 0.011082\n"
302+
]
303+
}
304+
],
305+
"source": [
306+
"#Create the RB fitter\n",
307+
"rb_fit = rb.RBFitter(None, xdata, rb_opts['rb_pattern'])\n",
308+
"for rb_seed,rb_circ_seed in enumerate(rb_circs):\n",
309+
" qobj = qiskit.compile(rb_circ_seed,\n",
310+
" backend=backend,\n",
311+
" basis_gates=basis_gates)\n",
312+
" job = backend.run(qobj, noise_model=noise_model)\n",
313+
"\n",
314+
" #add data to the fitter\n",
315+
" rb_fit.add_data(job.result())\n",
316+
" print('After seed %d, EPC %f'%(rb_seed,rb_fit.fit[0]['epc']))"
317+
]
318+
},
319+
{
320+
"cell_type": "code",
321+
"execution_count": null,
322+
"metadata": {},
323+
"outputs": [],
324+
"source": []
325+
}
326+
],
327+
"metadata": {
328+
"kernelspec": {
329+
"display_name": "Python 3",
330+
"language": "python",
331+
"name": "python3"
332+
},
333+
"language_info": {
334+
"codemirror_mode": {
335+
"name": "ipython",
336+
"version": 3
337+
},
338+
"file_extension": ".py",
339+
"mimetype": "text/x-python",
340+
"name": "python",
341+
"nbconvert_exporter": "python",
342+
"pygments_lexer": "ipython3",
343+
"version": "3.6.8"
344+
}
345+
},
346+
"nbformat": 4,
347+
"nbformat_minor": 2
348+
}

0 commit comments

Comments
 (0)