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 0x10bccc748>
w.FitComparisonBarPlot(gss.Ls, results1.gatestring_structs['iteration'],
results1.estimates['default'].gatesets['iteration estimates'], ds1)
<pygsti.report.workspaceplots.FitComparisonBarPlot at 0x10c3fc710>
w.GramMatrixBarPlot(ds1,tgt)
<pygsti.report.workspaceplots.GramMatrixBarPlot at 0x10c3fc400>
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.073677 | 0.049118 | 0.076347 | 0.076544 | 0.073344 | 0.048896 |
Gx | 0.077153 | 0.051435 | 0.077337 | 0.077362 | 0.077119 | 0.051413 |
Gy | 0.074562 | 0.049708 | 0.074687 | 0.07471 | 0.07454 | 0.049693 |
<pygsti.report.workspacetables.GatesVsTargetTable at 0x10c3fc828>
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 0x10c3fca90>
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 0x10c04c048>
#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 | 85.32401 | 61 | 24.32401 | 11.04536 | 2.2 | 92 | 31 | ★★★★ |
2 | 174.8544 | 137 | 37.8544 | 16.55295 | 2.29 | 168 | 31 | ★★★★ |
<pygsti.report.workspacetables.FitComparisonTable at 0x10bd46358>
# 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 | 174.8544 | 137 | 37.8544 | 16.55295 | 2.29 | 168 | 31 | ★★★★ |
GS2 | 4080.239 | 137 | 3943.239 | 16.55295 | 2×102 | 168 | 31 | ★★ |
GS3 | 1011.162 | 137 | 874.1619 | 16.55295 | 52.8 | 168 | 31 | ★★★ |
<pygsti.report.workspacetables.FitComparisonTable at 0x10bca0f28>
w.ChoiTable(gs3, display=('matrix','barplot'))
Gate | Choi matrix (Pauli-Product basis) | Eigenvalue Magnitudes |
---|---|---|
Gi | $ \begin{pmatrix} 0.945288 & 0.010275e^{i0.457\pi} & 0.008389e^{i0.461\pi} & 0.003784e^{i0.585\pi} \\ 0.010275e^{-i0.457\pi} & 0.015084 & 0.00101e^{i0.446\pi} & 0.00151e^{i0.239\pi} \\ 0.008389e^{-i0.461\pi} & 0.00101e^{-i0.446\pi} & 0.020759 & 0.001615e^{-i0.671\pi} \\ 0.003784e^{-i0.585\pi} & 0.00151e^{-i0.239\pi} & 0.001615e^{i0.671\pi} & 0.018868 \end{pmatrix} $ | |
Gx | $ \begin{pmatrix} 0.481096 & 0.462824e^{i0.501\pi} & 0.000737e^{i0.583\pi} & 0.000757e^{i0.540\pi} \\ 0.462824e^{-i0.501\pi} & 0.481492 & 0.001962e^{i0.015\pi} & 0.000775e^{-i0.922\pi} \\ 0.000737e^{-i0.583\pi} & 0.001962e^{-i0.015\pi} & 0.017386 & 0.00086e^{i0.479\pi} \\ 0.000757e^{-i0.540\pi} & 0.000775e^{i0.922\pi} & 0.00086e^{-i0.479\pi} & 0.020027 \end{pmatrix} $ | |
Gy | $ \begin{pmatrix} 0.480139 & 0.002583e^{i0.523\pi} & 0.463077e^{i0.500\pi} & 0.000684e^{i0.419\pi} \\ 0.002583e^{-i0.523\pi} & 0.017842 & 0.000197e^{-i0.340\pi} & 0.000052e^{i0.742\pi} \\ 0.463077e^{-i0.500\pi} & 0.000197e^{i0.340\pi} & 0.485588 & 0.000687e^{i0.914\pi} \\ 0.000684e^{-i0.419\pi} & 0.000052e^{-i0.742\pi} & 0.000687e^{-i0.914\pi} & 0.016431 \end{pmatrix} $ |
<pygsti.report.workspacetables.ChoiTable at 0x10c3fc978>
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 0x10b4235c0>
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 0x10b425668>
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 0x10b473ef0>
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 0x10b489eb8>
w.ErrgenTable(gs3,tgt)
Gate | Error Generator | Pauli Hamiltonian Projections | Pauli Stochastic Projections | Pauli Affine Projections |
---|---|---|---|---|
Gi | ||||
Gx | ||||
Gy |
<pygsti.report.workspacetables.ErrgenTable at 0x10b43ac18>
w.PolarEigenvaluePlot([np.linalg.eigvals(gs2['Gx'])],["purple"],scale=1.5)
<pygsti.report.workspaceplots.PolarEigenvaluePlot at 0x10b425400>
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 0x10bd46c50>
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.005597 \\ -0.005597 \end{pmatrix} $ π | 0.011194π | 0 | 0.323973π | 0.193153π | ||
Gx | $ \begin{pmatrix} 0.248752 \\ -0.248752 \end{pmatrix} $ π | 0.497505π | 0 | 0.323973π | 0.502221π | ||
Gy | $ \begin{pmatrix} -0.250936 \\ 0.250936 \end{pmatrix} $ π | 0.501872π | 0 | 0.193153π | 0.502221π |
<pygsti.report.workspacetables.GateDecompTable at 0x10bd46a58>
#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 0x10e2bd5f8>
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 0x10c0296d8>
w.DatasetComparisonHistogramPlot(dscmps[(1,2)])
<pygsti.report.workspaceplots.DatasetComparisonHistogramPlot at 0x10b473dd8>
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.073677 | 0.049118 | 0.076347 | 0.076544 | 0.073344 | 0.048896 |
Gx | 0.077153 | 0.051435 | 0.077337 | 0.077362 | 0.077119 | 0.051413 |
Gy | 0.074562 | 0.049708 | 0.074687 | 0.07471 | 0.07454 | 0.049693 |
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).