{
"cells": [
{
"cell_type": "markdown",
"id": "7265bed0",
"metadata": {
"editable": true
},
"source": [
"\n",
""
]
},
{
"cell_type": "markdown",
"id": "70409aa5",
"metadata": {
"editable": true
},
"source": [
"# Introduction to the FRIB-TA Summer School: Quantum Computing and Nuclear Few- and Many-Body Problems with teaching plan and learning outcomes\n",
"**Facility for Rare Isotope Beams, Michigan State University, USA**\n",
"\n",
"Date: **June 20**"
]
},
{
"cell_type": "markdown",
"id": "8bec05a8",
"metadata": {
"editable": true
},
"source": [
"## Introduction\n",
"\n",
"Recent developments in quantum information systems and technologies\n",
"offer the possibility to address some of the most challenging\n",
"large-scale problems in science, whether they are represented by\n",
"complicated interacting quantum mechanical systems or classical\n",
"systems. The last years have seen a rapid and exciting development in\n",
"algorithms and quantum hardware. The emphasis of this summer school\n",
"is to highlight, through a series of lectures and hands-on exercises\n",
"and practice sessions, how quantum computing algorithms can be used to\n",
"study nuclear few- and many-body problems of relevance for low-energy\n",
"nuclear physics. And how quantum computing algorithms can aid in\n",
"studying systems with increasingly many more degrees of freedom\n",
"compared with more classical few- and many-body methods. Several\n",
"quantum algorithms for solving quantum-mechanical few- and\n",
"many-particle problems with be discussed. The lectures will start\n",
"with the basic ideas of quantum computing. Thereafter, through\n",
"examples from nuclear physics, we will elucidate how different quantum\n",
"algorithms can be used to study these systems. The results from\n",
"various quantum computing algorithms will be compared to standard\n",
"nuclear few- and many-body methods"
]
},
{
"cell_type": "markdown",
"id": "1d0cf511",
"metadata": {
"editable": true
},
"source": [
"### Organizers:\n",
"\n",
"Alexei Bazavov (MSU), Scott Bogner (MSU), Heiko Hergert (MSU), Matthew Hirn (MSU), Morten Hjorth-Jensen (MSU), Dean Lee (MSU), Huey-Wen Lin (MSU), and Andrea Shindler (MSU)\n",
"\n",
"Contact person: Morten Hjorth-Jensen, hjensen@msu.edu"
]
},
{
"cell_type": "markdown",
"id": "455ee825",
"metadata": {
"editable": true
},
"source": [
"### Additional material in these slides\n",
"\n",
"In addition to containing information about the school, we provide a reminder on **numpy** and a brief introduction to Qiskit. Please take a look at these notes before coming to the school. This material is provided at the end of the these introductory notes."
]
},
{
"cell_type": "markdown",
"id": "95f21fa0",
"metadata": {
"editable": true
},
"source": [
"## Aims and Learning Outcomes"
]
},
{
"cell_type": "markdown",
"id": "53e6872c",
"metadata": {
"editable": true
},
"source": [
"### The following topics will be covered\n",
"\n",
"1. Basic elements of quantum computing (first day) with introduction to relevant software, including\n",
"\n",
"a. Introduction to quantum computing, qubits and systems of qubits\n",
"\n",
"b. Measurements, Superposition and Entanglement\n",
"\n",
"c. Gates, unitary transformations and quantum circuits\n",
"\n",
"d. Quantum algorithms and implementation on a real quantum computer\n",
"\n",
"5. Simulating quantum-mechanical few- and many-body systems\n",
"\n",
"a. Quantum algorithms for quantum mechanical systems\n",
"\n",
"b. Quantum simulation of the Schroedinger equation\n",
"\n",
"c. Quantum computing and nuclear few- and many-body systems\n",
"\n",
"d. Quantum state preparation and Quantum simulations\n",
"\n",
"e. Quantum simulations on a real quantum computer\n",
"\n",
"6. Quantum field theory and quantum computing\n",
"\n",
"7. Noise, error correction and mitigation\n",
"\n",
"All of the above topics will be supported by examples, hands-on exercises and project work.\n",
"In these introductory notes, after a presentation of the program and useful links, you will find a short overview of **Numpy** and **Qiskit**.\n",
"Feel free to study these notes before the school starts."
]
},
{
"cell_type": "markdown",
"id": "f9dd84cd",
"metadata": {
"editable": true
},
"source": [
"## Practicalities\n",
"\n",
"1. Lectures Monday through Wednesday, starting at 830am, see schedule below\n",
"\n",
"2. Hands-on sessions before lunch and in the afternoons till 6pm\n",
"\n",
"3. For all lecture days we provide relevant jupyter-notebooks you can work on\n",
"\n",
"4. Lectures are in auditorium 1200. Hands-on sessions will be in both the main lecture hall 1200 and in rooms 1221 A&B (12 noon - 6 pm) and room 1309 (8:30am-6pm)."
]
},
{
"cell_type": "markdown",
"id": "b310e2e0",
"metadata": {
"editable": true
},
"source": [
"## Learning material and resources\n",
"1. Qiskit textbook, free online, see \n",
"\n",
"2. Scherer, The Mathematics of Quantum Computing, see \n",
"\n",
"3. Chuang and Nielsen, Quantum Computation and Quantum Information, \n",
"\n",
"4. Hundt, Quantum Computing for programmers, "
]
},
{
"cell_type": "markdown",
"id": "e1b4fee1",
"metadata": {
"editable": true
},
"source": [
"### Good resources\n",
"\n",
"With the hands-on programming component we strongly recommend that you install Qiskit on your computer before the school starts. \n",
"1. For Qiskit, follow the instructions at \n",
"\n",
"2. We strongly recommend using the Jupyter notebook environment at . This environment has Qiskit already set up and is free, just requires an email to register. It has built in support for Jupyter notebooks and should be sufficient for everything needed.\n",
"\n",
"3. See also Ryan Larose's (from 2019) Quantum computing bootcamp with Qiskit - \n",
"\n",
"4. See also "
]
},