diff --git a/docs/examples/volumetrics.ipynb b/docs/examples/volumetrics.ipynb new file mode 100644 index 00000000..c0d5d8b1 --- /dev/null +++ b/docs/examples/volumetrics.ipynb @@ -0,0 +1,2067 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Volumetrics\n", + "\n", + "\n", + "This module that generates circuits on a graph which represents the QPU or QVM lattice. The basic idea is it will compute error rates of circuits as a function of depth and width.\n", + "\n", + "The `width` of the circuit is the number of connected vertices on a particular subgraph.\n", + "\n", + "The `depth` is defined in context-dependent way; to avoid confusion with circuit depth we may use the term 'repetitions'." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/kylegulshen/anaconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n", + " return f(*args, **kwds)\n" + ] + } + ], + "source": [ + "import random\n", + "import itertools\n", + "import networkx as nx\n", + "import numpy as np\n", + "import time\n", + "\n", + "from matplotlib import pyplot as plt\n", + "from pyquil.api import get_qc, QuantumComputer, get_benchmarker\n", + "from pyquil.gates import CNOT, CCNOT, Z, X, I, H, CZ, MEASURE, RESET\n", + "from pyquil.quilbase import Pragma\n", + "\n", + "from forest.benchmarking.volumetrics import *\n", + "\n", + "\n", + "bm = get_benchmarker()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get lattice" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from pyquil import *\n", + "# if you want to run on a \"real lattice\"\n", + "#list_quantum_computers()\n", + "#perfect_qc = get_qc(\"Aspen-1-16Q-A\", as_qvm=True, noisy=False)\n", + "#noisy_qc = get_qc(\"Aspen-1-16Q-A\") #, as_qvm=True, noisy=True)\n", + "\n", + "noisy_qc = get_qc(\"9q-square-qvm\", as_qvm=True, noisy=True)\n", + "perfect_qc = get_qc(\"9q-square-qvm\", as_qvm=True, noisy=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/kylegulshen/anaconda3/lib/python3.6/site-packages/networkx/drawing/nx_pylab.py:518: MatplotlibDeprecationWarning: \n", + "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", + " if not cb.iterable(width):\n", + "/home/kylegulshen/anaconda3/lib/python3.6/site-packages/networkx/drawing/nx_pylab.py:565: MatplotlibDeprecationWarning: \n", + "The is_numlike function was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use isinstance(..., numbers.Number) instead.\n", + " if cb.is_numlike(alpha):\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "nx.draw(perfect_qc.qubit_topology(),with_labels=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "G = perfect_qc.qubit_topology()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Gate sets\n", + "\n", + "### Classical" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def two_q_id(qb1,qb2):\n", + " prog = Program()\n", + " prog +=I(qb1)\n", + " prog +=I(qb2)\n", + " return prog\n", + "\n", + "one_c_gates = [X,I]\n", + "two_c_gates = [two_q_id, CNOT]\n", + "two_c_toffoli = two_c_gates + [CCNOT]\n", + "\n", + "# x basis gates\n", + "from forest.benchmarking.classical_logic import CNOT_X_basis, CCNOT_X_basis\n", + "one_x_c_gates = [Z, I]\n", + "two_x_c_gates = [two_q_id, CNOT_X_basis]\n", + "two_x_c_toffoli = two_x_c_gates + [CCNOT_X_basis]\n", + "# if you want to do something in the X basis, add Hadamard layers appropriately; see below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Some quantum" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "one_q_gates = [X,Z,I]\n", + "two_q_gates = [two_q_id,CZ]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Random Cliffords\n", + "\n", + "We use a benchmarker for this. Typically we use the native gates from `get_rb_gateset` to implement each clifford." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RX(pi/2) 0\n", + "\n" + ] + } + ], + "source": [ + "from forest.benchmarking.randomized_benchmarking import get_rb_gateset\n", + "print(bm.generate_rb_sequence(depth=2, gateset=get_rb_gateset([0]))[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get random gates on a graph" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X 0\n", + "I 1\n", + "X 2\n", + "Z 3\n", + "Z 4\n", + "I 5\n", + "X 6\n", + "X 7\n", + "I 8\n", + "I 0\n", + "I 3\n", + "CZ 0 1\n", + "I 1\n", + "I 4\n", + "CZ 1 2\n", + "I 2\n", + "I 5\n", + "CZ 3 6\n", + "I 3\n", + "I 4\n", + "I 4\n", + "I 7\n", + "I 4\n", + "I 5\n", + "CZ 5 8\n", + "I 6\n", + "I 7\n", + "I 7\n", + "I 8\n", + "\n" + ] + } + ], + "source": [ + "from forest.benchmarking.volumetrics._generators import random_single_qubit_gates, random_two_qubit_gates\n", + "prog1 = random_single_qubit_gates(G, one_q_gates)\n", + "prog2 = random_two_qubit_gates(G, two_q_gates)\n", + "print(prog1+prog2)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RX(-pi/2) 0\n", + "RZ(-pi/2) 0\n", + "RX(-pi/2) 0\n", + "RX(-pi/2) 1\n", + "RZ(-pi/2) 1\n", + "RX(-pi) 2\n", + "RZ(-pi/2) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 4\n", + "RX(-pi) 4\n", + "RX(pi/2) 5\n", + "RZ(-pi) 5\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RZ(-pi) 7\n", + "RZ(-pi) 7\n", + "RX(-pi/2) 8\n", + "RZ(pi/2) 8\n", + "RX(-pi/2) 8\n", + "\n" + ] + } + ], + "source": [ + "from forest.benchmarking.volumetrics._generators import random_single_qubit_cliffords\n", + "\n", + "rand1qcliff = random_single_qubit_cliffords(bm, G)\n", + "print(rand1qcliff)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Make some circuit templates and sample programs from them\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I 5\n", + "X 8\n", + "X 5\n", + "X 8\n", + "\n" + ] + } + ], + "source": [ + "classical_1q_layer = get_rand_1q_template(one_c_gates)\n", + "print(classical_1q_layer.sample_program(G, repetitions=2, width=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CNOT 6 7\n", + "CNOT 6 7\n", + "\n" + ] + } + ], + "source": [ + "classical_2q_layer = get_rand_2q_template(two_c_gates)\n", + "print(classical_2q_layer.sample_program(G, repetitions=2, width=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CZ 4 5\n", + "RZ(pi/2) 5\n", + "RX(pi/2) 5\n", + "RX(pi/2) 4\n", + "CZ 4 5\n", + "RX(pi/2) 5\n", + "RZ(-pi/2) 5\n", + "RX(-pi/2) 4\n", + "CZ 4 5\n", + "RX(-pi/2) 5\n", + "RZ(pi/2) 4\n", + "RX(pi/2) 4\n", + "CZ 4 5\n", + "RX(-pi/2) 5\n", + "RX(pi/2) 4\n", + "CZ 4 5\n", + "RX(-pi/2) 5\n", + "\n" + ] + } + ], + "source": [ + "clifford_1q_layer = get_rand_1q_cliff_template(bm)\n", + "clifford_2q_layer = get_rand_2q_cliff_template(bm)\n", + "print(clifford_2q_layer.sample_program(G, repetitions=2, width=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DEFGATE LYR0_RSU4_8_5:\n", + " -0.06740625349879759-0.014045321406165294i, 0.2968943368678356-0.4765007530477127i, 0.15175567111229893-0.30564943412758033i, -0.6954532809045382-0.2827601188259824i\n", + " 0.6638702337657884+0.026452398485650015i, -0.09700059763023283+0.11342360586736261i, 0.24893503615880685-0.6703191115524492i, 0.15689771231565453+0.019730619752048928i\n", + " -0.36190874503911585-0.3828986284927636i, -0.07124472148124422-0.5342898321092627i, 0.34887965587582004-0.20161203347299655i, 0.5142180741895144+0.07130646099736504i\n", + " 0.4754516917187752-0.2240359316589525i, -0.49516048709318333-0.35609185859768144i, 0.021039783792687297+0.4576518079672631i, -0.05393976351873825-0.37278803964631857i\n", + "\n", + "LYR0_RSU4_8_5 8 5\n", + "\n" + ] + } + ], + "source": [ + "rand_su4_layer = get_rand_su4_template()\n", + "print(rand_su4_layer.sample_program(G, 1, qc=noisy_qc, width=2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compose templates" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X 2\n", + "X 3\n", + "X 4\n", + "X 5\n", + "CNOT 2 5\n", + "CNOT 3 4\n", + "CNOT 4 5\n", + "X 2\n", + "I 3\n", + "I 4\n", + "X 5\n", + "CNOT 2 5\n", + "CNOT 3 4\n", + "I 4\n", + "I 5\n", + "\n" + ] + } + ], + "source": [ + "classical_1q_2q = classical_1q_layer + classical_2q_layer\n", + "print(classical_1q_2q.sample_program(G, repetitions=2, width=4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Classical Logic in X basis\n", + "\n", + "Add a `sequence_transform` for the template to insert the basis change H gates at beginning and end." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "H 0\n", + "H 1\n", + "I 0\n", + "I 1\n", + "H 0\n", + "CZ 0 1\n", + "H 0\n", + "Z 0\n", + "I 1\n", + "H 0\n", + "CZ 0 1\n", + "H 0\n", + "I 0\n", + "Z 1\n", + "I 0\n", + "I 1\n", + "H 0\n", + "H 1\n", + "\n" + ] + } + ], + "source": [ + "classical_x_1q_2q = get_rand_1q_template(one_x_c_gates) + get_rand_2q_template(two_x_c_gates)\n", + "# here we demonstrate a simple use of a sequence_transform. We want to switch to the x basis \n", + "# at thebeginning of our circuite and switch back to the Z basis before measurement. \n", + "# To accomplish this we set a 'sequnce_transform' to be applied after the circuit sequence is generated.\n", + "classical_x_1q_2q.sequence_transforms.append(hadamard_sandwich)\n", + "print(classical_x_1q_2q.sample_program(G, repetitions=3, width=2))\n", + "# note that the x basis CNOT(0, 1) is H(0) CZ(0, 1) H(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Daggering the circuit to get a self-inverting sandwich.\n", + "Here we again add a `sequence_transform` to transform the sampled sequence by appending its dagger (aka Hermitian conjugate, adjoint, etc.)." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RX(-pi/2) 1\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 1 4\n", + "RZ(-pi/2) 4\n", + "RX(pi/2) 4\n", + "RX(pi/2) 1\n", + "CZ 1 4\n", + "RZ(-pi/2) 4\n", + "RZ(pi/2) 1\n", + "RZ(-pi) 1\n", + "RZ(-pi/2) 4\n", + "RX(-pi) 4\n", + "RX(-pi/2) 4\n", + "CZ 1 4\n", + "RX(-pi/2) 1\n", + "CZ 1 4\n", + "RX(-pi/2) 4\n", + "RZ(-pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(-pi) 1\n", + "RZ(pi/2) 1\n", + "RX(-pi) 4\n", + "RX(-pi/2) 4\n", + "RX(pi/2) 1\n", + "CZ 1 4\n", + "RX(pi/2) 4\n", + "RZ(-pi/2) 1\n", + "RX(pi/2) 1\n", + "CZ 1 4\n", + "RX(-pi/2) 4\n", + "RX(-pi/2) 1\n", + "DAGGER RX(-pi/2) 1\n", + "DAGGER RX(-pi/2) 4\n", + "DAGGER CZ 1 4\n", + "DAGGER RX(pi/2) 1\n", + "DAGGER RZ(-pi/2) 1\n", + "DAGGER RX(pi/2) 4\n", + "DAGGER CZ 1 4\n", + "DAGGER RX(pi/2) 1\n", + "DAGGER RX(-pi/2) 4\n", + "DAGGER RX(-pi) 4\n", + "DAGGER RZ(pi/2) 1\n", + "DAGGER RZ(-pi) 1\n", + "DAGGER RX(-pi/2) 4\n", + "DAGGER RZ(-pi/2) 4\n", + "DAGGER RX(-pi/2) 4\n", + "DAGGER CZ 1 4\n", + "DAGGER RX(-pi/2) 1\n", + "DAGGER CZ 1 4\n", + "DAGGER RX(-pi/2) 4\n", + "DAGGER RX(-pi) 4\n", + "DAGGER RZ(-pi/2) 4\n", + "DAGGER RZ(-pi) 1\n", + "DAGGER RZ(pi/2) 1\n", + "DAGGER RZ(-pi/2) 4\n", + "DAGGER CZ 1 4\n", + "DAGGER RX(pi/2) 1\n", + "DAGGER RX(pi/2) 4\n", + "DAGGER RZ(-pi/2) 4\n", + "DAGGER CZ 1 4\n", + "DAGGER RX(-pi/2) 4\n", + "DAGGER RZ(pi/2) 4\n", + "DAGGER RX(pi/2) 4\n", + "DAGGER RX(-pi/2) 1\n", + "\n", + "This program compiles away to nothing: \n", + "HALT\n", + "\n" + ] + } + ], + "source": [ + "clifford_sandwich = clifford_1q_layer + clifford_2q_layer\n", + "clifford_sandwich.sequence_transforms.append(dagger_sequence)\n", + "prog = clifford_sandwich.sample_program(G, repetitions=3, width=2, qc=noisy_qc)\n", + "print(prog)\n", + "\n", + "# We can check that this is the identity by compiling it fully\n", + "print(\"This program compiles away to nothing: \")\n", + "print(noisy_qc.compiler.quil_to_native_quil(prog))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Quantum Volume" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You could easily make your own Quantum Volume template:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RZ(2.4567535228446093) 2\n", + "RX(pi/2) 2\n", + "RZ(1.9079844139625592) 2\n", + "RX(-pi/2) 2\n", + "RZ(-0.98387329480434) 2\n", + "RZ(-2.9491179617564063) 5\n", + "RX(pi/2) 5\n", + "RZ(1.8350280635126637) 5\n", + "RX(-pi/2) 5\n", + "RZ(2.9144094282733226) 5\n", + "CZ 2 5\n", + "RZ(-pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(pi/2) 5\n", + "RX(pi/2) 5\n", + "RZ(2.555017505371151) 5\n", + "RX(-pi/2) 5\n", + "CZ 2 5\n", + "RZ(1.8140489262142276) 2\n", + "RX(pi/2) 2\n", + "RX(pi/2) 5\n", + "RZ(-1.5878683423805606) 5\n", + "RX(-pi/2) 5\n", + "CZ 2 5\n", + "RZ(-1.810401907235648) 8\n", + "RX(pi/2) 8\n", + "RZ(1.5887962435158791) 8\n", + "RX(-pi/2) 8\n", + "RZ(-2.180441355911783) 8\n", + "RZ(2.9971046352051487) 1\n", + "RX(pi/2) 1\n", + "RZ(1.7590571700067648) 1\n", + "RX(-pi/2) 1\n", + "RZ(-1.4375538292718586) 1\n", + "RZ(-0.2950219757493664) 2\n", + "RX(pi/2) 2\n", + "RZ(1.3247687649811228) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 1\n", + "RZ(-1.4015247592496605) 1\n", + "RX(pi/2) 1\n", + "RZ(1.7400678943401324) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 1\n", + "RX(-pi/2) 1\n", + "RX(pi/2) 2\n", + "CZ 2 1\n", + "RZ(2.713646613685171) 5\n", + "RX(pi/2) 5\n", + "RZ(1.8323569565381046) 5\n", + "RX(-pi/2) 5\n", + "CZ 8 5\n", + "RZ(-1.3009855714721716) 5\n", + "RX(pi/2) 5\n", + "RZ(-pi/2) 8\n", + "RX(-pi/2) 8\n", + "CZ 8 5\n", + "RX(-pi/2) 5\n", + "RX(pi/2) 8\n", + "CZ 8 5\n", + "RZ(-0.6349319473600517) 1\n", + "RX(pi/2) 1\n", + "RZ(1.9708638634728546) 1\n", + "RX(-pi/2) 1\n", + "RZ(1.712394198134794) 1\n", + "RZ(2.161700600790245) 2\n", + "RX(pi/2) 2\n", + "RZ(2.8439336725891353) 2\n", + "RX(-pi/2) 2\n", + "RZ(-2.713982049212584) 2\n", + "RZ(0.7875400069404053) 5\n", + "RX(pi/2) 5\n", + "RZ(2.7680474067191723) 5\n", + "RX(-pi/2) 5\n", + "RZ(-2.8177002556501947) 5\n", + "CZ 2 5\n", + "RZ(-pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(-pi/2) 5\n", + "RX(pi/2) 5\n", + "RZ(2.6034694674389662) 5\n", + "RX(-pi/2) 5\n", + "CZ 2 5\n", + "RZ(1.5071539967088885) 2\n", + "RX(pi/2) 2\n", + "RX(pi/2) 5\n", + "RZ(-2.0240752180248474) 5\n", + "RX(-pi/2) 5\n", + "CZ 2 5\n", + "RZ(-1.9435237706069035) 2\n", + "RX(pi/2) 2\n", + "RZ(1.8402109262991528) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 1\n", + "RX(pi/2) 1\n", + "RZ(2.281590186801594) 1\n", + "RX(-pi/2) 1\n", + "RZ(-0.609309162375796) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 1\n", + "RX(pi/2) 1\n", + "RZ(-1.6791446794781564) 1\n", + "RX(-pi/2) 1\n", + "RZ(1.1637589335866698) 2\n", + "RX(pi/2) 2\n", + "CZ 2 1\n", + "RZ(-0.9191936239279155) 5\n", + "RX(pi/2) 5\n", + "RZ(0.9042684144627463) 5\n", + "RX(-pi/2) 5\n", + "RZ(1.1235172543269112) 5\n", + "RZ(2.0631328405059177) 8\n", + "RX(pi/2) 8\n", + "RZ(1.7726950216386586) 8\n", + "RX(-pi/2) 8\n", + "RZ(1.8549693322791247) 8\n", + "CZ 8 5\n", + "RZ(pi/2) 5\n", + "RX(pi/2) 5\n", + "RZ(2.5851228139049667) 5\n", + "RX(-pi/2) 5\n", + "RZ(-pi/2) 8\n", + "RX(-pi/2) 8\n", + "CZ 8 5\n", + "RX(pi/2) 5\n", + "RZ(-1.6323140605487065) 5\n", + "RX(-pi/2) 5\n", + "RZ(1.5013193855621343) 8\n", + "RX(pi/2) 8\n", + "CZ 8 5\n", + "RZ(-0.1795276289121972) 1\n", + "RX(pi/2) 1\n", + "RZ(2.2436045644689595) 1\n", + "RX(-pi/2) 1\n", + "RZ(3.1360145503011747) 1\n", + "RZ(0.07626773627125427) 2\n", + "RX(-pi/2) 2\n", + "RZ(2.204863451859244) 2\n", + "RX(-pi/2) 2\n", + "RZ(-0.8781969895490516) 2\n", + "RZ(-1.073386212205921) 5\n", + "RX(pi/2) 5\n", + "RZ(1.1316436735509159) 5\n", + "RX(-pi/2) 5\n", + "RZ(-2.4727856505954606) 5\n", + "RZ(3.0002623587069106) 8\n", + "RX(-pi/2) 8\n", + "RZ(2.660816523342417) 8\n", + "RX(-pi/2) 8\n", + "RZ(-2.715960997245383) 8\n", + "\n" + ] + } + ], + "source": [ + "from forest.benchmarking.volumetrics._transforms import compile_merged_sequence\n", + "custom_qv_template = rand_su4_layer\n", + "# we want to compile the output sequences with graph-restricted compilation.\n", + "custom_qv_template.sequence_transforms.append(compile_merged_sequence)\n", + "qv_prog = custom_qv_template.sample_program(G, repetitions=2, qc=noisy_qc, width=4)\n", + "print(qv_prog)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "but we also provide this template" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RZ(-0.16578807316550104) 1\n", + "RX(pi/2) 1\n", + "RZ(0.8951760925703465) 1\n", + "RX(-pi/2) 1\n", + "RZ(-3.10079491833949) 1\n", + "RZ(-1.4409737603193395) 4\n", + "RX(pi/2) 4\n", + "RZ(1.3605854011246243) 4\n", + "RX(-pi/2) 4\n", + "RZ(-2.4254994565738994) 4\n", + "CZ 4 1\n", + "RZ(pi/2) 1\n", + "RX(pi/2) 1\n", + "RZ(2.595980783014279) 1\n", + "RX(-pi/2) 1\n", + "RZ(-pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 1\n", + "RX(pi/2) 1\n", + "RZ(-1.6629939074364621) 1\n", + "RX(-pi/2) 1\n", + "RZ(1.804901097823322) 4\n", + "RX(pi/2) 4\n", + "CZ 4 1\n", + "RZ(1.4253771658324803) 1\n", + "RX(pi/2) 1\n", + "RZ(1.912096271646144) 1\n", + "RX(-pi/2) 1\n", + "RZ(2.072941377163399) 1\n", + "RZ(0.7670487358338374) 4\n", + "RX(-pi/2) 4\n", + "RZ(1.8935724315033482) 4\n", + "RX(-pi/2) 4\n", + "RZ(2.6425255170910775) 4\n", + "\n" + ] + } + ], + "source": [ + "qv_template = get_quantum_volume_template()\n", + "print(qv_template.sample_program(G, repetitions=2, qc=noisy_qc, width=2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## First, an example of a single width and depth \n", + "\n", + "We'll use the Quantum Volume template to demonstrate.\n", + "\n", + "Run quantum volume for one width and depth\n", + "\n", + "1. Generate the programs\n", + "2. Collect experimental data\n", + "3. Determine the heavy outputs -- this uses the special quantum volume submodule" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This can be a bit slow" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# 1) Generate the programs for this circuit template with the given {width: [depths]} dimensions\n", + "d = 2 # depth = width for quantum volume\n", + "dimensions = {d: [d]}\n", + "qv_progs = generate_volumetric_program_array(perfect_qc, qv_template, \n", + " dimensions, num_circuit_samples=200)\n", + "\n", + "# 2) Run each of these programs on a quantum resource, here a QVM without noise.\n", + "experimental_data = acquire_volumetric_data(perfect_qc, qv_progs)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "from pyquil.numpy_simulator import NumpyWavefunctionSimulator\n", + "from forest.benchmarking.volumetrics.quantum_volume import collect_heavy_outputs\n", + "\n", + "wfn_sim = NumpyWavefunctionSimulator(9)\n", + "\n", + "# 3) For quantum volume we need to simulate the whole circuit.\n", + "# For this we use a dedicated fumction from the `quantum_volume` sub module\n", + "heavy_outputs = collect_heavy_outputs(wfn_sim, qv_progs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now for this example we can perform the analysis for quantum volume using more functions from the `quantum_volume` module" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.7865600000000006\n", + "{2: {2: 0.7286146177163358}}\n", + "{2: {2: True}}\n" + ] + } + ], + "source": [ + "from forest.benchmarking.volumetrics.quantum_volume import (get_success_probabilities,\n", + " determine_prob_success_lower_bounds,\n", + " determine_successes)\n", + "\n", + "qvol_success_probs = get_success_probabilities(experimental_data, heavy_outputs)\n", + "print(np.average(qvol_success_probs[d][d]))\n", + "\n", + "print(determine_prob_success_lower_bounds(qvol_success_probs, 500))\n", + "\n", + "qvol_successes = determine_successes(qvol_success_probs, 500)\n", + "print(qvol_successes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Acquire data for ranges of (width, depth)\n", + "\n", + "Here we will use a more generic type of volumetric benchmark whith a single ideal solution. We will run this template on a larger collection of different widths and depths. The basic idea is the same:\n", + "\n", + "1. generate the program samples from the circuit family\n", + "2. collect data for each program\n", + "3. analyse, potentially utilizing ideal simulations (we do here)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2: {2: [, , , , , , , , , , , , , , , , , , , ], 3: [, , , , , , , , , , , , , , , , , , , ], 4: [, , , , , , , , , , , , , , , , , , , ], 5: [, , , , , , , , , , , , , , , , , , , ], 10: [, , , , , , , , , , , , , , , , , , , ]}, 3: {2: [, , , , , , , , , , , , , , , , , , , ], 3: [, , , , , , , , , , , , , , , , , , , ], 4: [, , , , , , , , , , , , , , , , , , , ], 5: [, , , , , , , , , , , , , , , , , , , ], 10: [, , , , , , , , , , , , , , , , , , , ]}, 4: {2: [, , , , , , , , , , , , , , , , , , , ], 3: [, , , , , , , , , , , , , , , , , , , ], 4: [, , , , , , , , , , , , , , , , , , , ], 5: [, , , , , , , , , , , , , , , , , , , ], 10: [, , , , , , , , , , , , , , , , , , , ]}, 5: {2: [, , , , , , , , , , , , , , , , , , , ], 3: [, , , , , , , , , , , , , , , , , , , ], 4: [, , , , , , , , , , , , , , , , , , , ], 5: [, , , , , , , , , , , , , , , , , , , ], 10: [, , , , , , , , , , , , , , , , , , , ]}}\n" + ] + } + ], + "source": [ + "widths = [2, 3, 4, 5]\n", + "depths = [2, 3, 4, 5, 10]\n", + "dimensions = {w: depths for w in widths}\n", + "ckt_family = classical_1q_2q\n", + "prog_array = generate_volumetric_program_array(noisy_qc, ckt_family, dimensions, num_circuit_samples=20)\n", + "print(prog_array)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are slow" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "num_shots = 500\n", + "noisy_results = acquire_volumetric_data(noisy_qc, prog_array, num_shots)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2: {2: [array([[1, 1]]), array([[0, 1]]), array([[1, 1]]), array([[1, 0]]), array([[1, 0]]), array([[1, 0]]), array([[1, 0]]), array([[1, 0]]), array([[1, 0]]), array([[0, 0]]), array([[1, 1]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[1, 1]]), array([[1, 0]]), array([[0, 0]]), array([[1, 1]])], 3: [array([[0, 0]]), array([[1, 0]]), array([[0, 0]]), array([[1, 1]]), array([[0, 1]]), array([[1, 1]]), array([[0, 0]]), array([[1, 1]]), array([[0, 0]]), array([[1, 1]]), array([[1, 0]]), array([[1, 1]]), array([[1, 0]]), array([[1, 1]]), array([[1, 1]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[1, 1]]), array([[0, 0]])], 4: [array([[1, 1]]), array([[1, 1]]), array([[0, 0]]), array([[1, 1]]), array([[0, 0]]), array([[1, 1]]), array([[0, 0]]), array([[1, 0]]), array([[0, 1]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[1, 0]]), array([[0, 0]]), array([[1, 1]]), array([[1, 1]]), array([[1, 1]]), array([[1, 1]]), array([[1, 0]]), array([[1, 1]])], 5: [array([[0, 1]]), array([[0, 1]]), array([[1, 0]]), array([[0, 1]]), array([[0, 0]]), array([[0, 0]]), array([[1, 0]]), array([[0, 0]]), array([[0, 0]]), array([[1, 0]]), array([[1, 0]]), array([[1, 1]]), array([[1, 0]]), array([[1, 0]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[1, 0]]), array([[0, 0]]), array([[0, 0]])], 10: [array([[0, 0]]), array([[0, 0]]), array([[1, 1]]), array([[0, 1]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[0, 0]]), array([[1, 1]]), array([[1, 1]]), array([[1, 1]]), array([[1, 0]]), array([[1, 1]]), array([[1, 0]]), array([[0, 0]]), array([[1, 1]]), array([[0, 0]]), array([[1, 1]]), array([[1, 1]]), array([[0, 0]])]}, 3: {2: [array([[1, 0, 0]]), array([[0, 1, 0]]), array([[1, 1, 1]]), array([[1, 1, 1]]), array([[1, 0, 0]]), array([[1, 0, 1]]), array([[1, 1, 0]]), array([[0, 0, 1]]), array([[1, 0, 0]]), array([[0, 0, 1]]), array([[0, 1, 1]]), array([[0, 1, 0]]), array([[1, 1, 0]]), array([[1, 1, 1]]), array([[0, 1, 1]]), array([[0, 1, 0]]), array([[1, 1, 1]]), array([[1, 0, 0]]), array([[1, 1, 1]]), array([[1, 1, 1]])], 3: [array([[1, 0, 0]]), array([[0, 1, 1]]), array([[1, 0, 1]]), array([[0, 0, 1]]), array([[0, 1, 1]]), array([[0, 1, 1]]), array([[1, 0, 1]]), array([[0, 0, 0]]), array([[1, 1, 1]]), array([[1, 0, 1]]), array([[1, 1, 0]]), array([[0, 1, 1]]), array([[1, 0, 0]]), array([[0, 0, 1]]), array([[1, 1, 1]]), array([[1, 1, 0]]), array([[0, 1, 1]]), array([[0, 0, 1]]), array([[1, 0, 1]]), array([[0, 1, 0]])], 4: [array([[0, 1, 1]]), array([[1, 1, 1]]), array([[1, 0, 1]]), array([[1, 0, 1]]), array([[1, 1, 0]]), array([[1, 1, 1]]), array([[0, 0, 0]]), array([[0, 0, 0]]), array([[1, 1, 0]]), array([[1, 0, 1]]), array([[1, 1, 1]]), array([[1, 0, 0]]), array([[1, 0, 0]]), array([[1, 0, 0]]), array([[1, 1, 1]]), array([[0, 0, 1]]), array([[0, 0, 0]]), array([[0, 1, 0]]), array([[0, 0, 0]]), array([[1, 1, 1]])], 5: [array([[0, 1, 1]]), array([[0, 0, 0]]), array([[0, 1, 1]]), array([[0, 0, 0]]), array([[1, 0, 1]]), array([[1, 0, 0]]), array([[0, 1, 0]]), array([[0, 0, 1]]), array([[1, 1, 0]]), array([[1, 0, 0]]), array([[0, 0, 0]]), array([[1, 1, 1]]), array([[0, 1, 1]]), array([[1, 0, 1]]), array([[0, 0, 1]]), array([[0, 1, 1]]), array([[0, 1, 0]]), array([[1, 1, 1]]), array([[0, 1, 1]]), array([[1, 1, 1]])], 10: [array([[0, 0, 0]]), array([[1, 1, 0]]), array([[1, 0, 0]]), array([[1, 1, 1]]), array([[0, 1, 0]]), array([[0, 0, 1]]), array([[1, 1, 0]]), array([[1, 1, 1]]), array([[0, 1, 1]]), array([[1, 1, 0]]), array([[0, 1, 0]]), array([[0, 1, 0]]), array([[0, 1, 0]]), array([[0, 1, 0]]), array([[0, 0, 1]]), array([[1, 1, 1]]), array([[1, 1, 0]]), array([[1, 1, 1]]), array([[1, 0, 0]]), array([[1, 0, 1]])]}, 4: {2: [array([[0, 1, 0, 0]]), array([[1, 1, 1, 0]]), array([[1, 0, 1, 1]]), array([[0, 1, 1, 1]]), array([[0, 0, 1, 0]]), array([[0, 0, 0, 0]]), array([[1, 1, 1, 0]]), array([[1, 1, 0, 1]]), array([[0, 0, 1, 0]]), array([[0, 1, 1, 1]]), array([[0, 1, 1, 1]]), array([[1, 0, 0, 1]]), array([[0, 1, 1, 1]]), array([[0, 1, 1, 0]]), array([[0, 1, 0, 1]]), array([[0, 1, 1, 0]]), array([[0, 1, 0, 1]]), array([[1, 1, 1, 1]]), array([[0, 0, 0, 0]]), array([[0, 1, 0, 0]])], 3: [array([[0, 0, 0, 1]]), array([[0, 1, 1, 0]]), array([[0, 0, 0, 0]]), array([[1, 0, 0, 1]]), array([[1, 1, 0, 1]]), array([[1, 0, 0, 0]]), array([[1, 1, 1, 0]]), array([[0, 0, 0, 0]]), array([[1, 0, 0, 0]]), array([[1, 1, 0, 1]]), array([[1, 0, 1, 1]]), array([[0, 0, 0, 0]]), array([[0, 1, 1, 1]]), array([[0, 0, 1, 0]]), array([[1, 1, 0, 1]]), array([[0, 0, 1, 0]]), array([[0, 0, 0, 0]]), array([[0, 1, 1, 0]]), array([[0, 0, 1, 1]]), array([[1, 0, 0, 1]])], 4: [array([[1, 1, 1, 1]]), array([[1, 1, 0, 0]]), array([[1, 1, 0, 0]]), array([[1, 1, 0, 1]]), array([[1, 1, 0, 0]]), array([[0, 1, 1, 0]]), array([[0, 0, 0, 1]]), array([[1, 1, 0, 1]]), array([[1, 0, 1, 1]]), array([[1, 0, 1, 0]]), array([[0, 0, 0, 1]]), array([[0, 0, 0, 0]]), array([[0, 1, 0, 0]]), array([[0, 1, 1, 1]]), array([[0, 0, 0, 1]]), array([[1, 1, 1, 1]]), array([[1, 0, 0, 0]]), array([[0, 0, 1, 1]]), array([[1, 1, 0, 0]]), array([[1, 1, 0, 0]])], 5: [array([[1, 1, 0, 1]]), array([[1, 0, 0, 0]]), array([[0, 0, 1, 1]]), array([[1, 1, 0, 0]]), array([[0, 0, 1, 0]]), array([[0, 1, 0, 0]]), array([[1, 1, 0, 1]]), array([[1, 1, 0, 0]]), array([[1, 1, 1, 0]]), array([[1, 0, 1, 1]]), array([[0, 1, 0, 0]]), array([[1, 1, 1, 1]]), array([[1, 1, 1, 1]]), array([[1, 1, 1, 1]]), array([[1, 0, 0, 0]]), array([[1, 0, 1, 1]]), array([[1, 0, 1, 1]]), array([[1, 0, 0, 0]]), array([[0, 0, 1, 1]]), array([[1, 1, 0, 1]])], 10: [array([[0, 1, 1, 0]]), array([[0, 1, 0, 0]]), array([[1, 1, 0, 1]]), array([[0, 1, 0, 1]]), array([[1, 1, 1, 0]]), array([[0, 1, 1, 0]]), array([[1, 1, 1, 0]]), array([[0, 1, 1, 1]]), array([[1, 1, 1, 1]]), array([[1, 1, 1, 1]]), array([[1, 1, 1, 1]]), array([[1, 0, 0, 0]]), array([[0, 1, 0, 1]]), array([[1, 1, 0, 0]]), array([[0, 0, 1, 1]]), array([[1, 1, 0, 1]]), array([[0, 1, 1, 1]]), array([[1, 1, 0, 1]]), array([[1, 1, 0, 0]]), array([[1, 0, 0, 1]])]}, 5: {2: [array([[1, 1, 1, 1, 1]]), array([[0, 1, 1, 0, 1]]), array([[0, 0, 0, 0, 1]]), array([[0, 0, 1, 1, 0]]), array([[1, 1, 0, 0, 1]]), array([[1, 1, 1, 0, 1]]), array([[0, 1, 1, 0, 1]]), array([[0, 0, 0, 1, 0]]), array([[0, 0, 1, 0, 1]]), array([[0, 1, 0, 0, 1]]), array([[0, 0, 1, 0, 1]]), array([[0, 1, 0, 0, 1]]), array([[0, 1, 1, 0, 1]]), array([[1, 0, 0, 1, 0]]), array([[0, 1, 1, 0, 0]]), array([[1, 0, 1, 1, 1]]), array([[1, 0, 1, 0, 1]]), array([[1, 0, 0, 0, 0]]), array([[1, 0, 0, 0, 0]]), array([[1, 1, 1, 1, 0]])], 3: [array([[1, 0, 0, 0, 0]]), array([[1, 0, 1, 1, 1]]), array([[0, 1, 0, 0, 1]]), array([[1, 0, 0, 0, 0]]), array([[0, 1, 0, 1, 1]]), array([[1, 0, 0, 0, 0]]), array([[0, 1, 1, 1, 0]]), array([[0, 1, 1, 1, 1]]), array([[0, 1, 1, 0, 1]]), array([[1, 0, 0, 1, 0]]), array([[0, 0, 1, 1, 0]]), array([[0, 1, 0, 0, 0]]), array([[1, 1, 0, 0, 0]]), array([[1, 0, 1, 0, 0]]), array([[0, 0, 1, 1, 0]]), array([[1, 0, 0, 1, 1]]), array([[1, 1, 0, 0, 0]]), array([[1, 1, 0, 1, 0]]), array([[0, 1, 0, 0, 0]]), array([[1, 1, 0, 1, 0]])], 4: [array([[1, 0, 0, 0, 0]]), array([[0, 1, 1, 1, 0]]), array([[0, 0, 1, 1, 1]]), array([[1, 1, 0, 1, 1]]), array([[1, 0, 0, 1, 0]]), array([[1, 1, 1, 0, 0]]), array([[0, 0, 0, 0, 1]]), array([[1, 0, 1, 0, 1]]), array([[1, 1, 0, 1, 1]]), array([[1, 1, 0, 0, 0]]), array([[1, 0, 1, 1, 0]]), array([[1, 0, 0, 0, 1]]), array([[0, 0, 0, 1, 1]]), array([[0, 1, 1, 1, 1]]), array([[0, 1, 1, 0, 0]]), array([[0, 1, 1, 0, 1]]), array([[0, 1, 1, 1, 1]]), array([[0, 0, 0, 1, 1]]), array([[0, 1, 0, 1, 1]]), array([[0, 0, 1, 0, 1]])], 5: [array([[1, 0, 1, 0, 1]]), array([[1, 0, 0, 1, 1]]), array([[0, 0, 1, 1, 0]]), array([[0, 1, 0, 0, 0]]), array([[0, 1, 1, 1, 1]]), array([[0, 1, 1, 1, 0]]), array([[1, 1, 1, 1, 1]]), array([[0, 1, 0, 0, 0]]), array([[0, 1, 1, 1, 1]]), array([[0, 1, 0, 1, 0]]), array([[1, 1, 1, 1, 1]]), array([[1, 1, 0, 1, 1]]), array([[1, 1, 0, 1, 0]]), array([[1, 1, 0, 1, 0]]), array([[0, 0, 1, 1, 0]]), array([[1, 0, 0, 0, 0]]), array([[1, 1, 0, 0, 0]]), array([[1, 1, 1, 1, 1]]), array([[1, 0, 0, 1, 0]]), array([[0, 1, 1, 0, 0]])], 10: [array([[0, 0, 0, 1, 1]]), array([[1, 0, 1, 0, 0]]), array([[1, 1, 0, 0, 0]]), array([[0, 1, 1, 0, 0]]), array([[0, 1, 1, 0, 0]]), array([[0, 1, 0, 1, 1]]), array([[0, 0, 0, 0, 1]]), array([[0, 0, 0, 0, 1]]), array([[1, 0, 1, 1, 1]]), array([[0, 1, 1, 1, 0]]), array([[0, 0, 1, 1, 0]]), array([[1, 1, 0, 1, 0]]), array([[1, 0, 1, 1, 0]]), array([[1, 0, 0, 0, 0]]), array([[0, 0, 1, 0, 0]]), array([[0, 1, 1, 0, 1]]), array([[0, 1, 0, 1, 1]]), array([[0, 1, 1, 1, 0]]), array([[0, 1, 1, 0, 0]]), array([[1, 0, 0, 1, 1]])]}}\n" + ] + } + ], + "source": [ + "ideal_results = acquire_volumetric_data(perfect_qc, prog_array, num_shots=1)\n", + "print(ideal_results)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2: {2: [array([0.84, 0.15, 0.01]), array([0.884, 0.112, 0.004]), array([0.838, 0.148, 0.014]), array([0.898, 0.096, 0.006]), array([0.884, 0.116, 0. ]), array([0.914, 0.08 , 0.006]), array([0.896, 0.102, 0.002]), array([0.878, 0.12 , 0.002]), array([0.876, 0.124, 0. ]), array([0.942, 0.058, 0. ]), array([0.852, 0.132, 0.016]), array([0.95, 0.05, 0. ]), array([0.946, 0.052, 0.002]), array([0.942, 0.058, 0. ]), array([0.952, 0.048, 0. ]), array([0.952, 0.048, 0. ]), array([0.832, 0.16 , 0.008]), array([0.892, 0.102, 0.006]), array([0.94 , 0.052, 0.008]), array([0.8 , 0.194, 0.006])], 3: [array([0.942, 0.056, 0.002]), array([0.848, 0.15 , 0.002]), array([0.95 , 0.044, 0.006]), array([0.852, 0.144, 0.004]), array([0.894, 0.102, 0.004]), array([0.804, 0.188, 0.008]), array([0.932, 0.068, 0. ]), array([0.846, 0.138, 0.016]), array([0.944, 0.054, 0.002]), array([0.84 , 0.154, 0.006]), array([0.88, 0.12, 0. ]), array([0.818, 0.168, 0.014]), array([0.896, 0.102, 0.002]), array([0.81, 0.18, 0.01]), array([0.842, 0.15 , 0.008]), array([0.964, 0.034, 0.002]), array([0.948, 0.05 , 0.002]), array([0.944, 0.056, 0. ]), array([0.828, 0.16 , 0.012]), array([0.964, 0.036, 0. ])], 4: [array([0.846, 0.15 , 0.004]), array([0.848, 0.14 , 0.012]), array([0.94, 0.06, 0. ]), array([0.832, 0.156, 0.012]), array([0.944, 0.054, 0.002]), array([0.836, 0.158, 0.006]), array([0.966, 0.032, 0.002]), array([0.884, 0.106, 0.01 ]), array([0.878, 0.12 , 0.002]), array([0.954, 0.046, 0. ]), array([0.956, 0.044, 0. ]), array([0.936, 0.064, 0. ]), array([0.874, 0.124, 0.002]), array([0.956, 0.044, 0. ]), array([0.826, 0.166, 0.008]), array([0.838, 0.148, 0.014]), array([0.832, 0.158, 0.01 ]), array([0.848, 0.142, 0.01 ]), array([0.848, 0.146, 0.006]), array([0.84 , 0.152, 0.008])], 5: [array([0.884, 0.112, 0.004]), array([0.886, 0.104, 0.01 ]), array([0.892, 0.104, 0.004]), array([0.848, 0.152, 0. ]), array([0.962, 0.038, 0. ]), array([0.942, 0.058, 0. ]), array([0.878, 0.116, 0.006]), array([0.924, 0.076, 0. ]), array([0.952, 0.048, 0. ]), array([0.894, 0.104, 0.002]), array([0.9 , 0.096, 0.004]), array([0.812, 0.184, 0.004]), array([0.892, 0.106, 0.002]), array([0.89 , 0.106, 0.004]), array([0.956, 0.044, 0. ]), array([0.936, 0.054, 0.01 ]), array([0.968, 0.03 , 0.002]), array([0.888, 0.112, 0. ]), array([0.942, 0.056, 0.002]), array([0.938, 0.058, 0.004])], 10: [array([0.926, 0.072, 0.002]), array([0.926, 0.058, 0.016]), array([0.802, 0.18 , 0.018]), array([0.852, 0.142, 0.006]), array([0.944, 0.056, 0. ]), array([0.944, 0.054, 0.002]), array([0.938, 0.062, 0. ]), array([0.918, 0.072, 0.01 ]), array([0.818, 0.166, 0.016]), array([0.802, 0.184, 0.014]), array([0.806, 0.178, 0.016]), array([0.884, 0.108, 0.008]), array([0.816, 0.168, 0.016]), array([0.864, 0.12 , 0.016]), array([0.958, 0.042, 0. ]), array([0.814, 0.17 , 0.016]), array([0.926, 0.066, 0.008]), array([0.802, 0.166, 0.032]), array([0.818, 0.172, 0.01 ]), array([0.944, 0.056, 0. ])]}, 3: {2: [array([0.844, 0.15 , 0.006, 0. ]), array([0.86 , 0.134, 0.006, 0. ]), array([0.716, 0.256, 0.028, 0. ]), array([0.742, 0.232, 0.026, 0. ]), array([0.834, 0.148, 0.016, 0.002]), array([0.79, 0.2 , 0.01, 0. ]), array([0.826, 0.158, 0.016, 0. ]), array([0.888, 0.108, 0.004, 0. ]), array([0.884, 0.116, 0. , 0. ]), array([0.852, 0.146, 0.002, 0. ]), array([0.844, 0.144, 0.012, 0. ]), array([0.854, 0.142, 0.004, 0. ]), array([0.812, 0.176, 0.012, 0. ]), array([0.746, 0.228, 0.026, 0. ]), array([0.796, 0.188, 0.016, 0. ]), array([0.88 , 0.112, 0.008, 0. ]), array([0.734, 0.226, 0.036, 0.004]), array([0.832, 0.16 , 0.006, 0.002]), array([0.72 , 0.256, 0.024, 0. ]), array([0.772, 0.196, 0.032, 0. ])], 3: [array([0.862, 0.122, 0.016, 0. ]), array([0.796, 0.19 , 0.014, 0. ]), array([0.792, 0.188, 0.016, 0.004]), array([0.862, 0.132, 0.006, 0. ]), array([0.818, 0.172, 0.01 , 0. ]), array([0.808, 0.178, 0.014, 0. ]), array([0.818, 0.168, 0.014, 0. ]), array([0.928, 0.07 , 0.002, 0. ]), array([0.746, 0.234, 0.02 , 0. ]), array([0.802, 0.186, 0.012, 0. ]), array([0.82 , 0.174, 0.006, 0. ]), array([0.788, 0.194, 0.014, 0.004]), array([0.87 , 0.116, 0.008, 0.006]), array([0.854, 0.142, 0.004, 0. ]), array([0.694, 0.276, 0.028, 0.002]), array([0.796, 0.19 , 0.014, 0. ]), array([0.846, 0.142, 0.012, 0. ]), array([0.85 , 0.148, 0.002, 0. ]), array([0.772, 0.22 , 0.008, 0. ]), array([0.856, 0.136, 0.008, 0. ])], 4: [array([0.768, 0.216, 0.016, 0. ]), array([0.752, 0.222, 0.024, 0.002]), array([0.824, 0.17 , 0.006, 0. ]), array([0.776, 0.19 , 0.026, 0.008]), array([0.838, 0.144, 0.018, 0. ]), array([0.718, 0.266, 0.016, 0. ]), array([0.924, 0.074, 0. , 0.002]), array([0.928, 0.064, 0.002, 0.006]), array([0.78 , 0.192, 0.028, 0. ]), array([0.778, 0.208, 0.012, 0.002]), array([0.754, 0.216, 0.028, 0.002]), array([0.876, 0.114, 0.01 , 0. ]), array([0.854, 0.136, 0.008, 0.002]), array([0.862, 0.128, 0.01 , 0. ]), array([0.766, 0.206, 0.026, 0.002]), array([0.878, 0.12 , 0.002, 0. ]), array([0.926, 0.068, 0.006, 0. ]), array([0.846, 0.142, 0.012, 0. ]), array([0.924, 0.074, 0.002, 0. ]), array([0.73, 0.23, 0.03, 0.01])], 5: [array([0.806, 0.182, 0.012, 0. ]), array([0.914, 0.086, 0. , 0. ]), array([0.794, 0.19 , 0.016, 0. ]), array([0.9 , 0.084, 0.008, 0.008]), array([0.794, 0.192, 0.014, 0. ]), array([0.866, 0.132, 0.002, 0. ]), array([0.818, 0.17 , 0.008, 0.004]), array([0.86 , 0.136, 0.004, 0. ]), array([0.804, 0.18 , 0.016, 0. ]), array([0.854, 0.132, 0.014, 0. ]), array([0.914, 0.08 , 0.006, 0. ]), array([0.724, 0.244, 0.03 , 0.002]), array([0.828, 0.152, 0.02 , 0. ]), array([0.79, 0.2 , 0.01, 0. ]), array([0.854, 0.146, 0. , 0. ]), array([0.802, 0.182, 0.016, 0. ]), array([0.868, 0.12 , 0.012, 0. ]), array([0.792, 0.19 , 0.012, 0.006]), array([0.77 , 0.204, 0.026, 0. ]), array([0.778, 0.196, 0.024, 0.002])], 10: [array([0.906, 0.09 , 0.002, 0.002]), array([0.792, 0.18 , 0.014, 0.014]), array([0.848, 0.13 , 0.02 , 0.002]), array([0.748, 0.23 , 0.018, 0.004]), array([0.83 , 0.162, 0.004, 0.004]), array([0.842, 0.15 , 0.008, 0. ]), array([0.808, 0.156, 0.026, 0.01 ]), array([0.738, 0.212, 0.05 , 0. ]), array([0.784, 0.192, 0.024, 0. ]), array([0.804, 0.17 , 0.024, 0.002]), array([0.88 , 0.118, 0.002, 0. ]), array([0.852, 0.118, 0.028, 0.002]), array([0.866, 0.116, 0.012, 0.006]), array([0.816, 0.148, 0.03 , 0.006]), array([0.844, 0.136, 0.02 , 0. ]), array([0.706, 0.246, 0.042, 0.006]), array([0.756, 0.218, 0.026, 0. ]), array([0.72 , 0.228, 0.042, 0.01 ]), array([0.846, 0.134, 0.016, 0.004]), array([0.828, 0.158, 0.014, 0. ])]}, 4: {2: [array([0.86, 0.13, 0.01, 0. , 0. ]), array([0.742, 0.232, 0.024, 0.002, 0. ]), array([0.776, 0.19 , 0.03 , 0.004, 0. ]), array([0.722, 0.242, 0.036, 0. , 0. ]), array([0.838, 0.152, 0.01 , 0. , 0. ]), array([0.886, 0.11 , 0.004, 0. , 0. ]), array([0.738, 0.23 , 0.032, 0. , 0. ]), array([0.756, 0.222, 0.02 , 0.002, 0. ]), array([0.824, 0.162, 0.012, 0.002, 0. ]), array([0.738, 0.232, 0.028, 0.002, 0. ]), array([0.762, 0.2 , 0.036, 0.002, 0. ]), array([0.752, 0.228, 0.02 , 0. , 0. ]), array([0.72 , 0.252, 0.026, 0.002, 0. ]), array([0.782, 0.2 , 0.014, 0.004, 0. ]), array([0.792, 0.184, 0.022, 0.002, 0. ]), array([0.794, 0.19 , 0.016, 0. , 0. ]), array([0.756, 0.228, 0.016, 0. , 0. ]), array([0.68 , 0.256, 0.062, 0.002, 0. ]), array([0.89 , 0.106, 0.004, 0. , 0. ]), array([0.838, 0.16 , 0.002, 0. , 0. ])], 3: [array([0.83 , 0.158, 0.012, 0. , 0. ]), array([0.782, 0.2 , 0.018, 0. , 0. ]), array([0.904, 0.092, 0.004, 0. , 0. ]), array([0.782, 0.194, 0.022, 0. , 0.002]), array([0.7 , 0.252, 0.048, 0. , 0. ]), array([0.828, 0.156, 0.016, 0. , 0. ]), array([0.72 , 0.254, 0.026, 0. , 0. ]), array([0.914, 0.082, 0.004, 0. , 0. ]), array([0.82 , 0.172, 0.006, 0.002, 0. ]), array([0.746, 0.216, 0.036, 0.002, 0. ]), array([0.71 , 0.252, 0.034, 0.002, 0.002]), array([0.914, 0.08 , 0.002, 0.004, 0. ]), array([0.736, 0.23 , 0.032, 0.002, 0. ]), array([0.854, 0.128, 0.016, 0.002, 0. ]), array([0.718, 0.236, 0.042, 0.002, 0.002]), array([0.848, 0.14 , 0.012, 0. , 0. ]), array([0.896, 0.096, 0.008, 0. , 0. ]), array([0.774, 0.198, 0.024, 0.002, 0.002]), array([0.784, 0.196, 0.02 , 0. , 0. ]), array([0.788, 0.186, 0.024, 0.002, 0. ])], 4: [array([0.66 , 0.298, 0.04 , 0.002, 0. ]), array([0.764, 0.218, 0.018, 0. , 0. ]), array([0.802, 0.18 , 0.018, 0. , 0. ]), array([0.726, 0.246, 0.02 , 0.008, 0. ]), array([0.762, 0.21 , 0.026, 0.002, 0. ]), array([0.802, 0.184, 0.014, 0. , 0. ]), array([0.852, 0.14 , 0.008, 0. , 0. ]), array([0.74 , 0.238, 0.014, 0.008, 0. ]), array([0.734, 0.226, 0.034, 0.006, 0. ]), array([0.794, 0.18 , 0.026, 0. , 0. ]), array([0.834, 0.152, 0.014, 0. , 0. ]), array([0.888, 0.108, 0.004, 0. , 0. ]), array([0.814, 0.172, 0.014, 0. , 0. ]), array([0.762, 0.202, 0.032, 0.004, 0. ]), array([0.83 , 0.164, 0.006, 0. , 0. ]), array([0.656, 0.292, 0.05 , 0. , 0.002]), array([0.866, 0.122, 0.012, 0. , 0. ]), array([0.792, 0.176, 0.028, 0.004, 0. ]), array([0.8 , 0.196, 0.004, 0. , 0. ]), array([0.784, 0.188, 0.024, 0.004, 0. ])], 5: [array([0.732, 0.236, 0.03 , 0.002, 0. ]), array([0.838, 0.14 , 0.022, 0. , 0. ]), array([0.776, 0.204, 0.02 , 0. , 0. ]), array([0.736, 0.242, 0.018, 0.004, 0. ]), array([0.85 , 0.138, 0.012, 0. , 0. ]), array([0.82 , 0.164, 0.014, 0.002, 0. ]), array([0.704, 0.242, 0.04 , 0.014, 0. ]), array([0.778, 0.21 , 0.01 , 0.002, 0. ]), array([0.712, 0.24 , 0.044, 0.004, 0. ]), array([0.688, 0.288, 0.022, 0.002, 0. ]), array([0.838, 0.152, 0.008, 0.002, 0. ]), array([0.622, 0.32 , 0.052, 0.004, 0.002]), array([0.69 , 0.238, 0.068, 0.004, 0. ]), array([0.69 , 0.258, 0.042, 0.01 , 0. ]), array([0.804, 0.174, 0.012, 0.01 , 0. ]), array([0.714, 0.252, 0.032, 0.002, 0. ]), array([0.698, 0.276, 0.024, 0.002, 0. ]), array([0.85 , 0.142, 0.008, 0. , 0. ]), array([0.746, 0.236, 0.018, 0. , 0. ]), array([0.712, 0.24 , 0.04 , 0.008, 0. ])], 10: [array([0.752, 0.21 , 0.032, 0.006, 0. ]), array([0.814, 0.146, 0.036, 0.004, 0. ]), array([0.734, 0.214, 0.048, 0.004, 0. ]), array([0.714, 0.236, 0.04 , 0. , 0.01 ]), array([0.708, 0.24 , 0.05 , 0.002, 0. ]), array([0.778, 0.19 , 0.032, 0. , 0. ]), array([0.688, 0.256, 0.046, 0.01 , 0. ]), array([0.706, 0.234, 0.052, 0.006, 0.002]), array([0.678, 0.23 , 0.072, 0.018, 0.002]), array([0.63 , 0.286, 0.074, 0.01 , 0. ]), array([0.68 , 0.244, 0.056, 0.018, 0.002]), array([0.85 , 0.13 , 0.018, 0.002, 0. ]), array([0.776, 0.194, 0.026, 0. , 0.004]), array([0.772, 0.188, 0.03 , 0.01 , 0. ]), array([0.768, 0.208, 0.024, 0. , 0. ]), array([0.692, 0.24 , 0.05 , 0.018, 0. ]), array([0.718, 0.236, 0.042, 0.004, 0. ]), array([0.682, 0.264, 0.05 , 0.004, 0. ]), array([0.748, 0.212, 0.036, 0.004, 0. ]), array([0.796, 0.188, 0.016, 0. , 0. ])]}, 5: {2: [array([0.606, 0.314, 0.074, 0.006, 0. , 0. ]), array([0.722, 0.238, 0.038, 0.002, 0. , 0. ]), array([0.778, 0.206, 0.016, 0. , 0. , 0. ]), array([0.774, 0.208, 0.018, 0. , 0. , 0. ]), array([0.724, 0.238, 0.036, 0.002, 0. , 0. ]), array([0.696, 0.254, 0.038, 0.01 , 0.002, 0. ]), array([0.716, 0.244, 0.038, 0.002, 0. , 0. ]), array([0.842, 0.132, 0.026, 0. , 0. , 0. ]), array([0.742, 0.234, 0.024, 0. , 0. , 0. ]), array([0.738, 0.224, 0.038, 0. , 0. , 0. ]), array([0.792, 0.182, 0.026, 0. , 0. , 0. ]), array([0.758, 0.2 , 0.04 , 0.002, 0. , 0. ]), array([0.712, 0.252, 0.034, 0.002, 0. , 0. ]), array([0.82 , 0.16 , 0.016, 0.002, 0.002, 0. ]), array([0.788, 0.186, 0.024, 0.002, 0. , 0. ]), array([0.7 , 0.248, 0.042, 0.006, 0.004, 0. ]), array([0.702, 0.252, 0.044, 0.002, 0. , 0. ]), array([0.814, 0.174, 0.01 , 0.002, 0. , 0. ]), array([0.812, 0.17 , 0.012, 0.006, 0. , 0. ]), array([0.664, 0.286, 0.044, 0.006, 0. , 0. ])], 3: [array([0.81 , 0.172, 0.018, 0. , 0. , 0. ]), array([0.67 , 0.286, 0.04 , 0.004, 0. , 0. ]), array([0.728, 0.248, 0.022, 0.002, 0. , 0. ]), array([0.828, 0.162, 0.01 , 0. , 0. , 0. ]), array([0.722, 0.222, 0.046, 0.004, 0.006, 0. ]), array([0.774, 0.206, 0.02 , 0. , 0. , 0. ]), array([0.692, 0.266, 0.028, 0.012, 0.002, 0. ]), array([0.716, 0.24 , 0.034, 0.008, 0.002, 0. ]), array([0.734, 0.228, 0.03 , 0.006, 0.002, 0. ]), array([0.744, 0.242, 0.014, 0. , 0. , 0. ]), array([0.776, 0.194, 0.026, 0.004, 0. , 0. ]), array([0.794, 0.192, 0.014, 0. , 0. , 0. ]), array([0.78 , 0.184, 0.034, 0.002, 0. , 0. ]), array([0.748, 0.23 , 0.02 , 0.002, 0. , 0. ]), array([0.738, 0.224, 0.034, 0.004, 0. , 0. ]), array([0.706, 0.258, 0.02 , 0.014, 0.002, 0. ]), array([0.72 , 0.262, 0.016, 0.002, 0. , 0. ]), array([0.724, 0.236, 0.032, 0.008, 0. , 0. ]), array([0.794, 0.188, 0.018, 0. , 0. , 0. ]), array([0.694, 0.27 , 0.034, 0.002, 0. , 0. ])], 4: [array([0.81 , 0.168, 0.022, 0. , 0. , 0. ]), array([0.714, 0.244, 0.038, 0.004, 0. , 0. ]), array([0.66 , 0.274, 0.052, 0.002, 0.012, 0. ]), array([0.658, 0.268, 0.07 , 0.004, 0. , 0. ]), array([0.75 , 0.226, 0.024, 0. , 0. , 0. ]), array([0.74 , 0.226, 0.03 , 0.004, 0. , 0. ]), array([0.838, 0.154, 0.006, 0.002, 0. , 0. ]), array([0.696, 0.274, 0.028, 0.002, 0. , 0. ]), array([0.698, 0.266, 0.032, 0. , 0.004, 0. ]), array([0.756, 0.216, 0.024, 0.004, 0. , 0. ]), array([0.68 , 0.264, 0.05 , 0.006, 0. , 0. ]), array([0.766, 0.206, 0.022, 0.004, 0.002, 0. ]), array([0.766, 0.204, 0.028, 0.002, 0. , 0. ]), array([0.634, 0.298, 0.06 , 0.006, 0.002, 0. ]), array([0.784, 0.194, 0.018, 0.004, 0. , 0. ]), array([0.712, 0.246, 0.03 , 0.01 , 0.002, 0. ]), array([0.66 , 0.312, 0.026, 0.002, 0. , 0. ]), array([0.742, 0.206, 0.03 , 0.006, 0.008, 0.008]), array([0.734, 0.236, 0.026, 0.004, 0. , 0. ]), array([0.798, 0.18 , 0.022, 0. , 0. , 0. ])], 5: [array([0.694, 0.252, 0.048, 0.006, 0. , 0. ]), array([0.7 , 0.244, 0.054, 0.002, 0. , 0. ]), array([0.772, 0.198, 0.026, 0.004, 0. , 0. ]), array([0.82 , 0.158, 0.022, 0. , 0. , 0. ]), array([0.646, 0.278, 0.066, 0.01 , 0. , 0. ]), array([0.702, 0.26 , 0.03 , 0.008, 0. , 0. ]), array([0.596, 0.332, 0.07 , 0.002, 0. , 0. ]), array([0.796, 0.182, 0.02 , 0.002, 0. , 0. ]), array([0.68 , 0.262, 0.054, 0.004, 0. , 0. ]), array([0.728, 0.246, 0.024, 0.002, 0. , 0. ]), array([0.58, 0.33, 0.07, 0.02, 0. , 0. ]), array([0.65 , 0.25 , 0.088, 0.012, 0. , 0. ]), array([0.66 , 0.292, 0.04 , 0.006, 0.002, 0. ]), array([0.686, 0.268, 0.042, 0.004, 0. , 0. ]), array([0.724, 0.23 , 0.046, 0. , 0. , 0. ]), array([0.8 , 0.19, 0.01, 0. , 0. , 0. ]), array([0.748, 0.206, 0.03 , 0.014, 0.002, 0. ]), array([0.606, 0.34 , 0.048, 0.006, 0. , 0. ]), array([0.748, 0.22 , 0.028, 0.004, 0. , 0. ]), array([0.766, 0.186, 0.036, 0.01 , 0.002, 0. ])], 10: [array([0.756, 0.22 , 0.018, 0.006, 0. , 0. ]), array([0.74 , 0.23 , 0.026, 0.004, 0. , 0. ]), array([0.736, 0.184, 0.058, 0.022, 0. , 0. ]), array([0.734, 0.192, 0.044, 0.016, 0.014, 0. ]), array([0.738, 0.216, 0.036, 0.01 , 0. , 0. ]), array([0.7 , 0.244, 0.042, 0.014, 0. , 0. ]), array([0.818, 0.158, 0.02 , 0.004, 0. , 0. ]), array([0.796, 0.158, 0.036, 0.01 , 0. , 0. ]), array([0.678, 0.27 , 0.038, 0.01 , 0.004, 0. ]), array([0.714, 0.244, 0.032, 0.008, 0.002, 0. ]), array([0.72 , 0.252, 0.028, 0. , 0. , 0. ]), array([0.68 , 0.26 , 0.048, 0.004, 0. , 0.008]), array([0.632, 0.276, 0.056, 0.02 , 0.012, 0.004]), array([0.796, 0.176, 0.02 , 0.008, 0. , 0. ]), array([0.786, 0.184, 0.024, 0.006, 0. , 0. ]), array([0.684, 0.26 , 0.046, 0.01 , 0. , 0. ]), array([0.68 , 0.264, 0.05 , 0.006, 0. , 0. ]), array([0.694, 0.258, 0.038, 0.006, 0.002, 0.002]), array([0.748, 0.224, 0.024, 0.004, 0. , 0. ]), array([0.708, 0.214, 0.052, 0.02 , 0.006, 0. ])]}}\n" + ] + } + ], + "source": [ + "err_hamm_distrs = get_error_hamming_weight_distributions(noisy_results, ideal_results)\n", + "print(err_hamm_distrs)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2: {2: array([0.8954, 0.1001, 0.0045]), 3: array([0.8873, 0.1077, 0.005 ]), 4: array([0.8841, 0.1105, 0.0054]), 5: array([0.9092, 0.0879, 0.0029]), 10: array([0.8751, 0.1146, 0.0103])}, 3: {2: array([8.113e-01, 1.738e-01, 1.450e-02, 4.000e-04]), 3: array([8.189e-01, 1.689e-01, 1.140e-02, 8.000e-04]), 4: array([0.8251, 0.159 , 0.0141, 0.0018]), 5: array([0.8265, 0.1599, 0.0125, 0.0011]), 10: array([0.8107, 0.1646, 0.0211, 0.0036])}, 4: {2: array([0.7823, 0.1953, 0.0212, 0.0012, 0. ]), 3: array([8.024e-01, 1.759e-01, 2.030e-02, 1.000e-03, 4.000e-04]), 4: array([7.831e-01, 1.946e-01, 2.030e-02, 1.900e-03, 1.000e-04]), 5: array([7.499e-01, 2.196e-01, 2.680e-02, 3.600e-03, 1.000e-04]), 10: array([0.7342, 0.2173, 0.0415, 0.006 , 0.001 ])}, 5: {2: array([7.450e-01, 2.201e-01, 3.190e-02, 2.600e-03, 4.000e-04, 0.000e+00]), 3: array([7.446e-01, 2.255e-01, 2.550e-02, 3.700e-03, 7.000e-04, 0.000e+00]), 4: array([7.298e-01, 2.331e-01, 3.190e-02, 3.300e-03, 1.500e-03, 4.000e-04]), 5: array([7.051e-01, 2.462e-01, 4.260e-02, 5.800e-03, 3.000e-04, 0.000e+00]), 10: array([7.269e-01, 2.242e-01, 3.680e-02, 9.400e-03, 2.000e-03, 7.000e-04])}}\n" + ] + } + ], + "source": [ + "avg_err_hamm_distrs = average_distributions(err_hamm_distrs)\n", + "print(avg_err_hamm_distrs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot a particular depth and width" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "w = 3 # width\n", + "d = 4 # depth\n", + "\n", + "avg_distr = avg_err_hamm_distrs[3][4]\n", + "\n", + "# rand data\n", + "rand_distr = get_random_hamming_wt_distr(w)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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CMys03ASaFsl58iJwMysznmMwMw6pWFn3FzV/a344cEbvc20adPo3bs3X//611t8f+bMmYwcOZLRo0e3N7xcuUVgZpaTmTNnsnjx4lqH0SYnAjOzjfD973+fkSNHsvfee7N06VIALr/8cnbZZRfGjRvHEUccwZo1a7jvvvuYNWsW3/jGNxg/fjxPPvlki/U6AicCM7OMHnroIWbMmEFDQwO33HIL8+fPB+Dwww9n/vz5/PnPf2aHHXbgF7/4BXvuuSeHHHIIP/rRj2hoaGC77bZrsV5H4DECM7OM5syZw6RJk9hiiy0AOOSQQwB47LHHOOuss3jllVdYvXo1H//4x1vcPmu9ojkRmJm105QpU5g5cybjxo3jqquu4u67725XvaK5a8jMLKN9992XmTNn8sYbb7Bq1Sp+97vfAbBq1SoGDRrE+vXrufbaa9+p36dPH1atWvXOemv1as0tAjPrlCq53LO9JkyYwFFHHcW4cePYaqut2GWXXQD47ne/y2677cbAgQPZbbfd3vnynzx5MieccAI/+clPuPHGG1utV2tK5n7rPPxgGrP6tGTJEnbYYYdah9EptHSuJD0UERNbqu+uITOzOudEYGZW55wIzMzqnBOBmVmdcyIwM6tzTgRmZnXO9xGYWec0rW+V9/dqdfeXwbBhw1iwYAEDBgwo/NilMrUIJA2VdEC63FNSn3zDMjPr2CKCt99+u9ZhVEWbiUDSCcCNwM/SosHAzDyDMjPriFasWMGoUaP43Oc+x9ixYznuuOOYOHEiY8aM4Zxzznmn3rBhwzjnnHOYMGECO+64I48//jgAK1eu5GMf+xhjxozh+OOPp/SG3osvvpixY8cyduxYfvzjH79zvO23354pU6YwcuRIjjnmGO6880722msvRowYwYMPPliVz5WlRfAVYC/gNYCIeALYqipHNzPrZJ544glOOukkFi1axEUXXcSCBQtYuHAhs2fPZuHChe/UGzBgAA8//DAnnngiF154IQDf+c532HvvvVm0aBGTJk3i6aefBpLpra+88koeeOAB5s2bx+WXX84jjzwCwLJly/ja177G448/zuOPP851113H3LlzufDCCznvvPOq8pmyJIJ1EfFm04qkTYDONS+FmVmVDB06lN133x2A66+/ngkTJrDTTjuxaNGi9zyN7PDDDwdg5513ZsWKFQDcc889HHvs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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x_labels = np.arange(0, len(avg_distr))\n", + "plt.bar(x_labels, avg_distr, width=0.61, align='center')\n", + "plt.bar(x_labels, rand_distr, width=0.31, align='center')\n", + "plt.xticks(x_labels)\n", + "plt.xlabel('Hamming Weight of Error')\n", + "plt.ylabel('Relative Frequency of Occurrence')\n", + "plt.ylim([0, 1])\n", + "plt.grid(axis='y', alpha=0.75)\n", + "plt.legend(['data','random'])\n", + "plt.title(f'Width = {w}, Depth = {d}')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using our helper function" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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Q8BmbY8jSZIkSZIk1aYiRdpqtL4D5z/K8yRJkiRJkrQSO+mkk1YfOnTopnV1dZtvu+22o1955ZUeDcePOeaYIZtsssmGffv2HTNo0KDNtt1229GPP/54z/rxLbbYYv0nnnii97XXXjsoIsZFxLjJkycPAjjrrLMGjRs3bv3+/fuP6dev35gtt9xyvT//+c+9V/Sfsagit3a+CYxuZc46wCqxVE+SJEmSJKmzuvTSSwd873vf+8jEiRPf2H333efeeeedfQ899NCRDee88sorPb7+9a+/vvbaay9+6623upx77rmrb7311hs899xzjw8aNGjpr371q5f22muvdT7ykY8s+uEPfzgLYMMNN1wEMH369B5f+tKX/rHuuusuWrRoUVx++eUf/uxnP7vBlClTHt9oo40Wd8AfuSJFirT7gC9ExHqZ+WzjwYhYH9gV+L9qhZMkSZIkSdKKd/LJJw/79Kc/Pe+yyy6bAbDHHnvMe/PNN7tdeeWV79+JeMEFF7xc//OSJUvYdddd5w0ZMmTM5ZdfPuCwww77x7hx4xb27t172aBBg5Zst9127za8/s9//vNZ9T8vXbqU3Xbbbd56663X5ze/+c2ghmO1psitnacBPYB7I+K/ImJURPQsv38DuJdSMffz9ggqSZIkSZKk9vfee+/x1FNP9f7c5z73gbsOd9999zkNP99+++19ttpqq3UHDBgwpnv37uP69u07dv78+V2effbZnrRiypQpvbbffvt1Bg0atFm3bt3G9ejRY9z06dN7Pffcc72q/eeppopXpGXmXyPiMODM8quxZcA3M/Mv1QonSZIkSZKkFWvWrFndli5dypAhQ95reHzYsGFL6n9+7rnneuy6667rbbrppu+efvrpL40YMWJxz549c7fddlt34cKFLS7cmjNnTpedd955vdVWW+29n/zkJy+PGjVqcV1d3bJJkyaNXLRoUbTXn6saitzaSWb+OiLuA/4L2BIYQOmZaH8Fzs7Mx6sfUZIkSZIkSSvKsGHDlnTt2pXZs2d3b3h81qxZ7/dI119/fb+FCxd2ufnmm5/v16/fMiitZHvrrbe6tnb9O++880OzZ8/uftNNNz27+eabL6w//vbbb7d6bkcrcmsnAJn5WGYempljM3NU+f2/LNEkSZIkSZJWft27d2eDDTaYf8MNNwxoePzaa68dWP/zggULukREdu/ePeuPXXDBBR9eunRpNLpWLlq06AP90/z587sA1NXVLas/duutt/aZOXPmB3YFrUWFVqRJkiRJkiRp1fed73xn1le/+tV19ttvv4/ssccec++8886+d911V//68R122OHtY489Nvbee++RBx988JuPPfZY3S9/+cshffv2XdrwOqNHj154991397vmmmv6rb766kvWW2+9RRMmTHind+/eyw488MCRRx555GszZszofvLJJw8fPHjwe/+epLYUXpEWJetFxJYRsVVTr/YIKkmSJEmSpBXjK1/5ytyf/vSnM2677bYB++233zqPPircrH0AACAASURBVPpo3dlnnz29fnyLLbZYMHny5L9PnTq1zz777LPuVVdd9eHLLrvsxcZF2nHHHTdz9OjRCw844IBREyZM2PD3v//9gDXXXHPJb3/72xfeeOON7hMnThx99tlnDznjjDNmrLXWWotW+B+0oMjM1mfVT474HvA/wMCW5mVmzd/T2pLx48fnww8/3NEx2mTkd2/s6AjqpKaftEtHR5AkSZKkdhURj2Tm+NbmTZs2bfpmm2325orIpOqbNm3aapttttnIpsYqvrUzIv4H+CnwNnA58DKwpMWTJEmSJEmSpFVEkWekfR2YCYzLzNntlEeSJEmSJEmqSUWekfYR4H8t0SRJkiRJktQZFSnSZgMr9bPPJEmSJEmSpLYqUqRdDWwfET3bK4wkSZIkSZJUq4oUaT8E3gCujIg12ymPJEmSJEmSVJOKbDYwFegBbAl8PiL+AcxtYl5m5vrVCCdJkiRJkiTViiJFWm8gKe3cWa+uunEkSZIkSZKk2lRxkZaZI9oziCRJkiRJklTLijwjTZIkSZIkSWoXb731VpeIGDd58uRBHZ2lOW0u0iKib0QMq2YYSZIkSZIkqVYVeUYaEdEbOAbYDxhG6Zlp3cpjWwBHAz/KzKlVzilJkiRJkrRyO7b/uI753rceWd5LLFmyhCVLlkSvXr2yGpFWVhWvSIuIvsD9wFHAP4FngGgw5QlgW2BiNQNKkiRJkiRpxdpjjz1GbrLJJhtecsklA0aPHr1xr169xt5111199tprr5EjRoz4aK9evcaOHDlyk29961vDFy5c+H4/9Mwzz/SIiHHnn3/+wIkTJ67Vt2/fMUOGDNn029/+9vClS5d+4DsuuuiiASNHjtykV69eY8ePH7/+tGnTejXOsWTJEo444ojhw4YN+2iPHj3Gjh49euNf//rXH24q6xVXXNF/nXXW2biurm7zbbbZZvTs2bO7Pv744z233HLL9erq6jbfZJNNNnzggQeWa+PMIrd2Hg1sChycmZsCv284mJnvAncD2y1PIEmSJEmSJHW8V199tccPf/jDEUccccSsq6+++jmAgQMHLjnxxBNfvuaaa5795je/+doVV1yx2oEHHviRxucec8wxI/r06bP04osvfnGPPfb4xxlnnDHswgsvHFg/fu+99/Y++OCD19lwww3nX3zxxc/vtNNOcydOnLhO4+t8+9vfXmPy5MlD999//zcvv/zy5z/2sY+9c+ihh659zjnnfKBMmzlzZo8f//jHw3/0ox+9euqpp740ZcqUD331q19da9999x215557/vO3v/3tC0uWLImJEyeOWrZsWZv/Torc2rkH8KfM/E35c1NL+aYD49ucRpIkSZIkSTVh7ty53W688cZnt9pqqwX1x3bcccd36n/+7Gc/+06fPn2WHX744SMXLlw4o+Ftn1tsscXb55133isAu+2227w77rij/3XXXTfw4IMPngNwwgknDF1rrbUW3njjjS926dKFvffee97ixYvjlFNOWaP+GrNnz+56/vnnDz788MNnnXLKKbMA9thjj3kzZ87sfuKJJw7/+te//s/6ufPmzet2zz33PL3xxhsvAnj00Ud7n3POOUPOPPPM6Ycddtg/ADLz1X333Xf01KlTe40dO3ZhW/5OiqxIGwFMa2XOO0D/tgSRJEmSJElS7Rg8ePB7DUu0ZcuWcfzxxw9eZ511Nu7Vq9fYHj16jDv00EPXXrx4cTz//PM9Gp67/fbbz2v4ed11110wa9as7vWfp02b1meHHXaY26XLv6qpffbZZ27Dc6ZMmVK3cOHCLhMnTpzT8Piee+4556WXXuo5c+bM9xeIDR8+fFF9iQYwevTohQA77bTT+zk23HDDhQAzZszoThsVKdLeAVZvZc7awJttDSNJkiRJkqTasNpqq73X8POPf/zjwccff/yaO++889zf/e53z991111PnXjiiTMAFixY0PA5+gwcOPADD0Tr0aNHLlq06P0e6s033+w+ePDgJQ3nDB8+/APf98orr3QHWGONNT5wfNiwYe8BvPHGG13rj/Xr1+/fvq/8Z3j/eM+ePbOctUgf9gFFbu18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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from forest.benchmarking.volumetrics.plotting import plot_error_distributions\n", + "fig, axs = plot_error_distributions(avg_err_hamm_distrs, widths=[w], depths=[d], plot_rand_distr=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### For a particular width, plot all depths" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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t99++8fPnDnzgFmzZh2wZMmS2TfccMPsif55JtJ4VqQtS7LbGGMekeQX618OAAAAAFPptttum7l69ersvPPO9w9vX7BgwaqhP99www2zjjzyyEc+7nGP++3ZZ59902677XbfVltt1Z73vOc9YuXKletcuLVs2bIZz372sx+5ww473P93f/d3/7nHHnvcN2fOnDUnnXTSwnvvvbfWNXeqjSdI+3qS/1JVO7XWfjmys6r2TPKsJB+bqOIAAAAA2LgWLFiwaosttsjtt9++5fD222677Xc50j//8z9vu3Llyhmf//znb9x2223XJL2VbHfdddcWY93/y1/+8oNuv/32LT/3uc/95AlPeMLKofbf/OY3Y86dauN5tPOtSbZOcmVVHZZkdpJU1Vb9688kaUnePuFVAgAAALBRbLnlltl7773v+exnP7vd8PZLLrlk/tCfV6xYMaOq2pZbbtmG2j7wgQ88ePXq1TXiXu3ee+99QP50zz33zEiSOXPmrBlq++IXv7jN0qVLH3Aq6CDqvCKttfaNqjo5yXlJPj+s657+++okJ7TWvjeB9QEAAACwkb3mNa+57UUvetGeL3jBCx529NFH3/nlL3957pVXXjlvqP/www//zeLFi+uYY45ZeOKJJ97xve99b84//MM/7Dx37tzVw++z1157rbzqqqu2/fSnP73tjjvuuOqRj3zkvYcccsjdW2+99ZqXvOQlC1/96lf/4uabb97yzDPP3HWnnXa6/w8rGSzjebQzrbX3VdVXk/yPJH+cZPskdyX59yTvbK39cOJLBAAAANj0LTnjiO9OdQ1d/dVf/dWdt9xyy83nnnvugksuuWT7Aw888Dfvete7lhx99NGPSJIDDzxwxTve8Y6fn3HGGbsee+yx8x/1qEfdc9FFF/3shS984R7D73P66acvPfHEE2cdf/zxe9x9991bnHvuuUtOOeWUX3/4wx/+6amnnvrQ4447bq+HPexhK88555yb3/a2t+0yNT9td9VaG3vUZmbRokXtO9/5zlSXsV4WvvayqS6BzdSSM46Y6hLY1CyeN/YY1m3xXVNdAUwc3wkbzncCwKSrqu+21haNNe7aa69d8vjHP/6OjVETE+/aa6/d4fGPf/zC0fo675FWVT+pqndMWFUAAAAAsAkZz2EDC5LcPVmFAAAAAMAgG0+Q9sMke4w5CgAAAACmofEEaecl+bOq2neyigEAAACAQTWeUzt/muSKJP9WVe9K8u0kv0jyB6cVtNb+bWLKAwAAAIDBMJ4g7WvphWaV5DUZJUAbZosNKQoAAAAABs14grQ3Z93hGQAAAABMW52DtNba6yazEAAAAAAYZOM5bAAAAAAANlvrDNKq6g1VdfDGKgYAAAAABtVYj3Yu7r++MtRQVa9I8orW2h6TVxYAAADANLN43gFT87l3fXdKPnec7rrrrhnbbbfdE84999wlp5xyyq+nup7RrM+jndsl2X2iCwEAAACAQTbwe6RV1WOq6oqquqeqllbVG6tqizHm/FFVfaiqbuzP+3FVnVZVszdW3QAAAADTxapVq7Jy5cqa6jqm2kAHaVU1P8nlSVqSI5O8MclfJzl9jKnHJtkzyZlJnp3kH5K8KslFk1YsAAAAwDRx9NFHL9x3330f/ZGPfGS7vfbaa5/Zs2fvf+WVV27z/Oc/f+Fuu+322NmzZ++/cOHCfU855ZRdhwdsP/7xj2dV1QHvf//75x933HG7z507d7+dd975ca985St3Xb169QM+44ILLthu4cKF+86ePXv/RYsWPeraa6/9gwVQq1aI4l11AAAgAElEQVStyqte9apdFyxY8NhZs2btv9dee+3znve858Gj1XrxxRfP23PPPfeZM2fOE57ylKfsdfvtt2/x/e9/f6uDDjrokXPmzHnCvvvu++hvfvObczbkv8tYe6RNtZclmZPkqNba8iRfrKptkyyuqrP6baM5o7V2x7DrK6tqZZL3VtXurbWbJrluAAAAgE3arbfeOuv1r3/9bq95zWuW7rrrrvcnyfz581e95S1v+c8HP/jBq66//vrZZ5555q533HHHlh/72McekLWcdtppuz372c9eduGFF/7si1/84txzzjlnwT777LPixBNPXJYkX/va17Y+8cQT9zzssMOWnXXWWTd/73vfm3PcccftObKGV77ylQ9597vfvfOrXvWq2w466KDffupTn5p/8sknP7yq8tKXvvT/DY1bunTprDe96U27vuENb7j1t7/97YzXvva1D3vRi160+y233LLVi170ol/99V//9S/e8IY37HbcccftccMNN/xgxoz1W1vWJUjbrqoeNvw6SarqoUlGXdLXWrt5var5Q89K8oURgdnF6a00OyTJZ9by+XeM0vwf/fddkwjSAAAAANbhzjvvnHnZZZf95ElPetKKobZnPvOZdw/9+RnPeMbd22yzzZpXvOIVC1euXHnz7Nmz21DfgQce+Jv3ve99tyTJ8573vOVf+tKX5l166aXzh4K0N7/5zbvsvvvuKy+77LKfzZgxI8ccc8zy++67r84666yHDN3j9ttv3+L973//Tq94xStuO+uss25LkqOPPnr50qVLt3zLW96y6/Agbfny5TO/+tWvXr/PPvvcmyTXXXfd1u9973t3fuc737nk5S9/+a+TpLV261/8xV/sdc0118zef//9V67Pf5Mu8dsrkvx82OuUfvuSEe1Dr5+tTyFrsXeS64c39EO6e/p94/HEJGuS/HRiSgMAAACYvnbaaaf7h4doa9asyRvf+Mad9txzz31mz569/6xZsw44+eSTH37ffffVjTfeOGv43MMOO+wBTxE+4hGPWHHbbbdtOXR97bXXbnP44YffOXxl2LHHHnvn8DlXX331nJUrV8447rjjlg1v//M///NlN91001ZLly793QKxXXfd9d6hEC1J9tprr5VJ8qxnPet3dTz60Y9emSQ333zzlllPY61Iuzm9/cmmyvwkd47Svqzf10lV7ZLkdUk+0lr75VrGnJTkpCRZsGBBrrnmmvFXOwCO2WP12INgEmyqvzNMoYceP9UVbPr83jGd+E7YcL4TAJhgO+yww/3Dr9/0pjft9KY3vemhJ5988i+e+tSn/mb77bdf9Y1vfGObU0899WErVqx4wFOL8+fPf0BAMWvWrHbvvff+LjW74447ttxpp51WDR8z9PjokFtuuWXLJHnIQx7ygPYFCxbcnyS/+tWvtth1111XJcm22277B5/X/xl+177VVlu1JFmxYsV6nxmwziCttbZwfW88KKpqVpJ/THJ3kleubVxr7fwk5yfJokWL2n777bdxCpxgz7341qkugc3UWSdtmr8zTKFLL5jqCjZ9J5w71RXAxPGdsOF8JwAwwaoeuKPXpZde+uBnPvOZy975znf+Lny47rrr1mvz/h122OH+X/7ylw/IpZYuXfqAlWK77bbb/UPtu+yyy+8CsaGVbTvuuONGX0000Kd2prfybN4o7fP7fetUvb/xC5Psk+TZrbUx5wAAAADwh1auXDlj1qxZa4a3XXzxxQ9e2/h1edzjHvfbL3zhC9utWfP7233iE5/YbviY/ffff8Xs2bPXfOxjH3vAU4mf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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plot_error_distributions(avg_err_hamm_distrs, widths=[w], plot_rand_distr=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot all of the distributions" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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W7sDzypOpGXm/RGxB/AT4KOlLYEoVXkWODwzH+x8uJIkSZIkVWji8E4cM7f2cXR4zh4Sp6QOVTMijcy8KyI2BnYExgLDgbnANOCuzDTbKkmSJEmSpF6p6oUBsnBnZp6dmaeWHu80iSZJkiRJktR73X///UMiYtvrrrtuWKXHfO9731vl5z//+YiujKs7VTUirUVEDAXGAO/LzPtqG5IkSZIkSVLv03TC9dvW47zNk/ap2zRcl1xyyaqbbLLJgkMOOWROvWKopapGpEXE6Ii4CpgDPATcVbbvQxHxSETsVOMYJUmSJEmSpLqrOJEWEWsAfwIOAG4E/sg7Cw1Q2rcWcFAtA5QkSZIkSVL3mzRp0qprrLHGVkOHDt1m1113HTN9+vRB5ftPOeWU1bfccsvNhg0btvWoUaP+Zddddx3z2GOPDW7Zv912223y+OOPr3DNNdeMiohtI2Lbc889dxTAeeedN2rbbbfdZPjw4VuvtNJKW2+//fYb33nnnSt092usVjW3dp4CjAb2zMybI+IUYPuWnZn5VkTcBTgiTZIkSZIkqQf7xS9+MeLEE09cd/z48a/sv//+c2677bZhRx99dFN5nenTpw/6/Oc///L666//5ty5c/tdcMEFq+60006bPv3004+NGjVqyY9+9KPnPvWpT2247rrrLvrGN77xIsBmm222CKC5uXnQpz/96Vc32mijRYsWLYorrrhi5Y997GObTps27bHNN9/8zTq85IpUk0jbB/hNZt68jDrPAx9evpAkSZIkSZJUT5MnTx694447zrvsssueBzjggAPmzZo1a8BVV121Skudiy+++B8tPy9evJh999133uqrr771FVdcMeLYY499ddttt124wgorLB01atTi3Xbb7Y3y9r/3ve+92PLzkiVL2G+//eZtvPHGK/7kJz8ZVb6v0VQzR9rqwFMd1FkErNj5cCRJkiRJklRPb731Fk888cQKH//4x9+1QMD+++8/u/z5LbfcsuIOO+yw0YgRI7YeOHDgtsOGDRs7f/78fk899dRgOjBt2rQhu++++4ajRo36lwEDBmw7aNCgbZubm4c8/fTTQ2r9emqpmhFps4G1O6izEfBS58ORJEmSJElSPb344osDlixZwuqrr/5Wefno0aMXt/z89NNPD9p333033mqrrd6YMmXKc2uvvfabgwcPzv3222+jhQsX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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plot_error_distributions(avg_err_hamm_distrs, widths=None, depths=None, plot_rand_distr=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can study the sucess probablity, i.e. the zero hamming weight entry above as a function of depth. We first need to extract the data." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2: {2: 0.8954000000000001, 3: 0.8873000000000001, 4: 0.8841000000000001, 5: 0.9091999999999999, 10: 0.8751}, 3: {2: 0.8112999999999999, 3: 0.8189, 4: 0.8251, 5: 0.8264999999999999, 10: 0.8107}, 4: {2: 0.7823, 3: 0.8024000000000001, 4: 0.7831000000000001, 5: 0.7499, 10: 0.7342}, 5: {2: 0.7449999999999999, 3: 0.7445999999999999, 4: 0.7298, 5: 0.7051, 10: 0.7268999999999999}}\n", + "{2: {2: 0.9955, 3: 0.9949999999999999, 4: 0.9945999999999998, 5: 0.9971, 10: 0.9896999999999998}, 3: {2: 0.9851000000000001, 3: 0.9878000000000002, 4: 0.9841000000000001, 5: 0.9864, 10: 0.9753000000000001}, 4: {2: 0.9987999999999999, 3: 0.9986, 4: 0.9979999999999999, 5: 0.9963, 10: 0.9929999999999998}, 5: {2: 0.9969999999999999, 3: 0.9956000000000002, 4: 0.9948, 5: 0.9938999999999998, 10: 0.9879}}\n", + "{2: {2: 0.6454000000000001, 3: 0.6373, 4: 0.6341, 5: 0.6592, 10: 0.6251}, 3: {2: 0.6863, 3: 0.6939, 4: 0.7001, 5: 0.7014999999999999, 10: 0.6857}, 4: {2: 0.7197999999999999, 3: 0.7399, 4: 0.7206, 5: 0.6874, 10: 0.6717}, 5: {2: 0.7776, 3: 0.7826, 4: 0.7754, 5: 0.7637999999999999, 10: 0.7636}}\n" + ] + } + ], + "source": [ + "# extract data from avg_err_hamm_distrs\n", + "widths = list(avg_err_hamm_distrs.keys())\n", + "depths = list(avg_err_hamm_distrs[widths[0]].keys())\n", + "\n", + "# get the probability of success for each circuit sampled\n", + "succ_probs = get_single_target_success_probabilities(noisy_results, ideal_results)\n", + "\n", + "# get the average probability of success over all samples\n", + "avg_pr_succ_arr = {w: {d: distr[0] for d, distr in d_distrs.items()} for w, d_distrs in avg_err_hamm_distrs.items()}\n", + "# this is equivalently wrapped up in the following\n", + "assert avg_pr_succ_arr == average_distributions(succ_probs)\n", + "\n", + "# count as success even if there are log many bits incorrect.\n", + "avg_pr_succ_allow_log_errors = average_distributions(get_single_target_success_probabilities(noisy_results, \n", + " ideal_results, \n", + " allowed_errors = basement_log_function))\n", + "\n", + "ideal_distrs = {w: [1] + [0 for _ in range(w)] for w in widths}\n", + "rand_distrs = {w: get_random_hamming_wt_distr(w) for w in widths}\n", + "\n", + "pr_succ_rand = {w: 1/2**w for w in widths}\n", + "pr_succ_rand_allow_log_errors = {w: sum(rand_distrs[w][0:basement_log_function(w)+1]) for w in widths}\n", + "\n", + "# total variation distance\n", + "tvd_noisy_ideal = {w: {d: get_total_variation_dist(distr, ideal_distrs[w]) for d, distr in d_distrs.items()}\n", + " for w, d_distrs in avg_err_hamm_distrs.items()}\n", + "\n", + "# tvd_noisy_ideal is equivalent to 1 - success probability.\n", + "np.testing.assert_allclose([pr for d_vals in avg_pr_succ_arr.values() for pr in d_vals.values()], \n", + " [1 - val for d_vals in tvd_noisy_ideal.values() for val in d_vals.values()])\n", + "\n", + "tvd_noisy_rand = {w: {d: get_total_variation_dist(distr, rand_distrs[w]) for d, distr in d_distrs.items()}\n", + " for w, d_distrs in avg_err_hamm_distrs.items()}\n", + "\n", + "print(avg_pr_succ_arr)\n", + "print(avg_pr_succ_allow_log_errors)\n", + "print(tvd_noisy_rand)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Success probablity and success probablity including a small number of errors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we will plot the success probablity of a circuit with a certain width as a function of depth. " + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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796d999vyscaZEOLuH00IsZGREVEVJSW1voNaTNrxiKCzz/f4APhrEiKmQiWsO6zTbul88xsE7Bw4UJ22WUXTjrpJMrLy1m0aBFnnnkmFRUV9OzZk8svv7y6bPfu3bn88svZfffd6dWrF/PmzQNg2bJlHHTQQfTs2ZPTTjuN3NGSr7/+esrLyykvL+eGG26o3uauu+7KiBEj2HnnnTnhhBOYMmUKlZWV7LTTTjz77LNfinPVqlUce+yxlJWVcdRRRzFw4MDqYWzat29fXW7ChAmMGDECgKVLl/Ltb3+b/v37079/f558Mnko22OPPUbfvn3p27cv/fr146OPPuKdd95h8ODB9O3bl/Lycp544okvxVBsxbx9dCJwjqQ7gIHABxHxThHjMdtkXXH/bOa8/WGj1lnWdUsu/1bPOsu8+uqrjBs3jj333BOAq666iq222oq1a9ey//778+KLL9K7d28AunTpwsyZMxkzZgzXXXcdf/jDH7jiiisYNGgQl112GZMmTeLmm28GYMaMGfzxj3/kmWeeISIYOHAg3/zmN+ncuTMLFizg7rvv5pZbbqF///6MHz+eadOmMXHiRK6++mruu+++dWIcM2YMnTt3Zs6cObz88sv07dt3g/t+7rnncv755zNo0CDeeusthg4dyty5c7nuuusYPXo0lZWVrFy5kpKSEsaOHcvQoUO55JJLWLt2LatWrWrIx11QBUsEkm4HhgBdJC0mefh3W4CIuJHkweqHAguAVcD3ChWLmRXHDjvsUJ0EAO666y7Gjh3LmjVreOedd5gzZ051Ijj66KMB2GOPPbjnnnsAePzxx6vfH3bYYXTu3BmAadOmcdRRR7HFFltUr/vEE08wbNgwevToQa9evQDo2bMn+++/P5Lo1asXCxcu/FKM06ZN49xzzwWgvLy8Op66TJkyhTlz5lRPf/jhh6xcuZLKykouuOACTjjhBI4++mi6detG//79OeWUU1i9ejVHHnlkvRJNUytYIoiI4RtYHsDZhdq+mX1hQ2fuhVJ1oAZ44403uO6663juuefo3LkzI0aMWOd+98033xyA1q1bs2bNmgZvs6oegFatWlVPt2rVKu96c2/FzI31888/5+mnn6akpGSd8hdffDGHHXYYDz74IJWVlUyePJnBgwfz+OOPM2nSJEaMGMEFF1zASSed1JBdK5gW0VlsZi3fhx9+yBZbbEHHjh159913eeihhza4zuDBgxk/fjwADz30EMuXLwdgn3324b777mPVqlV8/PHH3Hvvveyzzz4NiquyspK77roLgDlz5vDSSy9VL9tmm22YO3cun3/+Offee2/1/IMOOojf/va31dOzZs0C4LXXXqNXr1785Cc/oX///sybN48333yTbbbZhtNPP53TTjuNmTNnNijOQvIQE2bWJPr06UO/fv3Ydddd2W677aisrNzgOpdffjnDhw+nZ8+e7L333my//fYA7L777owYMYIBAwYAcNppp9GvX79am3425KyzzuLkk0+mrKyMXXfdlZ49e9KxY0cArrnmGg4//HBKS0upqKhg5cqVAPzmN7/h7LPPpnfv3qxZs4bBgwdz4403csMNNzB16lRatWpFz549OeSQQ7jjjju49tpradu2Le3bt+dPf/pT3jEWWot7ZnFFRUX4wTRmGzZ37lx22223YofR7K1du5bVq1dTUlLCa6+9xgEHHMD8+fPZbLPNih1ag9X2u5c0IyIqaivvKwIzy7RVq1ax7777snr1aiKCMWPGtOgk0BBOBGaWaR06dMj842/dWWxmlnFOBGZmGedEYGaWcU4EZmYZ50RgZgVz1VVX0bNnT3r37k3fvn155plnih0SCxcupF27dvTt25eysjLOOOOMvEZGXbhwIeXl5Xltc8iQIbV2SE+cOJFrrrkGgFGjRnHdddcBcNlllzFlyhQAbrjhhoKPT+S7hsysIJ566ikeeOABZs6cyeabb87777/PZ599VuywANhxxx2ZNWsWa9asYb/99uO+++6rHusIYM2aNbRpU/jD47Bhwxg2bNiX5l955ZXV72+44QZOPPFEvvKVrxQsDl8RmBkA9z2/hMprHqXHxZOovOZR7nt+40aFf+edd+jSpUv1WD9dunSha9euwLoPmJk+fTpDhgwBYOXKlXzve9+jV69e9O7dm7/+9a8APPzww+y1117svvvuHHPMMdXf8L344ospKyujd+/eXHjhhQDcfffdlJeX06dPHwYPHlxnjG3atGHvvfdmwYIF/P3vf2efffZh2LBhlJWVAbUPdQ1JojjhhBPYbbfd+M53vlN9xn7llVfSv39/ysvLGTly5DrDZt92223VQ1FXDYd96623cs4553wprhEjRjBhwgR+85vf8Pbbb7Pvvvuy7777csstt3DeeedVl7vppps4//zz6/PrqJMTgZlx3/NL+Ok9L7FkxScEsGTFJ/z0npc2KhkcdNBBLFq0iJ133pmzzjqLxx57bIPr/PznP6djx4689NJLvPjii+y33368//77/OIXv2DKlCnMnDmTiooKrr/+epYtW8a9997L7NmzefHFF7n00kuB5GA8efJkXnjhBSZOnFjn9latWsUjjzxSPVrpzJkz+fWvf80rr7yyzlDXTz/9NDfddBPPP/88APPnz+ess85i7ty5bLnllowZMwaAc845h+eee46XX36ZTz75hAceeGCdbc2aNYsxY8Zwyimn1Osz/OEPf0jXrl2ZOnUqU6dO5dhjj+X+++9n9erVAPzxj3+sd111cSIwM66dPJ9PVq9dZ94nq9dy7eT5Da6zffv2zJgxg7Fjx1JaWspxxx3HrbfeWuc6U6ZM4eyzvxiUuHPnzjz99NPMmTOHyspK+vbty7hx43jzzTfp2LEjJSUlnHrqqdxzzz3VTSeVlZWMGDGCm266ibVr19a6nddee42+fftSWVnJYYcdxiGHHALAgAED6NGjB7DuUNft27evHuoaWGespBNPPJFp06YBMHXqVAYOHEivXr149NFHmT17dvU2hw9PBmQePHgwH374IStWrMj3I6V9+/bst99+PPDAA8ybN4/Vq1dXJ7GN4T4CM+PtFZ/kNb++WrduzZAhQxgyZAi9evVi3LhxjBgxgjZt2lR30OYO71ybiODAAw/k9ttv/9KyZ599lkceeYQJEybwu9/9jkcffZQbb7yRZ555hkmTJrHHHnswY8YMtt5663XWq+ojqCl32Oy65A5PXTX96aefctZZZzF9+nS22247Ro0atc6+1bZOQ5x22mlcffXV7Lrrrnzve43zGBdfEZgZXTu1y2t+fcyfP59XX321enrWrFnssMMOQNJHMGPGDIDqfgCAAw88kNGjR1dPL1++nD333JMnn3ySBQsWAPDxxx/zyiuvsHLlSj744AMOPfRQfvWrX/HCCy8Aydn+wIEDufLKKyktLWXRokUNir+uoa7feustnnrqKQDGjx/PoEGDqg/6Xbp0YeXKlUyYMGGd+u68804gudLo2LFj9QinG9KhQwc++uij6umBAweyaNEixo8fX32VsbGcCMyMi4buQru2rdeZ165tay4aukuD61y5cmX18M69e/dmzpw5jBo1CkiGlz733HOpqKigdesvtnvppZeyfPny6s7eqVOnUlpayq233srw4cPp3bs3e+21F/PmzeOjjz7i8MMPp3fv3gwaNIjrr78+2ZeLLqJXr16Ul5ez995706dPnwbFnzvU9cCBA6uHugbYZZddGD16NLvtthvLly/nzDPPpFOnTpx++umUl5czdOhQ+vfvv059JSUl9OvXjzPOOKP6kZv1MXLkSA4++GD23Xff6nnHHnsslZWV1U9s21gehtpsE5XvMNT3Pb+EayfP5+0Vn9C1UzsuGroLR/bbtoARWkMdfvjhnH/++ey///61Lvcw1GbWIEf229YH/mZuxYoVDBgwgD59+qw3CTSEE4GZWQvRqVMnXnnllUav130EZpuwltb0axuvIb9zJwKzTVRJSQnLli1zMsiQiGDZsmWUlJTktZ6bhsw2Ud26dWPx4sUsXbq02KFYEyopKaFbt255reNEYLaJatu2bfW3ZM3q4qYhM7OMcyIwM8s4Nw1ZrZrrl4uaa1xmLZkTQZE1xwNb1ZDEVaNRVg1JDBQ1tuYal1lL56ahIirEGPCNoRBDEjeG5hqXWUuXmSuC5njmXdeBrZixFWpI4o3VXOMyK6SmOHZl4oqguZ55N9cDWyGGJG4MzTUus0JpqmNXQROBpIMlzZe0QNLFtSzfXtJUSc9LelHSoYWIo7k2KTTXA1shhiRuDM01LrNCaapjV8ESgaTWwGjgEKAMGC6prEaxS4G7IqIfcDwwphCxNNcz7+Z6YDuy37b859G92LZTOwRs26kd/3l0r6I3pTXXuMwKpamOXYXsIxgALIiI1wEk3QEcAczJKRPAlun7jsDbhQika6d2LKnlgyv2mXfVAay59V1A8x2SuLnGZVYITXXsKmQi2BbIfUbcYmBgjTKjgIcl/QDYAjigtookjQRGAmy//fZ5B3LR0F3Wue0QmseZN/jAZmbr11THrmJ3Fg8Hbo2IbsChwG2SvhRTRIyNiIqIqCgtLc17I25SMLOWqKmOXYW8IlgCbJcz3S2dl+tU4GCAiHhKUgnQBXivsYPxmbeZtURNcewq5BXBc8BOknpI2oykM3hijTJvAfsDSNoNKAE8Zq6ZWRMqWCKIiDXAOcBkYC7J3UGzJV0paVha7EfA6ZJeAG4HRoSfomFm1qQK+s3iiHgQeLDGvMty3s8BKgsZg5mZ1a3YncVmZlZkTgRmZhnnRGBmlnFOBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFt6ltQUiugD9AV+AR4OSLeK1RgZmbWNDaYCCTtCPwEOAB4FVgKlAA7S1oF/B4YFxGfFzJQMzMrjPpcEfwC+G/g+xERuQskfRX4LvDvwLjGD8/MzAptg30EETE8Ih6vmQTSZe9FxA0RUWsSkHSwpPmSFki6eD1ljpU0R9JsSePz3wUzM9sY9e4slnSMpA7p+/+QdI+k3eso3xoYDRwClAHDJZXVKLMT8FOgMiJ6Auc1YB/MzGwj5HPX0H9ExEeSBgH7AzeTNBmtzwBgQUS8HhGfAXcAR9QoczowOiKWQ3KFkUc8ZmbWCPJJBGvTn4cBYyNiErBZHeW3BRblTC9O5+XamaTT+UlJT0s6uLaKJI2UNF3S9KVLl+YRspmZbUg+iWCJpN8DxwEPSto8z/Vr0wbYCRgCDAduktSpZqGIGBsRFRFRUVpaupGbNDOzXPkcyI8FJgNDI2IFsBVwUR3llwDb5Ux3S+flWgxMjIjVEfEG8ApJYjAzsyaSTyL4GjApIl6VNAQ4Bni2jvLPATtJ6iFpM+B4YGKNMveRXA0gqQtJU9HrecRkZmYbKZ9E8FdgraRvAGNJzvbXe7tnRKwBziG5ipgL3BURsyVdKWlYWmwysEzSHGAqcFFELGvAfpiZWQOplq8H1F5QmhkRu0v6MfBJRPxW0vMR0a+wIa6roqIipk+f3pSbNDNr8STNiIiK2pblc0WwWtJw4CTggXRe240NzszMiiufRPA9YC/gqoh4Q1IP4LbChGVmZk2l3qOPRsQcST8Btk+n3wB+WajAzMysaeQzxMS3gFnA/6bTfSXVvAvIzMxamHyahkaRDBuxAiAiZgFfL0BMZmbWhPLqLI6ID2rM8zMIzMxauHr3EQCzJX0XaJ2OGvpD4B+FCcvMzJpKPlcEPwB6Av8i+SLZB3jYaDOzFi+fu4ZWAZekLzMz20Tkc9fQ33JHBpXUWdLkwoRlZmZNJZ+moS7pqKMApA+T+Wrjh2RmZk0pn0TwuaTtqyYk7QDUb6AiMzNrtvK5a+gSYJqkxwAB+wAjCxKVmZk1mXw6i/83fVj9nums8yLi/cKEZWZmTSWfzuKjSL5U9kBEPACskXRk4UIzM7OmkE8fweW53yxOO44vb/yQzMysKeWTCGorm08fg5mZNUP5JILpkq6XtGP6uh6YUajAzMysaeQ7xMRnwJ3p61/A2YUIyszMmk4+dw19DFxcwFjMzKwI6p0IJE2lli+QRcR+jRqRmZk1qXw6ey/MeV8CfBtY07jhmJlZU8unaahmx/CTkp5t5HjMzKyJ5dM0tFXOZCtgD6Bjo0dkZmZNKp+moRkkfQQiaRJ6Azi1EEGZmVnTyadpqEchAzEzs+LIZ6yhYyR1SN9fKumedBA6MzNrwfL5Qtl/RMRHkgYBBwA3A/9dmLDMzKyp5JMI1qY/DwPGRsQkYLPGD8nMzJpSPolgiaTfA8cBD0raPM/1zcysGcrnQH4sMBkYmg5BvRVwUUGiMjOzJrPBRCCpPUBErIqIeyLi1XT6nYh4OLdMLeseLGm+pAWS1jtOkaRvSwpJFQ3bDTMza6j6XBH8j6T/kjRY0hZVMyV9XdKpkiYDB9dcSVJrYDRwCFAGDJdUVku5DsC5wDMN3QkzM2u4DSaCiNgfeAT4PjBb0geSlgF/Bv4NODkiJtSy6gBgQUS8HhGfAXcAR9RS7ufAL4FPG7gPZma2Eer7hbKHgJciYlEedW8L5JZfDAzMLZB+D2G7iJgkab39DZJGAiMBtt9++zxCMDOzDalXZ3FEBPBgY25YUivgeuBH9dj+2IioiIiK0tLSxgzDzCzz8rlraKak/nmUXwJslzPdLZ1XpQNQDvxd0kJgT2CiO4zNzJpWPoPODQROTA/aH5MMPhcR0Xs95Z8DdpLUgyQBHA98t2phRHwAdKmalvR34MKImJ7PDpiZ2cbJJxEMzafiiFgj6RyS7x60Bm6JiNmSrgSmR8TEfOozM7PC2GAikFQCnAF8A3gJuDki6vVksoh4kBp9CxFx2XrKDqlPnWZm1rjq00cwDqggSQKHAP9V0IjMzKxJ1adpqCwiegFIuhnw4ynNzDYh9bkiWF31pr5NQmZm1nLU54qgj6QP0/cC2qXTVXcNbVmw6MzMrOA2mAgionVTBGJmZsXh5wmYmWWcE4GZWcY5EZiZZZwTgZlZxjkRmJllnBOBmVnGORGYmWWcE4GZWcY5EZiZZZwTgZlZxjkRmJllnBOBmVnGORGYmWWcE4GZWcY5EZiZZZwTgZlZxjkRmJllnBOBmVnGORGYmWWcE4GZWcY5EZiZZZwTgZlZxjkRmJllnBOBmVnGORGYmWVcQROBpIMlzZe0QNLFtSy/QNIcSS9KekTSDoWMx8zMvqxgiUBSa2A0cAhQBgyXVFaj2PNARUT0BiYA/69Q8ZiZWe0KeUUwAFgQEa9HxGfAHcARuQUiYmpErEonnwa6FTAeMzOrRSETwbbAopzpxem89TkVeKi2BZJGSpouafrSpUsbMUQzM2sWncWSTgQqgGtrWx4RYyOiIoo3ZnIAAAblSURBVCIqSktLmzY4M7NNXJsC1r0E2C5nuls6bx2SDgAuAb4ZEf8qYDxmZlaLQl4RPAfsJKmHpM2A44GJuQUk9QN+DwyLiPcKGIuZma1HwRJBRKwBzgEmA3OBuyJitqQrJQ1Li10LtAfuljRL0sT1VGdmZgVSyKYhIuJB4MEa8y7LeX9AIbdvZmYb1iw6i83MrHicCMzMMs6JwMws45wIzMwyzonAzCzjnAjMzDLOicDMLOOcCMzMMq6gXyhrbq64fzZz3v6w2GGYmeWtrOuWXP6tngWp21cEZmYZl6krgkJlUzOzlsxXBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGedEYGaWcU4EZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGedEYGaWcQVNBJIOljRf0gJJF9eyfHNJd6bLn5HUvZDxmJnZlxUsEUhqDYwGDgHKgOGSymoUOxVYHhHfAH4F/LJQ8ZiZWe0KeUUwAFgQEa9HxGfAHcARNcocAYxL308A9pekAsZkZmY1FDIRbAssyplenM6rtUxErAE+ALauWZGkkZKmS5q+dOnSAoVrZpZNLaKzOCLGRkRFRFSUlpYWOxwzs01KIRPBEmC7nOlu6bxay0hqA3QElhUwJjMzq6GQieA5YCdJPSRtBhwPTKxRZiJwcvr+O8CjEREFjMnMzGpoU6iKI2KNpHOAyUBr4JaImC3pSmB6REwEbgZuk7QA+D+SZGFmZk2oYIkAICIeBB6sMe+ynPefAscUMgYzM6tbi+gsNjOzwnEiMDPLOCcCM7OMcyIwM8s4tbS7NSUtBd7ciCq6AO83UjiNyXHlp7nGZVYoG/s3v0NE1PqN3BaXCDaWpOkRUVHsOGpyXPlprnGZFUoh/+bdNGRmlnFOBGZmGZfFRDC22AGsh+PKT3ONy6xQCvY3n7k+AjMzW1cWrwjMzCyHE4GZWcZlIhFI2k7SVElzJM2WdG6xYwKQVCLpWUkvpHFdUeyYcklqLel5SQ8UO5YqkhZKeknSLEnTix2PWSFIukXSe5Jezpm3laS/SXo1/dm5sbaXiUQArAF+FBFlwJ7A2ZLKihwTwL+A/SKiD9AXOFjSnkWOKde5wNxiB1GLfSOir79HYJuwW4GDa8y7GHgkInYCHkmnG0UmEkFEvBMRM9P3H5Ec3Go+P7nJRWJlOtk2fTWL3ntJ3YDDgD8UOxazrImIx0me0ZLrCGBc+n4ccGRjbS8TiSCXpO5AP+CZ4kaSSJtfZgHvAX+LiGYRF3AD8GPg82IHUkMAD0uaIWlksYMxa0LbRMQ76ft/Ats0VsWZSgSS2gN/Bc6LiA+LHQ9ARKyNiL4kz3QeIKm82DFJOhx4LyJmFDuWWgyKiN2BQ0ia+AYXOyCzppY+0rfRWg8ykwgktSVJAn+JiHuKHU9NEbECmMqX2wWLoRIYJmkhcAewn6Q/FzekREQsSX++B9wLDChuRGZN5l1JXwNIf77XWBVnIhFIEsnzkedGxPXFjqeKpFJJndL37YADgXnFjQoi4qcR0S0iupM8R/rRiDixyGEhaQtJHareAwcBL9e9ltkmYyJwcvr+ZOB/Gqvigj6zuBmpBP4deCltjwf4WfpM5WL6GjBOUmuSpHxXRDSbWzWboW2Ae5O8ThtgfET8b3FDMmt8km4HhgBdJC0GLgeuAe6SdCrJUPzHNtr2PMSEmVm2ZaJpyMzM1s+JwMws45wIzMwyzonAzCzjnAjMzDLOicCsBklr09FNZ6cjw/5IUoP/VyT9LOd999wRJc2aAycCsy/7JB3dtCfJl/wOIbmPu6F+tuEiZsXjRGBWh3Qoi5HAOUq0lnStpOckvSjp+wCShkh6XNIkSfMl3SiplaRrgHbpFcZf0mpbS7opveJ4OP1WuVnROBGYbUBEvA60Br4KnAp8EBH9gf7A6ZJ6pEUHAD8AyoAdgaMj4mK+uMI4IS23EzA6veJYAXy76fbG7MucCMzycxBwUjpUyTPA1iQHdoBnI+L1iFgL3A4MWk8db0RE1VAnM4DuBYzXbIOyMtaQWYNJ+jqwlmS0RwE/iIjJNcoM4cvDAq9v/JZ/5bxfC7hpyIrKVwRmdZBUCtwI/C4dA34ycGY6rDmSdk5HQoXkeRI90juMjgOmpfNXV5U3a458RWD2Ze3Spp+2JM+7vg2oGr78DyRNOTPT4c2X8sUjA58Dfgd8g+TZEvem88cCL0qaCVzSFDtglg+PPmrWCNKmoQsj4vBix2KWLzcNmZllnK8IzMwyzlcEZmYZ50RgZpZxTgRmZhnnRGBmlnFOBGZmGff/AXGKGQULm4ixAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "w=3\n", + "plt.scatter(depths, [avg_pr_succ_arr[w][d] for d in depths], label='Sucess Probability')\n", + "plt.plot(depths, [pr_succ_rand[w] for _ in depths], label='random guess')\n", + "plt.ylim([-0.05,1.05])\n", + "plt.xlabel('Depth')\n", + "plt.xticks(depths)\n", + "plt.ylabel('Pr(success)')\n", + "plt.title('Pr(success) vs Depth for Width = {}'.format(w))\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Sucess if we allow for a small number of errors**\n", + "\n", + "Some near term algorithms have robustness to noise. In light of that we might want to consider as successes answers that are only a little wrong.\n", + "\n", + "To make this notion formal we allow a logarithmic number of bits to be flipped from the correct answer and call all such instances \"success\".\n", + "\n", + "The logarithmic number of bits that we allow to flip is defined by the \"basement\" ${\\mathcal B}$ of \n", + "\n", + "$\\log_2 ({\\rm number\\ of\\ bits})$\n", + "\n", + "where the basement of a number is ${\\mathcal B}(number) = 0$ if number$<=0$ and ${\\mathcal B}(number) = {\\rm floor (number)}$.\n", + "\n", + "\n", + "Supose we have a circuit of width 4 so that the correct string has four bits, e.g. 1010. Then a logarithmic number of flips is $\\log_2(4) = 2$.\n", + "\n", + "So any string with hamming weight zero, one, or two counts as a success.\n", + "\n", + "Such error metrics might be important in noisy near term algorithms where getting the exact answer is not vital." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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lb9uqMePH09eXh47duwgMzOzMBH4dkP97rvvAk431AWvA3VDXTDvwoULGThwYGE31ECZu6Eu6P8nmG6ofbvQLtoN9XXXXccVV1xB06ZN6dChAzfffDO5ublcdtllxb6Ia9asydlnn82aNWv46quveOCBB1iwYAH5+fmFHel9/PHH9OnTp8SYFi1axNChQwFo06YNzZs3Z/369WXavnXr1vHtt99y4YUXAk63G759K1199dXHlB80aBARERGF633nnXcA6NmzJ7t27WLfPufZFwMHDiQ6OhqA888/nyeffJKsrCyuuOIKWrVqVeL2lEUwiWAo8AjwK84PyWbjPLTGGO8o5cw9VKwb6rJ1Q92tWzdmzZpFZGQkvXv3Jj09nfz8fMaMGQM41wceeCB0P1tSVeLi4vjiiy/8Tvd9H/0NB+Jb7tprryU1NZUZM2Zw0UUX8a9//YuePXuWP2iCu2vooKo+oqod3L9HVfVw6XMaYyqSdUMduBvqrl278txzz3H++ecTExPDrl27WLduHfHx8agqK1euLLXJqmvXrrz++usArF+/ni1bttC6desSt69A69atyc7OLkwEubm5rF69ukz7z3e98+fPp2HDhpxyyinFym3cuJGzzjqL++67j0svvbTwWsLxCObBNJ8Agwp6BhWRBsBbqtr3uKMwxpSZbzfUzZo1K3M31IMHDyYuLo7OnTv77YYaKOyG2l/TT2nuvvtubrzxRmJjY2nTpo3fbqhjYmJISUkhJycHcLqhvueee0hMTCQvL49u3brx0ksv8dxzzzFv3rzCp6P179+ft956izFjxhAZGUmdOnX473+Ld3WWmprKTz/9RLdu3QBITEzkxx9/RETIyMggOTmZItc5/W7HXXfdRUJCAjVr1mTChAnUqlWrxO0rcNJJJzF16lTuu+8+9u7dS15eHvfffz9xcaU/0GjkyJHcfPPNJCYmcvLJJzNxov+n/06ZMoXXXnuNyMhITj/9dB5++OFSl12aYLqh/lpVk0sbF2rWDbWpbNYNddlU9W6oR48ezTnnnFP4OM1gVfXt8xXKbqiPisiZqrrFXWhzoGxZxBhzwqvq3VA/+uijxzV/Vd++4xFMIngEWCQinwECdAVuD0lUxphq50TvhvpE3r4yJwJV/UhE2gEF97Ddr6re/I26McacQILpYuJynB+VfaiqHwJ5InJZ6EIzxhhTGYLpYmKEqu4tGHDvHhpRQnljjDHVQDCJwF/ZYK4xGGOMqYKCSQQZIvKMiJzt/j0DLAtVYMaY3zz55JPExcWRmJhIUlISS5YsCXdIbNq0iejoaJKSkoiNjeXOO+8MqmdUr3f9XJUE28XEY8Bkd/gT4J4Kj8gYc4wvvviCDz/8kOXLl1OrVi127tzJkSNHwh0WAGeffTYrVqwgLy+Pnj17Mm3atMK+jsDpNrlmTWs4qOqC6WLigKoOV9UU9+8vqnoglMEZUx1N+3obaU99SsvhM0h76lOmfb3tuJa3Y8cOGjZsWNjXT8OGDWncuAqhmo8AABQMSURBVDFw7ANmMjIy6NGjBwA5OTmFXSknJiYWdmb28ccfc/7559OuXTsGDRpU+Avf4cOHExsbS2JiIn/6058AePvtt4mPj6dt27aFv9QNpGbNmnTu3JkNGzYwf/58unbtysCBA4mNjQX8d3UNTqK47rrrOO+88/j9739frEdRUzmC6WJiHn5+QKaqx9fbkTEnkGlfb+Mv767iUK7TNfC2PYf4y7tOnzSXJTcp1zL79OnDqFGjOPfcc+nduzdXX3013bt3L3Gev/71r9SrV6+wP5zdu3ezc+dORo8ezZw5c6hduzZPP/00zzzzDPfccw/vvfcea9euRUTYs2cPAKNGjWL27Nk0adKkcFwgBw8eZO7cuYwaNQqA5cuX8+2339KyZcsSu7pet24dL7/8Mmlpadx88828+OKLhYnIVJ5grhH8CXjQ/XsM52llJ+avK4wppzGz1xUmgQKHcvMZM3tduZdZp04dli1bxvjx44mJieHqq69mwoQJJc4zZ84c7rnnt5bbBg0a8OWXX5KZmUlaWhpJSUlMnDiRzZs3U69ePaKiorjlllt49913OfnkkwGnE7n09HT+/e9/B+zz/vvvvycpKYm0tDQGDBhA//79AejYsSMtW7YEju3quk6dOoVdXQPH9JU0ZMgQFi1aVO79ZMovmB+UFb0wvFhEij+myBgP277nUFDjyyoiIoIePXrQo0cPEhISmDhxIunp6dSsWbPwAq1v987+qCoXXnghb775ZrFpX331FXPnzmXq1Kn885//5NNPP+Wll15iyZIlzJgxg/bt27Ns2TJOO+20Y+YruEZQVFm7Vy7aAVxpHcKZ0AjmB2Wn+vw1FJG+QODH/BjjQY3rRwc1vizWrVt3zOMIV6xYQfPmzQHnGsGyZc45WsF1AIALL7yQcePGFQ7v3r2bTp06sXjxYjZs2ADAgQMHWL9+PTk5Oezdu5eLLrqIZ599lm+++QZwzvZTU1MZNWoUMTExbN26tVzxl9TV9ZYtWwq7bH7jjTfo0qVLudZhjk8wTUPLcJqClgFfAH8EbglFUMZUVw/2bU10ZMQx46IjI3iwb+tyLzMnJ6ew++PExEQyMzMZOXIk4HQvPWzYMFJSUgqfdAVOB2u7d+8uvNg7b948YmJimDBhAoMHDyYxMZHzzz+ftWvXsn//fi6++GISExPp0qULzzzzjLMtDz5IQkIC8fHxdO7cmbZt25Yrft+urlNTUwu7ugan//5x48Zx3nnnsXv3bu66665y7ydTfmXuhrqqsG6oTWULthvqaV9vY8zsdWzfc4jG9aN5sG/rcl8oNqY8QtYNtYgMAj5S1f0i8ijQDhitqsUfE2SMh12W3MS++E21EkzT0GNuEugC9AZeBv4vNGEZY4ypLMEkgoL7xwYA41V1BnBiPJXBGGM8LJhEsE1E/gVcDcwUkVpBzm+MMaYKCuaL/CpgNtDX7YL6VJwflxljjKnGSk0EIlIHQFUPquq7qvqdO7xDVT/2LeNn3n4isk5ENojI8BLWcaWIqIj4vaJtjDEmdMpSI3hfRP5XRLqJSOHPBUXkLBG5RURmA/2KziQiEcA4oD8QCwwWkVg/5eoCw4Dw96trTBVl3VCXbMeOHfTp06fY+Dp1/J6jmiJKTQSq2guYC9wBrBaRvSKyC5gEnA7cqKpT/czaEdigqhtV9QjwFnCpn3J/BZ4GSv59vDEe5dsN9cqVK5kzZw7NmjULd1jAb11MrFy5kszMTKZNm3bM9Ly8vEqJ46OPPqJv376Vsq5Aim5rWbe9svZRScp6jWAWMFxVW6hqPVU9TVU7q+qTqvpjgHmaAL6/Sc9yxxUSkXZAM/cOpIBE5HYRyRCRjOzs7DKGbEyYrJwCz8bDyPrO/5VTjmtxXu6G+ueff6Z9+/YAfPPNN4gIW7ZsAZwkVFD+o48+Kuzwzh9V5cEHHyQ+Pp6EhAQmT3Yeq3L06FHuvvtu2rRpw4UXXshFF13E1KnFz2u///57+vXrR/v27enatStr164FID09nTvvvJPU1FQeeughRo4cyfXXX09aWhrXX389hw8fLnwfkpOTmTdvHgATJkxg4MCB9OzZk169erFjxw66detGUlIS8fHxhZ3yVRpVLdMfsKqsZd3yvwf+4zN8PfBPn+EawHyghTs8H0gpbbnt27dXYypTZmZm2Qt/M1l1dCPVEaf89je6kTO+nPbv369t27bVVq1a6V133aXz588vnNa8eXPNzs5WVdWlS5dq9+7dVVX1oYce0mHDhhWW++WXXzQ7O1u7du2qOTk5qqr61FNP6RNPPKE7d+7Uc889V48ePaqqqrt371ZV1fj4eM3KyjpmnK8ffvhB4+LiVFX1wIEDmpKSojNnztR58+bpySefrBs3blRV1YyMDI2Pj9ecnBzdv3+/xsbG6vLly/WHH35QQBctWqSqqjfddJOOGTOm2HpiY2N17969+sILL2hKSopOmjRJN23apJ06dVJV1by8PG3btq3ffVe7dm1VVZ06dar27t1b8/Ly9Mcff9RmzZrp9u3b9e2339b+/ftrfn6+7tixQ+vXr69vv/12seX07NlT169fr6qqX375pV5wwQWqqnrjjTfqgAEDNC8vT1VVR4wYoe3atdODBw+qqurYsWP1pptuUlXVNWvWaLNmzfTQoUP66quvapMmTXTXrl2F5UaPHl24Pfv27fO7PWXl75gFMjTA92owdw0tF5EOQZTfBvjWX5u64wrUBeKB+SKyCegETLcLxqZamzsKcov0NJp7yBlfTl7vhrpz584sXryYBQsW8PDDD7NgwQIWLlxY2HHdkiVLSE1NLXF/LFq0iMGDBxMREUGjRo3o3r07S5cuZdGiRQwaNIgaNWpw+umnc8EFFxSbNycnh88//5xBgwaRlJTEHXfcwY4dOwqnDxo06Jh+ngYOHEh0dHTheocMGQJAmzZtaN68OevXrwecjgFPPfVUADp06MCrr77KyJEjWbVqFXXr1i1xeypaMM+QSwWGuF/aBwABVFUTA5RfCrQSkZY4CeAa4NqCiaq6F2hYMCwi84E/qap1JGSqr71ZwY0vIy93Q92tWzcWLlzI5s2bufTSS3n66acREQYMGADArFmz6Nev2P0qFebo0aPUr1/f73ZC8W0t67b7luvWrRsLFixgxowZpKen88ADD3DDDTeUP+ggBVMj6AucBfQELgEudv/7pap5wL04vz1YA0xR1dUiMkpEBpY/ZGOqsHpNgxtfBl7vhrpr165MmjSJVq1aUaNGDU499VRmzpxZWHbu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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "w=4\n", + "plt.scatter(depths, [avg_pr_succ_arr[w][d] for d in depths], label='Sucess Prob')\n", + "plt.plot(depths, [pr_succ_rand[w] for _ in depths], label='random guess')\n", + "plt.scatter(depths, [avg_pr_succ_allow_log_errors[w][d] for d in depths], label='Sucess Prob w/ log errors')\n", + "plt.plot(depths, [pr_succ_rand_allow_log_errors[w] for _ in depths], label='random guess w/ log errors')\n", + "plt.ylim([-0.05, 1.05])\n", + "plt.xlabel('Depth')\n", + "plt.xticks(depths)\n", + "plt.ylabel('Pr(success)')\n", + "plt.title('Pr(success) (& w/ log errors) vs Depth for Width = {}'.format(w))\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Total variation distance from ideal answer and random distribution" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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rDo+d3rfvn331HY+EiUJIiISEzec0X3bLy8pWNOxXdpeAzq2S9v7y0sK1hzN7Ib6XHfdddtKS0tbjxgx4qB7rF27Ni00BfJb3/rWiWPHjt0cmtkwZMiQ3cuWLcsIjRuYPHnyv6dOndoxLy+vYP369Qd+0EeNGrVt8eLFbfLy8gqeeOKJzB49elRAYMbFoEGDdvfq1avvmDFjutZWb//+/axZsyYtvGujpu7du++76667Npxxxhl9CgsL8/Py8ipC56ZOnbp20aJFbfLy8gpOPPHEvo888kg2wF133VV2zz33dO3Tp09BVVXtPRpvvfVWuyuuuGLn4XyfFt4v0xQUFhb6ggUL4h2GiEiTYmYL3b3waK+zePHizwYMGLClIWJKJN/97ne7XX755TuuuOKKXbG6R1FRUfqUKVOypk+fvi5W96jN2rVrU4YNG9Zz3rx5yyOdX7x4cdaAAQNya5arJUFERFq8CRMmbAzvMoiF0047rSIeCQLAqlWrUh988MG19dc8mAYuiohIi9etW7eq66+//rCa4puS8847r9ZBnHVRS4KIiIhEpCRBREREIlKSICIiIhEpSRAREZGIlCSIiEiT0Vy3im5oV199de6f/vSn4wAuueSSnkuWLDlk06doKEkQEZHYKXqsAw/k9eeeYwfxQF5/ih47qh0gQ1tFl5SUFI8YMaJ87Nixm0pKSorvv//+NU8//fRB1545c2aHG264YRv8Z6voVatWLZsxY8bKyZMnd3r44YcPJAoPPfTQ8XfeeecRbfUc2ir6aD5XuLoWRDoS3/ve9zb/9re/Pf5I3qskQUREYqPosQ68+rPu7N6UCg67N6Xy6s+6H22iEElT3yq6S5cu/b/3ve91KSgo6PP4448f9+CDD2b169evT+/evQuGDBly4q5du5Ig0EJw0003dRs4cGB+165d+4daC6qrqxkxYkRObm5uv7POOitvy5YtB5Y4GDp06O633377mH379tV2+1opSRARkdh483ddqKo8+HemqjKJN3+nraIjyMzMrCouLv5k9OjR26+//vrtS5cu/aS0tLS4d+/eeyZOnHhgT4ZNmza1WrBgQcmLL7746a9+9asuEOguWbFiRdqKFSuW/u1vf1u9aNGiA1tCJycn071794r58+dnHO73qiRBRERiY/fmyNsS11Z+lEJbRQM8//zzHW688cZa94iob6voW265ZRsEtooOlYe2gM7Lyyu44IIL8urbKrq+ejWNGDFie+j1woULWw8aNKh3Xl5ewcyZMzOXLVuWHjp32WWX7UhOTmbQoEEVW7dubQXw5ptvths2bNi2lJQUcnNz95155pkHLS+dlZVVtXbt2lo3lqqNkgQREYmNth0jbwldW/lRGj58+I533333mCPZKrqiouKg38P6toouKSkpzszM3FffVtF11aupXbt2B5obRo8e3eORRx759/Lly4vvuuuuDZWV/2mRSU9PPxBbtPsvVVZWJmVkZBzWNtGgJEFERGLlvLvWk5J28A9TSlo1592lraLr8eWXXybl5OTsq6ystGeeeabeMRznnXferueee65DVVUVa9asaTV//vx24edXr16dduqppx7WNtGgJEFERGLltJHbGHLvGtp22gsGbTvtZci9azhtpLaKrsf48eM3DB48uE9hYWF+r169Kuqrf+ONN+7o2bNn5UknndTv29/+du7AgQMPDNhcu3ZtSlpamufk5Bz2tAltFS0i0gJoq+i6Neeton/96193POaYY6rvuOOOWv+5aatoERGRWjTnraKPPfbY/bfeeusRJXbaKlpERFq85rxVdKhb5UioJUFEREQiUpIgIiIiESlJEBERkYiUJIiISMyt27XusFf7k/hTkiAiIjG1YfeGVrNXzT5uw+4NDZIoXHPNNbkdOnQY0KtXr75H8v7Bgwf3zs3N7de7d++CU089NX/x4sURt1EO1fvrX//aHmDOnDltTj755Pz8/PyCnj179h03btwJkd4XL9OmTTsuJyen3wUXXHBSQ11TSYKIiMRUUVlRm4qqiqSisqI2DXG9m2++ecusWbM+PZprPPnkk6tKS0uLhw8fvuWOO+7oVvN8aLvmJ598clVo1sPIkSN7TJkyZU1JSUnx8uXLl11//fUxWxTqSNxyyy3bJ0+evKYhr6kkQUREYmbD7g2t1u1al5rTLqdy3a51qQ3RmnDxxRfvjmbVwmhceOGFu9esWZMGh27XXLPutm3bUnJycvYBpKSkMGjQoAqAcePGnXD33Xd3CtXr1atX39LS0lSARx55JDMvL6+gd+/eBVdccUUPCKyA+LWvfe3E3r17F/Tu3bvg9ddfbwMwefLkDv379++Tn59fMHz48O5VVVVUVVVx9dVX5/bq1atvXl5ewa9//euOAP/93//d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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "plt.scatter(depths, [tvd_noisy_ideal[w][d] for d in depths], label='TVD(data, ideal)')\n", + "plt.scatter(depths, [tvd_noisy_rand[w][d] for d in depths], label='TVD(data, rand)')\n", + "plt.scatter(depths, 1-np.asarray([avg_pr_succ_arr[w][d] for d in depths]),\n", + " label='1 - Pr[Success]', alpha=0.33, marker='^', s=80)\n", + "plt.ylim([-0.05,1.05])\n", + "plt.xlabel('Depth')\n", + "plt.xticks(depths)\n", + "plt.ylabel('Total variation distance')\n", + "plt.title('Width = {}'.format(w))\n", + "plt.legend(bbox_to_anchor=(1.04,1), loc=\"upper left\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot success probablity landscape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is just the success probablity as a function of depth and width." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "X, Y = np.meshgrid(widths, depths)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "Zdata = np.reshape([avg_pr_succ_arr[w][d] for d in depths for w in widths], X.shape)\n", + "Zrand = np.reshape([pr_succ_rand[w] for d in depths for w in widths], X.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "extent = -0.5, len(widths) - 0.5, -0.5, len(depths) - 0.5\n", + "ax = plt.gca()\n", + "img = ax.imshow(Zdata, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0.0, vmax=1.0)\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('Success Probability')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax = plt.gca()\n", + "img = ax.imshow(Zrand, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0.0,vmax=1.0)\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('Success Probability of Random Guess')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(
,\n", + " )" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from forest.benchmarking.volumetrics.plotting import plot_success\n", + "\n", + "success_threshold = .8\n", + "ckt_success_probs = get_single_target_success_probabilities(noisy_results, ideal_results)\n", + "successes = determine_successes(ckt_success_probs, num_shots)\n", + "plot_success(successes, f\"Volumetric Benchmark\\n Random Classical Circuits\\n Pr[Success] > {success_threshold}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(
,\n", + " )" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from forest.benchmarking.volumetrics.plotting import plot_pareto_frontier\n", + "\n", + "plot_pareto_frontier(successes, 'Pareto Frontier', widths=[2,3,4,5,6], depths = [2,3,4,5,7,10,15])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot total variation distance landscape" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "Ztvd_ideal = np.reshape([tvd_noisy_ideal[w][d] for d in depths for w in widths], X.shape)\n", + "Ztvd_rand = np.reshape([tvd_noisy_rand[w][d] for d in depths for w in widths], X.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAARMAAAEWCAYAAABFZHMLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAdYUlEQVR4nO3debQdZZnv8e8vJwkJEMYIIgmDGhRwADtCC15FFG9EmlyvwwUFx2vElm5nG9CFiq5WsRu9vW4uGpElrQIiikZFERWkFYMEVCABmhiBJAIhDEloNMM5z/3jrYOV7R7qnF3nVNXJ77NWrbNr2G89ezjPfuutt95SRGBm1q9JVQdgZhODk4mZlcLJxMxK4WRiZqVwMjGzUjiZmFkpapNMJE2TFJJmjdP+dpD0mKSnjPL5b5P0vbLjKrjvvmKvO0mflfSQpLvHoOyDJD1adrljSdISSaeUUM6nJV1QRkztdE0m2Rd2eBqS9Kfc/Bt6PHeepBVlBCnpK5IWtVl+pKTHJe0y0jIjYlNE7BwRfyyw/2dK2try/C9HxN+NdL8F9jUve6+H3+dVki6RdPhIYy/zMxgvkuYA7wTmRMQBbdbPy350zmtZvlTSSb3Kj4j/jIjdSgs47fs0ST/p4/lj+k8+Xromk+wLu3NE7AzcC/xdbtnXxydEAC4CXitpWsvyU4ErImLDSAqTNLm0yMbGyuw93wU4CvgDcL2k/1ZtWONif+D+iHi4yzYbgP8tad9xiskK6OswR9J0SQsl3SdpdVY9nSJpT+AK4Km5X9g9JR0t6QZJj0r6o6TPFfzHvhZYD5yY2/cU4CTg37P5jmXnDqHeKen3wG2th1WSXiXpd5I2SLpX0lm5/V8HDORey+Gtv0aSXizpZknrs2rp83Prlkj6aPZ3g6QrJe3e60VHxFBErIqIs4CvA59qeT3Dsc+XdIekjVlN5h9H8xnkyl0g6feSHpH0uZbP/O9z+7pV0rOz5bMlfVfSOkkrJZ3W6XVJ2kPSxZIelPQHSR9ScgLwvVzMX+hQxIPAN4CPdCh/QNLHs8/xAUkXSpqRrdumlinp7ZLuzl7PSkmvlbRj9jnNyW03S6kWvFvLvg4HPg8ck8V8f7fX2Ok9aSnzlZLuyj6j89qsf4ekOyU9LOkHyiVVSecr/S9ukPRrSX9bZJ+liIhCE3A38LKWZecC/wHMBPYGbgQ+nK2bB6xo2f4I4PnAAPA0YAVwWrZuGhDArA77/wTw/dz8fGANMDCCsn8A7AZMb90f8FLgUFKCfR7wMDAvW/dMYGtLPKcBP8ke70X6tXwdMBl4M+kLv2u2fglwZxbXTsD1wMc6vM6/et+y5ccDW4EpbWJ/CDgie7wncHifn8G3SbWiA4FHgWOy9acC9wCHAwKeAczKyroV+CdgKnAQqSb74g6v8TLgm8DOwNNJNa83dHv9re8PMBvYCByYLV8KnJQ9/nvgdlItZxfg+8CXWj9LYPfs9T0tm38KcHD2+ELg47n9/hPwzQ4xPfFdKPIa2zz/08AF2eN9gP8i/XBOAc7MPvdTsvX/K3ttB2XrPwlckyvrjdnrmgJ8GFgFTGndz1hM/SaTNcCxLf/gdxT5UmTbnAFcUjCZzAE2A3tl898CPjPCso/Kre+1vy8An2r9Arb7AgFvB65rWf+b3Jd7CfCB3Lr3Ad/p9s/SZvlhWbx7tsYOrAXeAswoUlaB92lubv1i4D3Z458D72hTxouBu1qWfRw4v822OwCDwFNzy94N/KhIzPn1wL8BF2WP88nkl8Bbc895LvA4KQG2SybzgWltXtOK3PytwIkdYtommfR6jW2en08mC4Brc+sGss93OJlcQy4pkZLGFmDvNuUqe93PaN3PWEyjPszJqmxPJv1SDbsH6HgcK+kQST/Mqp4bgLNJtZqeIuIuUs3n9dkhwivJDnFGUPaqLrEdLennWbV0Pal2USg20i/aPS3LWt+L+3OPHyf9Yo3EvqQvaLv2ofnAq4F7Jf0sf4jVquD71CnW2cDv2xS7P3BAVi1/VOlsyftI349WTybV/u7NLev6venin4FXSXpmy/LWz+MeUm10j/xGEfEI8AbgH4H7JS2W9PRs9fCh7QskHUaqMfywYFz9vMankPueRsQg6Ud72P7AF3Lv84OkmsvwIe+Z2SHQeuAR0g9E0e9xX0adTCKluvtJL27Yfvzlhbe7HPlLwM2kauUuwDmk7FnURaRq3OuA2yJi2QjL7naJ9GWk4/DZEbEr8JXc83tdWv1Htn0fYNv3ogyvApZExJbWFRHxq4g4gXSo+WPg4uFVbcrp5zNYRTo0arf8jojYLTfNiIhXtdn2fmCI9P4MG9V7FRH3A/+P9BryWj+P/YA/kQ5dW8v4QUS8lPRPfC9wfrY8SD9Wp5AO7y5t994PF9My389rvI+UtAGQNIltk9Aq4M0t7/X0iLhJ0nHAP5C+K7uRkuefGNn/2Kj128/kEuCjWcPeXqRjtK9l6x4A9pKU/wWeAayPiMckHUo6PBiJy4CDSceRF7WsG3XZWS1rZ+ChiPizpKOA1+Y2WUv6ldqvbQHpUOBwSa+RNFnSG0lfnqK/ZB3jyhr+PkH6Un+4zTY7STpJ6fT4FlI7wlC2uuzP4ALgDEnPzWI7SKkR+BdZLO9RasSdLOk5kp7XWkBEbCI1DP9zFvvTSIcAX2vdtqBzgeOAp+aWXQJ8QNJ+WcPrJ4GLswTxBEn7Zo2dOwKbgMf4y3sHKZm8DjiZXC24jQeA2UonBfp9jYuB50s6ISvvg2xbo/oC8BFJz8hew+6SXp2tm0H6DjxIars6h1QzGRf9JpOzgeXAMuC3pGPVc7N1vyO9MfdkVbI9gPeSTuk9Biwk1QQKi4hHge+SfkUuaVk96rKzL9lpwL9I2gh8iNR4Nrz+kex13ZS9lsNanv8AqcHsw6TG0NOBEyJi/UheX85Ts9fxGHADqaHzhRHx8w7bv5VUjV5Pqrm9MVte6mcQEV8FzgMuJyWty4Hdsl/s40mnse8hfZnPp/Oh3Duyv/cAPyMlqVF1NYh0CvlzpPaPYeeTGpGvJx2WPUw67Go1QGozup/0uT2f9NkNl/17UsP5xoj4dZcwfkRqU1wraXW2bFSvMSLuI52l/Dzpfdyb1B40vP4S4P8C384OU39LSqaQzoRdl73mlcC6rIxxoZZkbWY5ki4GlkfEJ6uOpe6cTMw6yBpjbyadLi6z/WtCqs21OWZ1Iulc0un9cyZaIlHqxLdW0m0d1kvSv0laIemWdm1fbZ/nmonZ9kXSi0jtcf8eEc9qs/540lmh44Ejgf8TEUf2Ktc1E7PtTERcR5vT5DnzSYkmImIJsJukfXqVW/cL3v7K1Mk7xvQpu1YdRiExuVm5emhKs+Jtkv96ZPW6iHjSaJ//31+yUzz08GChbW+6ZdMy4M+5RYsi4q+uuu9iX7bt4Lk6W3Zftyc1LplMn7IrL3jaW6sOo5AtT9qp6hBG5PG9plYdQnHFrpmrjSXf+EBrD+kReejhQX59VaduTtsa2OeuP0fE3H72NxqNSyZm26MAhrbpTzem1pDrhUvqqt+zEdr1WrMGCIItMVhoKsFi4I3ZWZ2/JfWY7nqIA66ZmDVGWTUTSZcAxwAzsx67HyVdfUxEfAG4knQmZwXpQs+3FCnXycSsAYJgsKRuHBFxco/1AbxrpOU6mZg1xFDPi9er5WRi1gABDDqZmFkZXDMxs74FsKXml744mZg1QBA+zDGzEgQM1juXOJmYNUHqAVtvTiZmjSAGx2dc6FFzMjFrgNQA62RiZn1K/UycTMysBEOumZhZv1wzMbNSBGKw5iOGjEt07UbDlrSHpKsl3ZX93b1bGWbbu6FQoakq45XqvkK6e33eGcBPI2IO8NNs3szaCMTmGCg0VWVckkmH0bDn85f7BV8E/I/xiMWsiVKntUmFpqpU2Wayd24ouPtJ91RtS9ICYAHAtCm7jENoZvXjBtgCIiIkdbzyIBumfxHArtP3qfkVCmblixCD4QbYTh4YvrFP9ndthbGY1d4QKjRVpcpkshh4U/b4TcB3K4zFrNZSA+zkQlNVxmXPHUbD/jRwmaS3AfcArxuPWMyaaLgBts7GJZl0GQ37peOxf7OJYNDd6c2sX03oAetkYtYQQzU/m+NkYtYA6UI/JxMz61MgtlTYVb4IJxOzBoig9p3WnEzMGqHaDmlFOJmYNUDgmomZlcQNsGbWt6DagY+KcDIxa4B0q4t6/7vWOzozy/gmXGZWgsA9YM2sJHWvmdQ71ZkZkEZaG4pJhaYiJM2TdKekFZL+ajB3SftJukbSbyTdIun4XmW6ZmLWAKkBtpzu9JIGgIXAccBq4EZJiyNieW6zjwCXRcT5kg4BrgQO6Fauk4lZI5Q6BuwRwIqIWAkg6VLS3SLyySSA4dHbdwX+2KvQ5iWToUCP/7nqKArRlulVhzAik7ZWHUFxW3aqOoLxlRpgC7eZzJS0NDe/KBuUfdi+wKrc/GrgyJYyPgb8WNI/ADsBL+u10+YlE7Pt1Ah6wK6LiLl97u5k4CsR8a+SXgB8VdKzImKo0xOcTMwaoOQesGuA2bn5WdmyvLeR3YUzIn4laRowky53kfDZHLOGKPGOfjcCcyQdKGkqcBLpbhF595KN0SzpYGAa8GC3Ql0zMWuACNgyVM5vf0RslXQ6cBUwAFwYEcsknQMsjYjFwPuBL0l6L6nJ5s0R0fUGeE4mZg2QDnPKO5CIiCtJp3vzy87OPV4OHD2SMp1MzBqi7j1gnUzMGmCEp4Yr4WRi1gjlHuaMBScTs4bwGLBm1rd0Nse3ujCzPnnYRjMrjQ9zzKxvPptjZqXx2Rwz61uE2OpkYmZl8GGOmfXNbSYFSLob2AgMAltLGNTFbEJyMinmJRGxruogzOrK/UzMrDTuZ9JbkAauDeCLLQPfmhmpO/3WkgZHGit1SCYvjIg1kvYCrpZ0R0Rcl99A0gJgAcC0gRlVxGhWubof5lSe6iJiTfZ3LXAF6Z4erdssioi5ETF36sCO4x2iWeWG20yKTFWpNJlI2knSjOHHwMuB26qMyayuIlRoqkrVhzl7A1dIGo7l4oj4UbUhmdWTG2C7yG5P+NwqYzBrgoj6t5lUXTMxs0LEoM/mmFkZqmwPKcLJxKwBfG2OmZUjUrtJnTmZmDWEz+aYWd/CDbBmVhYf5phZKXw2x8z6FuFkYmYl8alhMyuF20zMrG+BGPLZHDMrQ80rJtUPjmRmBUS545lImifpTkkrJJ3RYZvXSVouaZmki3uV6ZqJWVOUVDWRNAAsBI4DVgM3SlocEctz28wBzgSOjohHsmFVu3LNxKwhSqyZHAGsiIiVEbEZuBSY37LN24GFEfFI2nes7VVo82omk0TsMLXqKCakyY8PVh1CYUNTmvfV7UcAQ0OFTw3PlLQ0N7+o5a4P+wKrcvOrgSNbyjgIQNIvgQHgY71GQdy+PhGzpgqgeD+TdSXcGXMyMAc4BpgFXCfp2RHxaKcn+DDHrCEiik0FrAFm5+ZnZcvyVgOLI2JLRPwB+E9ScunIycSsKaLg1NuNwBxJB0qaCpwELG7Z5jukWgmSZpIOe1Z2K9SHOWaNUN5tLCJiq6TTgatI7SEXRsQySecASyNicbbu5ZKWA4PAByPioW7lOpmYNUWJvdYi4krgypZlZ+ceB/C+bCrEycSsCQKi+NmcSjiZmDWGk4mZlaHmF+c4mZg1xURLJpJ2AF4NHJB/fkScU15YZraNkXVaq8RoaibfBdYDNwGbyg3HzDqZiIMjzYqIeaVHYmbd1fxszmh6wF4v6dmlR2JmXSmKTVUpXDORdCvpyG0y8BZJK0mHOSL1cXnO2IRoZiPoKl+ZkRzmnDBmUZhZD5o4DbARcQ+ApK9GxKn5dZK+Cpza9olmVo4JVDMZdmh+JhsC7m/KCcfMOhqqOoDuCjfASjpT0kbgOZI2SNqYza8lnS42s7Ey3M+kyFSRwskkIj4VETOAz0bELhExI5v2jIgz+wlC0oCk30j6fj/lmE1kE+ZsTs5Zkv4n8EJSvvyPiPhOn3G8G7gd2KXPcswmrpq3mYymn8lC4DTgVuA24DRJC0cbgKRZwCuBC0ZbhplVbzQ1k2OBg7PBU5B0EbCsjxg+D3wImNFpA0kLgAUA0ya78mLbpyoPYYoYTc1kBbBfbn52tmzEJJ0ArI2Im7ptFxGLImJuRMydOnnH0ezKrNmC1J2+yFSR0dRMZgC3S/o16SUeASyVtBggIk4cQVlHAydKOh6YBuwi6WsRccoo4jKb2GpeMxlNMjm79ybFZGeBzgSQdAzwAScSs/bqfpgz4mQSET+XtD8wJyJ+Imk6MDkiNpYfnpk9oebJZMRtJpLeDlwOfDFbNIt0j42+RMS1EeHrf8w6Ke++OWNiNA2w7yK1dWwAiIi7gJ53SDez0SvaYa1pndY2RcRmKbUaS5pM7StgZhPABBwc6eeSzgKmSzoO+CbwvXLDMrNWda+ZjCaZnAE8SOoB+w7SXcE+UmZQZtZGzdtMRnM2Z0jSd4DvRMSDYxCTmbWquNZRxEiGIJCkj0laB9wJ3CnpQUml9Tsxsy5qXjMZyWHOe0lncZ4fEXtExB7AkcDRkt47JtGZ2RM0VGyqykiSyanAyRHxh+EFEbESOAV4Y9mBmVmzjKTNZEpErGtdGBEPSppSYkxm1k7N20xGkkw2j3KdmfWrAQ2wI0kmz5W0oc1yka74NbOxNFGSSUQMjGUgZtbDREkmZlYdUe2ZmiJG0wPWzMZbyRf6SZon6U5JKySd0WW7V0sKSXN7lelkYtYUJXVay26ctxB4BXAIcLKkQ9psN4N054gbioTnZGLWFOX1gD0CWBERKyNiM3ApML/Ndp8APgP8uUihzWszCSBq3hKViUn1vmS81cDmmh+U50za2ozvQJlGcGp4pqSluflFEbEoN78vsCo3v5rUm/0v+5KeB8yOiB9I+mCRnTYvmZhtr4onk3UR0bONoxNJk4DzgDeP5HlOJmZNEKWezVlDukXNsFnZsmEzgGcB12aDoD0ZWCzpxIjI13i24WRi1hTlHdndCMyRdCApiZwEvP6J3USsB2YOz0u6lnTniI6JBNwAa9YYZZ0ajoitwOnAVaR7fF8WEcsknSNpJPe92oZrJmZNUWKbc0RcSRolMb+s7dhEEXFMkTKdTMyaoOKBj4pwMjFrADGxrho2swo5mZhZOZxMzKwUTiZm1rcJNtKamVXJycTMylD3wZGcTMwawoc5ZtY/d1ozs9I4mZhZv9wDtgdJ04DrgB2yWC6PiI9WGZNZXWmo3tmk6prJJuDYiHgsu8XoLyT9MCKWVByXWb24zaS7iAjgsWx2SjbV/C0zq0bdD3MqHxxJ0oCk3wJrgasjotCw+mbbnfJGpx8TlSeTiBiMiMNI41AeIelZrdtIWiBpqaSlmwcfH/8gzWqgzJtwjYXKk8mwiHgUuAaY12bdooiYGxFzpw7sOP7BmdWBayadSXqSpN2yx9OB44A7qozJrJay0emLTFWp+mzOPsBF2e0KJ5EGtv1+xTGZ1Y77mfQQEbcAh1cZg1lj1PxOllXXTMysINdMzKx/7rRmZmXxeCZmVgonEzPrX+AGWDMrhxtgzawcTiZm1i93WjOzckR4cCQzK0m9c4mTiVlT+DDHzPoXgA9zzKwU9c4l9Rkcycy6K3OkNUnzJN0paYWkM9qsf5+k5ZJukfRTSfv3KtPJxKwhNBSFpp7lpPGDFgKvAA4BTpZ0SMtmvwHmRsRzgMuBc3uV62Ri1gRFh2wsVjM5AlgRESsjYjNwKTB/m91FXBMRwwMuLyGN0dxVA9tMAoZqfsXTsAFVHcGIDE71b0tdpU5rhRtNZkpamptfFBGLcvP7Aqty86uBI7uU9zbgh7122sBkYradKv4bui4i5paxS0mnAHOBF/fa1snErCFGUDPpZQ0wOzc/K1u27f6klwEfBl4cEZt6Fep6rVkTlNtmciMwR9KBkqYCJwGL8xtIOhz4InBiRKwtUqhrJmaNUN61ORGxVdLpwFXAAHBhRCyTdA6wNCIWA58Fdga+KQng3og4sVu5TiZmTVHi4EgRcSVwZcuys3OPXzbSMp1MzJogPGyjmZXFwzaaWSnqnUucTMyaQjXvrOlkYtYEwUg6rVXCycSsAUSU2WltTDiZmDWFk4mZlcLJxMz65jYTMyuLz+aYWQnChzlmVgLfuNzMSlPvo5xqxzORNFvSNdko2MskvbvKeMzqTBGFpqpUXTPZCrw/Im6WNAO4SdLVEbG84rjM6seHOZ1FxH3AfdnjjZJuJw1262RilhcBg/U+zqm6ZvIESQcAhwM3tFm3AFgAMG3yLuMal1lt1LxmUosxYCXtDHwLeE9EbGhdHxGLImJuRMydOjB9/AM0q4OIYlNFKq+ZSJpCSiRfj4hvVx2PWS35xuXdKY1U+2Xg9og4r8pYzOotIOrdZlL1Yc7RwKnAsZJ+m03HVxyTWf0EqQG2yFSRqs/m/IJ050Mz66XmDbCVt5mYWUFOJmbWP1/oZ2ZlCMBDEJhZKVwzMbP+uTu9mZUhIGrez8TJxKwp3APWzErhNhMz61uEz+aYWUlcMzGz/gUxOFh1EF05mZg1gYcgMLPS1PzUcNVDEJhZAQHEUBSaipA0T9KdklZIOqPN+h0kfSNbf0M2rGpXTiZmTRDZ4EhFph4kDQALgVcAhwAnSzqkZbO3AY9ExNOBzwGf6VWuk4lZQ8TgYKGpgCOAFRGxMiI2A5cC81u2mQ9clD2+HHhpNjJiR41rM9mw6YF1V9312XtKLnYmsK7kMuGu0kscNjbxjo0mxQpjF+/+/Tx5I49c9ZO4fGbBzadJWpqbXxQRi3Lz+wKrcvOrgSNbynhim4jYKmk9sCdd3pvGJZOIeFLZZUpaGhFzyy53rDQp3ibFCvWNNyLmVR1DLz7MMdv+rAFm5+ZnZcvabiNpMrAr8FC3Qp1MzLY/NwJzJB0oaSpwErC4ZZvFwJuyx68BfhbRvQtu4w5zxsii3pvUSpPibVKs0Lx4RyxrAzkduAoYAC6MiGWSzgGWRsRi0i1ovippBfAwKeF0pR7JxsysEB/mmFkpnEzMrBTbdTKRNFvSNZKWS1om6d1Vx9SJpGmSfi3pd1msH686piIkDUj6jaTvVx1LN5LulnRrdlfJpb2fYa229wbYrcD7I+JmSTOAmyRdHRHLqw6sjU3AsRHxWHaz919I+mFELKk6sB7eDdwO7FJ1IAW8JCKa1MGuVrbrmklE3BcRN2ePN5K+9PtWG1V7kTyWzU7Jplq3nkuaBbwSuKDqWGzsbdfJJC+7KvJw4IZqI+ksO2T4LbAWuDoiahtr5vPAh4B6XzufBPBjSTdJWlB1ME3kZAJI2hn4FvCeiNhQdTydRMRgRBxG6rF4hKRnVR1TJ5JOANZGxE1Vx1LQCyPieaQrad8l6UVVB9Q0230yydofvgV8PSK+XXU8RUTEo8A1QJ2v1zgaOFHS3aSrUo+V9LVqQ+osItZkf9cCV5CurLUR2K6TSXZJ9ZeB2yPivKrj6UbSkyTtlj2eDhwH3FFtVJ1FxJkRMSsiDiD1nvxZRJxScVhtSdopa4BH0k7Ay4Hbqo2qebb3szlHA6cCt2ZtEQBnRcSVFcbUyT7ARdnANpOAyyKi1qdbG2Rv4IpsuI7JwMUR8aNqQ2oed6c3s1Js14c5ZlYeJxMzK4WTiZmVwsnEzErhZGJmpXAymWAkfU7Se3LzV0m6IDf/r5LOknR5h+dfK2lu9vis3PIDJLnvhXXkZDLx/BI4CkDSJNKtGw7NrT+K1IHsNQXKOqv3JmaJk8nEcz3wguzxoaSenBsl7S5pB+Bg4OHhWoak6ZIulXS7pCuA6dnyTwPTs/E9vp6VNyDpS9l4Kj/OeuKaAU4mE05E/BHYKmk/Ui3kV6QroV8AzAVuBTbnnvJO4PGIOBj4KPA3WTlnAH+KiMMi4g3ZtnOAhRFxKPAo8OpxeEnWEE4mE9P1pEQynEx+lZv/Zcu2LwK+BhARtwC3dCn3DxExfNnBTcAB5YVsTedkMjENt5s8m3SYs4RUMzmKlGhGa1Pu8SC+tstynEwmpuuBE4CHszFQHgZ2IyWU1mRyHfB6gGx8lOfk1m3Jhmgw68nJZGK6lXQWZ0nLsvVtxjg9H9hZ0u3AOaTDl2GLgFtyDbBmHfmqYTMrhWsmZlYKJxMzK4WTiZmVwsnEzErhZGJmpXAyMbNSOJmYWSn+P1F2AwUsXBR5AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax = plt.gca()\n", + "img = ax.imshow(Ztvd_ideal, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0.0,vmax=1.0)\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('Total Variation Distance of Noisy to Ideal')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax = plt.gca()\n", + "img = ax.imshow(Ztvd_rand, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0.0,vmax=1.0)\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('Total Variation Distance of Noisy to Random')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data exploration" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.optimize import curve_fit" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 20)\n", + "(1, 20)\n" + ] + } + ], + "source": [ + "shape = Zdata.shape\n", + "size = Zdata.size\n", + "width_1d = X.reshape((1,size))\n", + "depth_1d = Y.reshape((1,size))\n", + "data_1d = Zdata.reshape((1,size))\n", + "print(data_1d.shape)\n", + "print(width_1d.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0],\n", + " [ 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5,\n", + " 2, 3, 4, 5],\n", + " [ 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5,\n", + " 10, 10, 10, 10]])" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dims = np.zeros_like(width_1d)\n", + "dims[0,0] = shape[0]\n", + "dims[0,1] = shape[1]\n", + "\n", + "xdata = np.vstack((dims, width_1d, depth_1d))\n", + "xdata" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fitting models" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Two parameter model \n", + "\n", + "\n", + "$f(W,D,p_W,p_D) = (1-p_W)^W * (1-p_D)^D $\n", + "\n", + "The fidelity is proporional to $1 - p$" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "def two_param(x, pw, pd):\n", + " num_depths, num_widths = x[0][:2]\n", + " widths = x[1].reshape(num_depths, num_widths)\n", + " depths = x[2].reshape(num_depths, num_widths)\n", + " pcheck = (1-pw)**(widths) * (1-pd)**depths\n", + " rpcheck = pcheck.reshape((1, num_depths * num_widths))\n", + " return rpcheck.ravel()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One parameter model\n", + "\n", + "$f(W,D,p) = (1-p)^{W * D} $" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "def one_param(x,p):\n", + " num_depths, num_widths = x[0][:2]\n", + " widths = x[1].reshape(num_depths, num_widths)\n", + " depths = x[2].reshape(num_depths, num_widths)\n", + " pcheck = (1-p)**(widths * depths)\n", + " rpcheck = pcheck.reshape((1, num_depths * num_widths))\n", + " return rpcheck.ravel()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Josh: \"From my prior work a better model to fit to is \"\n", + "\n", + "Pcheck$(W,D,p,a,b,c) = \\exp[ -(a p^2 + b p + c)* W*D] $\n" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "def two_param_exp(x,p,a,b):\n", + " num_depths, num_widths = x[0][:2]\n", + " widths = x[1].reshape(num_depths, num_widths)\n", + " depths = x[2].reshape(num_depths, num_widths)\n", + " pcheck = np.exp(-(a*p + b) * widths * depths)\n", + " rpcheck = pcheck.reshape((1, num_depths * num_widths))\n", + " return rpcheck.ravel()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Start with one paramter model**" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "pguess = 0.1\n", + "popt, pcov = curve_fit(one_param, xdata, data_1d.ravel(), p0=pguess, bounds=(0, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The estimated error is p = 0.0113\n", + "The estimated product of the one and two qubit fidelity is F = 0.9887\n" + ] + } + ], + "source": [ + "print('The estimated error is p = ', str(np.round(popt[0],4)))\n", + "print('The estimated product of the one and two qubit fidelity is F = ', str(1-np.round(popt[0],4)))\n", + "#print('The one standard deviation on the estimate is ', str(np.round(np.sqrt(np.diag(pcov)[0]),5)))" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "zfit = one_param(xdata, popt)\n", + "Z_fit = zfit.reshape(shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax = plt.gca()\n", + "img = ax.imshow(Z_fit, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0.0,vmax=1.0)\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('One parameter fit to success prob')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax = plt.gca()\n", + "img = ax.imshow(Zdata, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0.0,vmax=1.0)\n", + "\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('Success prob')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Two parameter model**" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "# pguess2d_exp = [0.0276, 0.01, 0.4]\n", + "# popt2d, pcov2d = curve_fit(two_param_exp, xdata, data_1d.ravel(), p0=pguess2d, bounds=(0., 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [], + "source": [ + "popt2d, pcov2d = curve_fit(two_param, xdata, data_1d.ravel(), bounds=(0., 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.05877651, 0.00253226])" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "popt2d" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0.88142068 0.82961385 0.78085204 0.73495628]\n", + " [0.87918869 0.82751305 0.77887472 0.73309518]\n", + " [0.87696236 0.82541757 0.77690241 0.7312388 ]\n", + " [0.87474167 0.8233274 0.77493509 0.72938711]\n", + " [0.86372226 0.81295568 0.76517298 0.72019878]]\n" + ] + } + ], + "source": [ + "zfit2d = two_param(xdata, popt2d[0], popt2d[1])\n", + "Z_fit2d = zfit2d.reshape(shape)\n", + "print(Z_fit2d)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax = plt.gca()\n", + "img = ax.imshow(Z_fit2d, interpolation='none', extent=extent,\n", + " cmap='viridis', origin='lowerleft', vmin=0, vmax=1.0)\n", + "\n", + "ax.set_xticks(range(len(widths)))\n", + "ax.set_xticklabels(widths)\n", + "\n", + "ax.set_yticks(range(len(depths)))\n", + "ax.set_yticklabels(depths)\n", + "\n", + "ax.set_aspect('equal')\n", + "plt.colorbar(img, ax=ax)\n", + "plt.xlabel('Width')\n", + "plt.ylabel('Depth')\n", + "plt.title('Two parameter fit success prob')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot the distribution of sublattice widths" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "G = perfect_qc.qubit_topology()\n", + "len(perfect_qc.qubit_topology())\n", + "# distribution of graph lengths\n", + "distr = []\n", + "for num_nodes in range(1, len(G.nodes) + 1):\n", + " listg = generate_connected_subgraphs(G, num_nodes)\n", + " distr.append(len(listg))\n", + "\n", + "cir_wid = list(range(1, len(G.nodes) + 1))\n", + "plt.bar(cir_wid, distr, width=0.61, align='center')\n", + "plt.xticks(cir_wid)\n", + "plt.xlabel('sublattice / circuit width')\n", + "plt.ylabel('Frequency of Occurence')\n", + "plt.grid(axis='y', alpha=0.75)\n", + "plt.title('Distribution of sublattice widths')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/forest/benchmarking/compilation.py b/forest/benchmarking/compilation.py index c0c85b7e..39df768c 100644 --- a/forest/benchmarking/compilation.py +++ b/forest/benchmarking/compilation.py @@ -239,6 +239,8 @@ def basic_compile(program: Program): new_prog += _H(inst.qubits[0]) elif inst.name == "X": new_prog += _X(inst.qubits[0]) + elif inst.name == "Z": + new_prog += RZ(pi, inst.qubits[0]) elif inst.name in [gate.name for gate in new_prog.defined_gates]: if needs_dagger and inst.name not in daggered_defgates: new_prog.defgate(inst.name + 'DAG', inst.matrix.T.conj()) diff --git a/forest/benchmarking/tests/test_volumetrics.py b/forest/benchmarking/tests/test_volumetrics.py new file mode 100644 index 00000000..6e12ee78 --- /dev/null +++ b/forest/benchmarking/tests/test_volumetrics.py @@ -0,0 +1,34 @@ +import numpy as np +from pyquil.numpy_simulator import NumpyWavefunctionSimulator + +from forest.benchmarking.volumetrics import * +from forest.benchmarking.volumetrics.quantum_volume import (collect_heavy_outputs, + get_success_probabilities, + calculate_success_prob_est_and_err) + +np.random.seed(1) + + +def test_ideal_sim_heavy_probs(qvm): + qvm.qam.random_seed = 1 + + qv_ckt_template = get_quantum_volume_template() + depths = [2, 3] + dimensions = {d: [d] for d in depths} + + num_ckt_samples = 40 + qv_progs = generate_volumetric_program_array(qvm, qv_ckt_template, dimensions, + num_circuit_samples=num_ckt_samples) + wfn_sim = NumpyWavefunctionSimulator(len(qvm.qubits())) + heavy_outputs = collect_heavy_outputs(wfn_sim, qv_progs) + + num_shots = 50 + results = acquire_volumetric_data(qvm, qv_progs, num_shots=num_shots) + + probs_by_width_depth = get_success_probabilities(results, heavy_outputs) + num_successes = [sum(probs_by_width_depth[depth][depth]) * num_shots for depth in depths] + + qv_success_probs = [calculate_success_prob_est_and_err(n_success, num_ckt_samples, num_shots)[0] + for n_success in num_successes] + target_probs = [0.788765, 0.852895] + np.testing.assert_allclose(qv_success_probs, target_probs, atol=.05) diff --git a/forest/benchmarking/volumetrics/__init__.py b/forest/benchmarking/volumetrics/__init__.py new file mode 100644 index 00000000..dd6982cd --- /dev/null +++ b/forest/benchmarking/volumetrics/__init__.py @@ -0,0 +1,2 @@ +from forest.benchmarking.volumetrics._main import * +from forest.benchmarking.volumetrics._templates import * diff --git a/forest/benchmarking/volumetrics/_generators.py b/forest/benchmarking/volumetrics/_generators.py new file mode 100644 index 00000000..6fd283d6 --- /dev/null +++ b/forest/benchmarking/volumetrics/_generators.py @@ -0,0 +1,143 @@ +from typing import Sequence, List +import networkx as nx +import numpy as np +import random + +from pyquil.quilbase import Pragma, Gate, DefGate, DefPermutationGate +from pyquil.quilatom import QubitPlaceholder +from pyquil.quil import Program, address_qubits, merge_programs +from pyquil.api import BenchmarkConnection +from pyquil.gates import * + +from forest.benchmarking.randomized_benchmarking import get_rb_gateset +from forest.benchmarking.operator_tools.random_operators import haar_rand_unitary + + +def random_single_qubit_gates(graph: nx.Graph, gates: Sequence[Gate]) -> Program: + """ + Create a program comprised of random single qubit gates acting on the qubits of the + specified graph; each gate is chosen uniformly at random from the list provided. + + :param graph: The graph. Nodes are used as arguments to gates, so they should be qubit-like. + :param gates: A list of gates e.g. [I, X, Z] or [I, X]. + :return: A program that randomly places single qubit gates on a graph. + """ + program = Program() + for q in graph.nodes: + gate = random.choice(gates) + program += gate(q) + return program + + +def random_two_qubit_gates(graph: nx.Graph, gates: Sequence[Gate]) -> Program: + """ + Create a program to randomly place two qubit gates on edges of the specified graph. + + :param graph: The graph. Nodes are used as arguments to gates, so they should be qubit-like. + :param gates: A list of gates e.g. [I otimes I, CZ] or [CZ, SWAP, CNOT] + :return: A program that has two qubit gates randomly placed on the graph edges. + """ + program = Program() + # TODO: two coloring with pragmas + for a, b in graph.edges: + gate = random.choice(gates) + program += gate(a, b) + return program + + +def random_single_qubit_cliffords(bm: BenchmarkConnection, graph: nx.Graph) -> Program: + """ + Create a program comprised of single qubit Clifford gates randomly placed on the nodes of + the specified graph. Each uniformly random choice of Clifford is implemented in the native + gateset. + + :param bm: A benchmark connection that will do the grunt work of generating the Cliffords + :param graph: The graph. Nodes are used as arguments to gates, so they should be qubit-like. + :return: A program that randomly places single qubit Clifford gates on a graph. + """ + num_qubits = len(graph.nodes) + + q_placeholder = QubitPlaceholder() + gateset_1q = get_rb_gateset([q_placeholder]) + + # the +1 is because the depth includes the inverse + clif_n_inv = bm.generate_rb_sequence(depth=(num_qubits + 1), gateset=gateset_1q, seed=None) + rand_cliffords = clif_n_inv[0:num_qubits] + + prog = Program() + for q, clif in zip(graph.nodes, rand_cliffords): + gate = address_qubits(clif, qubit_mapping={q_placeholder: q}) + prog += gate + return prog + + +def random_two_qubit_cliffords(bm: BenchmarkConnection, graph: nx.Graph) -> Program: + """ + Write a program to place random two qubit Clifford gates on edges of the graph. + + :param bm: A benchmark connection that will do the grunt work of generating the Cliffords + :param graph: The graph. Nodes are used as arguments to gates, so they should be qubit-like. + :return: A program that has two qubit gates randomly placed on the graph edges. + """ + num_2q_gates = len(graph.edges) + q_placeholders = QubitPlaceholder.register(n=2) + gateset_2q = get_rb_gateset(q_placeholders) + + # the +1 is because the depth includes the inverse + clif_n_inv = bm.generate_rb_sequence(depth=(num_2q_gates + 1), gateset=gateset_2q, seed=None) + rand_cliffords = clif_n_inv[0:num_2q_gates] + + prog = Program() + # TODO: two coloring with PRAGMAS? + # TODO: longer term, fence to be 'simultaneous'? + for edges, clif in zip(graph.edges, rand_cliffords): + gate = address_qubits(clif, qubit_mapping={q_placeholders[0]: edges[0], + q_placeholders[1]: edges[1]}) + prog += gate + return prog + + +def dagger_previous(sequence: List[Program], n: int = 1) -> Program: + """ + Create a program which is the inverse (conjugate transpose; adjoint; dagger) of the last n + layers of the provided sequence. + + :param sequence: a sequence of PyQuil programs whose elements are layers in a circuit + :param n: the number of layers at the end of the sequence that will be inverted + :return: a program that inverts the last n layers of the provided sequence. + """ + return merge_programs(sequence[-n:]).dagger() + + +def random_su4_pairs(graph: nx.Graph, idx_label: int) -> Program: + """ + Create a program that enacts a Haar random 2 qubit gate on random pairs of qubits in the + graph, irrespective of graph topology. + + If the graph contains an odd number of nodes, then one random qubit will not be acted upon by + any gate. + + The output program will need to be compiled into native gates. + + This generator is the repeated unit of the quantum volume circuits described in [QVol]_. Note + that the qubit permutation is done implicitly--the compiler will have to figure out how to + move potentially distant qubits onto a shared edge in order to enact the random two qubit gate. + + :param graph: a graph containing qubits that will be randomly paired together. Note that + the graph topology (the edges) are ignored. + :param idx_label: a label that uniquely identifies the set of gate definitions used in the + output program. This prevents subsequent calls to this method from producing a program + with definitions that overwrite definitions in previously generated programs. + :return: a program with random two qubit gates between random pairs of qubits. + """ + qubits = list(graph.nodes) + qubits = [qubits[idx] for idx in np.random.permutation(range(len(qubits)))] + prog = Program() + # ignore the edges in the graph + for q1, q2 in zip(qubits[::2], qubits[1::2]): + matrix = haar_rand_unitary(4) + gate_definition = DefGate(f"LYR{idx_label}_RSU4_{q1}_{q2}", matrix) + RSU4 = gate_definition.get_constructor() + prog += gate_definition + prog += RSU4(q1, q2) + return prog diff --git a/forest/benchmarking/volumetrics/_main.py b/forest/benchmarking/volumetrics/_main.py new file mode 100644 index 00000000..c16f9c9f --- /dev/null +++ b/forest/benchmarking/volumetrics/_main.py @@ -0,0 +1,404 @@ +from typing import Callable, Dict, List, Union +import networkx as nx +import numpy as np +import random +import itertools +from scipy.spatial.distance import hamming +from scipy.special import comb +from dataclasses import dataclass, field + +from pyquil.quil import Program, address_qubits, merge_programs +from pyquil.api import QuantumComputer +from pyquil.gates import MEASURE, RESET + +from forest.benchmarking.distance_measures import total_variation_distance as tvd + + +@dataclass +class CircuitTemplate: + """ + This dataclass enables us to specify various families of circuits and sample from a specified + family random circuits of various width and depth acting on different groups of qubits. + + 'Width' is simply the number of qubits measured at then end of the circuit. 'Depth' is not + simply circuit depth, but rather the number of repeated structured groups of gates, + each of which constitutes some distinct unit. A depth d circuit could consist of d + consecutive rounds of random single qubit, then two qubit gates. It could also mean d + consecutive random Cliffords followed by the d conjugated Cliffords that invert the first d + gates. + + Because these families of circuits are quite diverse, specifying the family and drawing + samples can potentially require a wide variety of parameters. The compiler may be required to + map an abstract circuit into native quil; a sample acting on a specific qubit topology + may be desired; the sequence of 'layers' generated so far may be necessary to compute an + inverse. + + We represent each sampled circuit as a list of PyQuil Programs, which we call a 'sequence' + since each element of the list holds a distinctly structured group of gates that, + when applied altogether in series, constitute the circuit. This core functionality is found in + :func:`sample_sequence`. In this function `generators` are applied in series in a loop + `repetitions` number of times. Each call to a generator will contribute an element to the + output sequence (some combination of which will constitute a unit of depth). After a + sequence is generated from the output of the various `generators`, each `sequence_transform` + is then applied in series on the generated sequence to create a final output sequence. The + sequence transforms account for any features of the circuit that do increase with depth, + cannot neatly be fit into repeated units, or otherwise require performing a global + transformation on the sequence. See :func:`sample_sequence` for more information. + + This functionality is intended to enable creation and use of any of a wide variety of + 'volumetric benchmarks' described in the sources below. + + .. [Vol] A volumetric framework for quantum computer benchmarks. + Blume-Kohout and Young. + arXiv:1904.05546v2 (2019) + https://arxiv.org/pdf/1904.05546.pdf + + .. [QVol] Validating quantum computers using randomized model circuits. + Cross et al. + arXiv:1811.12926v1 (2018). + https://arxiv.org/abs/1811.12926 + """ + generators: List[Callable] = field(default_factory=lambda: []) + sequence_transforms: List[Callable] = field(default_factory=lambda: []) + + def append(self, other): + """ + Mutates the CircuitTemplate object by appending new generators. + TODO: The behavior of sequence_transforms may not conform with expectations. + """ + if isinstance(other, list): + self.generators += other + elif isinstance(other, CircuitTemplate): + self.generators += other.generators + self.sequence_transforms += other.sequence_transforms + else: + raise ValueError(f'Cannot append type {type(other)}.') + + def __add__(self, other): + """ + Concatenate two circuits together, returning a new one. + """ + ckt = CircuitTemplate() + ckt.append(self) + ckt.append(other) + return ckt + + def __iadd__(self, other): + """ + Concatenate two circuits together using +=, returning a new one. + """ + self.append(other) + return self + + def sample_sequence(self, graph: nx.Graph, repetitions: int, qc: QuantumComputer = None, + width: int = None, sequence: List[Program] = None): + """ + The sequence_transforms are distinct from generators in that they take in a sequence and + output a new sequence. These are applied in series after the entire sequence has been + generated. A family of interest that motivates this distinction is + + C_0 P_0 C_1 P_1 ... P_{N-1} C_N P_N C_N^t P_{N+1} ... C_1^t P_{2N-1} C_0^t + + where C_j is a clifford, P_j is a random local Pauli. We can specify this family by a + generator of random Cliffords, a conjugation sequence transform, and a Pauli frame + randomization transform. + + :param graph: the qubit topology on which the circuit should act. Unless width is + specified, the number of qubits in the graph should be considered circuit width. + :param repetitions: the number of times the loop of generators should be applied. + :param qc: a quantum computer, likely the one on which the circuit will be run, providing + access to the full chip topology and associated compiler. + :param width: the number of qubits that will be measured at the end of the circuit. If + the supplied graph contains more qubits, an induced subgraph of width-many qubits + will be selected uniformly at random from the graph. + :param sequence: an optional initialization of a sequence to build off of/append to. + :return: the list of programs whose sum constitutes a circuit sample from the family of + circuits specified by the generators and sequence_transforms. + """ + if width is not None: + graph = random.choice(generate_connected_subgraphs(graph, width)) + + if sequence is None: + sequence = [] + + # run through the generators 'repetitions' many times; append each generated program to + # the sequence. + for _ in range(repetitions): + for generator in self.generators: + sequence.append(generator(graph=graph, qc=qc, width=width, sequence=sequence)) + + for sequence_transform in self.sequence_transforms: + sequence = sequence_transform(graph=graph, qc=qc, width=width, sequence=sequence) + + return sequence + + def sample_program(self, graph, repetitions, qc=None, width=None, sequence=None): + return merge_programs(self.sample_sequence(graph, repetitions, qc, width, sequence)) + + +def generate_volumetric_program_array(qc: QuantumComputer, ckt: CircuitTemplate, + dimensions: Dict[int, List[int]], num_circuit_samples: int, + graphs: Dict[int, List[nx.Graph]] = None) \ + -> Dict[int, Dict[int, List[Program]]]: + """ + Creates a dictionary containing random circuits sampled from the input `ckt` family for each + width and depth. + + :param qc: + :param ckt: + :param dimensions + :param num_circuit_samples: + :param graphs: + :return: + """ + if graphs is None: + graphs = {w: sample_random_connected_graphs(qc.qubit_topology(), w, + len(depths) * num_circuit_samples) + for w, depths in dimensions.items()} + + programs = {width: {depth: [] for depth in depths} for width, depths in dimensions.items()} + + for width, depth_array in programs.items(): + circuit_number = 0 + for depth, prog_list in depth_array.items(): + for _ in range(num_circuit_samples): + graph = graphs[width][circuit_number] + circuit_number += 1 + prog = ckt.sample_program(graph, repetitions=depth, width=width, qc=qc) + prog_list.append(prog) + + return programs + + +def sample_random_connected_graphs(graph: nx.Graph, width: int, num_ckts: int): + """ + Helper to uniformly randomly sample `num_ckts` many connected induced subgraphs of + `graph` of `width` many qubits. + + :param graph: + :param width: + :param num_ckts: + :return: + """ + connected_subgraphs = generate_connected_subgraphs(graph, width) + random_indices = np.random.choice(range(len(connected_subgraphs)), size=num_ckts) + return [connected_subgraphs[idx] for idx in random_indices] + + +def generate_connected_subgraphs(graph: nx.Graph, n_vert: int): + """ + Given a lattice on the QPU or QVM, specified by a networkx graph, return a list of all + subgraphs with n_vert connect vertices. + + :params n_vert: number of vertices of connected subgraph. + :params graph: networkx graph + :returns: list of subgraphs with n_vert connected vertices + """ + subgraph_list = [] + for sub_nodes in itertools.combinations(graph.nodes(), n_vert): + subg = graph.subgraph(sub_nodes) + if nx.is_connected(subg): + subgraph_list.append(subg) + return subgraph_list + + +def acquire_volumetric_data(qc: QuantumComputer, program_array: Dict[int, Dict[int, List[Program]]], + num_shots: int = 500, + measure_qubits: Dict[int, Dict[int, List[int]]] = None, + use_active_reset: bool = False, use_compiler: bool = False) \ + -> Dict[int, Dict[int, List[np.ndarray]]]: + """ + Runs each program in `program_array` on the qc and stores the results, organized again by + width and depth. + + :param qc: + :param program_array: + :param num_shots: + :param measure_qubits: + :param use_active_reset: + :param use_compiler: + :return: + """ + reset_prog = Program() + if use_active_reset: + reset_prog += RESET() + + results = {width: {depth: [] for depth in depth_array.keys()} + for width, depth_array in program_array.items()} + + for width, depth_array in program_array.items(): + for depth, prog_list in depth_array.items(): + for idx, program in enumerate(prog_list): + prog = program.copy() + + if measure_qubits is not None: + qubits = measure_qubits[width][depth][idx] + else: + qubits = sorted(list(program.get_qubits())) + + ro = prog.declare('ro', 'BIT', len(qubits)) + for ro_idx, q in enumerate(qubits): + prog += MEASURE(q, ro[ro_idx]) + + prog.wrap_in_numshots_loop(num_shots) + + if use_compiler: + prog = qc.compiler.quil_to_native_quil(prog) + + exe = qc.compiler.native_quil_to_executable(prog) + shots = qc.run(exe) + results[width][depth].append(shots) + + return results + + +def get_error_hamming_weight_distributions(noisy_results: Dict[int, Dict[int, List[np.ndarray]]], + ideal_results: Dict[int, Dict[int, List[np.ndarray]]]): + """ + Calculate the hamming distance to the ideal for each noisy shot of each circuit sampled for + each width and depth. + + Note that this method is only appropriate when the ideal result for each circuit is a single + deterministic (circuit-dependent) output; therefore, ideal_results should only contain one + shot per circuit. + + :param noisy_results: + :param ideal_results: + :return: + """ + distrs = {width: {depth: [] for depth in depth_array.keys()} + for width, depth_array in noisy_results.items()} + + for width, depth_array in distrs.items(): + for depth, samples in depth_array.items(): + + noisy_ckt_sample_results = noisy_results[width][depth] + ideal_ckt_sample_results = ideal_results[width][depth] + + # iterate over circuits + for noisy_shots, ideal_result in zip(noisy_ckt_sample_results, + ideal_ckt_sample_results): + if len(ideal_result) > 1: + raise ValueError("You have provided ideal results with more than one shot; " + "this method is intended to analyze results where the ideal " + "result is deterministic, which makes multiple shots " + "unnecessary.") + + hamm_dist_per_shot = [hamming_distance(ideal_result, shot) for shot in + noisy_shots] + + # Hamming weight distribution + hamm_wt_distr = get_hamming_wt_distr_from_list(hamm_dist_per_shot, width) + samples.append(np.asarray(hamm_wt_distr)) + return distrs + + +def get_single_target_success_probabilities(noisy_results, ideal_results, + allowed_errors: Union[int, Callable[[int], int]] = 0): + """ + For circuit results of various width and depth, calculate the fraction of noisy results + that match the single ideal result for each circuit. + + Note that this method is only appropriate when the ideal result for each circuit is a single + deterministic (circuit-dependent) output. + + :param noisy_results: noisy shots from each circuit sampled for each width and depth + :param ideal_results: a single ideal result for each circuit + :param allowed_errors: either a number indicating the maximum hamming distance from the ideal + result is still considered a success, or a function which returns the max hamming + distance allowed for a given width. + :return: + """ + if isinstance(allowed_errors, int): + def error_func(num_bits): + return allowed_errors + else: + error_func = allowed_errors + + hamming_distrs = get_error_hamming_weight_distributions(noisy_results, ideal_results) + + return {w: {d: [sum(distr[0:error_func(w) + 1]) for distr in distrs] + for d, distrs in d_distrs.items()} + for w, d_distrs in hamming_distrs.items()} + + +def average_distributions(distrs): + """ + E.g. take in output of :func:`get_error_hamming_weight_distributions` or + :func:`get_single_target_success_probabilities` + + :param distrs: + :return: + """ + return {w: {d: sum([np.asarray(distr) for distr in distr_list]) / len(distr_list) + for d, distr_list in d_arr.items()} + for w, d_arr in distrs.items()} + + +def get_total_variation_dist(distr1, distr2): + return tvd(np.asarray([distr1]).T, np.asarray([distr2]).T) + + +def hamming_distance(arr1, arr2): + """ + Compute the hamming distance between arr1 and arr2, or the total number of indices which + differ between them. + + The hamming distance is equivalently the hamming weight of the 'error vector' between the + two arrays. + + :return: hamming distance between arr1 and arr2 + """ + n_bits = np.asarray(arr1).size + if not n_bits == np.asarray(arr2).size: + raise ValueError('Arrays must be equal size.') + + return hamming(arr1, arr2) * n_bits + + +def get_hamming_wt_distr_from_list(wt_list, n_bits): + """ + Get the distribution of the hamming weight of the error vector. + + :param wt_list: a list of length num_shots containing the hamming weight. + :param n_bits: the number of bit in the original binary strings. The hamming weight is an + integer between 0 and n_bits. + :return: the relative frequency of observing each hamming weight + """ + num_shots = len(wt_list) + + if n_bits < max(wt_list): + raise ValueError("Hamming weight can't be larger than the number of bits in a string.") + + # record the fraction of shots that resulted in an error of the given weight + return [wt_list.count(weight) / num_shots for weight in range(n_bits + 1)] + + +def get_random_hamming_wt_distr(num_bits: int): + """ + Return the distribution of Hamming weight for randomly drawn bitstrings of length num_bits. + + This is equivalent to the error distribution, e.g. from + :func:`get_error_hamming_weight_distributions` where the `noisy_results` are entirely random. + Comparing real data against this distribution may be a useful benchmark in determining + whether the real data contains any actual information. + + :param num_bits: number of bits in string + returns: list of hamming weights + """ + # comb(N, k) = N choose k + return [comb(num_bits, num_ones) / (2 ** num_bits) for num_ones in range(0, num_bits + 1)] + + +def basement_log_function(number: float): + return basement_function(np.log2(number)) + + +def basement_function(number: float): + """ + Return the floor of the number, or 0 if the number is negative. + + :param number: the basement function is applied to this number. + :returns: basement of the number + """ + return max(int(np.floor(number)), 0) diff --git a/forest/benchmarking/volumetrics/_templates.py b/forest/benchmarking/volumetrics/_templates.py new file mode 100644 index 00000000..d9d36821 --- /dev/null +++ b/forest/benchmarking/volumetrics/_templates.py @@ -0,0 +1,95 @@ +from typing import Sequence + +from pyquil.quilbase import Gate +from pyquil.api import BenchmarkConnection +from forest.benchmarking.volumetrics._main import CircuitTemplate +from forest.benchmarking.volumetrics._generators import * +from forest.benchmarking.volumetrics._transforms import * + + +def get_rand_1q_template(gates: Sequence[Gate]): + """ + Creates a CircuitTemplate representing the family of circuits generated by repeated layers of + random single qubit gates pulled from the input set of gates. + + :param gates: + :return: + """ + + def func(graph, **kwargs): + return random_single_qubit_gates(graph, gates=gates) + + return CircuitTemplate([func]) + + +def get_rand_2q_template(gates: Sequence[Gate]): + """ + Creates a CircuitTemplate representing the family of circuits generated by repeated layers of + random two qubit gates pulled from the input set of gates. + + :param gates: + :return: + """ + + def func(graph, **kwargs): + return random_two_qubit_gates(graph, gates=gates) + + return CircuitTemplate([func]) + + +def get_rand_1q_cliff_template(bm: BenchmarkConnection): + """ + Creates a CircuitTemplate representing the family of circuits generated by repeated layers of + random single qubit Clifford gates. + """ + + def func(graph, **kwargs): + return random_single_qubit_cliffords(bm, graph) + + return CircuitTemplate([func]) + + +def get_rand_2q_cliff_template(bm: BenchmarkConnection): + """ + Creates a CircuitTemplate representing the family of circuits generated by repeated layers of + random two qubit Clifford gates. + """ + + def func(graph, **kwargs): + return random_two_qubit_cliffords(bm, graph) + + return CircuitTemplate([func]) + + +def get_dagger_previous(n: int = 1): + """ + Creates a CircuitTemplate that can be appended to another template to generate families of + circuits with repeated (layer, inverse-layer) units. + """ + + def func(sequence, **kwargs): + return dagger_previous(sequence, n) + + return CircuitTemplate([func]) + + +def get_rand_su4_template(): + """ + Creates a CircuitTemplate representing the family of circuits generated by repeated layers of + Haar-random two qubit gates acting on random pairs of qubits. This is the generator used in + quantum volume [QVol]_ . + """ + + def func(graph, sequence, **kwargs): + return random_su4_pairs(graph, len(sequence)) + + return CircuitTemplate([func]) + + +def get_quantum_volume_template(): + """ + Creates a quantum volume CircuitTemplate. See [QVol]_ . + """ + template = get_rand_su4_template() + template.sequence_transforms.append(compile_merged_sequence) + return template diff --git a/forest/benchmarking/volumetrics/_transforms.py b/forest/benchmarking/volumetrics/_transforms.py new file mode 100644 index 00000000..18a0fde9 --- /dev/null +++ b/forest/benchmarking/volumetrics/_transforms.py @@ -0,0 +1,163 @@ +from typing import List +import networkx as nx +from copy import copy + +from pyquil.quil import Program, address_qubits, merge_programs +from pyquil.api import QuantumComputer +from pyquil.gates import * +from rpcq.messages import TargetDevice +from rpcq._utils import RPCErrorError +from forest.benchmarking.compilation import basic_compile +from forest.benchmarking.volumetrics._generators import random_single_qubit_gates + + +def hadamard_sandwich(sequence: List[Program], graph: nx.Graph, **kwargs) -> List[Program]: + """ + Insert a Hadamard gate on each qubit at the beginning and end of the sequence. + + This can be viewed as switching from the computational Z basis to the X basis. + + :param sequence: the sequence to be sandwiched by Hadamards + :param graph: the graph containing the qubits to be acted on by Hadamards + :param kwargs: extraneous arguments + :return: a new sequence which is the input sequence with new starting and ending layers of + Hadamards. + """ + prog = Program() + for node in graph.nodes: + prog.inst(H(node)) + return [prog] + sequence + [prog.copy()] + + +def dagger_sequence(sequence: List[Program], **kwargs): + """ + Returns the original sequence with its layer-by-layer inverse appended on the end. + + The net result of the output sequence is the Identity. + + .. CAUTION:: + Merging this sequence and compiling the resulting program will result in a trivial + empty program. To avoid this, consider using a sequence transform to compile each + element of the sequence first, then combine the result. For example, see + :func:`compile_individual_sequence_elements`. Using :func:`compile_merged_sequence` + with `use_basic_compile` set to True will also avoid this issue, but will not compile + gate definitions and will not compile gates onto the chip topology. + + :param sequence: the sequence of programs comprising a circuit that will be inverted and + appended to the sequence. + :param kwargs: extraneous arguments + :return: a new sequence the input sequence and its inverse + """ + return sequence + [prog.dagger() for prog in reversed(sequence)] + + +def pauli_frame_randomize_sequence(sequence: List[Program], graph: nx.Graph, **kwargs) \ + -> List[Program]: + """ + Inserts random single qubit Pauli gates on each qubit in between elements of the input sequence. + + :param sequence: + :param graph: a graph containing qubits that will be randomly paired together. Note that + the graph topology (the edges) are ignored. + :param kwargs: extraneous arguments + :return: + """ + paulis = [I, X, Y, Z] + random_paulis = [random_single_qubit_gates(graph, paulis) for _ in range(len(sequence) + 1)] + new_sequence = [None for _ in range(2 * len(sequence) + 1)] + new_sequence[::2] = random_paulis + new_sequence[1::2] = sequence + return new_sequence + + +def compile_individual_sequence_elements(qc: QuantumComputer, sequence: List[Program], + graph: nx.Graph, **kwargs) -> List[Program]: + """ + Returns the sequence where each element is individually compiled into native quil in a way + that respects the given graph topology. + + :param qc: + :param sequence: + :param graph: + :param kwargs: extraneous arguments + :return: + """ + compiled_sequence = [] + for prog in sequence: + native_quil = graph_restricted_compilation(qc, graph, prog) + # remove gate definitions and HALT + compiled_sequence.append(Program([instr for instr in native_quil.instructions][:-1])) + return compiled_sequence + + +def compile_merged_sequence(qc: QuantumComputer, sequence: List[Program], graph: nx.Graph, + use_basic_compile: bool = False, **kwargs) -> List[Program]: + """ + Merges the sequence into a Program and returns a 'sequence' comprised of the corresponding + compiled native quil program that respects the given graph topology. + + .. CAUTION:: + The option to only use basic_compile will only result in native quil if the merged + sequence contains no gate definitions and if all multi-qubit gates already respect + the graph topology. If this is not the case, the output program may not be able to be + converted properly to an executable that can be run on the qc. + + :param qc: + :param sequence: + :param graph: + :param use_basic_compile: + :param kwargs: extraneous arguments + :return: + """ + merged = merge_programs(sequence) + if use_basic_compile: + return [basic_compile(merged)] + else: + native_quil = graph_restricted_compilation(qc, graph, merged) + # remove gate definitions and terminous HALT + return [Program([instr for instr in native_quil.instructions][:-1])] + + +def graph_restricted_compilation(qc: QuantumComputer, graph: nx.Graph, + program: Program) -> Program: + """ + A useful helper that temporarily modifies the supplied qc's qubit topology to match the + supplied graph so that the given program may be compiled onto the graph topology. + + :param qc: a qc object with a compiler where the given graph is a subraph of the qc's qubit + topology. + :param graph: The desired subraph of the qc's full topology on which we wish to run a program. + :param program: a program we wish to run on a particular graph on the qc. + :return: the program compiled into native quil gates respecting the graph topology. + """ + qubits = list(graph.nodes) + + # restrict compilation to chosen qubits + isa_dict = qc.device.get_isa().to_dict() + single_qs = isa_dict['1Q'] + two_qs = isa_dict['2Q'] + + new_1q = {} + for key, val in single_qs.items(): + if int(key) in qubits: + new_1q[key] = val + new_2q = {} + for key, val in two_qs.items(): + q1, q2 = key.split('-') + if (int(q1), int(q2)) in graph.edges: + new_2q[key] = val + + new_isa = {'1Q': new_1q, '2Q': new_2q} + + new_compiler = copy(qc.compiler) + new_compiler.target_device = TargetDevice(isa=new_isa, specs=qc.device.get_specs().to_dict()) + # try to compile with the restricted qubit topology + try: + native_quil = new_compiler.quil_to_native_quil(program) + except RPCErrorError as e: + if "Multiqubit instruction requested between disconnected components of the QPU graph:" \ + in str(e): + raise ValueError("The program could not be compiled onto the given subgraph.") + raise + + return native_quil diff --git a/forest/benchmarking/volumetrics/plotting.py b/forest/benchmarking/volumetrics/plotting.py new file mode 100644 index 00000000..f918fe94 --- /dev/null +++ b/forest/benchmarking/volumetrics/plotting.py @@ -0,0 +1,218 @@ +from forest.benchmarking.volumetrics._main import get_random_hamming_wt_distr +from typing import Sequence, Dict +import numpy as np +import matplotlib.pyplot as plt + + +def plot_error_distributions(distr_arr: Dict[int, Dict[int, Sequence[float]]], widths=None, + depths=None, plot_rand_distr=False): + """ + For each width and depth plot the distribution of errors provided in distr_arr. + + :param distr_arr: + :param widths: + :param depths: + :param plot_rand_distr: + :return: + """ + if widths is None: + widths = list(distr_arr.keys()) + + if depths is None: + depths = list(list(distr_arr.values())[0].keys()) + + legend = ['data'] + if plot_rand_distr: + legend.append('random') + + fig = plt.figure(figsize=(18, 6 * len(depths))) + axs = fig.subplots(len(depths), len(widths), sharex='col', sharey=True) + + for w_idx, w in enumerate(widths): + x_labels = np.arange(0, w + 1) + depth_distrs = distr_arr[w] + + if plot_rand_distr: + rand_distr = get_random_hamming_wt_distr(w) + + for d_idx, d in enumerate(depths): + distr = depth_distrs[d] + + idx = d_idx * len(widths) + w_idx + if len(widths) == len(depths) == 1: + ax = axs + else: + ax = axs.flatten()[idx] + ax.bar(x_labels, distr, width=0.61, align='center') + + if plot_rand_distr: + ax.bar(x_labels, rand_distr, width=0.31, align='center') + + ax.set_xticks(x_labels) + ax.grid(axis='y', alpha=0.75) + ax.set_title(f'w = {w}, d = {d}', size=20) + + for tick in ax.xaxis.get_major_ticks(): + tick.label.set_fontsize(15) + + for tick in ax.yaxis.get_major_ticks(): + tick.label.set_fontsize(15) + + fig.legend(legend, loc='right', fontsize=15) + plt.ylim(0, 1) + fig.text(0.5, 0.05, 'Hamming Weight of Error', ha='center', va='center', fontsize=20) + fig.text(0.06, 0.5, 'Relative Frequency of Occurrence', ha='center', va='center', + rotation='vertical', fontsize=20) + plt.subplots_adjust(wspace=0, hspace=.15, left=.1) + + return fig, axs + + +def plot_success(successes, title, widths=None, depths=None, boxsize=1500): + """ + Plot the given successes at each width and depth. + + If a given (width, depth) is not recorded in successes then nothing is plotted for that + point. Successes are displayed as filled boxes while failures are simply box outlines. + + :param successes: + :param title: + :param widths: + :param depths: + :param boxsize: + :return: + """ + if widths is None: + widths = list(successes.keys()) + + if depths is None: + depths = list(set(d for w in successes.keys() for d in successes[w].keys())) + + fig_width = min(len(widths), 15) + fig_depth = min(len(depths), 15) + + fig, ax = plt.subplots(figsize=(fig_width, fig_depth)) + + margin = .5 + ax.set_xlim(-margin, len(widths) + margin - 1) + ax.set_ylim(-margin, len(depths) + margin - 1) + ax.set_xticks(range(len(widths))) + ax.set_xticklabels(widths) + ax.set_yticks(range(len(depths))) + ax.set_yticklabels(depths) + ax.set_xlabel('Width') + ax.set_ylabel('Depth') + + colors = ['white', 'lightblue'] + + for w_idx, w in enumerate(widths): + if w not in successes.keys(): + continue + depth_succ = successes[w] + for d_idx, d in enumerate(depths): + if d not in depth_succ.keys(): + continue + color = colors[0] + if depth_succ[d]: + color = colors[1] + ax.scatter(w_idx, d_idx, marker='s', s=boxsize, color=color, + edgecolors='black') + + # legend + labels = ['Fail', 'Pass'] + for color, label in zip(colors, labels): + plt.scatter([], [], marker='s', c=color, label=label, edgecolors='black') + ax.legend() + + ax.set_title(title) + + return fig, ax + + +def plot_pareto_frontier(successes, title, widths=None, depths=None): + """ + Given the successes at measured widths and depths, draw the frontier that separates success + from failure. + + Specifically, the frontier is drawn as follows:: + + For a given width, draw a line separating all low-depth successes from the minimum + depth failure. For each depth smaller than the minimum failure depth, draw a line + separating the neighboring (width +/- 1, depth) cell if depth is less than the + minimum depth failure for that neighboring width. + + If a requested (width, depth) cell is not specified in successes then no lines will be drawn + around that cell. + + :param successes: + :param title: + :param widths: + :param depths: + :return: + """ + if widths is None: + widths = list(successes.keys()) + + if depths is None: + depths = list(set(d for w in successes.keys() for d in successes[w].keys())) + + fig_width = min(len(widths), 15) + fig_depth = min(len(depths), 15) + + fig, ax = plt.subplots(figsize=(fig_width, fig_depth)) + + margin = .5 + ax.set_xlim(-margin, len(widths) + margin - 1) + ax.set_ylim(-margin, len(depths) + margin - 1) + ax.set_xticks(range(len(widths))) + ax.set_xticklabels(widths) + ax.set_yticks(range(len(depths))) + ax.set_yticklabels(depths) + ax.set_xlabel('Width') + ax.set_ylabel('Depth') + + min_depth_idx_failure_at_width = [] + for w_idx, w in enumerate(widths): + if w not in successes.keys(): + min_depth_idx_failure_at_width.append(None) + continue + + depth_succ = successes[w] + min_depth_failure = len(depths) + for d_idx, d in enumerate(depths): + if d not in depth_succ.keys(): + continue + if not depth_succ[d]: + min_depth_failure = d_idx + break + min_depth_idx_failure_at_width.append(min_depth_failure) + + for w_idx, failure_idx in enumerate(min_depth_idx_failure_at_width): + if failure_idx is None: + continue # this width was not measured, so leave the boundary open + + # horizontal line for this width + if failure_idx < len(depths): # measured a failure + ax.plot((w_idx - margin, w_idx + margin), (failure_idx - margin, failure_idx - margin), + color='black') + + # vertical lines + if w_idx < len(widths) - 1: # check not at max width + for d_idx in range(len(depths)): + # check that the current depth was measured for this width + if depths[d_idx] not in [d for d in successes[widths[w_idx]].keys()]: + continue # do not plot line if this depth was not measured + + # if the adjacent width is not measured leave the boundary open + if min_depth_idx_failure_at_width[w_idx + 1] is None: + continue + + # check if in the interior but adjacent to exterior + # or if in the exterior but adjacent to interior + if failure_idx > d_idx >= min_depth_idx_failure_at_width[w_idx + 1] \ + or failure_idx <= d_idx < min_depth_idx_failure_at_width[w_idx + 1]: + ax.plot((w_idx + margin, w_idx + margin), (d_idx - margin, d_idx + margin), + color='black') + + ax.set_title(title) + return fig, ax diff --git a/forest/benchmarking/volumetrics/quantum_volume.py b/forest/benchmarking/volumetrics/quantum_volume.py new file mode 100644 index 00000000..11d4c552 --- /dev/null +++ b/forest/benchmarking/volumetrics/quantum_volume.py @@ -0,0 +1,163 @@ +from typing import Tuple, Dict, List, Optional +import numpy as np +from statistics import median + +from pyquil.quil import Program, address_qubits, merge_programs +from pyquil.gates import * +from pyquil.numpy_simulator import NumpyWavefunctionSimulator + +from forest.benchmarking.utils import bit_array_to_int +from forest.benchmarking.volumetrics._templates import get_quantum_volume_template + + +def collect_heavy_outputs(wfn_sim: NumpyWavefunctionSimulator, + program_array: Dict[int, Dict[int, List[Program]]], + measure_qubits: Optional[Dict[int, Dict[int, List[int]]]] = None) \ + -> Dict[int, Dict[int, List[List[int]]]]: + """ + Collects and returns those 'heavy' bitstrings which are output with greater than median + probability among all possible bitstrings on the given qubits. + + The method uses the provided wfn_sim to calculate the probability of measuring each bitstring + from the output of the circuit comprised of the given permutations and gates. + + :param wfn_sim: a NumpyWavefunctionSimulator that can simulate the provided program + :param program_array: a collection of PyQuil Programs sampled from the circuit family for + each (width, depth) pair. + :param measure_qubits: optional list of qubits to measure for each Program in + `program_array`. By default all qubits in the Program are measured + :return: a list of the heavy outputs of the circuit, represented as ints + """ + heavy_output_array = {w: {d: [] for d in d_arr.keys()} for w, d_arr in program_array.items()} + + for w, d_progs in program_array.items(): + for d, ckts in d_progs.items(): + for idx, ckt in enumerate(ckts): + wfn_sim.reset() + for gate in ckt: + wfn_sim.do_gate(gate) + + if measure_qubits is not None: + qubits = measure_qubits[w][d][idx] + else: + qubits = sorted(list(ckt.get_qubits())) + + # Note that probabilities are ordered lexicographically with qubit 0 leftmost. + # we need to restrict attention to the subset `qubits` + probs = abs(wfn_sim.wf) ** 2 + probs = probs.reshape([2] * wfn_sim.n_qubits) + marginal = probs + for q in reversed(range(wfn_sim.n_qubits)): + if q in qubits: + continue + marginal = np.sum(marginal, axis=q) + + probabilities = marginal.reshape(-1) + + median_prob = median(probabilities) + + # store the integer indices, which implicitly represent the bitstring outcome. + heavy_outputs = [idx for idx, prob in enumerate(probabilities) if + prob > median_prob] + heavy_output_array[w][d].append(heavy_outputs) + + return heavy_output_array + + +def get_success_probabilities(noisy_results, ideal_results): + """ + For circuit results of various width and depth, calculate the fraction of noisy results + that are also found in the collection of ideal results for each circuit. + + Quantum volume employs this method to calculate success_probabilities where the ideal_results + are the heavy hitters of each circuit. + + :param noisy_results: noisy shots from each circuit sampled for each width and depth + :param ideal_results: a collection of ideal results for each circuit; membership of a noisy + shot from a particular circuit in the corresponding set of ideal_results constitutes a + success. + :return: the estimated success probability for each circuit. + """ + prob_success = {width: {depth: [] for depth in depth_array.keys()} + for width, depth_array in noisy_results.items()} + + assert set(noisy_results.keys()) == set(ideal_results.keys()) + + for width, depth_array in prob_success.items(): + for depth in depth_array.keys(): + + noisy_ckt_sample_results = noisy_results[width][depth] + ideal_ckt_sample_results = ideal_results[width][depth] + + # iterate over circuits + for noisy_shots, targets in zip(noisy_ckt_sample_results, ideal_ckt_sample_results): + if not isinstance(targets[0], int): + targets = [bit_array_to_int(res) for res in targets] + + pr_success = 0 + # determine if each result bitstring is a success, i.e. matches an ideal_result + for result in noisy_shots: + # convert result to int for comparison with heavy outputs. + output = bit_array_to_int(result) + if output in targets: + pr_success += 1 / len(noisy_shots) + prob_success[width][depth].append(pr_success) + + return prob_success + + +def calculate_success_prob_est_and_err(num_success: int, num_circuits: int, num_shots: int) \ + -> Tuple[float, float]: + """ + Helper to calculate the estimate for the probability of sampling a successful output at a + particular depth as well as the 2 sigma one-sided confidence interval on this estimate. + + :param num_success: total number of successful outputs sampled at particular depth across all + circuits and shots + :param num_circuits: the total number of model circuits of a particular depth and width whose + output was sampled + :param num_shots: the total number of shots taken for each circuit + :return: estimate for the probability of sampling a successful output at a particular depth as + well as the 2 sigma one-sided confidence interval on this estimate. + """ + total_sampled_outputs = num_circuits * num_shots + prob_sample_heavy = num_success / total_sampled_outputs + + # Eq. (C3) of [QVol]. Assume that num_heavy/num_shots is worst-case binomial with param + # num_circuits and take gaussian approximation. Get 2 sigma one-sided confidence interval. + sigma = np.sqrt(num_success * (num_shots - num_success / num_circuits)) / total_sampled_outputs + one_sided_confidence_interval = prob_sample_heavy - 2 * sigma + + return prob_sample_heavy, one_sided_confidence_interval + + +def determine_prob_success_lower_bounds(ckt_success_probs, num_shots_per_ckt): + """ + Wrapper around `calculate_success_prob_est_and_err` to determine success lower bounds for a + collection of circuits at various depths and widths. + + :param ckt_success_probs: + :param num_shots_per_ckt: + :return: + """ + return {w: {d: calculate_success_prob_est_and_err( + sum(np.asarray(succ_probs) * num_shots_per_ckt), len(succ_probs), num_shots_per_ckt)[1] + for d, succ_probs in d_ckt_succ_probs.items()} + for w, d_ckt_succ_probs in ckt_success_probs.items()} + + +def determine_successes(ckt_success_probs: Dict[int, Dict[int, List[float]]], num_shots_per_ckt, + success_threshold: float = 2 / 3): + """ + Indicate whether the collection of circuit success probabilities for given width and depth + recorded in `ckt_success_probs` is considered a success with respect to the specified + `success_threshold` and given the number of shots used to estimate each success probability. + + :param ckt_success_probs: + :param num_shots_per_ckt: + :param success_threshold: + :return: + """ + lower_bounds = determine_prob_success_lower_bounds(ckt_success_probs, num_shots_per_ckt) + return {w: {d: lb > success_threshold for d, lb in d_lower_bounds.items()} + for w, d_lower_bounds in lower_bounds.items()}