{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "# Using GST to test for context dependence\n", "This example shows how to introduce new gate labels into a GST analysis so as to test for context dependence. In particular, we'll look at the 1-qubit X, Y, I gateset. Suppose a usual GST analysis cannot fit the model well, and that we think this is due to the fact that a \"Gi\" gate which immediately follows a \"Gx\" gate is affected by some residual noise that isn't otherwise present. In this case, we can model the system as having two different \"Gi\" gates: \"Gi\" and \"Gi2\", and model the \"Gi\" gate as \"Gi2\" whenever it follows a \"Gx\" gate." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "from __future__ import print_function\n", "import pygsti\n", "from pygsti.construction import std1Q_XYI" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "First we'll create a mock data set that exhibits this context dependence. To do this, we add an additional \"Gi2\" gate to the data-generating gate set, generate some data using \"Gi2\"-containing gate sequences, and finally replace all instances of \"Gi2\" with \"Gi\" so that it looks like data that was supposed to have just a single \"Gi\" gate. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "# The usual setup: identify the target gateset, fiducials, germs, and max-lengths\n", "gs_target = std1Q_XYI.gs_target\n", "fiducials = std1Q_XYI.fiducials\n", "germs = std1Q_XYI.germs\n", "maxLengths = [1,2,4,8,16,32]\n", "\n", "# Create a GateSet to generate the data - one that has two identity gates: Gi and Gi2\n", "gs_datagen = gs_target.depolarize(gate_noise=0.1, spam_noise=0.001)\n", "gs_datagen[\"Gi2\"] = gs_datagen[\"Gi\"].copy()\n", "gs_datagen[\"Gi2\"].depolarize(0.1) # depolarize Gi2 even further\n", "gs_datagen[\"Gi2\"].rotate( (0,0,0.1), gs_datagen.basis) # and rotate it slightly about the Z-axis\n", "\n", "# Create a set of gate sequences by constructing the usual set of experiments and using \n", "# \"manipulate_gatestring_list\" to replace Gi with Gi2 whenever it follows Gx. Create a \n", "# DataSet using the resulting Gi2-containing list of sequences.\n", "listOfExperiments = pygsti.construction.make_lsgst_experiment_list(gs_target, fiducials, fiducials, germs, maxLengths)\n", "rules = [ ((\"Gx\",\"Gi\") , (\"Gx\",\"Gi2\")) ] # a single replacement rule: GxGi => GxGi2 \n", "listOfExperiments = pygsti.construction.manipulate_gatestring_list(listOfExperiments, rules)\n", "ds = pygsti.construction.generate_fake_data(gs_datagen, listOfExperiments, nSamples=10000,\n", " sampleError=\"binomial\", seed=1234)\n", "\n", "# Revert all the Gi2 labels back to Gi, so that the DataSet doesn't contain any Gi2 labels.\n", "rev_rules = [ ((\"Gi2\",) , (\"Gi\",)) ] # returns all Gi2's to Gi's \n", "ds.process_gate_strings(lambda gstr: pygsti.construction.manipulate_gatestring(gstr,rev_rules))" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Running \"standard\" GST on this `DataSet` resulst in a bad fit: " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- Gate Sequence Creation ---\n", " 1702 sequences created\n", " Dataset has 1702 entries: 1702 utilized, 0 requested sequences were missing\n", "--- LGST ---\n", " Singular values of I_tilde (truncating to first 4 of 6) = \n", " 4.244087195801075\n", " 1.168281483622616\n", " 0.9583432784288527\n", " 0.946089812454173\n", " 0.02268906619381714\n", " 0.008669671149062112\n", " \n", " Singular values of target I_tilde (truncating to first 4 of 6) = \n", " 4.242640687119285\n", " 1.4142135623730954\n", " 1.4142135623730947\n", " 1.4142135623730945\n", " 3.1723744950054595e-16\n", " 1.0852733691121267e-16\n", " \n", "--- Iterative MLGST: Iter 1 of 6 92 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 115.723 (92 data params - 31 model params = expected mean of 61; p-value = 2.97873e-05)\n", " Completed in 0.2s\n", " 2*Delta(log(L)) = 115.482\n", " Iteration 1 took 0.3s\n", " \n", "--- Iterative MLGST: Iter 2 of 6 168 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 336.854 (168 data params - 31 model params = expected mean of 137; p-value = 0)\n", " Completed in 0.2s\n", " 2*Delta(log(L)) = 335.155\n", " Iteration 2 took 0.3s\n", " \n", "--- Iterative MLGST: Iter 3 of 6 450 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 1423.84 (450 data params - 31 model params = expected mean of 419; p-value = 0)\n", " Completed in 0.4s\n", " 2*Delta(log(L)) = 1413.48\n", " Iteration 3 took 0.6s\n", " \n", "--- Iterative MLGST: Iter 4 of 6 862 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 3030.54 (862 data params - 31 model params = expected mean of 831; p-value = 0)\n", " Completed in 0.6s\n", " 2*Delta(log(L)) = 3011\n", " Iteration 4 took 1.1s\n", " \n", "--- Iterative MLGST: Iter 5 of 6 1282 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 4123.46 (1282 data params - 31 model params = expected mean of 1251; p-value = 0)\n", " Completed in 1.0s\n", " 2*Delta(log(L)) = 4101.89\n", " Iteration 5 took 1.8s\n", " \n", "--- Iterative MLGST: Iter 6 of 6 1702 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 4637.95 (1702 data params - 31 model params = expected mean of 1671; p-value = 0)\n", " Completed in 1.0s\n", " 2*Delta(log(L)) = 4616.1\n", " Iteration 6 took 2.4s\n", " \n", " Switching to ML objective (last iteration)\n", " --- MLGST ---\n", " Maximum log(L) = 2307.72 below upper bound of -2.85002e+07\n", " 2*Delta(log(L)) = 4615.44 (1702 data params - 31 model params = expected mean of 1671; p-value = 0)\n", " Completed in 1.9s\n", " 2*Delta(log(L)) = 4615.44\n", " Final MLGST took 1.9s\n", " \n", "Iterative MLGST Total Time: 8.3s\n", " -- Adding Gauge Optimized (go0) --\n", "--- Re-optimizing logl after robust data scaling ---\n", " --- MLGST ---\n", " Maximum log(L) = 789.179 below upper bound of -2.85002e+07\n", " 2*Delta(log(L)) = 1578.36 (1702 data params - 31 model params = expected mean of 1671; p-value = 0.947548)\n", " Completed in 3.5s\n", " -- Adding Gauge Optimized (go0) --\n" ] } ], "source": [ "gs_target.set_all_parameterizations(\"TP\")\n", "results = pygsti.do_long_sequence_gst(ds, gs_target, fiducials, fiducials,\n", " germs, maxLengths, verbosity=2)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "So, since we have a hunch that the reason for the bad fit is that when \"Gi\" follows \"Gx\" it looks different, we can fit that data to a model that has two identity gates, call them \"Gi\" and \"Gi2\" again, and tell GST to perform the \"GxGi => GxGi2\" manipulation rule before computing the probability of a gate sequence:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- Gate Sequence Creation ---\n", " 1738 sequences created\n", " Dataset has 1702 entries: 1738 utilized, 0 requested sequences were missing\n", "--- LGST ---\n", " Singular values of I_tilde (truncating to first 4 of 6) = \n", " 4.244087195801075\n", " 1.168281483622616\n", " 0.9583432784288527\n", " 0.946089812454173\n", " 0.02268906619381714\n", " 0.008669671149062112\n", " \n", " Singular values of target I_tilde (truncating to first 4 of 6) = \n", " 4.242640687119285\n", " 1.4142135623730954\n", " 1.4142135623730947\n", " 1.4142135623730945\n", " 3.1723744950054595e-16\n", " 1.0852733691121267e-16\n", " \n", "--- Iterative MLGST: Iter 1 of 6 128 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 191.092 (128 data params - 43 model params = expected mean of 85; p-value = 3.89572e-10)\n", " Completed in 0.7s\n", " 2*Delta(log(L)) = 190.747\n", " Iteration 1 took 0.9s\n", " \n", "--- Iterative MLGST: Iter 2 of 6 204 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 443.127 (204 data params - 43 model params = expected mean of 161; p-value = 0)\n", " Completed in 0.6s\n", " 2*Delta(log(L)) = 441.115\n", " Iteration 2 took 1.0s\n", " \n", "--- Iterative MLGST: Iter 3 of 6 486 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 1217.02 (486 data params - 43 model params = expected mean of 443; p-value = 0)\n", " Completed in 1.3s\n", " 2*Delta(log(L)) = 1208.34\n", " Iteration 3 took 2.1s\n", " \n", "--- Iterative MLGST: Iter 4 of 6 898 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 1843.95 (898 data params - 43 model params = expected mean of 855; p-value = 0)\n", " Completed in 1.7s\n", " 2*Delta(log(L)) = 1837.55\n", " Iteration 4 took 2.8s\n", " \n", "--- Iterative MLGST: Iter 5 of 6 1318 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 2350.22 (1318 data params - 43 model params = expected mean of 1275; p-value = 0)\n", " Completed in 2.5s\n", " 2*Delta(log(L)) = 2345.31\n", " Iteration 5 took 4.0s\n", " \n", "--- Iterative MLGST: Iter 6 of 6 1738 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 2781.38 (1738 data params - 43 model params = expected mean of 1695; p-value = 0)\n", " Completed in 2.5s\n", " 2*Delta(log(L)) = 2776.35\n", " Iteration 6 took 4.4s\n", " \n", " Switching to ML objective (last iteration)\n", " --- MLGST ---\n", " Maximum log(L) = 1387.58 below upper bound of -2.90842e+07\n", " 2*Delta(log(L)) = 2775.16 (1738 data params - 43 model params = expected mean of 1695; p-value = 0)\n", " Completed in 4.1s\n", " 2*Delta(log(L)) = 2775.16\n", " Final MLGST took 4.1s\n", " \n", "Iterative MLGST Total Time: 19.4s\n", " -- Adding Gauge Optimized (go0) --\n", "--- Re-optimizing logl after robust data scaling ---\n", " --- MLGST ---\n", " Maximum log(L) = 791.537 below upper bound of -2.90842e+07\n", " 2*Delta(log(L)) = 1583.07 (1738 data params - 43 model params = expected mean of 1695; p-value = 0.9747)\n", " Completed in 4.9s\n", " -- Adding Gauge Optimized (go0) --\n" ] } ], "source": [ "#Create a target gate set which includes a duplicate Gi called Gi2\n", "gs_targetB = gs_target.copy()\n", "gs_targetB['Gi2'] = gs_target['Gi'].copy() # Gi2 should just be another Gi\n", "\n", "#Run GST with:\n", "# 1) replacement rules giving instructions how to process all of the gate sequences\n", "# 2) data set aliases which replace labels in the *processed* strings before querying the DataSet.\n", "rules = [ ((\"Gx\",\"Gi\") , (\"Gx\",\"Gi2\")) ] # a single replacement rule: GxGi => GxGi2 \n", "resultsB = pygsti.do_long_sequence_gst(ds, gs_targetB, fiducials, fiducials,\n", " germs, maxLengths, \n", " advancedOptions={\"gateLabelAliases\": {'Gi2': ('Gi',)},\n", " \"stringManipRules\": rules},\n", " verbosity=2)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "This gives a better fit, but not as good as it should (given that we know the data was generated from exactly the model being used). This is due to the (default) LGST seed being a bad starting point, which can happen, particularly when looking for context dependence. (The LGST estimate - which you can print using `print(resultsB.estimates['default'].gatesets['seed'])` - generates the *same* estimate for Gi and Gi2 which is roughly between the true values of Gi and Gi2, which can be a bad estimate for both gates.) To instead use our own custom guess as the starting point, we do the following:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- Gate Sequence Creation ---\n", " 1738 sequences created\n", " Dataset has 1702 entries: 1738 utilized, 0 requested sequences were missing\n", "--- Iterative MLGST: Iter 1 of 6 128 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 191.092 (128 data params - 43 model params = expected mean of 85; p-value = 3.89571e-10)\n", " Completed in 0.4s\n", " 2*Delta(log(L)) = 190.747\n", " Iteration 1 took 0.5s\n", " \n", "--- Iterative MLGST: Iter 2 of 6 204 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 443.127 (204 data params - 43 model params = expected mean of 161; p-value = 0)\n", " Completed in 0.4s\n", " 2*Delta(log(L)) = 441.115\n", " Iteration 2 took 0.6s\n", " \n", "--- Iterative MLGST: Iter 3 of 6 486 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 1217.02 (486 data params - 43 model params = expected mean of 443; p-value = 0)\n", " Completed in 0.8s\n", " 2*Delta(log(L)) = 1208.34\n", " Iteration 3 took 1.4s\n", " \n", "--- Iterative MLGST: Iter 4 of 6 898 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 1843.95 (898 data params - 43 model params = expected mean of 855; p-value = 0)\n", " Completed in 1.3s\n", " 2*Delta(log(L)) = 1837.55\n", " Iteration 4 took 2.2s\n", " \n", "--- Iterative MLGST: Iter 5 of 6 1318 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 2350.22 (1318 data params - 43 model params = expected mean of 1275; p-value = 0)\n", " Completed in 2.0s\n", " 2*Delta(log(L)) = 2345.31\n", " Iteration 5 took 3.3s\n", " \n", "--- Iterative MLGST: Iter 6 of 6 1738 gate strings ---: \n", " --- Minimum Chi^2 GST ---\n", " Sum of Chi^2 = 2781.38 (1738 data params - 43 model params = expected mean of 1695; p-value = 0)\n", " Completed in 1.9s\n", " 2*Delta(log(L)) = 2776.35\n", " Iteration 6 took 3.4s\n", " \n", " Switching to ML objective (last iteration)\n", " --- MLGST ---\n", " Maximum log(L) = 1387.58 below upper bound of -2.90842e+07\n", " 2*Delta(log(L)) = 2775.16 (1738 data params - 43 model params = expected mean of 1695; p-value = 0)\n", " Completed in 3.1s\n", " 2*Delta(log(L)) = 2775.16\n", " Final MLGST took 3.1s\n", " \n", "Iterative MLGST Total Time: 14.5s\n", " -- Adding Gauge Optimized (go0) --\n", "--- Re-optimizing logl after robust data scaling ---\n", " --- MLGST ---\n", " Maximum log(L) = 791.536 below upper bound of -2.90842e+07\n", " 2*Delta(log(L)) = 1583.07 (1738 data params - 43 model params = expected mean of 1695; p-value = 0.974701)\n", " Completed in 3.7s\n", " -- Adding Gauge Optimized (go0) --\n" ] } ], "source": [ "#Create a guess, which we'll use instead of LGST - here we just\n", "# take a slightly depolarized target.\n", "gs_start = gs_targetB.depolarize(gate_noise=0.01, spam_noise=0.01)\n", "\n", "#Run GST with the replacement rules as before.\n", "resultsC = pygsti.do_long_sequence_gst(ds, gs_targetB, fiducials, fiducials,\n", " germs, maxLengths, \n", " advancedOptions={\"gateLabelAliases\": {'Gi2': ('Gi',)},\n", " \"stringManipRules\": rules,\n", " \"starting point\": gs_start},\n", " verbosity=2)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "This results is a much better fit and estimate, as seen from the final `2*Delta(log(L))` number." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Diff between truth and standard GST: 0.019523448717256444\n", "Diff between truth and context-dep GST w/LGST starting pt: 0.006162275000479365\n", "Diff between truth and context-dep GST w/custom starting pt: 0.0061622943105866254\n" ] } ], "source": [ "gsA = pygsti.gaugeopt_to_target(results.estimates['default'].gatesets['final iteration estimate'], gs_datagen)\n", "gsB = pygsti.gaugeopt_to_target(resultsB.estimates['default'].gatesets['final iteration estimate'], gs_datagen)\n", "gsC = pygsti.gaugeopt_to_target(resultsC.estimates['default'].gatesets['final iteration estimate'], gs_datagen)\n", "gsA['Gi2'] = gsA['Gi'] #so gsA is comparable with gs_datagen\n", "print(\"Diff between truth and standard GST: \", gs_datagen.frobeniusdist(gsA))\n", "print(\"Diff between truth and context-dep GST w/LGST starting pt: \", gs_datagen.frobeniusdist(gsB))\n", "print(\"Diff between truth and context-dep GST w/custom starting pt: \", gs_datagen.frobeniusdist(gsC))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "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.5.2" } }, "nbformat": 4, "nbformat_minor": 2 }