
{
"cell_type": "markdown",
"id": "8f8190f7",
"metadata": {
"editable": true
},
"source": [
"### Scientific articles of interest\n",
"\n",
"1. Adam Smith, M. S. Kim, Frank Pollmann, and Johannes Knolle, Simulating quantum many-body dynamics on a current digital quantum computer, NPJ Quantum Information 5, Article number: 106 (2019), see "
]
},
{
"cell_type": "markdown",
"id": "0819a839",
"metadata": {
"editable": true
},
"source": [
"## Detailed lecture plan\n",
"\n",
"The duration of each lecture is approximately 45-50 minutes and there\n",
"is a small break of 10-15 minutes between each lecture. Longer breaks\n",
"at 1030am-11am and 3pm-330pm, except for Monday where there is also\n",
"the possibility fora guided FRIB tour. In-person attendance is the\n",
"main teaching modus, but lectures and hands-on sessions will be\n",
"broadcasted via zoom for those who cannot attend in person. The zoom\n",
"link will be sent to those who have expressed that they cannot attend\n",
"in person. The lectures will also be recorded."
]
},
{
"cell_type": "markdown",
"id": "5b96ca46",
"metadata": {
"editable": true
},
"source": [
"### Teachers\n",
"\n",
"* AB = Alexei Bazavov\n",
"\n",
"* BH = Benjamin Hall\n",
"\n",
"* DJ = Danny Jammoa (online discussions and hands-on sessions)\n",
"\n",
"* DL = Dean Lee\n",
"\n",
"* JW = Jacob Watkins\n",
"\n",
"* JB = Joey Bonitati\n",
"\n",
"* MHJ = Morten Hjorth-Jensen\n",
"\n",
"* RL = Ryan Larose\n",
"\n",
"* QZ - Zhenrong Qian"
]
},
{
"cell_type": "markdown",
"id": "838a8fd9",
"metadata": {
"editable": true
},
"source": [
"### Monday June 20\n",
"\n",
"* 8am-830am: Welcome and registration\n",
"\n",
"* 830am-930am: [Introduction to quantum computing, qubits, gates and superposition (AB)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 930am-1030am: [Quantum circuits, entanglement and measurements (AB)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 1030am-11am: Break, coffee, tea etc\n",
"\n",
"* 11am-12pm: [Hands-on session with applications and introduction to software libraries (AB, JW, RL)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 12pm-1pm: Lunch (shorter lunch, else 1h30m lunches)\n",
"\n",
"* 1pm-2pm: [Algorithms for quantum dynamics (DL), simple problems](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 2pm-3pm: [Quantum phase estimation and adiabatic evolution (ZQ and JB), simple problems](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 3pm-4pm: Break, coffee, tea or tour for FRIB for those interested. Please let us know if you are interested in a tour of FRIB.\n",
"\n",
"* 4pm-6pm: [Hands-on sessions and problem solving (AB+all)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)"
]
},
{
"cell_type": "markdown",
"id": "1c05656c",
"metadata": {
"editable": true
},
"source": [
"### Tuesday June 21\n",
"\n",
"* 830-930am: [Hamiltonian simulation: a general overview (JW)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 930am-1030am: [Introduction to VQE and simple model (BH)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html) \n",
"\n",
"* 1030am-11am: Break, coffee, tea etc\n",
"\n",
"* 11am-12pm: [Many-body theory and nuclear few- and many-body systems (BH and MHJ)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 12pm-130pm: Lunch\n",
"\n",
"* 130pm-230pm: [Quantum algorithms (VQE) and nuclear physics with applications (BH and MHJ), part 1](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 230pm-330pm: [Quantum algorithms (VQE) and nuclear physics with applications (BH and MHJ), part 2](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 330pm-4pm: Break, coffee, tea etc\n",
"\n",
"* 4pm-6pm: [Hands-on sessions and problem solving (BH and JW+all)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)"
]
},
{
"cell_type": "markdown",
"id": "fd363715",
"metadata": {
"editable": true
},
"source": [
"### Wednesday June 22\n",
"\n",
"* 830am-930am: [Noise, error correction and mitigation, part I (RL)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 930am-1030am: [Noise, error correction and mitigation, part II (RL)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 1030am-11am: Break, coffee, tea etc\n",
"\n",
"* 11am-12pm: [Practicing error correction and mitigation, hands-on part (RL)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 12pm-130pm: Lunch\n",
"\n",
"* 130pm-230pm: [Wrapping up and defining nuclear many-body system to study for hands-on session (All)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 230pm-330pm: [Start hands-on session (RL)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)\n",
"\n",
"* 330pm-4pm: Break, coffee, tea etc\n",
"\n",
"* 4pm-6pm: [Hands-on sessions and problem solving (all)](https://nuclearphysicsworkshops.github.io/FRIB-TASummerSchoolQuantumComputing/doc/web/course.html)"
]
},
{
"cell_type": "markdown",
"id": "b8912b3a",
"metadata": {
"editable": true
},
"source": [
"## Prerequisites\n",
"\n",
"You are expected to have operating programming skills in programming\n",
"languages like Python (preferred) and/or Fortran, C++, Julia or\n",
"similar and knowledge of quantum mechanics at an intermediate level\n",
"(senior undergraduate and/or beginning graduate). Knowledge of linear\n",
"algebra is essential. Additional modules for self-teaching on Python\n",
"and quantum mechanics are also provided."
]
},