{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from __future__ import print_function" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#Import relevant modules.\n", "\n", "import pygsti\n", "import numpy as _np\n", "\n", "from pygsti.algorithms import fiducialselection as FS\n", "\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "import time" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this notebook, we'll demonstrate how to select preparation and measurement fiducials for a standard two-qubit gate set. By \"standard\", we mean that a) measurements are made in the computational (Z) basis (and state prep is |00>), and b) gate set consists of independent X pi/2 and Y pi/2 gates on each qubit. Presumably there will be additional entangling gates available; however, we do not want (or need) such gates in our fiducial gate strings. (Two-qubit operations will typically be of lower fidelity, so it is \"safer\" to use single-qubit operations for fiducials.)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#Build the gate set. As mentioned above, no entangling operation is included; these results will be general for\n", "#any two-qubit gate set that has access to the Gix, Giy, Gxi, and Gyi gates \n", "#(and prepares in the state |00> and performs measurements in the computational basis).\n", "gs_target = pygsti.construction.build_gateset( [4], [('Q0','Q1')],['Gix','Giy','Gxi','Gyi'], \n", " [\"X(pi/2,Q1)\", \"Y(pi/2,Q1)\", \"X(pi/2,Q0)\", \"Y(pi/2,Q0)\"], \n", " prepLabels = [\"rho0\"], prepExpressions = [\"0\"], \n", " effectLabels = [\"E0\",\"E1\",\"E2\"], effectExpressions = [\"0\",\"1\",\"2\"], \n", " spamdefs={'upup': (0,0), 'updn': (0,1), 'dnup': (0,2), 'dndn': (0,-1) },\n", " basis=\"pp\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#Let's try to pick out a fiducial set. \n", "\n", "#First, we generate a candidate set which we'll attempt to prune.\n", "#We could look at all gate strings of up to a fixed length (using pygsti.construction.list_all_gatestrings),\n", "#but that grows quite rapidly.\n", "#Instead, we'll look at the tensor product of the standard 1-qubit fiducial set with itself.\n", "#This product set we define below.\n", "\n", "#{} x 1q fid list\n", "emptyList = pygsti.construction.gatestring_list([\n", " (),\n", " ('Gix',),\n", " ('Gix','Gix'),\n", " ('Gix','Gix','Gix'),\n", " ('Giy',),\n", " ('Giy','Giy','Giy')\n", " ])\n", "\n", "#Gx x 1q fid list\n", "XList = pygsti.construction.gatestring_list([\n", " ('Gxi',),\n", " ('Gxi','Gix',),\n", " ('Gxi','Gix','Gix'),\n", " ('Gxi','Gix','Gix','Gix'),\n", " ('Gxi','Giy',),\n", " ('Gxi','Giy','Giy','Giy')\n", " ])\n", "\n", "#GxGx x 1q fid list\n", "XXList = pygsti.construction.gatestring_list([\n", " ('Gxi','Gxi'),\n", " ('Gxi','Gxi','Gix',),\n", " ('Gxi','Gxi','Gix','Gix'),\n", " ('Gxi','Gxi','Gix','Gix','Gix'),\n", " ('Gxi','Gxi','Giy',),\n", " ('Gxi','Gxi','Giy','Giy','Giy')\n", " ])\n", "\n", "#GxGxGx x 1q fid list\n", "XXXList = pygsti.construction.gatestring_list([\n", " ('Gxi','Gxi','Gxi'),\n", " ('Gxi','Gxi','Gxi','Gix',),\n", " ('Gxi','Gxi','Gxi','Gix','Gix'),\n", " ('Gxi','Gxi','Gxi','Gix','Gix','Gix'),\n", " ('Gxi','Gxi','Gxi','Giy',),\n", " ('Gxi','Gxi','Gxi','Giy','Giy','Giy')\n", " ])\n", "\n", "#Gy x 1q fid list\n", "YList = pygsti.construction.gatestring_list([\n", " ('Gyi',),\n", " ('Gyi','Gix',),\n", " ('Gyi','Gix','Gix'),\n", " ('Gyi','Gix','Gix','Gix'),\n", " ('Gyi','Giy',),\n", " ('Gyi','Giy','Giy','Giy')\n", " ])\n", "\n", "#Gy x 1q fid list\n", "YYYList = pygsti.construction.gatestring_list([\n", " ('Gyi','Gyi'),\n", " ('Gyi','Gyi','Gyi','Gix',),\n", " ('Gyi','Gyi','Gyi','Gix','Gix'),\n", " ('Gyi','Gyi','Gyi','Gix','Gix','Gix'),\n", " ('Gyi','Gyi','Gyi','Giy',),\n", " ('Gyi','Gyi','Gyi','Giy','Giy','Giy')\n", " ])\n", "\n", "testFidList = emptyList + XList + XXList + XXXList + YList + YYYList\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#Don't worry if the optimize_integer_fiducials_slack function below throws a divide by zero warning;\n", "#this just means one of the tested cases was *really* bad." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial set optimization. Lower score is better.\n", "score = 1468.8\n", "weights = [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1]\n", "L1(weights) = 16\n", "Final fiducial set succeeds.\n", "\n", "Fiducial selection completed in 0.23148202896118164 seconds.\n", "{}\n", "GyiGiy\n", "GxiGxiGiy\n", "GyiGixGix\n", "GxiGxiGxiGix\n", "GxiGxiGxiGiy\n", "GyiGixGixGix\n", "GyiGiyGiyGiy\n", "GyiGyiGyiGiy\n", "GxiGxiGixGixGix\n", "GxiGxiGiyGiyGiy\n", "GxiGxiGxiGixGix\n", "GyiGyiGyiGixGix\n", "GxiGxiGxiGixGixGix\n", "GyiGyiGyiGixGixGix\n", "GyiGyiGyiGiyGiyGiy\n" ] } ], "source": [ "#We know that we should be able to find a prep fiducial set that has no more than 16 elements,\n", "#so if we are finding sets that are larger than that, we can always increase slackFrac or fixedSlack\n", "start = time.time()\n", "prepFidList1_all = FS.optimize_integer_fiducials_slack(gs_target,testFidList,prepOrMeas='prep',initialWeights=None,\n", " scoreFunc='all',slackFrac=.275)\n", "end = time.time()\n", "print('')\n", "print(\"Fiducial selection completed in\", end-start, \"seconds.\")\n", "print(\"\\n\".join(map(str,sorted(prepFidList1_all,key=len))))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial set optimization. Lower score is better.\n", "score = 249.001323854\n", "weights = [1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0]\n", "L1(weights) = 16\n", "Final fiducial set succeeds.\n", "\n", "Fiducial selection completed in 0.2091379165649414 seconds.\n", "{}\n", "Giy\n", "GyiGyi\n", "GixGixGix\n", "GxiGxiGix\n", "GxiGxiGxi\n", "GyiGixGix\n", "GyiGixGixGix\n", "GyiGiyGiyGiy\n", "GyiGyiGyiGix\n", "GyiGyiGyiGiy\n", "GxiGxiGiyGiyGiy\n", "GxiGxiGxiGixGix\n", "GyiGyiGyiGixGix\n", "GxiGxiGxiGixGixGix\n", "GxiGxiGxiGiyGiyGiy\n" ] } ], "source": [ "#We know that we should be able to find a prep fiducial set that has no more than 16 elements,\n", "#so if we are finding sets that are larger than that, we can always increase slackFrac or fixedSlack\n", "start = time.time()\n", "prepFidList1_worst = FS.optimize_integer_fiducials_slack(gs_target,testFidList,prepOrMeas='prep',initialWeights=None,\n", " scoreFunc='worst',slackFrac=.275)\n", "end = time.time()\n", "print('')\n", "print(\"Fiducial selection completed in\", end-start, \"seconds.\")\n", "print(\"\\n\".join(map(str,sorted(prepFidList1_worst,key=len))))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial set optimization. Lower score is better.\n", "score = 316.130180659\n", "weights = [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1]\n", "L1(weights) = 9\n", "Final fiducial set succeeds.\n", "\n", "Fiducial selection completed in 0.3222181797027588 seconds.\n", "{}\n", "GxiGxiGxiGiy\n", "GyiGyiGyiGix\n", "GxiGxiGixGixGix\n", "GxiGxiGiyGiyGiy\n", "GxiGxiGxiGixGix\n", "GyiGyiGyiGixGix\n", "GxiGxiGxiGixGixGix\n", "GyiGyiGyiGiyGiyGiy\n" ] } ], "source": [ "#We know that there might exist a fiducial measurement set with as few as 6 elements (as 6*3=18>16).\n", "#However, repeated attempts to find one to date have failed. We can reliably identify fiducial measurement sets\n", "#with only 9 elements, so 9 should be considered an upper bound. (If you do find a set with fewer than 9 elements,\n", "#the pyGSTi team would love to hear from you!)\n", "start = time.time()\n", "measFidList1_all = FS.optimize_integer_fiducials_slack(gs_target,testFidList,prepOrMeas='meas',initialWeights=None,\n", " scoreFunc='all',slackFrac=1)\n", "end = time.time()\n", "print('')\n", "print(\"Fiducial selection completed in\", end-start, \"seconds.\")\n", "print(\"\\n\".join(map(str,sorted(measFidList1_all,key=len))))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial set optimization. Lower score is better.\n", "score = 48.4574110103\n", "weights = [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0]\n", "L1(weights) = 9\n", "Final fiducial set succeeds.\n", "\n", "Fiducial selection completed in 0.314039945602417 seconds.\n", "{}\n", "GxiGxiGxiGix\n", "GyiGyiGyiGiy\n", "GxiGxiGixGixGix\n", "GxiGxiGiyGiyGiy\n", "GxiGxiGxiGixGix\n", "GyiGyiGyiGixGix\n", "GxiGxiGxiGiyGiyGiy\n", "GyiGyiGyiGixGixGix\n" ] } ], "source": [ "#Let's try the same as above, but with \"worst\" instead of \"all\" as the scoreFunc.\n", "start = time.time()\n", "measFidList1_worst = FS.optimize_integer_fiducials_slack(gs_target,testFidList,prepOrMeas='meas',initialWeights=None,\n", " scoreFunc='worst',slackFrac=1)\n", "end = time.time()\n", "print('')\n", "print(\"Fiducial selection completed in\", end-start, \"seconds.\")\n", "print(\"\\n\".join(map(str,sorted(measFidList1_worst,key=len))))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(True,\n", " [0.035777874246103326,\n", " 0.094384513594891764,\n", " 0.12472064408483972,\n", " 0.18406325009774369,\n", " 0.21922359359558477,\n", " 0.24878825006702784,\n", " 0.32992842070695388,\n", " 0.49999999999999961,\n", " 0.60106985528731904,\n", " 0.8952780966140732,\n", " 1.0000000000000002,\n", " 1.2601374932937572,\n", " 1.5082401339544393,\n", " 1.9793250220729006,\n", " 2.280776406404414,\n", " 4.7382864459799485],\n", " Score: 1152.0000000000025, N: 16)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FS.test_fiducial_list(gs_target, prepFidList1_all,'prep', scoreFunc='all', returnAll=True)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "prep fid_all spectrum:\n", " [0.035777874246103757, 0.094384513594892402, 0.12472064408484011, 0.18406325009774313, 0.21922359359558505, 0.24878825006702732, 0.32992842070695388, 0.5, 0.60106985528731915, 0.89527809661407276, 1.0, 1.2601374932937566, 1.5082401339544393, 1.9793250220729006, 2.2807764064044158, 4.7382864459799485]\n", "prep fid_all 'all-score': 1152.0\n", "prep fid_all 'worst-score': 447.20376314\n" ] } ], "source": [ "print(\"prep fid_all spectrum:\\n\", FS.test_fiducial_list(gs_target, prepFidList1_all, 'prep',\n", " returnAll=True)[1])\n", "print(\"prep fid_all 'all-score':\", FS.compute_composite_score(gs_target, prepFidList1_all, 'prep',\n", " scoreFunc='all').score)\n", "print(\"prep fid_all 'worst-score':\", FS.compute_composite_score(gs_target, prepFidList1_all, 'prep',\n", " scoreFunc='worst').score)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "prep fid_worst spectrum:\n", " [0.081927275262132032, 0.11388855211719048, 0.1320152782977117, 0.1951852156926718, 0.27205660994856667, 0.29289321881345226, 0.49999999999999944, 0.49999999999999967, 0.50000000000000011, 0.65555661468669424, 0.91892639567648526, 1.114993642934855, 1.7071067811865468, 2.1841101287185047, 2.1951284422577562, 4.6362118444074252]\n", "prep fid_worst 'all-score': 832.0\n", "prep fid_worst 'worst-score': 195.295155964\n" ] } ], "source": [ "print(\"prep fid_worst spectrum:\\n\", FS.test_fiducial_list(gs_target, prepFidList1_worst, 'prep',\n", " returnAll=True)[1])\n", "print(\"prep fid_worst 'all-score':\", FS.compute_composite_score(gs_target, prepFidList1_worst, 'prep',\n", " scoreFunc='all').score)\n", "print(\"prep fid_worst 'worst-score':\", FS.compute_composite_score(gs_target, prepFidList1_worst, 'prep',\n", " scoreFunc='worst').score)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#Interestingly, using the option \"worst\" instead of \"all\" yields a better scoring fiducial set, by both the \"worst\"\n", "#and \"all\"." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "prep meas_all spectrum:\n", " [0.3714602085566765, 0.50000000000000056, 0.56368584497043994, 0.64534972638934507, 0.71248175049995766, 0.71922359359558552, 0.744102543127522, 0.74999999999999989, 0.75000000000000011, 1.9166803725509385, 2.0000000000000022, 2.1610191647597001, 2.5209138803963618, 2.7710731135452389, 2.780776406404418, 7.0932333952038285]\n", "prep meas_all 'all-score': 158.065090329\n", "prep meas_all 'worst-score': 24.2287055051\n" ] } ], "source": [ "print(\"prep meas_all spectrum:\\n\", FS.test_fiducial_list(gs_target, measFidList1_all, 'meas',\n", " returnAll=True)[1])\n", "print(\"prep meas_all 'all-score':\", FS.compute_composite_score(gs_target, measFidList1_all, 'meas',\n", " scoreFunc='all').score)\n", "print(\"prep meas_all 'worst-score':\", FS.compute_composite_score(gs_target, measFidList1_all, 'meas',\n", " scoreFunc='worst').score)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "prep meas_worst spectrum:\n", " [0.3714602085566765, 0.50000000000000056, 0.56368584497044039, 0.64534972638934496, 0.71248175049995877, 0.71922359359558552, 0.74410254312752211, 0.74999999999999978, 0.75000000000000089, 1.9166803725509376, 2.0000000000000022, 2.1610191647597015, 2.52091388039636, 2.7710731135452402, 2.780776406404418, 7.093233395203832]\n", "prep meas_worst 'all-score': 158.065090329\n", "prep meas_worst 'worst-score': 24.2287055051\n" ] } ], "source": [ "print(\"prep meas_worst spectrum:\\n\", FS.test_fiducial_list(gs_target, measFidList1_worst, 'meas',\n", " returnAll=True)[1])\n", "print(\"prep meas_worst 'all-score':\", FS.compute_composite_score(gs_target, measFidList1_worst, 'meas',\n", " scoreFunc='all').score)\n", "print(\"prep meas_worst 'worst-score':\", FS.compute_composite_score(gs_target, measFidList1_worst, 'meas',\n", " scoreFunc='worst').score)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{} \t {} \t True\n", "GxiGxiGxiGiy \t GxiGxiGxiGix \t False\n", "GyiGyiGyiGix \t GyiGyiGyiGiy \t False\n", "GxiGxiGixGixGix \t GxiGxiGixGixGix \t True\n", "GxiGxiGiyGiyGiy \t GxiGxiGiyGiyGiy \t True\n", "GxiGxiGxiGixGix \t GxiGxiGxiGixGix \t True\n", "GyiGyiGyiGixGix \t GyiGyiGyiGixGix \t True\n", "GxiGxiGxiGixGixGix \t GxiGxiGxiGiyGiyGiy \t False\n", "GyiGyiGyiGiyGiyGiy \t GyiGyiGyiGixGixGix \t False\n" ] } ], "source": [ "for i in range(len(measFidList1_all)):\n", " print(sorted(measFidList1_all,key=len)[i], '\\t', sorted(measFidList1_worst,key=len)[i], '\\t', sorted(measFidList1_all,key=len)[i] == sorted(measFidList1_worst,key=len)[i])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#We have the same scores for \"all\" and \"worst\" for measurement fiducials, even though the fiducial sets themselves\n", "#are not quite the same." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#Lastly, let's see if we can find a minimal set of measurement fiducials (size 6), using the same input set as before." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial set optimization. Lower score is better.\n", "Output set is required to be of size6\n", "Total number of fiducial sets to be checked is324632.0\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "WARNING: If this is very large, you may wish to abort.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Switching!\n", "Switching!\n", "Switching!\n", "Switching!\n", "\n", "Fiducial selection completed in 103.61686706542969 seconds.\n", "{}\n", "GxiGxiGxiGix\n", "GyiGyiGyiGiy\n", "GxiGxiGixGixGix\n", "GxiGxiGiyGiyGiy\n", "GxiGxiGxiGixGix\n", "GyiGyiGyiGixGix\n", "GxiGxiGxiGiyGiyGiy\n", "GyiGyiGyiGixGixGix\n" ] } ], "source": [ "start = time.time()\n", "measFidList1_all_force6 = FS.optimize_integer_fiducials_slack(gs_target,testFidList,prepOrMeas='meas',initialWeights=None,fixedNum=6,\n", " scoreFunc='all',slackFrac=1)\n", "end = time.time()\n", "print('')\n", "print(\"Fiducial selection completed in\", end-start, \"seconds.\")\n", "print(\"\\n\".join(map(str,sorted(measFidList1_worst,key=len))))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(False,\n", " [0.0,\n", " 2.4995843092626328e-16,\n", " 2.7770928464217906e-16,\n", " 3.8492813519304379e-16,\n", " 0.42672875571022356,\n", " 0.4934886775389975,\n", " 0.6563680176830814,\n", " 0.67679045677623229,\n", " 0.74999999999999989,\n", " 1.0000000000000004,\n", " 1.0000000000000013,\n", " 1.4193625622157191,\n", " 1.7710921857106274,\n", " 2.1291505505848565,\n", " 2.645811040896072,\n", " 5.0312077528842014],\n", " Score: 78.11868131868127, N: 12)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FS.test_fiducial_list(gs_target,measFidList1_all_force6,'meas',scoreFunc='all',returnAll=True)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#Sadly, this did not work! However, one could try different input sets (or increasing fixedNum to 7 or 8, which would\n", "#still be better than 9.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "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.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }