Workspace
object¶PyGSTi's Workspace
object is first a foremost a container and factory for plots and tables. At the most basic level, it can be used to generate nice output based on quantities (e.g. GateSets, DataSets, etc.) that you've computed or loaded within a notebook. For this, it's useful to call init_notebook_mode
with autodisplay=True
(see below) so that you don't have to .display()
everything - display()
gets called automatically when a plot or table is created.
First, let's run GST on the standard 1Q gate set to get some results to play with.
import numpy as np
import pygsti
from pygsti.construction import std1Q_XYI
#The usual GST setup: we're going to run GST on the standard XYI 1-qubit gateset
gs_target = std1Q_XYI.gs_target
fiducials = std1Q_XYI.fiducials
germs = std1Q_XYI.germs
maxLengths = [1,2]
listOfExperiments = pygsti.construction.make_lsgst_experiment_list(
gs_target.gates.keys(), fiducials, fiducials, germs, maxLengths)
#Create some datasets for analysis
gs_datagen1 = gs_target.depolarize(gate_noise=0.1, spam_noise=0.02)
gs_datagen2 = gs_target.depolarize(gate_noise=0.05, spam_noise=0.01).rotate(rotate=(0.01,0.01,0.01))
ds1 = pygsti.construction.generate_fake_data(gs_datagen1, listOfExperiments, nSamples=1000,
sampleError="binomial", seed=1234)
ds2 = pygsti.construction.generate_fake_data(gs_datagen2, listOfExperiments, nSamples=1000,
sampleError="binomial", seed=1234)
ds3 = ds1.copy_nonstatic(); ds3.add_counts_from_dataset(ds2); ds3.done_adding_data()
#Run GST on all three datasets
gs_target.set_all_parameterizations("TP")
results1 = pygsti.do_long_sequence_gst(ds1, gs_target, fiducials, fiducials, germs, maxLengths, verbosity=0)
results2 = pygsti.do_long_sequence_gst(ds2, gs_target, fiducials, fiducials, germs, maxLengths, verbosity=0)
results3 = pygsti.do_long_sequence_gst(ds3, gs_target, fiducials, fiducials, germs, maxLengths, verbosity=0)
#make some shorthand variable names for later
tgt = results1.estimates['default'].gatesets['target']
ds1 = results1.dataset
ds2 = results2.dataset
ds3 = results3.dataset
gs1 = results1.estimates['default'].gatesets['go0']
gs2 = results2.estimates['default'].gatesets['go0']
gs3 = results3.estimates['default'].gatesets['go0']
gss = results1.gatestring_structs['final']
Workspace
and make some plots and tables.¶To get tables and plots to display properly, one must run init_notebook_mode
. The connected
argument indicates whether you want to rely on an active internet connection. If True
, then resources will be loaded from the web (e.g. a CDN), and if you save a notebook as HTML the file size may be smaller. If False
, then all the needed resources (except MathJax) are provided by pyGSTi, and an offline
directory is automatically created in the same directory as your notebook. This directory contains all the necessary resources, and must "tag along" with the notebook and any saved-as-HTML versions of it in order for everything to work. The second argument, autodisplay
, determines whether tables and plots are automatically displayed when they are created. If autodisplay=False
, one must call the display()
member function of a table or plot to display it.
from pygsti.report import workspace
w = workspace.Workspace()
w.init_notebook_mode(connected=False, autodisplay=True)
Plots and tables are created via member functions of a Workspace
(w
in our case). Note that you can start typing "w.
" and TAB-complete to see the different things a Workspace
can make for you. Furthermore, pressing SHIFT-TAB after the opening parenthesis of a function, e.g. after typing "w.GatesVsTargetTable(
", will bring up Jupyter's help window showing you the function signature (the arguments you need to give the function).
Note that displayed objects have a resize handle in their lower right corner.
w.ColorBoxPlot(("logl",), gss, ds1, gs1, typ='scatter')
w.ColorBoxPlot(("logl",), gss, ds1, gs1, typ='boxes')
w.ColorBoxPlot(("logl",), gss, ds1, gs1, typ='histogram')
<pygsti.report.workspaceplots.ColorBoxPlot at 0x10ea8edd8>
w.FitComparisonBarPlot(gss.Ls, results1.gatestring_structs['iteration'],
results1.estimates['default'].gatesets['iteration estimates'], ds1)
<pygsti.report.workspaceplots.FitComparisonBarPlot at 0x10d487978>
w.GramMatrixBarPlot(ds1,tgt)
<pygsti.report.workspaceplots.GramMatrixBarPlot at 0x10d4879b0>
w.GatesVsTargetTable(gs1, tgt)
Gate | Entanglement Infidelity | Avg. Gate Infidelity | 1/2 Trace Distance | 1/2 Diamond-Dist | Non-unitary Ent. Infidelity | Non-unitary Avg. Gate Infidelity |
---|---|---|---|---|---|---|
Gi | 0.074748 | 0.049832 | 0.076617 | 0.07684 | 0.074477 | 0.049652 |
Gx | 0.077108 | 0.051405 | 0.077591 | 0.077595 | 0.077018 | 0.051345 |
Gy | 0.075148 | 0.050098 | 0.075248 | 0.075267 | 0.07511 | 0.050073 |
<pygsti.report.workspacetables.GatesVsTargetTable at 0x10d487a20>
w.SpamVsTargetTable(gs2, tgt)
Prep/POVM | Infidelity | 1/2 Trace Distance | 1/2 Diamond-Dist |
---|---|---|---|
ρ0 | 0.042312 | 0.043714 | -- |
Mdefault | -0.04156 | 0.042419 | 0.043467 |
<pygsti.report.workspacetables.SpamVsTargetTable at 0x10f3ae9b0>
w.ColorBoxPlot(("chi2","logl"), gss, ds1, gs1, boxLabels=True)
#Notice how long it takes to switch between "chi2" and "logl". This
# is due to drawing all of the box labels (boxLabels=True).
<pygsti.report.workspaceplots.ColorBoxPlot at 0x10f439f98>
#This one requires knowng that each Results object holds a list of gatesets
# from each GST intation along with the corresponding gate strings that were used.
w.FitComparisonTable(gss.Ls, results1.gatestring_structs['iteration'],
results1.estimates['default'].gatesets['iteration estimates'], ds1)
L | 2Δ(log L) | k | 2Δ(log L)-k | √2k | Nsigma | Ns | Np | Rating |
---|---|---|---|---|---|---|---|---|
1 | 80.98834 | 61 | 19.98834 | 11.04536 | 1.81 | 92 | 31 | ★★★★★ |
2 | 166.8526 | 137 | 29.85256 | 16.55295 | 1.8 | 168 | 31 | ★★★★★ |
<pygsti.report.workspacetables.FitComparisonTable at 0x10f62f7b8>
# We can reuse 'gss' for all three since the gate sequences are the same.
w.FitComparisonTable(["GS1","GS2","GS3"], [gss, gss, gss], [gs1,gs2,gs3], ds1, Xlabel="GateSet")
GateSet | 2Δ(log L) | k | 2Δ(log L)-k | √2k | Nsigma | Ns | Np | Rating |
---|---|---|---|---|---|---|---|---|
GS1 | 166.8526 | 137 | 29.85256 | 16.55295 | 1.8 | 168 | 31 | ★★★★★ |
GS2 | 4088.064 | 137 | 3951.064 | 16.55295 | 2×102 | 168 | 31 | ★★ |
GS3 | 1006.891 | 137 | 869.8905 | 16.55295 | 52.6 | 168 | 31 | ★★★ |
<pygsti.report.workspacetables.FitComparisonTable at 0x10f956860>
w.ChoiTable(gs3, display=('matrix','barplot'))
Gate | Choi matrix (Pauli-Product basis) | Eigenvalue Magnitudes |
---|---|---|
Gi | $ \begin{pmatrix} 0.944851 & 0.010383e^{i0.450\pi} & 0.007336e^{i0.464\pi} & 0.001242e^{i0.710\pi} \\ 0.010383e^{-i0.450\pi} & 0.015242 & 0.003872e^{i0.063\pi} & 0.001952e^{i0.138\pi} \\ 0.007336e^{-i0.464\pi} & 0.003872e^{-i0.063\pi} & 0.020849 & 0.001798e^{-i0.639\pi} \\ 0.001242e^{-i0.710\pi} & 0.001952e^{-i0.138\pi} & 0.001798e^{i0.639\pi} & 0.019058 \end{pmatrix} $ | |
Gx | $ \begin{pmatrix} 0.482477 & 0.462924e^{i0.501\pi} & 0.00285e^{i0.508\pi} & 0.000055e^{i0.786\pi} \\ 0.462924e^{-i0.501\pi} & 0.480083 & 0.002985e^{i0.005\pi} & 0.000079e^{-i0.643\pi} \\ 0.00285e^{-i0.508\pi} & 0.002985e^{-i0.005\pi} & 0.019276 & 0.001123e^{i0.486\pi} \\ 0.000055e^{-i0.786\pi} & 0.000079e^{i0.643\pi} & 0.001123e^{-i0.486\pi} & 0.018164 \end{pmatrix} $ | |
Gy | $ \begin{pmatrix} 0.480739 & 0.002381e^{i0.514\pi} & 0.463008e^{i0.500\pi} & 0.00008e^{-i0.107\pi} \\ 0.002381e^{-i0.514\pi} & 0.017701 & 0.003456e^{-i0.007\pi} & 0.000538e^{-i0.531\pi} \\ 0.463008e^{-i0.500\pi} & 0.003456e^{i0.007\pi} & 0.484353 & 0.000107e^{i0.420\pi} \\ 0.00008e^{i0.107\pi} & 0.000538e^{i0.531\pi} & 0.000107e^{-i0.420\pi} & 0.017208 \end{pmatrix} $ |
<pygsti.report.workspacetables.ChoiTable at 0x10f62f6a0>
w.GateMatrixPlot(gs1['Gx'],scale=1.0, boxLabels=True,ylabel="hello")
w.GateMatrixPlot(pygsti.tools.error_generator(gs1['Gx'], tgt['Gx'], 'pp'), scale=1.5)
<pygsti.report.workspaceplots.GateMatrixPlot at 0x110c050b8>
from pygsti.construction import std2Q_XYCNOT
w.GateMatrixPlot(std2Q_XYCNOT.gs_target['Gxi'],scale=1.0, boxLabels=False,ylabel="hello",mxBasis="pp")
<pygsti.report.workspaceplots.GateMatrixPlot at 0x110c00ba8>
mx = np.array(
[[ 7.3380823, 8.28446943, 7.4593754, 3.91256384, 0.68631199],
[ 3.36139818, 7.42955114, 6.78516082, 0.35863173, 5.57713093],
[ 2.61489939, 3.40182958, 6.77389064, 9.29736475, 0.33824271],
[ 9.64258149, 9.45928809, 6.91516602, 5.61423854, 0.56480777],
[ 2.15195669, 9.37588783, 5.1781991, 7.20087591, 1.46096288]], 'd')
cMap = pygsti.report.colormaps.LinlogColormap(vmin=0, vmax=10, n_boxes=25, pcntle=0.55, dof_per_box=1, color='blue')
w.MatrixPlot(mx, colormap=cMap, colorbar=False)
<pygsti.report.workspaceplots.MatrixPlot at 0x112017128>
mx = np.identity(3,'d')
mx[0,1] = 2.1
mx[2,2] = 4.0
mx[2,0] = 3.0
mx[0,2] = 7.0
mx[2,1] = 10.0
mx[0,0] = np.nan
cMap = pygsti.report.colormaps.PiecewiseLinearColormap(
[[0,(0,0.5,0)],[1,(0,1.0,0)],[2,(1.0,1.0,0)],
[4,(1.0,0.5,0)],[10,(1.0,0,0)]])
#print(cMap.get_colorscale())
w.MatrixPlot(mx, colormap=cMap, colorbar=False, grid="white:1", boxLabels=True, prec=2,
xlabels=('TP',"CPTP","full"),ylabels=("DS0","DS1","DS2"))
<pygsti.report.workspaceplots.MatrixPlot at 0x112096550>
w.ErrgenTable(gs3,tgt)
Gate | Error Generator | Pauli Hamiltonian Projections | Pauli Stochastic Projections | Pauli Affine Projections |
---|---|---|---|---|
Gi | ||||
Gx | ||||
Gy |
<pygsti.report.workspacetables.ErrgenTable at 0x110c00e10>
w.PolarEigenvaluePlot([np.linalg.eigvals(gs2['Gx'])],["purple"],scale=1.5)
<pygsti.report.workspaceplots.PolarEigenvaluePlot at 0x110e37cf8>
w.GateEigenvalueTable(gs2, display=('evals','polar'))
Gate | Eigenvalues ($E$) | Eigenvalues |
---|---|---|
Gi | $ \begin{pmatrix} 1 \\ 0.955547 \\ 0.94681e^{i0.008\pi} \\ 0.94681e^{-i0.008\pi} \end{pmatrix} $ | |
Gx | $ \begin{pmatrix} 1 \\ 0.95118 \\ 0.949197e^{i0.502\pi} \\ 0.949197e^{-i0.502\pi} \end{pmatrix} $ | |
Gy | $ \begin{pmatrix} 1 \\ 0.957594 \\ 0.948507e^{i0.502\pi} \\ 0.948507e^{-i0.502\pi} \end{pmatrix} $ |
<pygsti.report.workspacetables.GateEigenvalueTable at 0x110bc3f60>
w.GateDecompTable(gs1,gs_target)
#w.old_GateDecompTable(gs1) #historical; 1Q only
Gate | Ham. Evals. | Rotn. angle | Rotn. axis | Log Error | Axis angle w/Gi | Axis angle w/Gx | Axis angle w/Gy |
---|---|---|---|---|---|---|---|
Gi | $ \begin{pmatrix} -0.004833 \\ 0.004833 \end{pmatrix} $ π | 0.009667π | 0 | 0.285541π | 0.222932π | ||
Gx | $ \begin{pmatrix} -0.24771 \\ 0.24771 \end{pmatrix} $ π | 0.495421π | 0 | 0.285541π | 0.496963π | ||
Gy | $ \begin{pmatrix} -0.25023 \\ 0.25023 \end{pmatrix} $ π | 0.500461π | 0 | 0.222932π | 0.496963π |
<pygsti.report.workspacetables.GateDecompTable at 0x110bc34a8>
#Note 2Q angle decompositions
from pygsti.construction import std2Q_XXYYII
from pygsti.construction import std2Q_XYCNOT
w.GateDecompTable(std2Q_XXYYII.gs_target, std2Q_XXYYII.gs_target)
import scipy
I = np.array([[1,0],[0,1]],'complex')
X = np.array([[0,1],[1,0]],'complex')
Y = np.array([[0,1j],[-1j,0]],'complex')
XX = np.kron(X,X)
YY = np.kron(Y,Y)
IX = np.kron(I,X)
XI = np.kron(X,I)
testU = scipy.linalg.expm(-1j*np.pi/2*XX)
testS = pygsti.unitary_to_process_mx(testU)
testS = pygsti.change_basis(testS,"std","pp")
std2Q_XYCNOT.gs_target.gates['Gtest'] = testS
w.GateDecompTable(std2Q_XYCNOT.gs_target, std2Q_XYCNOT.gs_target)
Gate | Ham. Evals. | Rotn. angle | Rotn. axis | Log Error | Axis angle w/Gii | Axis angle w/Gix | Axis angle w/Giy | Axis angle w/Gxi | Axis angle w/Gyi | Axis angle w/Gxx | Axis angle w/Gyy | Axis angle w/Gxy | Axis angle w/Gyx |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Gii | $ \begin{pmatrix} 0 \\ 0 \\ 0 \\ 0 \end{pmatrix} $ π | 0π | 0 | -- | -- | -- | -- | -- | -- | -- | -- | ||
Gix | $ \begin{pmatrix} 0.25 \\ -0.25 \\ 0.25 \\ -0.25 \end{pmatrix} $ π | 0.5π | 0 | -- | 0.5π | 0.5π | 0.5π | 0.25π | 0.499996π | 0.499993π | 0.25π | ||
Giy | $ \begin{pmatrix} -0.25 \\ 0.25 \\ -0.25 \\ 0.25 \end{pmatrix} $ π | 0.5π | 0 | -- | 0.5π | 0.5π | 0.5π | 0.5π | 0.25π | 0.25π | 0.500006π | ||
Gxi | $ \begin{pmatrix} -0.25 \\ 0.25 \\ -0.25 \\ 0.25 \end{pmatrix} $ π | 0.5π | 0 | -- | 0.5π | 0.5π | 0.5π | 0.25π | 0.499996π | 0.25π | 0.499993π | ||
Gyi | $ \begin{pmatrix} 0.25 \\ -0.25 \\ 0.25 \\ -0.25 \end{pmatrix} $ π | 0.5π | 0 | -- | 0.5π | 0.5π | 0.5π | 0.5π | 0.25π | 0.499996π | 0.25π | ||
Gxx | $ \begin{pmatrix} -0.500016 \\ 0.500017 \\ -0.000001 \\ 0 \end{pmatrix} $ π | 0.707131π | 0.002766 | -- | 0.25π | 0.5π | 0.25π | 0.5π | 0.499995π | 0.333328π | 0.333328π | ||
Gyy | $ \begin{pmatrix} -0.499994 \\ 0.499997 \\ -0.000002 \\ 0 \end{pmatrix} $ π | 0.7071π | 0.007928 | -- | 0.499996π | 0.25π | 0.499996π | 0.25π | 0.499995π | 0.333327π | 0.333335π | ||
Gxy | $ \begin{pmatrix} 0.499982 \\ -0.499982 \\ 0 \\ 3\times 10^{-7} \end{pmatrix} $ π | 0.707082π | 0.002956 | -- | 0.499993π | 0.25π | 0.25π | 0.499996π | 0.333328π | 0.333327π | 0.499991π | ||
Gyx | $ \begin{pmatrix} 0.499976 \\ -0.499975 \\ -0.000001 \\ 0 \end{pmatrix} $ π | 0.707072π | 0.003983 | -- | 0.25π | 0.500006π | 0.499993π | 0.25π | 0.333328π | 0.333335π | 0.499991π |
Gate | Ham. Evals. | Rotn. angle | Rotn. axis | Log Error | Axis angle w/Gix | Axis angle w/Giy | Axis angle w/Gxi | Axis angle w/Gyi | Axis angle w/Gcnot | Axis angle w/Gtest |
---|---|---|---|---|---|---|---|---|---|---|
Gix | $ \begin{pmatrix} 0.25 \\ -0.25 \\ 0.25 \\ -0.25 \end{pmatrix} $ π | 0.5π | 0 | 0.5π | 0.5π | 0.5π | 0.304092π | 0.5π | ||
Giy | $ \begin{pmatrix} -0.25 \\ 0.25 \\ -0.25 \\ 0.25 \end{pmatrix} $ π | 0.5π | 0 | 0.5π | 0.5π | 0.5π | 0.499999π | 0.500001π | ||
Gxi | $ \begin{pmatrix} -0.25 \\ 0.25 \\ -0.25 \\ 0.25 \end{pmatrix} $ π | 0.5π | 0 | 0.5π | 0.5π | 0.5π | 0.500001π | 0.499999π | ||
Gyi | $ \begin{pmatrix} 0.25 \\ -0.25 \\ 0.25 \\ -0.25 \end{pmatrix} $ π | 0.5π | 0 | 0.5π | 0.5π | 0.5π | 0.500001π | 0.499999π | ||
Gcnot | $ \begin{pmatrix} -0.749999 \\ 0.249988 \\ 0.250011 \\ 0.25 \end{pmatrix} $ π | 0.866024π | 0.004202 | 0.304092π | 0.499999π | 0.500001π | 0.500001π | 0.5π | ||
Gtest | $ \begin{pmatrix} -0.499977 \\ -0.499972 \\ 0.499979 \\ 0.499971 \end{pmatrix} $ π | 0.999949π | 0.000936 | 0.5π | 0.500001π | 0.499999π | 0.499999π | 0.5π |
<pygsti.report.workspacetables.GateDecompTable at 0x10655ae80>
dsLabels = ["A","B","C"]
datasets = [ds1, ds2, ds3]
dscmps = {}
for i,ds1 in enumerate(datasets):
for j,ds2 in enumerate(datasets[i+1:],start=i+1):
dscmps[(i,j)] = pygsti.objects.DataComparator([datasets[i],datasets[j]])
w.DatasetComparisonSummaryPlot(dsLabels, dscmps)
<pygsti.report.workspaceplots.DatasetComparisonSummaryPlot at 0x110767630>
w.DatasetComparisonHistogramPlot(dscmps[(1,2)])
<pygsti.report.workspaceplots.DatasetComparisonHistogramPlot at 0x110760a58>
You can also save plot and figures to separate files using their saveas
method. The output format is determined by the file extension, and allowed extensions are:
DataFrame
for tables, a dict for plots)obj = w.GatesVsTargetTable(gs1, tgt)
#obj = w.ErrgenTable(gs3,tgt)
#obj = w.ColorBoxPlot(("logl",), gss, ds1, gs1, typ='boxes')
obj.saveas("tutorial_files/tempTest/testSave.pdf")
obj.saveas("tutorial_files/tempTest/testSave.tex")
obj.saveas("tutorial_files/tempTest/testSave.pkl")
obj.saveas("tutorial_files/tempTest/testSave.html")
Gate | Entanglement Infidelity | Avg. Gate Infidelity | 1/2 Trace Distance | 1/2 Diamond-Dist | Non-unitary Ent. Infidelity | Non-unitary Avg. Gate Infidelity |
---|---|---|---|---|---|---|
Gi | 0.074748 | 0.049832 | 0.076617 | 0.07684 | 0.074477 | 0.049652 |
Gx | 0.077108 | 0.051405 | 0.077591 | 0.077595 | 0.077018 | 0.051345 |
Gy | 0.075148 | 0.050098 | 0.075248 | 0.075267 | 0.07511 | 0.050073 |
If you want, you can save this notebook as an HTML file by going to File => Download As => HTML in the Jupyter menu. The resulting file will retain all of the plot interactivity, so long as its in a directory with an offline
folder (because we set connected=False
above).