
{
"cell_type": "markdown",
"id": "51db4c0c",
"metadata": {
"editable": true
},
"source": [
"## Software and needed installations\n",
"\n",
"We will make extensive use of Python as programming language and its\n",
"myriad of available libraries. You will find\n",
"Jupyter notebooks invaluable in your work.\n",
"\n",
"If you have Python installed (we strongly recommend Python3) and you feel\n",
"pretty familiar with installing different packages, we recommend that\n",
"you install the following Python packages via **pip** as \n",
"\n",
"1. pip install numpy scipy matplotlib ipython scikit-learn mglearn sympy pandas pillow \n",
"\n",
"For Python3, replace **pip** with **pip3**.\n",
"\n",
"For OSX users we recommend, after having installed Xcode, to\n",
"install **brew**. Brew allows for a seamless installation of additional\n",
"software via for example \n",
"\n",
"1. brew install python3\n",
"\n",
"For Linux users, with its variety of distributions like for example the widely popular Ubuntu distribution,\n",
"you can use **pip** as well and simply install Python as \n",
"\n",
"1. sudo apt-get install python3 (or python for pyhton2.7)\n",
"\n",
"etc etc."
]
},
{
"cell_type": "markdown",
"id": "11f56944",
"metadata": {
"editable": true
},
"source": [
"## Python installers\n",
"\n",
"If you don't want to perform these operations separately and venture\n",
"into the hassle of exploring how to set up dependencies and paths, we\n",
"recommend two widely used distrubutions which set up all relevant\n",
"dependencies for Python, namely \n",
"\n",
"* [Anaconda](https://docs.anaconda.com/), \n",
"\n",
"which is an open source\n",
"distribution of the Python and R programming languages for large-scale\n",
"data processing, predictive analytics, and scientific computing, that\n",
"aims to simplify package management and deployment. Package versions\n",
"are managed by the package management system **conda**. \n",
"\n",
"* [Enthought canopy](https://www.enthought.com/product/canopy/) \n",
"\n",
"is a Python\n",
"distribution for scientific and analytic computing distribution and\n",
"analysis environment, available for free and under a commercial\n",
"license.\n",
"\n",
"Furthermore, [Google's Colab](https://colab.research.google.com/notebooks/welcome.ipynb) is a free Jupyter notebook environment that requires \n",
"no setup and runs entirely in the cloud. Try it out!"
]
},
{
"cell_type": "markdown",
"id": "1b60219a",
"metadata": {
"editable": true
},
"source": [
"## Useful Python libraries\n",
"Here we list several useful Python libraries we strongly recommend (if you use anaconda many of these are already there)\n",
"\n",
"* [NumPy](https://www.numpy.org/) is a highly popular library for large, multi-dimensional arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays\n",
"\n",
"* [The pandas](https://pandas.pydata.org/) library provides high-performance, easy-to-use data structures and data analysis tools \n",
"\n",
"* [Xarray](http://xarray.pydata.org/en/stable/) is a Python package that makes working with labelled multi-dimensional arrays simple, efficient, and fun!\n",
"\n",
"* [Scipy](https://www.scipy.org/) (pronounced “Sigh Pie”) is a Python-based ecosystem of open-source software for mathematics, science, and engineering. \n",
"\n",
"* [Matplotlib](https://matplotlib.org/) is a Python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms.\n",
"\n",
"* [Autograd](https://github.com/HIPS/autograd) can automatically differentiate native Python and Numpy code. It can handle a large subset of Python's features, including loops, ifs, recursion and closures, and it can even take derivatives of derivatives of derivatives\n",
"\n",
"* [SymPy](https://www.sympy.org/en/index.html) is a Python library for symbolic mathematics. \n",
"\n",
"* [scikit-learn](https://scikit-learn.org/stable/) has simple and efficient tools for machine learning, data mining and data analysis\n",
"\n",
"* [TensorFlow](https://www.tensorflow.org/) is a Python library for fast numerical computing created and released by Google\n",
"\n",
"* [Keras](https://keras.io/) is a high-level neural networks API, written in Python and capable of running on top of TensorFlow, CNTK, or Theano\n",
"\n",
"* And many more such as [pytorch](https://pytorch.org/), [Theano](https://pypi.org/project/Theano/) etc \n",
"\n",
"All learning material and teaching schedule pertinent to the course is\n",
"avaliable at this GitHub address. A simple **git clone** of the material\n",
"gives you access to all lecture notes and program examples. Similarly,\n",
"running a **git pull** gives you immediately the latest updates."
]
},
{
"cell_type": "markdown",
"id": "b2f523b3",
"metadata": {
"editable": true
},
"source": [
"## Numpy examples and Important Matrix and vector handling packages\n",
"\n",
"There are several central software libraries for linear algebra and eigenvalue problems. Several of the more\n",
"popular ones have been wrapped into ofter software packages like those from the widely used text **Numerical Recipes**. The original source codes in many of the available packages are often taken from the widely used\n",
"software package LAPACK, which follows two other popular packages\n",
"developed in the 1970s, namely EISPACK and LINPACK. We describe them shortly here.\n",
"\n",
" * LINPACK: package for linear equations and least square problems.\n",
"\n",
" * LAPACK:package for solving symmetric, unsymmetric and generalized eigenvalue problems. From LAPACK's website it is possible to download for free all source codes from this library. Both C/C++ and Fortran versions are available.\n",
"\n",
" * BLAS (I, II and III): (Basic Linear Algebra Subprograms) are routines that provide standard building blocks for performing basic vector and matrix operations. Blas I is vector operations, II vector-matrix operations and III matrix-matrix operations. Highly parallelized and efficient codes, all available for download from ."
]
},