├── xeb_post_appendix.pdf ├── README.md ├── LICENSE ├── intro.py ├── .gitignore ├── xeb.py └── xeb_calcs.ipynb /xeb_post_appendix.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msohaibalam/xeb/HEAD/xeb_post_appendix.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # (Quantum) Cross-Entropy Benchmark Fidelity 2 | Simulating quantum supremacy benchmarking with random unitary sampling. 3 | 4 | This repo collects and demos the code discussed in the blog post [`Unpacking the Quantum Supremacy Benchmark with Python`](https://medium.com/@sohaib.alam/unpacking-the-quantum-supremacy-benchmark-with-python-67a46709d) 5 | by [M. Sohaib Alam](https://github.com/msohaibalam) and [Will Zeng](https://github.com/willzeng). To view the output of the computations discussed in the blog, you can 6 | - Run the jupyter notebook `xeb_calcs.ipynb`, or 7 | - Execute `python xeb.py` from a terminal shell. 8 | 9 | A small appendix is available in `xeb_post_appendix.pdf`, and outlines the derivation for the theoretical values of the benchmark fidelity used in the blog post. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 M. Sohaib Alam & W. J. Zeng 2 | All rights reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 7 | the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 13 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 14 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /intro.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | if __name__ == "__main__": 4 | # the state of N qubits is a complex vector of dimension 2^N 5 | n_qubits = 2 6 | dimension = 2**n_qubits 7 | 8 | def print_probs(state, n_qubits): 9 | # the elements of this state are squared to calculate outcome probabilities 10 | for bitstring in range(2**n_qubits): 11 | probability = np.abs(state[bitstring]) ** 2 12 | print("Bitstring", format(bitstring, "0" + str(n_qubits) + "b"), \ 13 | " has probability ", probability) 14 | print() 15 | 16 | # as a first example, the i|0> state 17 | state = [1j, 0, 0, 0] 18 | print_probs(state, n_qubits) 19 | # an example with a "superposition" over outcomes 20 | print_probs([0, -1j / np.sqrt(2), 0, 1 / np.sqrt(2)], n_qubits) 21 | 22 | # evolution is then given by a unitary matrix 23 | identity = np.array([[1, 0], [0, 1]]) # identity on one qubit 24 | flip = np.array([[0, 1], [1, 0]]) # a flip or X-gate on one qubits, like the (classical) NOT gate 25 | 26 | # tensor products make this a two qubit operation 27 | flip_first = np.kron(flip, identity) # flip the first qubit, leave second qubit alone 28 | new_state = flip_first @ state 29 | print_probs(new_state, n_qubits) 30 | 31 | flip_second = np.kron(identity, flip) 32 | new_state = flip_second @ state 33 | print_probs(new_state, n_qubits) 34 | 35 | # if we start in the state with all qubits in zero 36 | # then we can take a shortcut to get the probabilities of any particular bitstring 37 | all_zeros = [1] + [0]*(dimension-1) 38 | bs = np.random.choice(range(dimension)) 39 | assert (flip_second @ all_zeros)[bs] == flip_second[bs, 0] 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | .idea/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | db.sqlite3 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # Environments 86 | .env 87 | .venv 88 | env/ 89 | venv/ 90 | ENV/ 91 | env.bak/ 92 | venv.bak/ 93 | 94 | # Spyder project settings 95 | .spyderproject 96 | .spyproject 97 | 98 | # Rope project settings 99 | .ropeproject 100 | 101 | # mkdocs documentation 102 | /site 103 | 104 | # mypy 105 | .mypy_cache/ 106 | -------------------------------------------------------------------------------- /xeb.py: -------------------------------------------------------------------------------- 1 | # xeb.py 2 | # 3 | # Authors M. Sohaib Alam & Will Zeng 4 | 5 | import matplotlib.pyplot as plt 6 | from typing import List, Callable 7 | import numpy as np 8 | import functools 9 | import itertools 10 | 11 | 12 | def random_unitary(dim: int) -> np.ndarray: 13 | # follows the algorithm in https://arxiv.org/pdf/math-ph/0609050.pdf 14 | # returns a unitary of size dim x dim 15 | Z = np.array([np.random.normal(0, 1) + np.random.normal(0, 1) * 1j for _ in range(dim ** 2)]).reshape(dim, dim) 16 | Q, R = np.linalg.qr(Z) 17 | diag = np.diagonal(R) 18 | lamb = np.diag(diag) / np.absolute(diag) 19 | unitary = np.matmul(Q, lamb) 20 | 21 | # this condition asserts that the matrix is unitary 22 | assert np.allclose(unitary.conj().T @ unitary, np.eye(dim)) 23 | 24 | return unitary 25 | 26 | 27 | def simulate_probability(unitary: np.ndarray, bitstring:int) -> float: 28 | # simulates the probability of measuring bitstring when evolving from the ground state 29 | # according to the quantum program given unitary 30 | return np.abs(unitary[bitstring, 0])**2 31 | 32 | 33 | def quantum_sample_probability(n_qubits: int, trials: int) -> List: 34 | # returns the probabilities of a randomly chosen bistring outcome over "trials" number of different 35 | # random quantum programs on n_qubits 36 | 37 | dimension = 2**n_qubits 38 | # picks a random bitstring as labelled by the integers 1 to 2**n_qubits 39 | bitstring = np.random.choice(dimension) 40 | 41 | # keeps track of the probability of sampling the (randomly) chosen bitstring 42 | probs_bitstring = [] 43 | # simulate the execution of many Haar-random quantum programs 44 | for _ in range(trials): 45 | unitary = random_unitary(dimension) 46 | prob = simulate_probability(unitary, bitstring) 47 | probs_bitstring.append(prob) 48 | 49 | return probs_bitstring 50 | 51 | 52 | def random_bitstring_probs(n_qubits: int, n_programs: int) -> List: 53 | dim = 2**n_qubits 54 | # keep track of probability of sampling (randomly) chosen bitstring 55 | probs_bitstring = [] 56 | # simulate many Haar-random circuits 57 | for _ in range(n_programs): 58 | unitary = random_unitary(dim) 59 | bitstring = np.random.choice(dim, p=[np.abs(unitary[b,0])**2 for b in range(dim)]) 60 | prob = np.abs(unitary[bitstring,0])**2 61 | probs_bitstring.append(prob) 62 | return probs_bitstring 63 | 64 | 65 | def fidelity_xeb(n_qubits: int, trials: int, n_samples: int, sampler: Callable[[np.ndarray, int], float]) -> float: 66 | dim = 2**n_qubits 67 | # keep track of the ideal simulated probabilities 68 | ideal_probs = [] 69 | # loop over the random programs 70 | for _ in range(trials): 71 | unitary = random_unitary(dim) 72 | sample_probs = [sampler(unitary, bb) for bb in range(dim)] 73 | samples = np.random.choice(dim, size=n_samples, p=sample_probs) 74 | for sample in samples: 75 | ideal_prob = simulate_probability(unitary, sample) 76 | ideal_probs.append(ideal_prob) 77 | 78 | return dim*np.mean(ideal_probs) - 1 79 | 80 | 81 | def fidelity_xeb_noisy(n_qubits: int, trials: int, n_samples: int, prob_no_error: float) -> float: 82 | dim = 2**n_qubits 83 | 84 | # keep track of ideal output probabilities 85 | ideal_probs = [] 86 | 87 | # identify 1q Pauli operators 88 | sI = np.array([[1, 0], [0, 1]]) 89 | sX = np.array([[0, 1], [1, 0]]) 90 | sY = np.array([[0, -1j], [1j, 0]]) 91 | sZ = np.array([[1, 0], [0, -1]]) 92 | paulis = [sI, sX, sY, sZ] 93 | 94 | # identify depolarizing operators over n-qubit space 95 | depolarizing_ops = [] 96 | for x in itertools.product(paulis, repeat=n_qubits): 97 | op = functools.reduce(lambda a, b: np.kron(a, b), x) 98 | depolarizing_ops.append(op) 99 | 100 | # loop over random programs 101 | for _ in range(trials): 102 | unitary = random_unitary(dim) 103 | 104 | # sample an operator according to specified probabilities 105 | all_ops = [unitary] + depolarizing_ops 106 | probabilities = [prob_no_error] + len(depolarizing_ops)*[(1-prob_no_error)/len(depolarizing_ops)] 107 | op_idx = np.random.choice(len(all_ops), p=probabilities) 108 | op = all_ops[op_idx] 109 | 110 | # draw samples from the resultant state 111 | sample_probs = [simulate_probability(op, bb) for bb in range(dim)] 112 | samples = np.random.choice(dim, size=n_samples, p=sample_probs) 113 | 114 | # collect ideal sampling probability for these samples 115 | for sample in samples: 116 | ideal_prob = simulate_probability(unitary, sample) 117 | ideal_probs.append(ideal_prob) 118 | 119 | # calculate and return the fidelity of the XEB 120 | return dim*np.mean(ideal_probs) - 1 121 | 122 | 123 | if __name__ == "__main__": 124 | # empirical Porter-Thomas distribution 125 | n_qubits = 4 126 | porter_thomas = quantum_sample_probability(n_qubits, 10_000) 127 | 128 | # theoretical Porter-Thomas distribution 129 | dim = 2**n_qubits 130 | xspace = np.linspace(0.0, 1.0, 100) 131 | yspace = dim * np.exp(-dim*xspace) 132 | 133 | # plot both empirical and theoretical calculations 134 | plt.figure(figsize=(9, 6)) 135 | plt.hist(porter_thomas, bins=50, density=True, label='Empirical Distribution') 136 | plt.plot(xspace, yspace, label='Theoretical Porter-Thomas Distribution') 137 | # plot the uniform distribution for reference 138 | plt.axvline(x=1/dim, linestyle='dotted', color='r', label='Uniform Distribution') 139 | 140 | plt.xlabel("Probability p") 141 | plt.ylabel("Probability that the random bistring occurs with probability p") 142 | plt.legend(loc='best') 143 | plt.show() 144 | 145 | # empirical distribution of random bitstring probabilities 146 | rand_bb_probs = random_bitstring_probs(n_qubits, 10_000) 147 | yspace = xspace*(dim**2)*np.exp(-dim*xspace) 148 | 149 | # plot both empirical and theoretical calculations 150 | plt.figure(figsize=(9, 6)) 151 | plt.hist(rand_bb_probs, bins=50, density=True, label='Empirical') 152 | plt.plot(xspace, yspace, label='Theoretical') 153 | # plot the uniform distribution for reference 154 | plt.axvline(x=1/dim, linestyle='dotted', color='r', label='Uniform Distribution') 155 | 156 | plt.xlabel("Probability p") 157 | plt.ylabel("Probability that the random bistring occurs with probability p") 158 | plt.legend(loc='best') 159 | plt.show() 160 | 161 | # sample f_xeb for an ideal processor using the same parameters as in the Google paper 162 | f_xeb = fidelity_xeb(n_qubits=n_qubits, trials=10, n_samples=10**5, sampler=simulate_probability) 163 | print("Empirical FXEB: ", f_xeb) 164 | print("Theoretical FXEB: ", dim*(2/(dim+1)) - 1) 165 | print('\n') 166 | 167 | # sample f_xeb for a uniform distribution sampler 168 | def unif_dist(unitary, bitstring): 169 | return 1/dim # all bitstrings have the same probability 170 | unif_xeb = fidelity_xeb(n_qubits=n_qubits, trials=10, n_samples=10**5, sampler=unif_dist) 171 | print("Empirical FXEB of a uniform sampler: ", unif_xeb) 172 | print("Theoretical FXEB of a uniform sampler", 0.0) 173 | print('\n') 174 | 175 | # run the noisy experiment 176 | p = 0.7 177 | noisy_xeb = fidelity_xeb_noisy(n_qubits=6, trials=10**3, n_samples=10, prob_no_error=p) 178 | print("Empirical FXEB of a noisy simulation: ", noisy_xeb) 179 | print("Theoretical FXEB of a noisy simulation: ", p*(dim-1)/(dim+1)) 180 | -------------------------------------------------------------------------------- /xeb_calcs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import numpy as np\n", 12 | "from xeb import (random_unitary, simulate_probability, quantum_sample_probability,\n", 13 | " random_bitstring_probs, fidelity_xeb, fidelity_xeb_noisy)" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## Background" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "#### QC Intro" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "A quick introduction to quantum states and unitary operations" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "Bitstring 00 has probability 1.0\n", 47 | "Bitstring 01 has probability 0\n", 48 | "Bitstring 10 has probability 0\n", 49 | "Bitstring 11 has probability 0\n", 50 | "\n", 51 | "Bitstring 00 has probability 0\n", 52 | "Bitstring 01 has probability 0.4999999999999999\n", 53 | "Bitstring 10 has probability 0\n", 54 | "Bitstring 11 has probability 0.4999999999999999\n", 55 | "\n", 56 | "Bitstring 00 has probability 0.0\n", 57 | "Bitstring 01 has probability 0.0\n", 58 | "Bitstring 10 has probability 1.0\n", 59 | "Bitstring 11 has probability 0.0\n", 60 | "\n", 61 | "Bitstring 00 has probability 0.0\n", 62 | "Bitstring 01 has probability 0.0\n", 63 | "Bitstring 10 has probability 1.0\n", 64 | "Bitstring 11 has probability 0.0\n", 65 | "\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# the state of N qubits is a complex vector of dimension 2^N\n", 71 | "n_qubits = 2\n", 72 | "dimension = 2 ** n_qubits\n", 73 | "state = [1j, 0, 0, 0]\n", 74 | "\n", 75 | "def print_probs(state, n_qubits):\n", 76 | " # the elements of this state are squared to calculate outcome probabilities\n", 77 | " for bitstring in range(n_qubits ** 2):\n", 78 | " probability = np.abs(state[bitstring]) ** 2\n", 79 | "\n", 80 | " print(\"Bitstring\", format(bitstring, \"0\" + str(n_qubits) + \"b\"), \" has probability \", probability)\n", 81 | " print()\n", 82 | "\n", 83 | "print_probs(state, n_qubits)\n", 84 | "# an example with a \"superposition\" over outcomes\n", 85 | "print_probs([0, -1j / np.sqrt(2), 0, 1 / np.sqrt(2)], n_qubits)\n", 86 | "\n", 87 | "# evolution is then given by a unitary matrix\n", 88 | "identity = np.array([[1, 0], [0, 1]]) # identity on one qubit\n", 89 | "flip = np.array([[0, 1], [1, 0]]) # a flip or X-gate on one qubits\n", 90 | "flip_first = np.kron(flip, identity) # tensor products make this a two qubit operation\n", 91 | "\n", 92 | "new_state = flip_first@state\n", 93 | "print_probs(new_state, n_qubits)\n", 94 | "\n", 95 | "flip_second = np.kron(identity, flip)\n", 96 | "print_probs(new_state, n_qubits)\n", 97 | "\n", 98 | "# if we start in the state with all qubits in zero\n", 99 | "# then we can take a shortcut to get the probabilities of any particular bitstring\n", 100 | "all_zeros = [1] + [0]*(dimension-1)\n", 101 | "bs = np.random.choice(range(dimension))\n", 102 | "assert (flip_second@all_zeros)[bs] == flip_second[bs, 0]" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "#### Porter-Thomas distribution" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "Fix a bitstring, sample several random quantum programs, and record the ideal probability of sampling this bitstring. The distribution over these ideal probabilities gives us the Porter-Thomas distribution." 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 3, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiYAAAFzCAYAAAAKZcKfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nOzde5zWc/7/8cdrprOmcxTFlE2oqemgk3QgtCSEJWtJP9pY5+9asTa0Dlms8zpuiiztipDDEpVNSGXIIYdSSuikk84zr98fn2vGlGuu+czMdV1zzdXzfrt9bp/rc3q/X3NR8+r9eR/M3RERERFJBRmVHYCIiIhIISUmIiIikjKUmIiIiEjKUGIiIiIiKUOJiYiIiKQMJSYiIiKSMqpVdgBhNGnSxLOzsys7jIorKAj2GcoHRURkzzVv3rzV7t402rUqkZhkZ2czd+7cyg5DRERE4sDMlpZ0Tf90T6aJE4NNREREoqoSLSZp49FHg/1ZZ1VuHCIiIilKiUkyvf56ZUcgIiKS0pSYJFP16pUdgUha27FjB8uXL2fr1q2VHYqIALVq1aJFixZUL8PvPyUmyTR+fLAfNqwyoxBJW8uXLycrK4vs7GzMrLLDEdmjuTtr1qxh+fLltGrVKvRz6vyaTOPH/5yciEjcbd26lcaNGyspEUkBZkbjxo3L3IKpFpNkmjGjsiMQSXtKSkRSR3n+PKrFREQkTtasWUNubi65ubk0a9aM/fbbj9zcXBo0aMChhx6a1Fjy8vJ4+eWXi45feOEFxo4dW66ysrOzWb16ddTzOTk5dOzYkWOOOYbvv/++TOXeddddbN68uVwxQcnfd25uLl988QXt27cvd9mJcP311xfF2KZNG4YMGcKnn35adP28887b5Xh348ePZ8WKFSVeHz16NNOmTQNK/m9WkiVLlvCvf/2r6Hju3LlccskloZ+PJyUmyfTII8EmImmpcePG5OXlkZeXx8iRI7n88suLjjMSMOPzzp07S7y2e2IyePBgRo0aFfcYpk+fzocffkjXrl25+eabQz+Xn59frsQkPz+/6HOs77tGjRplKjdZCmP88ssvOf300znyyCNZtWoVAI8++mjMBDZWYpKfn8+YMWMYMGBAueLaPTHp2rUr99xzT7nKqiglJsk0aVKwicgeJz8/n/PPP5927dpxzDHHsGXLFgAWLVrEwIED6dKlC0cccQQLFy4EYOnSpRx11FF06NCBo446im+++QaAYcOGccUVV9C/f3+uuuoqfvrpJ4YPH85hhx1Gp06deP7559m+fTujR49m0qRJ5ObmMmnSJMaPH89FF10EwA8//MDJJ59Mx44d6dixI7NnzwbgpJNOokuXLrRr146HH364TD9fnz59+OqrrwB46qmnyMnJoX379lx11VVF99StW5fRo0fTvXt3brrpJlasWEH//v3p378/AK+99ho9e/akc+fOnHbaaWzatAkI/vU/ZswYevfuzX/+858Kf+d5eXn06NGDDh06cPLJJ/Pjjz8C0K9fPy6//HL69OnDIYccwvvvv8+QIUNo06YN1157bVG50b6n/Px8hg0bRvv27cnJyeHOO+8sNb7TTz+dY445pigh6NevH3Pnzo1a1jPPPMPcuXP57W9/S25uLlu2bPnF9zJs2DCeeeaZovJvu+02unXrRrdu3Yr+2+x+T926dQEYNWoU//vf/8jNzeXOO+9kxowZDBo0CIC1a9dy0kkn0aFDB3r06MFHH30EBC1Aw4cPp1+/frRu3TpuiUyoPiZm1hnoDTjwtrvPD/HMOGAQsNLd2xc7fzFwEbATeMnd/1SewKukSBObiCTBK6Pg+wXxLbNZDvy6fK9DvvzyS5566ikeeeQRfvOb3zB58mTOOussRowYwYMPPkibNm147733uPDCC3nzzTe56KKLOPvssznnnHMYN24cl1xyCVOmTAHgiy++YNq0aWRmZnLNNddw5JFHMm7cONatW0e3bt0YMGAAY8aMYe7cudx3331A8K/tQpdccgl9+/blueeeIz8/vygBGDduHI0aNWLLli0cdthhnHLKKTRu3DjUzzd16lRycnJYsWIFV111FfPmzaNhw4Ycc8wxTJkyhZNOOomffvqJ9u3bM2bMmKL6pk+fTpMmTVi9ejU33ngj06ZNY6+99uLWW2/l73//O6NHjwaCYaezZs2Ky3d+9tlnc++999K3b19Gjx7NDTfcwF133QVAjRo1eOutt7j77rs58cQTmTdvHo0aNeLAAw/k8ssvp3HjxlG/pyVLlvDtt9/y8ccfA7Bu3bpQMXbu3LkoGS2Ul5f3i7IaNGjAfffdx+23307Xrl2L7i3+vbz66qu7lFOvXj3mzJnD448/zmWXXcbUqVNLjGPs2LHc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\n", 127 | "text/plain": [ 128 | "
" 129 | ] 130 | }, 131 | "metadata": { 132 | "needs_background": "light" 133 | }, 134 | "output_type": "display_data" 135 | } 136 | ], 137 | "source": [ 138 | "n_qubits = 4\n", 139 | "porter_thomas = quantum_sample_probability(n_qubits, 10_000)\n", 140 | "\n", 141 | "# theoretical Porter-Thomas distribution\n", 142 | "dim = 2**n_qubits\n", 143 | "xspace = np.linspace(0.0, 1.0, 100)\n", 144 | "yspace = dim * np.exp(-dim*xspace)\n", 145 | "\n", 146 | "# plot both empirical and theoretical calculations\n", 147 | "plt.figure(figsize=(9, 6))\n", 148 | "plt.hist(porter_thomas, bins=50, density=True, label='Empirical Distribution')\n", 149 | "plt.plot(xspace, yspace, label='Theoretical Porter-Thomas Distribution')\n", 150 | "# plot the uniform distribution for reference\n", 151 | "plt.axvline(x=1/dim, linestyle='dotted', color='r', label='Uniform Distribution')\n", 152 | "\n", 153 | "plt.xlabel(\"Probability p\")\n", 154 | "plt.ylabel(\"Probability that the random bistring occurs with probability p\")\n", 155 | "plt.legend(loc='best')\n", 156 | "plt.show()" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": {}, 162 | "source": [ 163 | "#### Probability distributions of random bitstrings" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "This time, we won't fix the bitstring in advance but rather sample it from the random quantum program, and then record its ideal probability. The distribution of these ideal probabilities is then plotted below." 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 4, 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "data": { 180 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAFzCAYAAACeg2ttAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nOzdeXhV5bn+8e+TzRBQEBlUBDXgBEIYBEERFJCKrRRHFK1VtD+peqpWe6wcq6i0WqxatbbVOuLUirMo1oEZRUEEFFEcoKBUBQSZCZC9n98fO8GAIVlJ1tprJ7k/17WunT296yaHHh7f0dwdERERkUzJiTuAiIiI1C4qPkRERCSjVHyIiIhIRqn4EBERkYxS8SEiIiIZpeJDREREMqpO3AFKat68uefl5cUdo+pSqfRjjmo7ERGpvd57771v3b3Fzq9nVfGRl5fH7Nmz444hIiIiITCzpaW9rv80j8Ljj6cvERER+YGs6vmoMR54IP14zjnx5hAREclCKj6i8MYbcScQERHJWio+olC3btwJRERCs23bNpYtW0ZBQUHcUSRL5ebm0rp1a+oG/PdPxUcUxoxJPw4bFmcKEZFQLFu2jEaNGpGXl4eZxR1Hsoy7s2rVKpYtW0abNm0CfUcTTqMwZsz3BYiISDVXUFBAs2bNVHhIqcyMZs2aVahnTD0fUZgyJe4EIiKhUuEhZano3w/1fIiISFZbtWoVXbp0oUuXLuyzzz60atWKLl260KRJEw477LCMZpk3bx6vvPLK9ufjxo1j9OjRlWorLy+Pb7/9Nqxo1YqKjyjcf3/6EhGRKmvWrBnz5s1j3rx5XHTRRVxxxRXbn+dEsJN0YWHhLt/bufgYPHgwI0aMCD1DTafiIwpjx6YvERGJVDKZ5MILL6RDhw4cf/zxbN68GYBFixZxwgkn0K1bN/r06cPChQsBWLp0KccddxydOnXiuOOO44svvgBg2LBhXHnllfTr14+rr76ajRs3csEFF3DEEUfQtWtXXnzxRbZu3crIkSMZO3YsXbp0YezYsYwZM4Zf/epXACxfvpxTTjmFzp0707lzZ2bMmAHAySefTLdu3ejQoQP33XdfDL+l7BNozoeZHQ70Bhx4y93nRJqqupswIe4EIiLR+PcI+GZ+uG3ukw8/rtzQxWeffca//vUv7r//fs444wyeffZZzjnnHIYPH869997LwQcfzMyZM7nkkkuYNGkSv/rVrzj33HM577zzeOihh7jssst44YUXAPj000+ZMGECiUSCa665hv79+/PQQw+xZs0aevTowYABAxg1ahSzZ8/mr3/9KwBjSiwuuOyyyzj22GN5/vnnSSaTbNiwAYCHHnqIpk2bsnnzZo444ghOO+00mjVrVrXfWTVXbvFhZiOBIcBzRS89bGZPu/sfIk0mIiJSjjZt2tClSxcAunXrxpIlS9iwYQMzZsxgyJAh2z+3ZcsWAN5++22eey79z9nPf/5zfvvb327/zJAhQ0gkEgC8/vrrjBs3jttuuw1Ir/gp7iXZlUmTJvHoo48CkEgk2GOPPQD4y1/+wvPPPw/Al19+yWeffabiI8BnzgK6unsBgJmNBuYAKj525e9/Tz9eckm8OUREwlbJHoqo1K9ff/vPiUSCzZs3k0qlaNKkCfPmzSv3+yVXaey2227bf3Z3nn32WQ499NAdPj9z5swK5ZsyZQoTJkzg7bffpmHDhvTt21ebtRFszscSILfE8/rAokjS1BQvvZS+gLwR439wiYhIdBo3bkybNm14+umngXQh8f777wPQq1cvnnzySQCeeOIJevfuXWobAwcO5O6778bdAZg7dy4AjRo1Yv369aV+57jjjuOee+4B0nNR1q1bx9q1a9lzzz1p2LAhCxcu5J133gnvD1qNBSk+tgALzGyMmT0MfAhsMLO/mNlfoo1XTf373+lLRERi8cQTT/Dggw/SuXNnOnTowIsvvgikh0AefvhhOnXqxGOPPcZdd91V6vevu+46tm3bRqdOnejYsSPXXXcdAP369eOjjz7aPuG0pLvuuovJkyeTn59Pt27dWLBgASeccAKFhYV06tSJ6667jiOPPDLaP3g1YcVV3S4/YHZeWe+7+yNhhenevbvPnj07rOayQmk9HUtGnxhDEhGRyvn4449p37593DEky5X298TM3nP37jt/ttw5H2EWF7VGcSV9+eXx5hAREclC2ucjChMnpi8RERH5AZ3tEoVx4+JOICIikrXK7fkws46ZCCIiIiK1Q5Bhl3vNbJaZXWJmTSJPVBPcdlv6EhERkR8IMuG0t5kdDFwAzDazWcDD7v5G5Omqq7ffjjuBiIhI1go04dTdPwOuBa4GjgX+YmYLzezUKMNVW88+m75ERKTKlixZQseOO84AuOGGG7Zvfb4rs2fP5rLLLgPS26sPGDCg1P05wpaXl0d+fj75+fkcdthhXHvttdu3d//qq684/fTTd/ndNWvW8PfiXbJ3oVevXkB699RBgwZVKNsLL7zARx99tP35yJEjmRDDeWRB5nx0MrM7gI+B/sBP3b190c93RJxPRESkUrp3785f/pLeC3Pu3Lls27aNefPmceaZZwb6fjKZrPS9J0+ezPz585k1axaLFy9m+PDhAOy7774888wzu/xeWcVHcZ7i03IrY+fiY9SoUQwYMKDS7VVWkJ6Pv5I+y6Wzu/9P8Ym27v4V6d4Q2dno0elLREQi17dvX66++mp69OjBIYccwvTp04HvewZWrFjBOeecw7x58+jSpQuLFi1i4sSJdO3alfz8fC644ILtPRN5eXmMGjWK3r178/TTT9O3b1+uuOIKjjnmGNq3b8+7777LqaeeysEHH8y115b/T+Duu+/OvffeywsvvMDq1at36MVZsGABPXr0oEuXLnTq1InPPvuMESNGsGjRIrp06cJVV13FlClT6NevH2effTb5+fnb2yy2bt06TjnlFA477DAuuugiUqnUDz7zzDPPMGzYMGbMmMG4ceO46qqrtv8ehg0btr0YKut3cv3113P44YeTn5/PwoULq/p/skDFx3Pu/pi7by5+wcwuB3D3x6qcoCaaNy99iYjURH37QvFR8tu2pZ8//nj6+aZN6efFQxtr16afF50ky7ffpp8XnX/FN9+EEqmwsJBZs2Zx5513cuONN+7w3l577cUDDzxAnz59mDdvHq1atWLYsGGMHTuW+fPnU1hYuP1MFoDc3FzefPNNhg4dCkC9evWYNm0aF110ESeddBJ/+9vf+PDDDxkzZgyrVq0qN1vxWTOfffbZDq/fe++9XH755cybN4/Zs2fTunVrRo8ezYEHHsi8efO49dZbAZg1axY33XTTDj0WxWbNmsXtt9/O/PnzWbRo0fYTe0vTq1cvBg8ezK233sq8efM48MADt79XUFBQ5u+kefPmzJkzh4svvrjc4a4gghQf55by2rAq37kme/LJ9CUiIlVW8uTZXb1+6qnpKYjdunVjyZIlZbb3ySef0KZNGw455BAAzjvvPKZNm7b9/Z2HZQYPHgxAfn4+HTp0oGXLltSvX5+2bdvy5ZdfBvozlHaUyVFHHcXNN9/MLbfcwtKlS2nQ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\n", 181 | "text/plain": [ 182 | "
" 183 | ] 184 | }, 185 | "metadata": { 186 | "needs_background": "light" 187 | }, 188 | "output_type": "display_data" 189 | } 190 | ], 191 | "source": [ 192 | "rand_bb_probs = random_bitstring_probs(n_qubits, 10_000)\n", 193 | "yspace = xspace*(dim**2)*np.exp(-dim*xspace)\n", 194 | "\n", 195 | "# plot both empirical and theoretical calculations\n", 196 | "plt.figure(figsize=(9, 6))\n", 197 | "plt.hist(rand_bb_probs, bins=50, density=True, label='Empirical')\n", 198 | "plt.plot(xspace, yspace, label='Theoretical')\n", 199 | "# plot the uniform distribution for reference\n", 200 | "plt.axvline(x=1/dim, linestyle='dotted', color='r', label='Uniform Distribution')\n", 201 | "\n", 202 | "plt.xlabel(\"Probability p\")\n", 203 | "plt.ylabel(\"Probability that the random bistring occurs with probability p\")\n", 204 | "plt.legend(loc='best')\n", 205 | "plt.show()" 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "metadata": {}, 211 | "source": [ 212 | "## Calculations of the Cross-Entropy Benchmark Fidelity" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "#### F_XEB of ideal quantum processor" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": {}, 225 | "source": [ 226 | "First, we'll pick a large number of random quantum programs, and draw one sample each from those programs. The resultant F_XEB has low variance (for a sufficiently large number of random quantum programs) compared to the choice of these parameters reported in the Nature paper." 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 5, 232 | "metadata": {}, 233 | "outputs": [ 234 | { 235 | "name": "stdout", 236 | "output_type": "stream", 237 | "text": [ 238 | "Empirical FXEB: 0.876306861535801\n", 239 | "Theoretical FXEB: 0.8823529411764706\n" 240 | ] 241 | } 242 | ], 243 | "source": [ 244 | "# sample f_xeb using parameters giving comparitively low-variance result\n", 245 | "n_qubits = 4\n", 246 | "dim = 2**n_qubits\n", 247 | "f_xeb = fidelity_xeb(n_qubits=n_qubits, trials=10**4, n_samples=10**0, sampler=simulate_probability)\n", 248 | "print(\"Empirical FXEB: \", f_xeb)\n", 249 | "print(\"Theoretical FXEB: \", dim*(2/(dim+1)) - 1)" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "Next, we'll run the same calculation, this time using the parameters from the supremacy paper appearing in Nature." 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 6, 262 | "metadata": {}, 263 | "outputs": [ 264 | { 265 | "name": "stdout", 266 | "output_type": "stream", 267 | "text": [ 268 | "Empirical FXEB: 0.8144051535557424\n", 269 | "Theoretical FXEB: 0.8823529411764706\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "# sample f_xeb using the same parameters as in the Google paper\n", 275 | "n_qubits = 4\n", 276 | "dim = 2**n_qubits\n", 277 | "f_xeb = fidelity_xeb(n_qubits=n_qubits, trials=10, n_samples=10**5, sampler=simulate_probability)\n", 278 | "print(\"Empirical FXEB: \", f_xeb)\n", 279 | "print(\"Theoretical FXEB: \", dim*(2/(dim+1)) - 1)" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": {}, 285 | "source": [ 286 | "#### F_XEB of uniform sampler" 287 | ] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "As a reference, we compare against a uniform sampler." 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": 7, 299 | "metadata": {}, 300 | "outputs": [ 301 | { 302 | "name": "stdout", 303 | "output_type": "stream", 304 | "text": [ 305 | "Empirical FXEB of a uniform sampler: -0.000531967620212459\n", 306 | "Theoretical FXEB of a uniform sampler: 0.0\n" 307 | ] 308 | } 309 | ], 310 | "source": [ 311 | "def unif_dist(unitary, bitstring):\n", 312 | " return 1/dim # all bitstrings have the same probability\n", 313 | "unif_xeb = fidelity_xeb(n_qubits=n_qubits, trials=10, n_samples=10**5, sampler=unif_dist)\n", 314 | "print(\"Empirical FXEB of a uniform sampler: \", unif_xeb)\n", 315 | "print(\"Theoretical FXEB of a uniform sampler: \", 0.0)" 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "metadata": {}, 321 | "source": [ 322 | "#### F_XEB of a noisy quantum processor" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "Depolarizing noise changes the value of F_XEB." 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 8, 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "name": "stdout", 339 | "output_type": "stream", 340 | "text": [ 341 | "Empirical FXEB of a noisy simulation: 0.6087378676438175\n", 342 | "Theoretical FXEB of a noisy simulation: 0.6176470588235294\n" 343 | ] 344 | } 345 | ], 346 | "source": [ 347 | "# run the noisy experiment\n", 348 | "p = 0.7\n", 349 | "n_qubits = 4\n", 350 | "dim = 2**n_qubits\n", 351 | "noisy_xeb = fidelity_xeb_noisy(n_qubits=4, trials=10**4, n_samples=10**0, prob_no_error=p)\n", 352 | "print(\"Empirical FXEB of a noisy simulation: \", noisy_xeb)\n", 353 | "print(\"Theoretical FXEB of a noisy simulation: \", p*(dim-1)/(dim+1))" 354 | ] 355 | } 356 | ], 357 | "metadata": { 358 | "kernelspec": { 359 | "display_name": "Python 3", 360 | "language": "python", 361 | "name": "python3" 362 | }, 363 | "language_info": { 364 | "codemirror_mode": { 365 | "name": "ipython", 366 | "version": 3 367 | }, 368 | "file_extension": ".py", 369 | "mimetype": "text/x-python", 370 | "name": "python", 371 | "nbconvert_exporter": "python", 372 | "pygments_lexer": "ipython3", 373 | "version": "3.6.9" 374 | } 375 | }, 376 | "nbformat": 4, 377 | "nbformat_minor": 2 378 | } 379 | --------------------------------------------------------------------------------