Workspace
¶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. Model
, DataSet
, etc. objects) 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 Gate Set Tomography (GST) on the standard 1-qubit model to get some results to play with. We generate a few DataSet
objects and then call do_long_sequence_gst
to run GST, generating a Results
object (essentially a container for Model
objects). For more details, see the tutorials GST overview tutorial, the tutorial on GST functions, and the tutorial explaining the Results object.
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 model
target_model = std1Q_XYI.target_model()
fiducials = std1Q_XYI.fiducials
germs = std1Q_XYI.germs
maxLengths = [1,2]
listOfExperiments = pygsti.construction.make_lsgst_experiment_list(
target_model.operations.keys(), fiducials, fiducials, germs, maxLengths)
#Create some datasets for analysis
mdl_datagen1 = target_model.depolarize(op_noise=0.1, spam_noise=0.02)
mdl_datagen2 = target_model.depolarize(op_noise=0.05, spam_noise=0.01).rotate(rotate=(0.01,0.01,0.01))
ds1 = pygsti.construction.generate_fake_data(mdl_datagen1, listOfExperiments, nSamples=1000,
sampleError="binomial", seed=1234)
ds2 = pygsti.construction.generate_fake_data(mdl_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
target_model.set_all_parameterizations("TP")
results1 = pygsti.do_long_sequence_gst(ds1, target_model, fiducials, fiducials, germs, maxLengths, verbosity=0)
results2 = pygsti.do_long_sequence_gst(ds2, target_model, fiducials, fiducials, germs, maxLengths, verbosity=0)
results3 = pygsti.do_long_sequence_gst(ds3, target_model, fiducials, fiducials, germs, maxLengths, verbosity=0)
#make some shorthand variable names for later
tgt = results1.estimates['default'].models['target']
ds1 = results1.dataset
ds2 = results2.dataset
ds3 = results3.dataset
mdl1 = results1.estimates['default'].models['go0']
mdl2 = results2.estimates['default'].models['go0']
mdl3 = results3.estimates['default'].models['go0']
gss = results1.circuit_structs['final']
Workspace
plots and tables.¶Now that we have some results, let's create a 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, mdl1, typ='scatter')
w.ColorBoxPlot(("logl",), gss, ds1, mdl1, typ='boxes')
w.ColorBoxPlot(("logl",), gss, ds1, mdl1, typ='histogram')
<pygsti.report.workspaceplots.ColorBoxPlot at 0x124a9fa58>
w.FitComparisonBarPlot(gss.Ls, results1.circuit_structs['iteration'],
results1.estimates['default'].models['iteration estimates'], ds1)
<pygsti.report.workspaceplots.FitComparisonBarPlot at 0x12352c9b0>
w.GramMatrixBarPlot(ds1,tgt)
<pygsti.report.workspaceplots.GramMatrixBarPlot at 0x12352c898>
w.GatesVsTargetTable(mdl1, 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.074335 | 0.049557 | 0.076094 | 0.07636 | 0.074098 | 0.049398 |
Gx | 0.076404 | 0.050936 | 0.076851 | 0.076926 | 0.076341 | 0.050894 |
Gy | 0.075533 | 0.050356 | 0.075764 | 0.075785 | 0.0755 | 0.050334 |
<pygsti.report.workspacetables.GatesVsTargetTable at 0x12551aba8>
w.SpamVsTargetTable(mdl2, 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 0x12551ab38>
w.ColorBoxPlot(("chi2","logl"), gss, ds1, mdl1, 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 0x12555d978>
#This one requires knowng that each Results object holds a list of models
# from each GST intation along with the corresponding operation sequences that were used.
w.FitComparisonTable(gss.Ls, results1.circuit_structs['iteration'],
results1.estimates['default'].models['iteration estimates'], ds1)
L | 2Δ(log L) | k | 2Δ(log L)-k | √2k | Nsigma | Ns | Np | Rating |
---|---|---|---|---|---|---|---|---|
1 | 81.29383 | 61 | 20.29383 | 11.04536 | 1.84 | 92 | 31 | ★★★★★ |
2 | 168.6496 | 137 | 31.6496 | 16.55295 | 1.91 | 168 | 31 | ★★★★★ |
<pygsti.report.workspacetables.FitComparisonTable at 0x127f8c860>
# We can reuse 'gss' for all three since the operation sequences are the same.
w.FitComparisonTable(["GS1","GS2","GS3"], [gss, gss, gss], [mdl1,mdl2,mdl3], ds1, Xlabel="Model")
Model | 2Δ(log L) | k | 2Δ(log L)-k | √2k | Nsigma | Ns | Np | Rating |
---|---|---|---|---|---|---|---|---|
GS1 | 168.6496 | 137 | 31.6496 | 16.55295 | 1.91 | 168 | 31 | ★★★★★ |
GS2 | 4061.611 | 137 | 3924.611 | 16.55295 | 2×102 | 168 | 31 | ★★ |
GS3 | 1002.246 | 137 | 865.2464 | 16.55295 | 52.3 | 168 | 31 | ★★★ |
<pygsti.report.workspacetables.FitComparisonTable at 0x127100278>
w.ChoiTable(mdl3, display=('matrix','barplot'))
Gate | Choi matrix (Pauli-Product basis basis) | Eigenvalue Magnitudes |
---|---|---|
Gi | $ \begin{pmatrix} 0.945004 & 0.009417e^{i0.444\pi} & 0.006951e^{i0.454\pi} & 0.001022e^{-i0.776\pi} \\ 0.009417e^{-i0.444\pi} & 0.015282 & 0.003276e^{i0.076\pi} & 0.002139e^{i0.155\pi} \\ 0.006951e^{-i0.454\pi} & 0.003276e^{-i0.076\pi} & 0.020808 & 0.001819e^{-i0.644\pi} \\ 0.001022e^{i0.776\pi} & 0.002139e^{-i0.155\pi} & 0.001819e^{i0.644\pi} & 0.018906 \end{pmatrix} $ | |
Gx | $ \begin{pmatrix} 0.482049 & 0.462895e^{i0.501\pi} & 0.002898e^{i0.512\pi} & 0.000548e^{-i0.538\pi} \\ 0.462895e^{-i0.501\pi} & 0.481094 & 0.004182e^{i0.005\pi} & 0.000556e^{-i0.065\pi} \\ 0.002898e^{-i0.512\pi} & 0.004182e^{-i0.005\pi} & 0.018149 & 0.00183e^{i0.502\pi} \\ 0.000548e^{i0.538\pi} & 0.000556e^{i0.065\pi} & 0.00183e^{-i0.502\pi} & 0.018709 \end{pmatrix} $ | |
Gy | $ \begin{pmatrix} 0.481416 & 0.003826e^{i0.509\pi} & 0.462881e^{i0.500\pi} & 0.00059e^{-i0.430\pi} \\ 0.003826e^{-i0.509\pi} & 0.018169 & 0.003254e^{-i0.013\pi} & 0.000502e^{-i0.573\pi} \\ 0.462881e^{-i0.500\pi} & 0.003254e^{i0.013\pi} & 0.483841 & 0.000585e^{i0.057\pi} \\ 0.00059e^{i0.430\pi} & 0.000502e^{i0.573\pi} & 0.000585e^{-i0.057\pi} & 0.016574 \end{pmatrix} $ |
<pygsti.report.workspacetables.ChoiTable at 0x127f8c550>
w.GateMatrixPlot(mdl1['Gx'],scale=1.0, boxLabels=True,ylabel="hello")
w.GateMatrixPlot(pygsti.tools.error_generator(mdl1['Gx'], tgt['Gx'], 'pp'), scale=1.5)
<pygsti.report.workspaceplots.GateMatrixPlot at 0x127c3b0b8>
from pygsti.construction import std2Q_XYCNOT
w.GateMatrixPlot(std2Q_XYCNOT.target_model()['Gxi'],scale=1.0, boxLabels=False,ylabel="hello",mxBasis="pp")
<pygsti.report.workspaceplots.GateMatrixPlot at 0x12772bb38>
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 0x126acc668>
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 0x12722f320>
w.ErrgenTable(mdl3,tgt)
Gate | Error Generator | Pauli Hamiltonian Projections | Pauli Stochastic Projections | Pauli Affine Projections |
---|---|---|---|---|
Gi | ||||
Gx | ||||
Gy |
<pygsti.report.workspacetables.ErrgenTable at 0x12352c4e0>
w.PolarEigenvaluePlot([np.linalg.eigvals(mdl2['Gx'])],["purple"],scale=1.5)
<pygsti.report.workspaceplots.PolarEigenvaluePlot at 0x1296d49e8>
w.GateEigenvalueTable(mdl2, 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 0x1296d4b70>
w.GateDecompTable(mdl1,target_model)
#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.006533 \\ 0.006533 \end{pmatrix} $ π | 0.00924π | 0 | 0.331649π | 0.242237π | ||
Gx | $ \begin{pmatrix} -0.351156 \\ 0.351156 \end{pmatrix} $ π | 0.496609π | 0 | 0.331649π | 0.495319π | ||
Gy | $ \begin{pmatrix} -0.353186 \\ 0.353186 \end{pmatrix} $ π | 0.49948π | 0 | 0.242237π | 0.495319π |
<pygsti.report.workspacetables.GateDecompTable at 0x1296d4550>
# import importlib
# importlib.reload(pygsti.report.workspace)
# importlib.reload(pygsti.report.workspaceplots)
# importlib.reload(pygsti.report.workspacetables)
#Note 2Q angle decompositions
from pygsti.construction import std2Q_XXYYII
from pygsti.construction import std2Q_XYCNOT
w.GateDecompTable(std2Q_XXYYII.target_model(), std2Q_XXYYII.target_model())
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")
#mdl_decomp = std2Q_XYCNOT.target_model()
#mdl_decomp.operations['Gtest'] = testS
#w.GateDecompTable(mdl_decomp, mdl_decomp)
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.5π | 0.500009π | 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.499987π | 0.25π | 0.25π | 0.499987π | ||
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.5π | 0.25π | 0.500008π | ||
Gyi | $ \begin{pmatrix} -0.25 \\ -0.25 \\ 0.25 \\ 0.25 \end{pmatrix} $ π | 0.5π | 0 | -- | 0.5π | 0.5π | 0.5π | 0.499987π | 0.25π | 0.500008π | 0.25π | ||
Gxx | $ \begin{pmatrix} -0.500005 \\ 0.500006 \\ -4\times 10^{-7} \\ 0 \end{pmatrix} $ π | 0.707114π | 0.003505 | -- | 0.25π | 0.499987π | 0.25π | 0.499987π | 0.499982π | 0.33333π | 0.33333π | ||
Gyy | $ \begin{pmatrix} -0.500557 \\ 0.500557 \\ 0 \\ 0 \end{pmatrix} $ π | 0.707895π | 0 | -- | 0.5π | 0.25π | 0.5π | 0.25π | 0.499982π | 0.33334π | 0.333323π | ||
Gxy | $ \begin{pmatrix} -0.500007 \\ 0.500006 \\ 0.000001 \\ 0 \end{pmatrix} $ π | 0.707116π | 0.00368 | -- | 0.500009π | 0.25π | 0.25π | 0.500008π | 0.33333π | 0.33334π | 0.500009π | ||
Gyx | $ \begin{pmatrix} 0.499981 \\ -0.49998 \\ -0.000002 \\ 0 \end{pmatrix} $ π | 0.707079π | 0.003891 | -- | 0.25π | 0.499987π | 0.500008π | 0.25π | 0.33333π | 0.333323π | 0.500009π |
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 0x12adbfd30>
w.DatasetComparisonHistogramPlot(dscmps[(1,2)])
<pygsti.report.workspaceplots.DatasetComparisonHistogramPlot at 0x129ba6240>
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(mdl1, tgt)
#obj = w.ErrgenTable(mdl3,tgt)
#obj = w.ColorBoxPlot(("logl",), gss, ds1, mdl1, 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.074335 | 0.049557 | 0.076094 | 0.07636 | 0.074098 | 0.049398 |
Gx | 0.076404 | 0.050936 | 0.076851 | 0.076926 | 0.076341 | 0.050894 |
Gy | 0.075533 | 0.050356 | 0.075764 | 0.075785 | 0.0755 | 0.050334 |
If you want, you can save figure-containing notebooks (like this one) 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).