
{
"cell_type": "markdown",
"id": "bf11af7a",
"metadata": {
"editable": true
},
"source": [
"## Numpy and arrays\n",
"[Numpy](http://www.numpy.org/) provides an easy way to handle arrays in Python. The standard way to import this library is as"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "693785bb",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "markdown",
"id": "87415efa",
"metadata": {
"editable": true
},
"source": [
"Here follows a simple example where we set up an array of ten elements, all determined by random numbers drawn according to the normal distribution,"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a932e05a",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"n = 10\n",
"x = np.random.normal(size=n)\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "eb9f05ad",
"metadata": {
"editable": true
},
"source": [
"We defined a vector $x$ with $n=10$ elements with its values given by the Normal distribution $N(0,1)$.\n",
"Another alternative is to declare a vector as follows"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "72153720",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"x = np.array([1, 2, 3])\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "7c77acf7",
"metadata": {
"editable": true
},
"source": [
"Here we have defined a vector with three elements, with $x_0=1$, $x_1=2$ and $x_2=3$. Note that both Python and C++\n",
"start numbering array elements from $0$ and on. This means that a vector with $n$ elements has a sequence of entities $x_0, x_1, x_2, \\dots, x_{n-1}$. We could also let (recommended) Numpy to compute the logarithms of a specific array as"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "f56e3fd7",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"x = np.log(np.array([4, 7, 8]))\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "2aca9494",
"metadata": {
"editable": true
},
"source": [
"In the last example we used Numpy's unary function $np.log$. This function is\n",
"highly tuned to compute array elements since the code is vectorized\n",
"and does not require looping. We normaly recommend that you use the\n",
"Numpy intrinsic functions instead of the corresponding **log** function\n",
"from Python's **math** module. The looping is done explicitely by the\n",
"**np.log** function. The alternative, and slower way to compute the\n",
"logarithms of a vector would be to write"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "7666a2be",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"from math import log\n",
"x = np.array([4, 7, 8])\n",
"for i in range(0, len(x)):\n",
" x[i] = log(x[i])\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "2cbc1c67",
"metadata": {
"editable": true
},
"source": [
"We note that our code is much longer already and we need to import the **log** function from the **math** module. \n",
"The attentive reader will also notice that the output is $[1, 1, 2]$. Python interprets automagically our numbers as integers (like the **automatic** keyword in C++). To change this we could define our array elements to be double precision numbers as"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5f955c16",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"x = np.log(np.array([4, 7, 8], dtype = np.float64))\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "5529d4c3",
"metadata": {
"editable": true
},
"source": [
"or simply write them as double precision numbers (Python uses 64 bits as default for floating point type variables), that is"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "d4b7d76d",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"x = np.log(np.array([4.0, 7.0, 8.0]))\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "21ed6656",
"metadata": {
"editable": true
},
"source": [
"To check the number of bytes (remember that one byte contains eight bits for double precision variables), you can use simple use the **itemsize** functionality (the array $x$ is actually an object which inherits the functionalities defined in Numpy) as"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "15ec7c17",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"x = np.log(np.array([4.0, 7.0, 8.0]))\n",
"print(x.itemsize)"
]
},
{
"cell_type": "markdown",
"id": "be110757",
"metadata": {
"editable": true
},
"source": [
"## Matrices in Python\n",
"\n",
"Having defined vectors, we are now ready to try out matrices. We can\n",
"define a $3 \\times 3 $ real matrix $\\boldsymbol{A}$ as (recall that we user\n",
"lowercase letters for vectors and uppercase letters for matrices)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "1e97010e",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"A = np.log(np.array([ [4.0, 7.0, 8.0], [3.0, 10.0, 11.0], [4.0, 5.0, 7.0] ]))\n",
"print(A)"
]
},
{
"cell_type": "markdown",
"id": "9a1692da",
"metadata": {
"editable": true
},
"source": [
"If we use the **shape** function we would get $(3, 3)$ as output, that is verifying that our matrix is a $3\\times 3$ matrix. We can slice the matrix and print for example the first column (Python organized matrix elements in a row-major order, see below) as"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "db840c44",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"A = np.log(np.array([ [4.0, 7.0, 8.0], [3.0, 10.0, 11.0], [4.0, 5.0, 7.0] ]))\n",
"# print the first column, row-major order and elements start with 0\n",
"print(A[:,0])"
]
},
{
"cell_type": "markdown",
"id": "e28fa744",
"metadata": {
"editable": true
},
"source": [
"We can continue this way by printing out other columns or rows. The example here prints out the second column"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "4b1d356a",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"A = np.log(np.array([ [4.0, 7.0, 8.0], [3.0, 10.0, 11.0], [4.0, 5.0, 7.0] ]))\n",
"# print the first column, row-major order and elements start with 0\n",
"print(A[1,:])"
]
},
{
"cell_type": "markdown",
"id": "7a829da1",
"metadata": {
"editable": true
},
"source": [
"Numpy contains many other functionalities that allow us to slice, subdivide etc etc arrays. We strongly recommend that you look up the [Numpy website for more details](http://www.numpy.org/). Useful functions when defining a matrix are the **np.zeros** function which declares a matrix of a given dimension and sets all elements to zero"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "6e2fc2e9",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"n = 10\n",
"# define a matrix of dimension 10 x 10 and set all elements to zero\n",
"A = np.zeros( (n, n) )\n",
"print(A)"
]
},
{
"cell_type": "markdown",
"id": "2745d1f1",
"metadata": {
"editable": true
},
"source": [
"or initializing all elements to"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "f3365c09",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"n = 10\n",
"# define a matrix of dimension 10 x 10 and set all elements to one\n",
"A = np.ones( (n, n) )\n",
"print(A)"
]
},
{
"cell_type": "markdown",
"id": "00755c56",
"metadata": {
"editable": true
},
"source": [
"or as unitarily distributed random numbers"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "5a76e309",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"n = 10\n",
"# define a matrix of dimension 10 x 10 and set all elements to random numbers with x \\in [0, 1]\n",
"A = np.random.rand(n, n)\n",
"print(A)"
]
},