{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Easy experiment setup" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook demonstrates some convenience functions for coming up with the\n", "experiments needed to do GST on a new gateset." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import pygsti\n", "import pygsti.algorithms.germselection as germsel\n", "import pygsti.algorithms.fiducialselection as fidsel\n", "import pygsti.construction as constr" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's construct a 1-qubit $X(\\pi/2)$, $Y(\\pi/2)$, $I$ gateset for which we will need to find germs and fiducials." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "gs_target = constr.build_gateset([2], [('Q0',)], ['Gi', 'Gx', 'Gy'],\n", " [\"I(Q0)\", \"X(pi/2,Q0)\", \"Y(pi/2,Q0)\"],\n", " prepLabels=['rho0'], prepExpressions=[\"0\"],\n", " effectLabels=['E0'], effectExpressions=[\"1\"],\n", " spamdefs={'plus': ('rho0', 'E0'),\n", " 'minus': ('rho0', 'remainder')})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hands-off" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We begin by demonstrating the most hands-off approach." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can generate a germ set simply by providing the target gateset." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using greedy algorithm.\n", "Constructed germ set:\n", "['Gi', 'Gx', 'Gy', 'GiGiGiGiGiGx', 'GxGy', 'GiGiGiGyGxGx', 'GiGiGiGxGxGy', 'GiGiGiGiGiGy', 'GxGxGyGyGxGy', 'GiGiGiGxGiGy']\n", "Score: 102.84227397720784\n" ] } ], "source": [ "germs = germsel.generate_germs(gs_target)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the same way we can generate preparation and measurement fiducials." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n", "Preparation fiducials:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Score: 31.999999999999986\n", "Measurement fiducials:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Score: 31.999999999999996\n" ] } ], "source": [ "prepFiducials, measFiducials = fidsel.generate_fiducials(gs_target)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have germs and fiducials, we can construct the list of experiments we need to perform in\n", "order to do GST. The only new things to provide at this point are the sizes for the experiments we want\n", "to perform (in this case we want to perform between 0 and 256 gates between fiducial pairs, going up\n", "by a factor of 2 at each stage)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "maxLengths = [0] + [2**n for n in range(8 + 1)]\n", "listOfExperiments = constr.make_lsgst_experiment_list(gs_target.gates.keys(), prepFiducials,\n", " measFiducials, germs, maxLengths)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The list of `GateString` that the previous function gave us isn't necessarily the most readable\n", "form to present the information in, so we can write the experiment list out to an empty data\n", "file to be filled in after the experiments are performed." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "pygsti.io.write_empty_dataset(\"tutorial_files/EasyDataTemplate.txt\", listOfExperiments)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's it! You can now take the data this file is asking for and come back to analyze the data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## More control" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are many ways you can assume more control over the experiment design process. We'll only demonstrate\n", "a few here, but all options are discussed in the documentation for the various functions we've used." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Different algorithms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are a number of different algorithms available for germ selection. You can choose a non-default\n", "algorithm by specifying the `algorithm` keyword argument." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Each of the available algorithms has a set of keyword arguments of its own with which you\n", "can more precisely specify how you want it to behave. These keyword arguments can be passed\n", "as a dictionary to `generate_germs` through the keyword argument `algorithm_kwargs`." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n", "Constructed germ set:\n", "['Gi', 'Gx', 'Gy', 'GxGy', 'GiGiGiGiGx', 'GiGiGiGiGiGy', 'GiGiGiGyGxGy', 'GiGiGxGyGyGy', 'GiGiGyGyGyGx', 'GxGxGyGyGxGy']\n", "Score: 77.62368004131187\n" ] } ], "source": [ "graspGerms = germsel.generate_germs(gs_target, algorithm='grasp', algorithm_kwargs={'iterations': 1})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fiducial selection can be controlled in much the same way." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using slack algorithm.\n", "Preparation fiducials:\n", "['{}', 'GxGy', 'GyGx', 'GyGy']\n", "Score: 32.00000000000001\n", "Measurement fiducials:\n", "['{}', 'GxGy', 'GyGx', 'GyGy']\n", "Score: 32.0\n" ] } ], "source": [ "slackPrepFids, slackMeasFids = fidsel.generate_fiducials(gs_target, algorithm='slack',\n", " algorithm_kwargs={'slackFrac': 0.25})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Germ and fiducial lengths" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "We can also adjust some algorithm-independent parameters for germ and fiducial selection. For instance, all\n", "of the algorithms currently rely on having a pool of gatestring from which they construct germs and fiducials.\n", "The size of this pool is set by specifying the longest germ or fiducial to include in this pool." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For germ selection, the default maximum germ length is 6, and we can see that our original construction\n", "indeed makes use of germs of length 6." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max([len(germ) for germ in germs])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can try and set the maximum germ length to 5 and see what we get." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using greedy algorithm.\n", "Constructed germ set:\n", "['Gi', 'Gx', 'Gy', 'GiGiGiGxGy', 'GxGy', 'GiGiGiGiGy', 'GiGiGyGxGx', 'GiGiGiGiGx', 'GiGiGyGxGy', 'GiGxGyGxGx']\n", "Score: 511298.1283741678\n" ] } ], "source": [ "germsMaxLength5 = germsel.generate_germs(gs_target, maxGermLength=5)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max([len(germ) for germ in germsMaxLength5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sure enough, we now have a germ set with a shorter longest germ. If we get too ambitious in shortening the maximum\n", "germ length, germ selection won't be able to find an amplificationally complete germ set. It will send a warning\n", "message to `stderr` if this happens and return `None`." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using greedy algorithm.\n", "None\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "WARNING: Complete initial germ set FAILS on gateset 0.\n", "\n", "WARNING: Aborting search.\n" ] } ], "source": [ "germsMaxLength3 = germsel.generate_germs(gs_target, maxGermLength=3)\n", "print(germsMaxLength3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fiducial selection defaults to a maximum fiducial length of 2. This allows us to construct an informationally\n", "complete set of states and measurements, but for this gateset we know that there is a uniformly\n", "informationally complete set of states and measurements that require fiducials of up to length 3. We can find\n", "that set of fiducials by telling `generate_fiducials` to consider longer fiducials." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n", "Preparation fiducials:\n", "['{}', 'Gx', 'Gy', 'GyGy', 'GyGyGx', 'GyGyGy']\n", "Score: 20.0\n", "Measurement fiducials:\n", "['{}', 'Gx', 'Gy', 'GxGx', 'GxGyGy', 'GyGyGy']\n", "Score: 20.0\n" ] } ], "source": [ "uniformPrepFids, uniformMeasFids = fidsel.generate_fiducials(gs_target, maxFidLength=3,\n", " algorithm='grasp',\n", " algorithm_kwargs={'iterations': 100})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As was the case with germ selection, if you are too aggressive in limiting fiducial length you may\n", "constrain the algorithm to the extent that it cannot even find a set of fiducials to generate an\n", "informationally complete set of states and measurements. In that case, it will also send a warning\n", "message to `stderr` and return `None` for the preparation and measurement fiducial sets." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "WARNING: Complete initial fiducial set FAILS.\n", "\n", "WARNING: Aborting search.\n", "\n", "WARNING: Complete initial fiducial set FAILS.\n", "\n", "WARNING: Aborting search.\n" ] } ], "source": [ "incompletePrepFids, incompleteMeasFids = fidsel.generate_fiducials(gs_target, maxFidLength=1)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None None\n" ] } ], "source": [ "print(incompleteMeasFids, incompletePrepFids)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Set requirements" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are several natural things to require of the returned germ and fiducial sets. For germ sets, you will usually\n", "want the individual gates to be included as germs. If for some reason you don't want this, you can set the\n", "*forceSingletons* keyword argument to `False`." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n", "Constructed germ set:\n", "['Gx', 'Gy', 'GxGy', 'GiGiGiGx', 'GiGiGiGy', 'GiGiGxGy', 'GiGiGyGx', 'GiGxGiGy', 'GiGxGyGx', 'GiGyGxGx', 'GiGyGxGy', 'GiGyGyGx']\n", "Score: 117417.46677453033\n" ] } ], "source": [ "nonSingletonGerms = germsel.generate_germs(gs_target, force=None, maxGermLength=4,\n", " algorithm='grasp', algorithm_kwargs={'iterations': 5})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In fiducial selection, it is likewise natural to require the empty gate string to be in the\n", "fiducial set. This requirement may be disabled by setting *forceEmpty* to `False`. It is also\n", "often desireable for identity gates to be left out of fiducials, since they add no diversity\n", "to the set of states and measurements generated. You can allow identity gates in fiducials by\n", "setting *omitIdentity* to `False`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A more common modification to the fiducial set requirements is to leave out additional gates from fiducials.\n", "This might be desireable if you have a multi-qubit system and you expect your 2-qubit gates to be of lower\n", "fidelity than your single-qubit gates. In this case you might want to construct fiducials from only\n", "single-qubit gates. A list of gates that you would like to omit from your fiducials can be provided as a\n", "list of gate labels to the *gatesToOmit* keyword argument." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our gateset doesn't have multi-qubit gates, but we can demonstrate several pieces of this\n", "functionality by setting *omitIdentity* to `False` and omitting the identity manually using\n", "*gatesToOmit*." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n", "Preparation fiducials:\n", "['{}', 'Gy', 'Gx', 'GxGx']\n", "Score: 31.999999999999986\n", "Measurement fiducials:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Score: 31.999999999999996\n" ] } ], "source": [ "omitIdentityPrepFids, omitIdentityMeasFids = fidsel.generate_fiducials(gs_target, omitIdentity=False,\n", " gatesToOmit=['Gi'])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[GateString({}), GateString(Gy), GateString(Gx), GateString(GxGx)]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "omitIdentityPrepFids" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[GateString({}), GateString(Gx), GateString(Gy), GateString(GxGx)]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "omitIdentityMeasFids" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Verbosity" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The various algorithms can tell you something of what's going on with them while they're running. By default,\n", "this output is silenced, but it can be turned on using the *verbosity* keyword argument." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A verbosity level of 1 is the default. This prints out what algorithm is being used, the returned set, and\n", "the score of that set." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A verbosity level of 0 silences all output (other than warnings that things have gone wrong)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A verbosity level of $n+1$ where $n\\geq0$ prints the output of verbosity level 1 in addition to\n", "the output that the current algorithm displays when its own verbosity is set to $n$." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GRASP algorithm.\n", "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial list optimization. Lower score is better.\n", "Starting iteration 1 of 5.\n", "Initial construction:\n", "['{}', 'GxGy', 'GyGy', 'Gx', 'GyGx']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx', 'GyGy']\n", "Finished iteration 1 of 5.\n", "Starting iteration 2 of 5.\n", "Initial construction:\n", "['{}', 'Gy', 'GxGx', 'GxGy']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Finished iteration 2 of 5.\n", "Starting iteration 3 of 5.\n", "Initial construction:\n", "['{}', 'GxGx', 'Gy', 'GxGy']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Finished iteration 3 of 5.\n", "Starting iteration 4 of 5.\n", "Initial construction:\n", "['{}', 'Gy', 'GxGx', 'Gx']\n", "Local optimum:\n", "['{}', 'Gy', 'GxGx', 'Gx']\n", "Finished iteration 4 of 5.\n", "Starting iteration 5 of 5.\n", "Initial construction:\n", "['{}', 'GxGx', 'Gy', 'GyGx', 'GyGy', 'GxGy']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGy', 'GyGx', 'GyGy']\n", "Finished iteration 5 of 5.\n", "Preparation fiducials:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Score: 31.999999999999986\n", "Complete initial fiducial set succeeds.\n", "Now searching for best fiducial set.\n", "Starting fiducial list optimization. Lower score is better.\n", "Starting iteration 1 of 5.\n", "Initial construction:\n", "['{}', 'Gx', 'GyGx', 'GyGy', 'GxGy']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx', 'GyGy']\n", "Finished iteration 1 of 5.\n", "Starting iteration 2 of 5.\n", "Initial construction:\n", "['{}', 'GxGy', 'Gy', 'GxGx', 'Gx']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx', 'GyGy']\n", "Finished iteration 2 of 5.\n", "Starting iteration 3 of 5.\n", "Initial construction:\n", "['{}', 'Gy', 'GyGy', 'GyGx']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Finished iteration 3 of 5.\n", "Starting iteration 4 of 5.\n", "Initial construction:\n", "['{}', 'Gy', 'GyGx', 'GxGx']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Finished iteration 4 of 5.\n", "Starting iteration 5 of 5.\n", "Initial construction:\n", "['{}', 'Gx', 'GyGx', 'GxGy', 'GyGy']\n", "Local optimum:\n", "['{}', 'Gx', 'Gy', 'GxGx', 'GyGy']\n", "Finished iteration 5 of 5.\n", "Measurement fiducials:\n", "['{}', 'Gx', 'Gy', 'GxGx']\n", "Score: 31.999999999999996\n" ] } ], "source": [ "verbosePrepFids, verboseMeasFids = fidsel.generate_fiducials(gs_target, verbosity=2)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [], "source": [ "silentGerms = germsel.generate_germs(gs_target, algorithm='slack', algorithm_kwargs={'maxIter': 5},\n", " verbosity=0)" ] }, { "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 }