Skip to content

Commit

Permalink
RB & measurement calibration documentation (Qiskit#151)
Browse files Browse the repository at this point in the history
* added measurement calibration doc

* Update measurement_calibration.rst

fixed numerical typo in matrix

* apdated the doc for measurement calibration

* added RB documentation

* fix lint erros

* fix lint error
  • Loading branch information
ShellyGarion authored and derivation committed Feb 28, 2019
1 parent 83a5788 commit dad99f6
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 1 deletion.
112 changes: 111 additions & 1 deletion docs/ignis/measurement_calibration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,125 @@
Measurement Calibration
=======================

The measurement calibration...
The measurement calibration is used to mitigate measurement errors.
The main idea is to prepare all :math:`2^n` basis input states and compute the
probability of measuring counts in the other basis states.
From these calibrations, it is possible to correct the average results
of another experiment of interest.

To use Qiskit Ignis Measurement Calibration module, import it with

.. code:: python
from qiskit.ignis.mitigation.measurement import (complete_measurement_calibration,
CompleteMeasFitter, MeasurementFilter)
Generating Measurement Calibration Circuits
-------------------------------------------

The goal is to generate a list of measurement calibration circuits for the full
Hilbert space. Each circuit creates a basis state.
If there are :math:`n` qubits, then you get :math:`2^n` calibration circuits.

The following function returns
a list **cal_circuits** of QuantumCircuit objects containing the calibration circuits,
and a list **state_labels** of the calibration state labels.

.. code:: python
cal_circuits, state_labels =
complete_measurement_calibration(qubit_list, qr, cr, circlabel)
The input to this function can be given in one of the following three forms:

- **qubit_list:** A list of qubits to perform the measurement correction on, or:
- **qr (QuantumRegister):** A quantum register, or:
- **cr (ClassicalRegister):** A classical register.

In addition, you can provide a string **circlabel**, which is added at
the beginning of the circuit names for unique identification.

For example, for a 5-qubit QuantumRegister, use

.. code:: python
cal_circuits, state_labels = complete_measurement_calibration(
qiskit.QuantumRegister(5))
Now, you can execute the calibration circuits either using
Qiskit Aer Simulator (with some noise model) or using IBMQ provider.


.. code:: python
job = qiskit.execute(cal_circuits)
cal_results = job.results()
Analyzing the Results
---------------------

After you run the calibration circuits and obtain the results **cal_results**,
you can compute the calibration matrix
(this matrix will be ordered according to the state_labels).

.. code:: python
meas_fitter = CompleteMeasFitter(cal_results, state_labels, circlabel)
print(meas_fitter.cal_matrix)
To compute the measurement fidelity, use

.. code:: python
fidelity = meas_fitter.readout_fidelity(label_list)
If **label_list** is None, then it returns the average assignment fidelity
of a single state. Otherwise it returns the assignment fidelity
to be in any one of these states averaged over the second index.


Applying the Calibration
------------------------

If you now perform another experiment using another circuits **my_circuits**
and obtain the results **my_results**, for example

.. code:: python
my_job = qiskit.execute(my_circuits)
my_results = my_job.results()
then you can compute the mitigated results **mitigated_results**

.. code:: python
# Results without mitigation
raw_counts = my_results.get_counts()
# Get the filter object
meas_filter = meas_fitter.filter
# Results with mitigation
mitigated_results = meas_filter.apply(my_results, method)
mitigated_counts = mitigated_results.get_counts(0)
The raw data to be corrected can be given in a number of forms:

- Form1: A counts dictionary from results.get_counts,
- Form2: A list of counts of length=len(state_labels),
- Form3: A list of counts of length=M*len(state_labels) where M is an integer
(e.g. for use with the tomography data),
- Form4: A qiskit Result (e.g. my_results as above).

There are two fitting methods for applying the calibration:

- **method='pseudo_inverse'**, which is a direct inversion of the calibration matrix.
- **method='least_squares'**, which constrained to have physical probabilities

If none method is defined, then 'least_squares' is used.



127 changes: 127 additions & 0 deletions docs/ignis/randomized_benchmarking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,140 @@ average gate performance by running sequences of random Clifford gates
that should return the qubits to the initial state. Ignis has tools
to generate one- and two-qubit Clifford gate sequences simultaneously.

To use Qiskit Ignis randomized benchmarking (RB) module, import it with

.. code:: python
import qiskit.ignis.verification.randomized_benchmarking as rb
Generating RB Sequences
-----------------------

In order to generate the RB sequences **rb_circs**, which is a list of lists of
quantum circuits, run

.. code:: python
rb_circs, xdata = randomized_benchmarking_seq(nseeds, length_vector,
rb_pattern, length_multiplier)
The parameters given to this function are:

- **nseeds:** The number of seeds. For each seed there you will get a separate list
of output circuits in **rb_circs**.
- **length_vector**: The length vector of Clifford lengths. Must be in ascending order.
RB sequences of increasing length grow on top of the previous sequences.
- **rb_pattern:** A list of the form [[i,j],[k],...] which will make simultaneous RB sequences
where Qi,Qj are a 2-qubit RB sequence and Qk is a 1-qubit sequence, etc. The number of qubits
is the sum of the entries. For 'regular' RB the qubit_pattern is just [[0]],[[0,1]].
- **length_multiplier:** If this is an array it scales each rb_sequence by the multiplier.

For example,

.. code:: python
# Number of qubits
nQ = 4
# i.e., [Q0,Q1,Q2,Q3]
# Number of seeds, which is the number of lists of RB sequences
nseeds = 5
# Number of Cliffords in each sequence (start, stop, steps)
length_vector = np.arange(1,200,20)
# Simultaneous 2-qubit RB on qubits Q0,Q2 and 1-qubit RB on qubits Q1 and Q3
rb_pattern = [[0,2],[3],[1]]
# Do three times as many 1Q Cliffords
length_multiplier = [1,3,3]
This function returns:

- **rb_circs:** A list of lists of circuits for the rb sequences (separate list for each seed).
- **xdata:** The Clifford lengths (with multiplier if applicable).
- **rb_opts_dict:** Option dictionary back out with default options appended.


Analyzing Results
-----------------
Now, you can execute the randomized benchmarking either using
Qiskit Aer Simulator (with some noise model) or using IBMQ provider,
and obtain a list of results **result_list** for the RB sequences.


.. code:: python
result_list = [] # Output results
for rb_seed,rb_circ_seed in enumerate(rb_circs):
print('Executing seed %d'%rb_seed)
# Executing each RB sequence
job = qiskit.execute(rb_circ_seed,
backend=backend, basis_gates=basis_gates,
shots=shots, noise_model=noise_model)
result_list.append(job.result())
To get the statistics about the survival probabilities, compute

.. code:: python
rbfit = rb.RBFitter(result_list, xdata, shots, rb_pattern)
where **results_list**, **xdata** and **rb_patterns** are as above,
and **shots** is the number of shots (the default value is 1024).

Now, you can fit the RB results to an exponential curve (fit each of the RB patterns
**pattern_index**) and calculate the statistical parameters:

.. code:: python
# The three parameters (a, alpha, b) of the function a * alpha ** x + b.
# The middle one is the exponent alpha.
rbfit._fit[pattern_index]['parmas']
# The error limits of the parameters.
rbfit._fit[pattern_index]['err']
# The error per Clifford
rbfit._fit[pattern_index]['epc']
# The error limit per Clifford
rbfit._fit[pattern_index]['epc_err']
To plot the exponential decaying curve, use

.. code:: python
rbfit.plot_rb_data(pattern_index, ax=ax, add_label=True, show_plt=False)
where:

- **pattern_index:** Which RB pattern to plot.
- **ax (Axes or None):** Plot axis (if passed in).
- **add_label (bool):** Add an EPC label.
- **show_plt (bool):** Display the plot.


Predicted Results
-----------------

From the known depolarizing errors on the simulation you can predict the fidelity.
First you need to count the number of gates per Clifford.

.. code:: python
gates_per_cliff = rb.rb_utils.gates_per_clifford(qobj_list,
xdata[0],
basis_gates,
rb_opts['rb_pattern'][0])
Then you need to prepare lists of the number of qubits and the errors
and calculate the predicted error per clifford (epc):

.. code:: python
pred_epc = rb.rb_utils.twoQ_clifford_error(ngates,gate_qubits,gate_errs)
where:

- **ngates:** A List of the number of gates per 2Q Clifford
- **gate_qubit:** A list of the qubit corresponding to the gate (0, 1 or -1).
-1 corresponds to the 2Q gate.
- **gate_err:** list of the gate errors

0 comments on commit dad99f6

Please sign in to comment.