
{
"cell_type": "markdown",
"id": "5a61247c",
"metadata": {
"editable": true
},
"source": [
"There are several other extremely useful functionalities in Numpy. Numpy contains many functions which are useful if we wish to perform a statistical analysis.\n",
"As an example, consider the discussion of the covariance matrix. Suppose we have defined three vectors\n",
"$\\boldsymbol{x}, \\boldsymbol{y}, \\boldsymbol{z}$ with $n$ elements each. The covariance matrix is defined as"
]
},
{
"cell_type": "markdown",
"id": "32bbe946",
"metadata": {
"editable": true
},
"source": [
"$$\n",
"\\boldsymbol{\\Sigma} = \\begin{bmatrix} \\sigma_{xx} & \\sigma_{xy} & \\sigma_{xz} \\\\\n",
" \\sigma_{yx} & \\sigma_{yy} & \\sigma_{yz} \\\\\n",
" \\sigma_{zx} & \\sigma_{zy} & \\sigma_{zz} \n",
" \\end{bmatrix},\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "6e92e4b6",
"metadata": {
"editable": true
},
"source": [
"where for example"
]
},
{
"cell_type": "markdown",
"id": "8d237db3",
"metadata": {
"editable": true
},
"source": [
"$$\n",
"\\sigma_{xy} =\\frac{1}{n} \\sum_{i=0}^{n-1}(x_i- \\overline{x})(y_i- \\overline{y}).\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "697f8bd4",
"metadata": {
"editable": true
},
"source": [
"The Numpy function **np.cov** calculates the covariance elements using the factor $1/(n-1)$ instead of $1/n$ since it assumes we do not have the exact mean values. \n",
"The following simple function uses the **np.vstack** function which takes each vector of dimension $1\\times n$ and produces a $3\\times n$ matrix $\\boldsymbol{W}$"
]
},
{
"cell_type": "markdown",
"id": "f3cd9898",
"metadata": {
"editable": true
},
"source": [
"$$\n",
"\\boldsymbol{W} = \\begin{bmatrix} x_0 & x_1 & x_2 & \\dots & x_{n-2} & x_{n-1} \\\\\n",
" y_0 & y_1 & y_2 & \\dots & y_{n-2} & y_{n-1} \\\\\n",
"\t\t\t z_0 & z_1 & z_2 & \\dots & z_{n-2} & z_{n-1} \\\\\n",
" \\end{bmatrix},\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "f041856e",
"metadata": {
"editable": true
},
"source": [
"which in turn is converted into into the $3\\times 3$ covariance matrix\n",
"$\\boldsymbol{\\Sigma}$ via the Numpy function **np.cov()**. We note that we can also calculate\n",
"the mean value of each set of samples $\\boldsymbol{x}$ etc using the Numpy\n",
"function **np.mean(x)**. We can also extract the eigenvalues of the\n",
"covariance matrix through the **np.linalg.eig()** function."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "0d4ea16f",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Importing various packages\n",
"import numpy as np\n",
"\n",
"n = 100\n",
"x = np.random.normal(size=n)\n",
"print(np.mean(x))\n",
"y = 4+3*x+np.random.normal(size=n)\n",
"print(np.mean(y))\n",
"z = x**3+np.random.normal(size=n)\n",
"print(np.mean(z))\n",
"W = np.vstack((x, y, z))\n",
"Sigma = np.cov(W)\n",
"print(Sigma)\n",
"Eigvals, Eigvecs = np.linalg.eig(Sigma)\n",
"print(Eigvals)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "a96984c1",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from scipy import sparse\n",
"eye = np.eye(4)\n",
"print(eye)\n",
"sparse_mtx = sparse.csr_matrix(eye)\n",
"print(sparse_mtx)\n",
"x = np.linspace(-10,10,100)\n",
"y = np.sin(x)\n",
"plt.plot(x,y,marker='x')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "2d9dbcb4",
"metadata": {
"editable": true
},
"source": [
"## Meet the Pandas\n",
"\n",
"Another useful Python package is\n",
"[pandas](https://pandas.pydata.org/), which is an open source library\n",
"providing high-performance, easy-to-use data structures and data\n",
"analysis tools for Python. **pandas** stands for panel data, a term borrowed from econometrics and is an efficient library for data analysis with an emphasis on tabular data.\n",
"**pandas** has two major classes, the **DataFrame** class with two-dimensional data objects and tabular data organized in columns and the class **Series** with a focus on one-dimensional data objects. Both classes allow you to index data easily as we will see in the examples below. \n",
"**pandas** allows you also to perform mathematical operations on the data, spanning from simple reshapings of vectors and matrices to statistical operations. \n",
"\n",
"The following simple example shows how we can, in an easy way make tables of our data. Here we define a data set which includes names, place of birth and date of birth, and displays the data in an easy to read way."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "40b1183f",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import pandas as pd\n",
"from IPython.display import display\n",
"data = {'First Name': [\"Frodo\", \"Bilbo\", \"Aragorn II\", \"Samwise\"],\n",
" 'Last Name': [\"Baggins\", \"Baggins\",\"Elessar\",\"Gamgee\"],\n",
" 'Place of birth': [\"Shire\", \"Shire\", \"Eriador\", \"Shire\"],\n",
" 'Date of Birth T.A.': [2968, 2890, 2931, 2980]\n",
" }\n",
"data_pandas = pd.DataFrame(data)\n",
"display(data_pandas)"
]
},
{
"cell_type": "markdown",
"id": "d897b200",
"metadata": {
"editable": true
},
"source": [
"In the above we have imported **pandas** with the shorthand **pd**, the latter has become the standard way we import **pandas**. We make then a list of various variables\n",
"and reorganize the aboves lists into a **DataFrame** and then print out a neat table with specific column labels as *Name*, *place of birth* and *date of birth*.\n",
"Displaying these results, we see that the indices are given by the default numbers from zero to three.\n",
"**pandas** is extremely flexible and we can easily change the above indices by defining a new type of indexing as"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "61a147c2",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"data_pandas = pd.DataFrame(data,index=['Frodo','Bilbo','Aragorn','Sam'])\n",
"display(data_pandas)"
]
},
{
"cell_type": "markdown",
"id": "8baa0591",
"metadata": {
"editable": true
},
"source": [
"Thereafter we display the content of the row which begins with the index **Aragorn**"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "0273009b",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"display(data_pandas.loc['Aragorn'])"
]
},
{
"cell_type": "markdown",
"id": "34240951",
"metadata": {
"editable": true
},
"source": [
"We can easily append data to this, for example"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "e4650a05",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"new_hobbit = {'First Name': [\"Peregrin\"],\n",
" 'Last Name': [\"Took\"],\n",
" 'Place of birth': [\"Shire\"],\n",
" 'Date of Birth T.A.': [2990]\n",
" }\n",
"data_pandas=data_pandas.append(pd.DataFrame(new_hobbit, index=['Pippin']))\n",
"display(data_pandas)"
]
},
{
"cell_type": "markdown",
"id": "49f124c8",
"metadata": {
"editable": true
},
"source": [
"Here are other examples where we use the **DataFrame** functionality to handle arrays, now with more interesting features for us, namely numbers. We set up a matrix \n",
"of dimensionality $10\\times 5$ and compute the mean value and standard deviation of each column. Similarly, we can perform mathematial operations like squaring the matrix elements and many other operations."
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "8c949d1c",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from IPython.display import display\n",
"np.random.seed(100)\n",
"# setting up a 10 x 5 matrix\n",
"rows = 10\n",
"cols = 5\n",
"a = np.random.randn(rows,cols)\n",
"df = pd.DataFrame(a)\n",
"display(df)\n",
"print(df.mean())\n",
"print(df.std())\n",
"display(df**2)"
]
},
{
"cell_type": "markdown",
"id": "64aacc6b",
"metadata": {
"editable": true
},
"source": [
"Thereafter we can select specific columns only and plot final results"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "994a6756",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"df.columns = ['First', 'Second', 'Third', 'Fourth', 'Fifth']\n",
"df.index = np.arange(10)\n",
"\n",
"display(df)\n",
"print(df['Second'].mean() )\n",
"print(df.info())\n",
"print(df.describe())\n",
"\n",
"from pylab import plt, mpl\n",
"plt.style.use('seaborn')\n",
"mpl.rcParams['font.family'] = 'serif'\n",
"\n",
"df.cumsum().plot(lw=2.0, figsize=(10,6))\n",
"plt.show()\n",
"\n",
"\n",
"df.plot.bar(figsize=(10,6), rot=15)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "3d3f52a8",
"metadata": {
"editable": true
},
"source": [
"We can produce a $4\\times 4$ matrix"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "9b894d7a",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"b = np.arange(16).reshape((4,4))\n",
"print(b)\n",
"df1 = pd.DataFrame(b)\n",
"print(df1)"
]
},
{
"cell_type": "markdown",
"id": "3b097092",
"metadata": {
"editable": true
},
"source": [
"and many other operations. \n",
"\n",
"The **Series** class is another important class included in\n",
"**pandas**. You can view it as a specialization of **DataFrame** but where\n",
"we have just a single column of data. It shares many of the same features as **DataFrame**. As with **DataFrame**,\n",
"most operations are vectorized, achieving thereby a high performance when dealing with computations of arrays, in particular labeled arrays.\n",
"\n",
"For multidimensional arrays, we recommend strongly [xarray](http://xarray.pydata.org/en/stable/). **xarray** has much of the same flexibility as **pandas**, but allows for the extension to higher dimensions than two. We will see examples later of the usage of both **pandas** and **xarray**."
]
},
{
"cell_type": "markdown",
"id": "168d6238",
"metadata": {
"editable": true
},
"source": [
"## Basic features of Qiskit"
]
},
{
"cell_type": "markdown",
"id": "c846a6c7",
"metadata": {
"editable": true
},
"source": [
"### Introduction\n",
"\n",
"This notebook constitutes some introductory information with relavant\n",
"examples on getting started with [Qiskit](https://qiskit.org/), an\n",
"open-source software for quantum computation. A more complete overview\n",
"of the available features can be found from the [Qiskit documentation](https://qiskit.org/documentation/tutorials.html) as\n",
"well as the [Qiskit textbook](https://qiskit.org/textbook/preface.html)."
]
},
{
"cell_type": "markdown",
"id": "4f4f89c3",
"metadata": {
"editable": true
},
"source": [
"### Step 0: Download the software and import packages\n",
"\n",
"[Here is a hands-on tutorial](https://www.youtube.com/watch?v=1kRfHNUbkrg&t=163s) to install Qiskit.\n",
"The first step is to create an IBM ID account. Then you will be able\n",
"to use Qiskit on the cloud through the IBM Quantum Lab on your\n",
"dashboard. To get started locally with Qiskit, we will use the\n",
"Anaconda distribution of Python. The tutorial explains how to download\n",
"Qiskit and store the account information locally."
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "2b18c712",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Import the relevant packages.\n",
"from qiskit import * \n",
"%matplotlib inline \n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.patches as mpatches"
]
},
{
"cell_type": "markdown",
"id": "acc7e9df",
"metadata": {
"editable": true
},
"source": [
"### Step 1: Construct your quantum circuit\n",
"\n",
"A [quantum circuit](https://wiki2.org/en/Quantum_circuit) is a\n",
"computational routine which incorporates classical computations into\n",
"coherent quantum operations on quantum data. The [Qiskit circuit library](https://qiskit.org/documentation/apidoc/circuit_library.html)\n",
"shows us the syntax to program a quantum circuit and add quantum\n",
"operations to the qubits of interest. To get started, we will\n",
"introduce the class\n",
"[QuantumCircuit](https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.html),\n",
"in which we will define the circuit and explore the available built-in\n",
"methods."
]
},
{
"cell_type": "markdown",
"id": "8df1bbe9",
"metadata": {
"editable": true
},
"source": [
"### Define the quantum circuit"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "efa968ca",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"from qiskit import QuantumCircuit # You can ignore this if 'from qiskit import *' has been executed."
]
},
{
"cell_type": "markdown",
"id": "94d00565",
"metadata": {
"editable": true
},
"source": [
"Here there are two ways we can define a quantum circuit, with three qubits and three classical bits:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "01f90b34",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Method 1: \n",
"qc_1p1a = QuantumCircuit(3,3) \n",
"qc_1p1a.draw('mpl')"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "d61931df",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Method 2: \n",
"qr = QuantumRegister(3)\n",
"cr = ClassicalRegister(3)\n",
"ar = AncillaRegister(1) # You can add ancilla qubit if it's needed, otherwise no need to include 'ar' in the line below.\n",
"qc_1p1b = QuantumCircuit(qr, ar, cr)\n",
"qc_1p1b.draw('mpl')"
]
},
{
"cell_type": "markdown",
"id": "2179cabc",
"metadata": {
"editable": true
},
"source": [
"### Combine two (or multiple) quantum circuits\n",
"\n",
"* **Method 1:** If two circuits $circ_1$ and $circ_2$ have the same number of qubits and classical bits,\n",
"\n",
"then their combination could just be implemented like adding two numbers $circ = circ_1 + circ_2$. A more flexible method\n",
"[QuantumCircuit.compose](https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.compose.html#qiskit.circuit.QuantumCircuit.compose)\n",
"is developed, which we can combine any two circuits and specify the qubits to compose onto. [This video](https://www.youtube.com/watch?v=3ja8uCqUS0s) shows an example to implement these features. Here's another example:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "969dfc88",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"circ_1p2a = QuantumCircuit(3)\n",
"circ_1p2a.x([0,1,2])\n",
"circ_1p2a.draw('mpl')"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "03ea279b",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"circ_1p2b = QuantumCircuit(2)\n",
"circ_1p2b.h(0)\n",
"circ_1p2b.cx(0,1)\n",
"circ_1p2b.draw('mpl')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "15c777aa",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"circa = circ_1p2a.compose(circ_1p2b, qubits=[2,1])\n",
"circa.draw('mpl')"
]
},
{
"cell_type": "markdown",
"id": "dadc435f",
"metadata": {
"editable": true
},
"source": [
"* **Method 2:** First convert a circuit into a quantum gate using [$to_gate$](https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.to_gate.html) method, then \n",
"\n",
"[append](https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.append.html#qiskit.circuit.QuantumCircuit.append) the gate to another circuit.\n",
"An example is provided [here](https://www.youtube.com/watch?v=krhPpzkT_z4).\n",
"Note that the circuits with classical bits cannot be converted to gate. We can alternatively generate the $circa$ as:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "eeffefd2",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"gate_x3 = circ_1p2a.to_gate()\n",
"gate_hcx = circ_1p2b.to_gate()\n",
"circb = QuantumCircuit(3)\n",
"circb.append(gate_x3, [0,1,2])\n",
"circb.append(gate_hcx, [2,1])\n",
"circb.measure_all() \n",
"circb.draw('mpl')"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "0fd09513",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Check circb and circa have the same construction.\n",
"circb.decompose().draw('mpl')"
]
},
{
"cell_type": "markdown",
"id": "41954981",
"metadata": {
"editable": true
},
"source": [
"### Generating parametrized circuits\n",
"\n",
"Parametrized quantum circuits is useful in solving variational problems. To construct parameterized circuits and assign values to circuit parameters in Qiskit, we will use Qiskit's [Parameter](https://qiskit.org/documentation/stubs/qiskit.circuit.Parameter.html) and [ParameterVector](https://qiskit.org/documentation/stubs/qiskit.circuit.ParameterVector.html) (construct multiple parameters at once) class."
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "64160835",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"from qiskit.circuit import Parameter, ParameterVector\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"id": "e6f8fa2a",
"metadata": {
"editable": true
},
"source": [
"* **Method 1:** use the **Parameter** class."
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "6055fc1d",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Define your parameters.\n",
"a, b, c = Parameter('a'), Parameter('b'), Parameter('c')\n",
"# Define the quantum circuit.\n",
"circ_1p3 = QuantumCircuit(3)\n",
"circ_1p3.rx(a, 0) # RX(a) on qubit 0.\n",
"circ_1p3.ry(b, 1) # RY(b) on qubit 1.\n",
"circ_1p3.h(2) # A regular gate no need for parametrization.\n",
"circ_1p3.crz(c, 0, 2) # CRZ(c) controlled on qubit 0, acting on qubit 2.\n",
"circ_1p3.draw('mpl')"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "6aa3104e",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Assign (bind) the values\n",
"circ1p3_bind = circ_1p3.bind_parameters({a: np.pi, b: np.pi/2, c: np.pi/2})\n",
"circ1p3_bind.draw('mpl')"
]
},
{
"cell_type": "markdown",
"id": "bd2c6ac0",
"metadata": {
"editable": true
},
"source": [
"* **Method 2:** use the **ParameterVector** class, where you assign all the parameters within a single vector. Therefore, we can generate the same circuit above by:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "fb1ceaf9",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Define your parameters.\n",
"p = ParameterVector('p', 3) \n",
"# Define the quantum circuit.\n",
"circ_1p3 = QuantumCircuit(3)\n",
"circ_1p3.rx(p[0], 0) # RX(a) on qubit 0.\n",
"circ_1p3.ry(p[1], 1) # RY(b) on qubit 1.\n",
"circ_1p3.h(2) # A regular gate no need for parametrization.\n",
"circ_1p3.crz(p[2], 0, 2) # CRZ(c) controlled on qubit 0, acting on qubit 2.\n",
"circ_1p3.measure_all() # A side note: measurement will add classical registers in your circuit, if they are not originally in QuantumCircuit. \n",
"circ_1p3.draw('mpl')"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "0c2e28db",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"circ1p3_bind = circ_1p3.bind_parameters({p: [np.pi, np.pi/2, np.pi/2]})\n",
"circ1p3_bind.draw('mpl')"
]
},
{
"cell_type": "markdown",
"id": "a78884ea",
"metadata": {
"editable": true
},
"source": [
"### Step 2: Run your quantum simulation & Data collection\n",
"\n",
"Having the quantum circuit(s) ready, we will run our quantum\n",
"simulation by creating and submitting jobs to the available\n",
"device. While the jobs are running, we can monitor their status. We\n",
"are also able to view the jobs we have submitted and are on the\n",
"waitlist through the dashboard of IBM Quantum account."
]
},
{
"cell_type": "markdown",
"id": "575a89e0",
"metadata": {
"editable": true
},
"source": [
"### Choosing the backend to run your circuit\n",
"\n",
"A useful package for simulating quantum circuits is called [Qiskit Aer](https://qiskit.org/documentation/tutorials/simulators/1_aer_provider.html),\n",
"which provides multiple backends for running a quantum simulation. The main simulator backend of the Aer provider is the **AerSimulator** backend, who mimics the execution of an actual quantum computer by default."
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "9aa11345",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"from qiskit import Aer, transpile # You can ignore this if 'from qiskit import *' has been executed.\n",
"from qiskit.tools.visualization import plot_histogram, plot_state_city"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "e0b8a3b7",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# List the available backends.\n",
"Aer.backends()"
]
},
{
"cell_type": "markdown",
"id": "33adf058",
"metadata": {
"editable": true
},
"source": [
"Here's a sample code for simulating the quantum circuit above, $circ1p3_bind$, with the $aer_simulator$. We generate the simulation result using the built-in visualization tool $plot_histogram$, which converts counts (a dictionary of results) into a histogram, where the probabilities of measuring each state is shown on the vertical axis."
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "fc75f108",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Let's see the results! \n",
"# Transpile for simulator\n",
"simulator = Aer.get_backend('aer_simulator')\n",
"circ = transpile(circ1p3_bind, simulator)\n",
"\n",
"# Run and get counts\n",
"result = simulator.run(circ).result()\n",
"counts = result.get_counts(circ)\n",
"print(counts) \n",
"plot_histogram(counts, title='Result for circ1p3_bind')"
]
},
{
"cell_type": "markdown",
"id": "6ccb11cf",
"metadata": {
"editable": true
},
"source": [
"### Monitor the status of your experiment and check your submitted jobs\n",
"\n",
"Using Qiskit, we can also send jobs to IBM Quantum computers, and monitor their status.\n",
"An overview of how to use your IBM Quantum account to access the systems and simulators available in IBM Quantum is available [here](https://quantum-computing.ibm.com/lab/docs/iql/manage/account/ibmq)."
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "0a85edd2",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"from qiskit.tools import job_monitor"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "3ee653f3",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"# Submit your job to a quantum computer 'ibmq_belem'.\n",
"# Select provider and backend.\n",
"provider = IBMQ.get_provider(hub='ibm-q') \n",
"backend = provider.get_backend('ibmq_belem') \n",
"# Run the circuit 'circ1p3_bind' and execute the job.\n",
"job = execute(circ1p3_bind, backend)\n",
"# Monitor the job.\n",
"job_monitor(job)\n",
"result = job.result()\n",
"counts = result.get_counts()\n",
"plot_histogram(counts)"
]
},
{
"cell_type": "markdown",
"id": "6c7e82a8",
"metadata": {
"editable": true
},
"source": [
"Once the job have been submitted to a quantum computer, you will be able to check and see the it appears on the pending list on your IBM Quantum dashboard."
]
},
{
"cell_type": "markdown",
"id": "7ae3d4d6",
"metadata": {
"editable": true
},
"source": [
"### Submit multiple quantum circuits to a backend\n",
"\n",
"If there are multiple circuits to be submitted, you can bundle the\n",
"circuits in a single job to reduce the queue times. For example, if we\n",
"want to the circuit $circ1p3_bind$ and $circb$ together on a simulator, we\n",
"can do:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "4b43f3b9",
"metadata": {
"collapsed": false,
"editable": true
},
"outputs": [],
"source": [
"simulator = Aer.get_backend('qasm_simulator')\n",
"qc_list = [circ1p3_bind, circb] # Include all the circuits in a single list.\n",
"job = execute(qc_list, simulator)\n",
"job.result().get_counts()"
]
},
{
"cell_type": "markdown",
"id": "4209871a",
"metadata": {
"editable": true
},
"source": [
"### Some visualization tools\n",
"\n",
"* If you want to visualize a quantum circuit in a LaTex document, Qiskit offers the [LaTex drawer](https://www.youtube.com/watch?v=Q_pkenZ05eM) which geynerates the code you can copy and paste into a LaTex document. Another useful package for graphing quantum circuit in Latex is called [Quantikz](http://mirrors.ibiblio.org/CTAN/graphics/pgf/contrib/quantikz/quantikz.pdf).\n",
"\n",
"* [Kaleidoscope](https://nonhermitian.org/kaleido/tutorials/interactive/bloch_sphere.html) provides an option to visualize the quantum states on on Bloch sphere. You can generate the plot in a Jupyter notebook."
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}