pyGSTi 0.9.12__cp310-cp310-win_amd64.whl → 0.9.13__cp310-cp310-win_amd64.whl
Sign up to get free protection for your applications and to get access to all the features.
- pyGSTi-0.9.13.dist-info/METADATA +197 -0
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +211 -220
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/WHEEL +1 -1
- pygsti/_version.py +2 -2
- pygsti/algorithms/contract.py +1 -1
- pygsti/algorithms/core.py +62 -35
- pygsti/algorithms/fiducialpairreduction.py +95 -110
- pygsti/algorithms/fiducialselection.py +17 -8
- pygsti/algorithms/gaugeopt.py +2 -2
- pygsti/algorithms/germselection.py +87 -77
- pygsti/algorithms/mirroring.py +0 -388
- pygsti/algorithms/randomcircuit.py +165 -1333
- pygsti/algorithms/rbfit.py +0 -234
- pygsti/baseobjs/basis.py +94 -396
- pygsti/baseobjs/errorgenbasis.py +0 -132
- pygsti/baseobjs/errorgenspace.py +0 -10
- pygsti/baseobjs/label.py +52 -168
- pygsti/baseobjs/opcalc/fastopcalc.cp310-win_amd64.pyd +0 -0
- pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
- pygsti/baseobjs/polynomial.py +13 -595
- pygsti/baseobjs/protectedarray.py +72 -132
- pygsti/baseobjs/statespace.py +1 -0
- pygsti/circuits/__init__.py +1 -1
- pygsti/circuits/circuit.py +753 -504
- pygsti/circuits/circuitconstruction.py +0 -4
- pygsti/circuits/circuitlist.py +47 -5
- pygsti/circuits/circuitparser/__init__.py +8 -8
- pygsti/circuits/circuitparser/fastcircuitparser.cp310-win_amd64.pyd +0 -0
- pygsti/circuits/circuitstructure.py +3 -3
- pygsti/circuits/cloudcircuitconstruction.py +27 -14
- pygsti/data/datacomparator.py +4 -9
- pygsti/data/dataset.py +51 -46
- pygsti/data/hypothesistest.py +0 -7
- pygsti/drivers/bootstrap.py +0 -49
- pygsti/drivers/longsequence.py +46 -10
- pygsti/evotypes/basereps_cython.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/chp/opreps.py +0 -61
- pygsti/evotypes/chp/statereps.py +0 -32
- pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
- pygsti/evotypes/densitymx/effectreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/densitymx/effectreps.pyx +1 -1
- pygsti/evotypes/densitymx/opreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/densitymx/opreps.pyx +2 -2
- pygsti/evotypes/densitymx/statereps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/densitymx/statereps.pyx +1 -1
- pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
- pygsti/evotypes/densitymx_slow/opreps.py +16 -23
- pygsti/evotypes/densitymx_slow/statereps.py +10 -3
- pygsti/evotypes/evotype.py +39 -2
- pygsti/evotypes/stabilizer/effectreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
- pygsti/evotypes/stabilizer/opreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/stabilizer/opreps.pyx +0 -4
- pygsti/evotypes/stabilizer/statereps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/stabilizer/statereps.pyx +1 -5
- pygsti/evotypes/stabilizer/termreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/stabilizer/termreps.pyx +0 -7
- pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
- pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
- pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
- pygsti/evotypes/statevec/effectreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/statevec/effectreps.pyx +1 -1
- pygsti/evotypes/statevec/opreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/statevec/opreps.pyx +2 -2
- pygsti/evotypes/statevec/statereps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/statevec/statereps.pyx +1 -1
- pygsti/evotypes/statevec/termreps.cp310-win_amd64.pyd +0 -0
- pygsti/evotypes/statevec/termreps.pyx +0 -7
- pygsti/evotypes/statevec_slow/effectreps.py +0 -3
- pygsti/evotypes/statevec_slow/opreps.py +0 -5
- pygsti/extras/__init__.py +0 -1
- pygsti/extras/drift/signal.py +1 -1
- pygsti/extras/drift/stabilityanalyzer.py +3 -1
- pygsti/extras/interpygate/__init__.py +12 -0
- pygsti/extras/interpygate/core.py +0 -36
- pygsti/extras/interpygate/process_tomography.py +44 -10
- pygsti/extras/rpe/rpeconstruction.py +0 -2
- pygsti/forwardsims/__init__.py +1 -0
- pygsti/forwardsims/forwardsim.py +50 -93
- pygsti/forwardsims/mapforwardsim.py +78 -20
- pygsti/forwardsims/mapforwardsim_calc_densitymx.cp310-win_amd64.pyd +0 -0
- pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
- pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
- pygsti/forwardsims/matrixforwardsim.py +72 -17
- pygsti/forwardsims/termforwardsim.py +9 -111
- pygsti/forwardsims/termforwardsim_calc_stabilizer.cp310-win_amd64.pyd +0 -0
- pygsti/forwardsims/termforwardsim_calc_statevec.cp310-win_amd64.pyd +0 -0
- pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
- pygsti/forwardsims/torchfwdsim.py +265 -0
- pygsti/forwardsims/weakforwardsim.py +2 -2
- pygsti/io/__init__.py +1 -2
- pygsti/io/mongodb.py +0 -2
- pygsti/io/stdinput.py +6 -22
- pygsti/layouts/copalayout.py +10 -12
- pygsti/layouts/distlayout.py +0 -40
- pygsti/layouts/maplayout.py +103 -25
- pygsti/layouts/matrixlayout.py +99 -60
- pygsti/layouts/prefixtable.py +1534 -52
- pygsti/layouts/termlayout.py +1 -1
- pygsti/modelmembers/instruments/instrument.py +3 -3
- pygsti/modelmembers/instruments/tpinstrument.py +2 -2
- pygsti/modelmembers/modelmember.py +0 -17
- pygsti/modelmembers/operations/__init__.py +3 -4
- pygsti/modelmembers/operations/affineshiftop.py +206 -0
- pygsti/modelmembers/operations/composederrorgen.py +1 -1
- pygsti/modelmembers/operations/composedop.py +1 -24
- pygsti/modelmembers/operations/denseop.py +5 -5
- pygsti/modelmembers/operations/eigpdenseop.py +2 -2
- pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
- pygsti/modelmembers/operations/embeddedop.py +0 -1
- pygsti/modelmembers/operations/experrorgenop.py +5 -2
- pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
- pygsti/modelmembers/operations/fullcptpop.py +2 -2
- pygsti/modelmembers/operations/fulltpop.py +28 -6
- pygsti/modelmembers/operations/fullunitaryop.py +5 -4
- pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
- pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
- pygsti/modelmembers/operations/linearop.py +7 -27
- pygsti/modelmembers/operations/opfactory.py +1 -1
- pygsti/modelmembers/operations/repeatedop.py +1 -24
- pygsti/modelmembers/operations/staticstdop.py +1 -1
- pygsti/modelmembers/povms/__init__.py +3 -3
- pygsti/modelmembers/povms/basepovm.py +7 -36
- pygsti/modelmembers/povms/complementeffect.py +4 -9
- pygsti/modelmembers/povms/composedeffect.py +0 -320
- pygsti/modelmembers/povms/computationaleffect.py +1 -1
- pygsti/modelmembers/povms/computationalpovm.py +3 -1
- pygsti/modelmembers/povms/effect.py +3 -5
- pygsti/modelmembers/povms/marginalizedpovm.py +3 -81
- pygsti/modelmembers/povms/tppovm.py +74 -2
- pygsti/modelmembers/states/__init__.py +2 -5
- pygsti/modelmembers/states/composedstate.py +0 -317
- pygsti/modelmembers/states/computationalstate.py +3 -3
- pygsti/modelmembers/states/cptpstate.py +4 -4
- pygsti/modelmembers/states/densestate.py +10 -8
- pygsti/modelmembers/states/fullpurestate.py +0 -24
- pygsti/modelmembers/states/purestate.py +1 -1
- pygsti/modelmembers/states/state.py +5 -6
- pygsti/modelmembers/states/tpstate.py +28 -10
- pygsti/modelmembers/term.py +3 -6
- pygsti/modelmembers/torchable.py +50 -0
- pygsti/modelpacks/_modelpack.py +1 -1
- pygsti/modelpacks/smq1Q_ZN.py +3 -1
- pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
- pygsti/modelpacks/smq2Q_XY.py +3 -3
- pygsti/modelpacks/smq2Q_XYI.py +2 -2
- pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
- pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
- pygsti/modelpacks/smq2Q_XYXX.py +1 -1
- pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
- pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
- pygsti/modelpacks/stdtarget.py +0 -121
- pygsti/models/cloudnoisemodel.py +1 -2
- pygsti/models/explicitcalc.py +3 -3
- pygsti/models/explicitmodel.py +3 -13
- pygsti/models/fogistore.py +5 -3
- pygsti/models/localnoisemodel.py +1 -2
- pygsti/models/memberdict.py +0 -12
- pygsti/models/model.py +801 -68
- pygsti/models/modelconstruction.py +4 -4
- pygsti/models/modelnoise.py +2 -2
- pygsti/models/modelparaminterposer.py +1 -1
- pygsti/models/oplessmodel.py +1 -1
- pygsti/models/qutrit.py +15 -14
- pygsti/objectivefns/objectivefns.py +75 -140
- pygsti/objectivefns/wildcardbudget.py +2 -7
- pygsti/optimize/__init__.py +1 -0
- pygsti/optimize/arraysinterface.py +28 -0
- pygsti/optimize/customcg.py +0 -12
- pygsti/optimize/customlm.py +129 -323
- pygsti/optimize/customsolve.py +2 -2
- pygsti/optimize/optimize.py +0 -84
- pygsti/optimize/simplerlm.py +841 -0
- pygsti/optimize/wildcardopt.py +19 -598
- pygsti/protocols/confidenceregionfactory.py +28 -14
- pygsti/protocols/estimate.py +31 -14
- pygsti/protocols/gst.py +238 -142
- pygsti/protocols/modeltest.py +19 -12
- pygsti/protocols/protocol.py +9 -37
- pygsti/protocols/rb.py +450 -79
- pygsti/protocols/treenode.py +8 -2
- pygsti/protocols/vb.py +108 -206
- pygsti/protocols/vbdataframe.py +1 -1
- pygsti/report/factory.py +0 -15
- pygsti/report/fogidiagram.py +1 -17
- pygsti/report/modelfunction.py +12 -3
- pygsti/report/mpl_colormaps.py +1 -1
- pygsti/report/plothelpers.py +11 -3
- pygsti/report/report.py +16 -0
- pygsti/report/reportables.py +41 -37
- pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
- pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
- pygsti/report/workspace.py +2 -14
- pygsti/report/workspaceplots.py +328 -505
- pygsti/tools/basistools.py +9 -36
- pygsti/tools/edesigntools.py +124 -96
- pygsti/tools/fastcalc.cp310-win_amd64.pyd +0 -0
- pygsti/tools/fastcalc.pyx +35 -81
- pygsti/tools/internalgates.py +151 -15
- pygsti/tools/jamiolkowski.py +5 -5
- pygsti/tools/lindbladtools.py +19 -11
- pygsti/tools/listtools.py +0 -114
- pygsti/tools/matrixmod2.py +1 -1
- pygsti/tools/matrixtools.py +173 -339
- pygsti/tools/nameddict.py +1 -1
- pygsti/tools/optools.py +154 -88
- pygsti/tools/pdftools.py +0 -25
- pygsti/tools/rbtheory.py +3 -320
- pygsti/tools/slicetools.py +64 -12
- pyGSTi-0.9.12.dist-info/METADATA +0 -157
- pygsti/algorithms/directx.py +0 -711
- pygsti/evotypes/qibo/__init__.py +0 -33
- pygsti/evotypes/qibo/effectreps.py +0 -78
- pygsti/evotypes/qibo/opreps.py +0 -376
- pygsti/evotypes/qibo/povmreps.py +0 -98
- pygsti/evotypes/qibo/statereps.py +0 -174
- pygsti/extras/rb/__init__.py +0 -13
- pygsti/extras/rb/benchmarker.py +0 -957
- pygsti/extras/rb/dataset.py +0 -378
- pygsti/extras/rb/io.py +0 -814
- pygsti/extras/rb/simulate.py +0 -1020
- pygsti/io/legacyio.py +0 -385
- pygsti/modelmembers/povms/denseeffect.py +0 -142
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
pygsti/protocols/rb.py
CHANGED
@@ -10,6 +10,7 @@ RB Protocol objects
|
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0 or in the LICENSE file in the root pyGSTi directory.
|
11
11
|
#***************************************************************************************************
|
12
12
|
|
13
|
+
from collections import defaultdict
|
13
14
|
import numpy as _np
|
14
15
|
|
15
16
|
from pygsti.protocols import protocol as _proto
|
@@ -65,6 +66,10 @@ class CliffordRBDesign(_vb.BenchmarkingDesign):
|
|
65
66
|
the ideal output a circuit is randomized to a uniformly random bit-string. This setting is
|
66
67
|
useful for, e.g., detecting leakage/loss/measurement-bias etc.
|
67
68
|
|
69
|
+
interleaved_circuit : Circuit, optional (default None)
|
70
|
+
Circuit to use in the constuction of an interleaved CRB experiment. When specified each
|
71
|
+
random clifford operation is interleaved with the specified circuit.
|
72
|
+
|
68
73
|
citerations : int, optional
|
69
74
|
Some of the Clifford compilation algorithms in pyGSTi (including the default algorithm) are
|
70
75
|
randomized, and the lowest-cost circuit is chosen from all the circuit generated in the
|
@@ -111,7 +116,7 @@ class CliffordRBDesign(_vb.BenchmarkingDesign):
|
|
111
116
|
"""
|
112
117
|
|
113
118
|
@classmethod
|
114
|
-
def from_existing_circuits(cls,
|
119
|
+
def from_existing_circuits(cls, data_by_depth, qubit_labels=None,
|
115
120
|
randomizeout=False, citerations=20, compilerargs=(), interleaved_circuit=None,
|
116
121
|
descriptor='A Clifford RB experiment', add_default_protocol=False):
|
117
122
|
"""
|
@@ -123,10 +128,12 @@ class CliffordRBDesign(_vb.BenchmarkingDesign):
|
|
123
128
|
|
124
129
|
Parameters
|
125
130
|
----------
|
126
|
-
|
127
|
-
A dictionary whose keys are integer depths and whose values are lists of
|
128
|
-
|
129
|
-
ideal (correct) outcome.
|
131
|
+
data_by_depth : dict
|
132
|
+
A dictionary whose keys are integer depths and whose values are lists of
|
133
|
+
`(circuit, ideal_outcome, num_native_gates)` tuples giving each RB circuit, its
|
134
|
+
ideal (correct) outcome, and (optionally) the number of native gates in the compiled Cliffords.
|
135
|
+
If only a 2-tuple is passed, i.e. number of native gates is not included,
|
136
|
+
the :meth:`average_gates_per_clifford()` function will not work.
|
130
137
|
|
131
138
|
qubit_labels : list, optional
|
132
139
|
If not None, a list of the qubits that the RB circuits are to be sampled for. This should
|
@@ -183,22 +190,27 @@ class CliffordRBDesign(_vb.BenchmarkingDesign):
|
|
183
190
|
-------
|
184
191
|
CliffordRBDesign
|
185
192
|
"""
|
186
|
-
depths = sorted(list(
|
187
|
-
circuit_lists = [[x[0] for x in
|
188
|
-
ideal_outs = [[x[1] for x in
|
189
|
-
|
193
|
+
depths = sorted(list(data_by_depth.keys()))
|
194
|
+
circuit_lists = [[x[0] for x in data_by_depth[d]] for d in depths]
|
195
|
+
ideal_outs = [[x[1] for x in data_by_depth[d]] for d in depths]
|
196
|
+
try:
|
197
|
+
native_gate_counts = [[x[2] for x in data_by_depth[d]] for d in depths]
|
198
|
+
except IndexError:
|
199
|
+
native_gate_counts = None
|
200
|
+
circuits_per_depth = [len(data_by_depth[d]) for d in depths]
|
190
201
|
self = cls.__new__(cls)
|
191
202
|
self._init_foundation(depths, circuit_lists, ideal_outs, circuits_per_depth, qubit_labels,
|
192
203
|
randomizeout, citerations, compilerargs, descriptor, add_default_protocol,
|
193
|
-
interleaved_circuit)
|
204
|
+
interleaved_circuit, native_gate_counts=native_gate_counts)
|
194
205
|
return self
|
195
206
|
|
196
207
|
def __init__(self, pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels=None, randomizeout=False,
|
197
|
-
interleaved_circuit=None, citerations=20, compilerargs=(),
|
198
|
-
add_default_protocol=False, seed=None, verbosity=1, num_processes=1):
|
208
|
+
interleaved_circuit=None, citerations=20, compilerargs=(), exact_compilation_key=None,
|
209
|
+
descriptor='A Clifford RB experiment', add_default_protocol=False, seed=None, verbosity=1, num_processes=1):
|
199
210
|
if qubit_labels is None: qubit_labels = tuple(pspec.qubit_labels)
|
200
211
|
circuit_lists = []
|
201
212
|
ideal_outs = []
|
213
|
+
native_gate_counts = []
|
202
214
|
|
203
215
|
if seed is None:
|
204
216
|
self.seed = _np.random.randint(1, 1e6) # Pick a random seed
|
@@ -214,26 +226,35 @@ class CliffordRBDesign(_vb.BenchmarkingDesign):
|
|
214
226
|
args_list = [(pspec, clifford_compilations, l)] * circuits_per_depth
|
215
227
|
kwargs_list = [dict(qubit_labels=qubit_labels, randomizeout=randomizeout, citerations=citerations,
|
216
228
|
compilerargs=compilerargs, interleaved_circuit=interleaved_circuit,
|
217
|
-
seed=lseed + i
|
229
|
+
seed=lseed + i, return_native_gate_counts=True, exact_compilation_key=exact_compilation_key)
|
230
|
+
for i in range(circuits_per_depth)]
|
218
231
|
results = _tools.mptools.starmap_with_kwargs(_rc.create_clifford_rb_circuit, circuits_per_depth,
|
219
232
|
num_processes, args_list, kwargs_list)
|
220
233
|
|
221
234
|
circuits_at_depth = []
|
222
235
|
idealouts_at_depth = []
|
223
|
-
|
236
|
+
native_gate_counts_at_depth = []
|
237
|
+
for c, iout, nng in results:
|
224
238
|
circuits_at_depth.append(c)
|
225
239
|
idealouts_at_depth.append((''.join(map(str, iout)),))
|
240
|
+
native_gate_counts_at_depth.append(nng)
|
226
241
|
|
227
242
|
circuit_lists.append(circuits_at_depth)
|
228
243
|
ideal_outs.append(idealouts_at_depth)
|
244
|
+
native_gate_counts.append(native_gate_counts_at_depth)
|
229
245
|
|
230
246
|
self._init_foundation(depths, circuit_lists, ideal_outs, circuits_per_depth, qubit_labels,
|
231
247
|
randomizeout, citerations, compilerargs, descriptor, add_default_protocol,
|
232
|
-
interleaved_circuit)
|
248
|
+
interleaved_circuit, native_gate_counts=native_gate_counts)
|
233
249
|
|
234
250
|
def _init_foundation(self, depths, circuit_lists, ideal_outs, circuits_per_depth, qubit_labels,
|
235
251
|
randomizeout, citerations, compilerargs, descriptor, add_default_protocol,
|
236
|
-
interleaved_circuit):
|
252
|
+
interleaved_circuit, native_gate_counts=None, exact_compilation_key=None):
|
253
|
+
self.native_gate_count_lists = native_gate_counts
|
254
|
+
if self.native_gate_count_lists is not None:
|
255
|
+
# If we have native gate information, pair this with circuit data so that we serialize/truncate properly
|
256
|
+
self.paired_with_circuit_attrs = ["native_gate_count_lists"]
|
257
|
+
|
237
258
|
super().__init__(depths, circuit_lists, ideal_outs, qubit_labels, remove_duplicates=False)
|
238
259
|
self.circuits_per_depth = circuits_per_depth
|
239
260
|
self.randomizeout = randomizeout
|
@@ -241,12 +262,102 @@ class CliffordRBDesign(_vb.BenchmarkingDesign):
|
|
241
262
|
self.compilerargs = compilerargs
|
242
263
|
self.descriptor = descriptor
|
243
264
|
self.interleaved_circuit = interleaved_circuit
|
265
|
+
self.exact_compilation_key = exact_compilation_key
|
244
266
|
if add_default_protocol:
|
245
267
|
if randomizeout:
|
246
268
|
defaultfit = 'A-fixed'
|
247
269
|
else:
|
248
270
|
defaultfit = 'full'
|
249
271
|
self.add_default_protocol(RB(name='RB', defaultfit=defaultfit))
|
272
|
+
|
273
|
+
#set some auxfile information for interleaved_circuit
|
274
|
+
self.auxfile_types['interleaved_circuit'] = 'circuit-str-json'
|
275
|
+
|
276
|
+
def average_native_gates_per_clifford_for_circuit(self, list_idx, circ_idx):
|
277
|
+
"""The average number of native gates per Clifford for a specific circuit
|
278
|
+
|
279
|
+
Parameters
|
280
|
+
----------
|
281
|
+
list_idx: int
|
282
|
+
The index of the circuit list (for a given depth)
|
283
|
+
|
284
|
+
circ_idx: int
|
285
|
+
The index of the circuit within the circuit list
|
286
|
+
|
287
|
+
Returns
|
288
|
+
-------
|
289
|
+
avg_gate_counts: dict
|
290
|
+
The average number of native gates, native 2Q gates, and native size
|
291
|
+
per Clifford as values with respective label keys
|
292
|
+
"""
|
293
|
+
if self.native_gate_counts_lists is None:
|
294
|
+
raise ValueError("Native gate counts not available, cannot compute average gates per Clifford")
|
295
|
+
|
296
|
+
num_clifford_gates = self.depths[list_idx] + 1
|
297
|
+
avg_gate_counts = {}
|
298
|
+
for key, native_gate_count in self.native_gate_count_lists[list_idx][circ_idx].items():
|
299
|
+
avg_gate_counts[key.replace('native', 'avg_native_per_clifford')] = native_gate_count / num_clifford_gates
|
300
|
+
|
301
|
+
return avg_gate_counts
|
302
|
+
|
303
|
+
def average_native_gates_per_clifford_for_circuit_list(self, list_idx):
|
304
|
+
"""The average number of gates per Clifford for a circuit list
|
305
|
+
|
306
|
+
This essentially gives the average number of native gates per Clifford
|
307
|
+
for a given depth (indexed by list index, not depth).
|
308
|
+
|
309
|
+
Parameters
|
310
|
+
----------
|
311
|
+
list_idx: int
|
312
|
+
The index of the circuit list (for a given depth)
|
313
|
+
|
314
|
+
circ_idx: int
|
315
|
+
The index of the circuit within the circuit list
|
316
|
+
|
317
|
+
Returns
|
318
|
+
-------
|
319
|
+
float
|
320
|
+
The average number of native gates per Clifford
|
321
|
+
"""
|
322
|
+
if self.native_gate_count_lists is None:
|
323
|
+
raise ValueError("Native gate counts not available, cannot compute average gates per Clifford")
|
324
|
+
|
325
|
+
gate_counts = defaultdict(int)
|
326
|
+
for native_gate_counts in self.native_gate_count_lists[list_idx]:
|
327
|
+
for k, v in native_gate_counts.items():
|
328
|
+
gate_counts[k] += v
|
329
|
+
|
330
|
+
num_clifford_gates = len(self.native_gate_count_lists[list_idx]) * (self.depths[list_idx] + 1)
|
331
|
+
avg_gate_counts = {}
|
332
|
+
for key, total_native_gate_counts in gate_counts.items():
|
333
|
+
avg_gate_counts[key.replace('native', 'avg_native_per_clifford')] = total_native_gate_counts / num_clifford_gates
|
334
|
+
|
335
|
+
return avg_gate_counts
|
336
|
+
|
337
|
+
def average_native_gates_per_clifford(self):
|
338
|
+
"""The average number of native gates per Clifford for all circuits
|
339
|
+
|
340
|
+
Returns
|
341
|
+
-------
|
342
|
+
float
|
343
|
+
The average number of native gates per Clifford
|
344
|
+
"""
|
345
|
+
if self.native_gate_count_lists is None:
|
346
|
+
raise ValueError("Number of native gates not available, cannot compute average gates per Clifford")
|
347
|
+
|
348
|
+
gate_counts = defaultdict(int)
|
349
|
+
num_clifford_gates = 0
|
350
|
+
for list_idx in range(len(self.depths)):
|
351
|
+
for native_gate_counts in self.native_gate_count_lists[list_idx]:
|
352
|
+
for k, v in native_gate_counts.items():
|
353
|
+
gate_counts[k] += v
|
354
|
+
num_clifford_gates += len(self.native_gate_count_lists[list_idx]) * (self.depths[list_idx] + 1)
|
355
|
+
|
356
|
+
avg_gate_counts = {}
|
357
|
+
for key, total_native_gate_counts in gate_counts.items():
|
358
|
+
avg_gate_counts[key.replace('native', 'avg_native_per_clifford')] = total_native_gate_counts / num_clifford_gates
|
359
|
+
|
360
|
+
return avg_gate_counts
|
250
361
|
|
251
362
|
def map_qubit_labels(self, mapper):
|
252
363
|
"""
|
@@ -970,6 +1081,9 @@ class BinaryRBDesign(_vb.BenchmarkingDesign):
|
|
970
1081
|
def _init_foundation(self, depths, circuit_lists, measurements, signs, circuits_per_depth, qubit_labels, layer_sampling,
|
971
1082
|
sampler, samplerargs, addlocal, lsargs, descriptor,
|
972
1083
|
add_default_protocol):
|
1084
|
+
# Pair these attributes with circuit data so that we serialize/truncate properly
|
1085
|
+
self.paired_with_circuit_attrs = ["measurements", "signs"]
|
1086
|
+
|
973
1087
|
super().__init__(depths, circuit_lists, signs, qubit_labels, remove_duplicates=False)
|
974
1088
|
self.measurements = measurements
|
975
1089
|
self.signs = signs
|
@@ -986,11 +1100,185 @@ class BinaryRBDesign(_vb.BenchmarkingDesign):
|
|
986
1100
|
|
987
1101
|
defaultfit = 'A-fixed'
|
988
1102
|
self.add_default_protocol(RB(name='RB', defaultfit=defaultfit))
|
989
|
-
|
990
|
-
self.auxfile_types['signs'] = 'json' # Makes sure that signs and measurements are saved seperately
|
991
|
-
self.auxfile_types['measurements'] = 'json'
|
992
1103
|
|
993
1104
|
|
1105
|
+
class InterleavedRBDesign(_proto.CombinedExperimentDesign):
|
1106
|
+
"""
|
1107
|
+
Experiment design for interleaved randomized benchmarking (IRB).
|
1108
|
+
|
1109
|
+
IRB encapsulates a pair of "Clifford randomized benchmarking" (CRB) experiments.
|
1110
|
+
One of these CRB designs is a 'standard' one, but the other interleaves some
|
1111
|
+
clifford gate of interest between each random clifford operation.
|
1112
|
+
The circuits created by this function will respect the connectivity and gate-set of the device encoded by
|
1113
|
+
`pspec` (see the :class:`QubitProcessorSpec` object docstring for how to construct the relevant `pspec`
|
1114
|
+
for a device).
|
1115
|
+
|
1116
|
+
Parameters
|
1117
|
+
----------
|
1118
|
+
pspec : QubitProcessorSpec
|
1119
|
+
The QubitProcessorSpec for the device that the CRB experiment is being generated for, which defines the
|
1120
|
+
"native" gate-set and the connectivity of the device. The returned CRB circuits will be over the gates in
|
1121
|
+
`pspec`, and will respect the connectivity encoded by `pspec`.
|
1122
|
+
|
1123
|
+
clifford_compilations : dict
|
1124
|
+
A dictionary with the potential keys `'absolute'` and `'paulieq'` and corresponding class:`CompilationRules` values.
|
1125
|
+
These compilation rules specify how to compile the "native" gates of `pspec` into Clifford gates.
|
1126
|
+
|
1127
|
+
depths : list of ints
|
1128
|
+
The "CRB depths" of the circuit; a list of integers >= 0. The CRB length is the number of Cliffords in the
|
1129
|
+
circuit - 2 *before* each Clifford is compiled into the native gate-set.
|
1130
|
+
|
1131
|
+
circuits_per_depth : int
|
1132
|
+
The number of (possibly) different CRB circuits sampled at each length.
|
1133
|
+
|
1134
|
+
interleaved_circuit : Circuit
|
1135
|
+
Circuit to use in the constuction of the interleaved CRB experiment. This is the circuit
|
1136
|
+
whose error rate is to be estimated by the IRB experiment.
|
1137
|
+
|
1138
|
+
qubit_labels : list, optional
|
1139
|
+
If not None, a list of the qubits that the RB circuits are to be sampled for. This should
|
1140
|
+
be all or a subset of the qubits in the device specified by the QubitProcessorSpec `pspec`.
|
1141
|
+
If None, it is assumed that the RB circuit should be over all the qubits. Note that the
|
1142
|
+
ordering of this list is the order of the "wires" in the returned circuit, but is otherwise
|
1143
|
+
irrelevant. If desired, a circuit that explicitly idles on the other qubits can be obtained
|
1144
|
+
by using methods of the Circuit object.
|
1145
|
+
|
1146
|
+
randomizeout : bool, optional
|
1147
|
+
If False, the ideal output of the circuits (the "success" or "survival" outcome) is always
|
1148
|
+
the all-zeros bit string. This is probably considered to be the "standard" in CRB. If True,
|
1149
|
+
the ideal output a circuit is randomized to a uniformly random bit-string. This setting is
|
1150
|
+
useful for, e.g., detecting leakage/loss/measurement-bias etc.
|
1151
|
+
|
1152
|
+
citerations : int, optional
|
1153
|
+
Some of the Clifford compilation algorithms in pyGSTi (including the default algorithm) are
|
1154
|
+
randomized, and the lowest-cost circuit is chosen from all the circuit generated in the
|
1155
|
+
iterations of the algorithm. This is the number of iterations used. The time required to
|
1156
|
+
generate a CRB circuit is linear in `citerations * (CRB length + 2)`. Lower-depth / lower 2-qubit
|
1157
|
+
gate count compilations of the Cliffords are important in order to successfully implement
|
1158
|
+
CRB on more qubits.
|
1159
|
+
|
1160
|
+
compilerargs : list, optional
|
1161
|
+
A list of arguments that are handed to compile_clifford() function, which includes all the
|
1162
|
+
optional arguments of compile_clifford() *after* the `iterations` option (set by `citerations`).
|
1163
|
+
In order, this list should be values for:
|
1164
|
+
|
1165
|
+
* algorithm : str. A string that specifies the compilation algorithm. The default in
|
1166
|
+
compile_clifford() will always be whatever we consider to be the 'best' all-round
|
1167
|
+
algorithm.
|
1168
|
+
* aargs : list. A list of optional arguments for the particular compilation algorithm.
|
1169
|
+
* costfunction : 'str' or function. The cost-function from which the "best" compilation
|
1170
|
+
for a Clifford is chosen from all `citerations` compilations. The default costs a
|
1171
|
+
circuit as 10x the num. of 2-qubit gates in the circuit + 1x the depth of the circuit.
|
1172
|
+
* prefixpaulis : bool. Whether to prefix or append the Paulis on each Clifford.
|
1173
|
+
* paulirandomize : bool. Whether to follow each layer in the Clifford circuit with a
|
1174
|
+
random Pauli on each qubit (compiled into native gates). I.e., if this is True the
|
1175
|
+
native gates are Pauli-randomized. When True, this prevents any coherent errors adding
|
1176
|
+
(on average) inside the layers of each compiled Clifford, at the cost of increased
|
1177
|
+
circuit depth. Defaults to False.
|
1178
|
+
|
1179
|
+
For more information on these options, see the compile_clifford() docstring.
|
1180
|
+
|
1181
|
+
descriptor : str, optional
|
1182
|
+
A string describing the experiment generated, which will be stored in the returned
|
1183
|
+
dictionary.
|
1184
|
+
|
1185
|
+
add_default_protocol : bool, optional
|
1186
|
+
Whether to add a default RB protocol to the experiment design, which can be run
|
1187
|
+
later (once data is taken) by using a :class:`DefaultProtocolRunner` object.
|
1188
|
+
|
1189
|
+
seed : int, optional
|
1190
|
+
A seed to initialize the random number generator used for creating random clifford
|
1191
|
+
circuits. The first of the two subdesigns will use the specified seed directly,
|
1192
|
+
while the second will use seed+1.
|
1193
|
+
|
1194
|
+
verbosity : int, optional
|
1195
|
+
If > 0 the number of circuits generated so far is shown.
|
1196
|
+
|
1197
|
+
interleave : bool, optional
|
1198
|
+
Whether the circuits of the standard CRB and IRB sub designs should be interleaved to
|
1199
|
+
form the circuit ordering of this experiment design. E.g. when calling the `all_circuits_needing_data`
|
1200
|
+
attribute.
|
1201
|
+
"""
|
1202
|
+
|
1203
|
+
def __init__(self, pspec, clifford_compilations, depths, circuits_per_depth, interleaved_circuit, qubit_labels=None, randomizeout=False,
|
1204
|
+
citerations=20, compilerargs=(), exact_compilation_key=None,
|
1205
|
+
descriptor='An Interleaved RB experiment', add_default_protocol=False, seed=None, verbosity=1, num_processes=1,
|
1206
|
+
interleave = False):
|
1207
|
+
#Farm out the construction of the experiment designs to CliffordRBDesign:
|
1208
|
+
print('Constructing Standard CRB Subdesign:')
|
1209
|
+
crb_subdesign = CliffordRBDesign(pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels, randomizeout,
|
1210
|
+
None, citerations, compilerargs, exact_compilation_key,
|
1211
|
+
descriptor + ' (Standard)', add_default_protocol, seed, verbosity, num_processes)
|
1212
|
+
print('Constructing Interleaved CRB Subdesign:')
|
1213
|
+
icrb_subdesign = CliffordRBDesign(pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels, randomizeout,
|
1214
|
+
interleaved_circuit, citerations, compilerargs, exact_compilation_key,
|
1215
|
+
descriptor + ' (Interleaved)', add_default_protocol, seed+1 if seed is not None else None,
|
1216
|
+
verbosity, num_processes)
|
1217
|
+
|
1218
|
+
self._init_foundation(crb_subdesign, icrb_subdesign, circuits_per_depth, interleaved_circuit, randomizeout,
|
1219
|
+
citerations, compilerargs, exact_compilation_key, interleave)
|
1220
|
+
|
1221
|
+
@classmethod
|
1222
|
+
def from_existing_designs(cls, crb_subdesign, icrb_subdesign, circuits_per_depth, interleaved_circuit, randomizeout=False,
|
1223
|
+
citerations=20, compilerargs=(), exact_compilation_key=None, interleave=False):
|
1224
|
+
self = cls.__new__(cls)
|
1225
|
+
self._init_foundation(self, crb_subdesign, icrb_subdesign, circuits_per_depth, interleaved_circuit, randomizeout,
|
1226
|
+
citerations, compilerargs, exact_compilation_key, interleave)
|
1227
|
+
|
1228
|
+
#helper method for reducing code duplication on different class constructors.
|
1229
|
+
def _init_foundation(self, crb_subdesign, icrb_subdesign, circuits_per_depth, interleaved_circuit, randomizeout,
|
1230
|
+
citerations, compilerargs, exact_compilation_key, interleave):
|
1231
|
+
super().__init__({'crb':crb_subdesign,
|
1232
|
+
'icrb':icrb_subdesign}, interleave=interleave)
|
1233
|
+
self.circuits_per_depth = circuits_per_depth
|
1234
|
+
self.randomizeout = randomizeout
|
1235
|
+
self.citerations = citerations
|
1236
|
+
self.compilerargs = compilerargs
|
1237
|
+
self.interleaved_circuit = interleaved_circuit
|
1238
|
+
self.exact_compilation_key = exact_compilation_key
|
1239
|
+
|
1240
|
+
#set some auxfile information for serializing interleaved_circuit
|
1241
|
+
self.auxfile_types['interleaved_circuit'] = 'circuit-str-json'
|
1242
|
+
|
1243
|
+
def average_native_gates_per_clifford(self):
|
1244
|
+
"""
|
1245
|
+
The average number of native gates per Clifford for all circuits
|
1246
|
+
|
1247
|
+
Returns
|
1248
|
+
-------
|
1249
|
+
tuple of floats
|
1250
|
+
A tuple of the average number of native gates per Clifford
|
1251
|
+
for the contained standard CRB design, and interleaved CRB design,
|
1252
|
+
respectively.
|
1253
|
+
"""
|
1254
|
+
avg_gate_counts_crb = self['crb'].average_native_gates_per_clifford()
|
1255
|
+
avg_gate_counts_icrb = self['icrb'].average_native_gates_per_clifford()
|
1256
|
+
|
1257
|
+
return (avg_gate_counts_crb, avg_gate_counts_icrb)
|
1258
|
+
|
1259
|
+
def map_qubit_labels(self, mapper):
|
1260
|
+
"""
|
1261
|
+
Creates a new experiment design whose circuits' qubit labels are updated according to a given mapping.
|
1262
|
+
|
1263
|
+
Parameters
|
1264
|
+
----------
|
1265
|
+
mapper : dict or function
|
1266
|
+
A dictionary whose keys are the existing self.qubit_labels values
|
1267
|
+
and whose value are the new labels, or a function which takes a
|
1268
|
+
single (existing qubit-label) argument and returns a new qubit-label.
|
1269
|
+
|
1270
|
+
Returns
|
1271
|
+
-------
|
1272
|
+
InterleavedRBDesign
|
1273
|
+
"""
|
1274
|
+
|
1275
|
+
mapped_crb_design = self['crb'].map_qubit_labels(mapper)
|
1276
|
+
mapped_icrb_design = self['icrb'].map_qubit_labels(mapper)
|
1277
|
+
|
1278
|
+
return InterleavedRBDesign.from_existing_designs(mapped_crb_design, mapped_icrb_design, self.circuits_per_depth,
|
1279
|
+
self.randomizeout, self.citerations, self.compilerargs, self.interleaved_circuit,
|
1280
|
+
self.exact_compilation_key)
|
1281
|
+
|
994
1282
|
class RandomizedBenchmarking(_vb.SummaryStatistics):
|
995
1283
|
"""
|
996
1284
|
The randomized benchmarking protocol.
|
@@ -998,55 +1286,10 @@ class RandomizedBenchmarking(_vb.SummaryStatistics):
|
|
998
1286
|
This same analysis protocol is used for Clifford, Direct and Mirror RB.
|
999
1287
|
The standard Mirror RB analysis is obtained by setting
|
1000
1288
|
`datatype` = `adjusted_success_probabilities`.
|
1001
|
-
|
1002
|
-
Parameters
|
1003
|
-
----------
|
1004
|
-
datatype: 'success_probabilities', 'adjusted_success_probabilities', or 'energies', optional
|
1005
|
-
The type of summary data to extract, average, and the fit to an exponential decay. If
|
1006
|
-
'success_probabilities' then the summary data for a circuit is the frequency that
|
1007
|
-
the target bitstring is observed, i.e., the success probability of the circuit. If
|
1008
|
-
'adjusted_success_probabilties' then the summary data for a circuit is
|
1009
|
-
S = sum_{k = 0}^n (-1/2)^k h_k where h_k is the frequency at which the output bitstring is
|
1010
|
-
a Hamming distance of k from the target bitstring, and n is the number of qubits.
|
1011
|
-
This datatype is used in Mirror RB, but can also be used in Clifford and Direct RB.
|
1012
|
-
If 'energies', then the summary data is Pauli operator measurement results. This datatype is
|
1013
|
-
only used for Binary RB.
|
1014
|
-
|
1015
|
-
defaultfit: 'A-fixed' or 'full'
|
1016
|
-
The summary data is fit to A + Bp^m with A fixed and with A as a fit parameter.
|
1017
|
-
If 'A-fixed' then the default results displayed are those from fitting with A
|
1018
|
-
fixed, and if 'full' then the default results displayed are those where A is a
|
1019
|
-
fit parameter.
|
1020
|
-
|
1021
|
-
asymptote : 'std' or float, optional
|
1022
|
-
The summary data is fit to A + Bp^m with A fixed and with A has a fit parameter,
|
1023
|
-
with the default results returned set by `defaultfit`. This argument specifies the
|
1024
|
-
value used when 'A' is fixed. If left as 'std', then 'A' defaults to 1/2^n if
|
1025
|
-
`datatype` is `success_probabilities` and to 1/4^n if `datatype` is
|
1026
|
-
`adjusted_success_probabilities`.
|
1027
|
-
|
1028
|
-
rtype : 'EI' or 'AGI', optional
|
1029
|
-
The RB error rate definition convention. 'EI' results in RB error rates that are associated
|
1030
|
-
with the entanglement infidelity, which is the error probability with stochastic Pauli errors.
|
1031
|
-
'AGI' results in RB error rates that are associated with the average gate infidelity.
|
1032
|
-
|
1033
|
-
seed : list, optional
|
1034
|
-
Seeds for the fit of B and p (A is seeded to the asymptote defined by `asympote`).
|
1035
|
-
|
1036
|
-
bootstrap_samples : float, optional
|
1037
|
-
The number of samples for generating bootstrapped error bars.
|
1038
|
-
|
1039
|
-
depths: list or 'all'
|
1040
|
-
If not 'all', a list of depths to use (data at other depths is discarded).
|
1041
|
-
|
1042
|
-
name : str, optional
|
1043
|
-
The name of this protocol, also used to (by default) name the
|
1044
|
-
results produced by this protocol. If None, the class name will
|
1045
|
-
be used.
|
1046
1289
|
"""
|
1047
1290
|
|
1048
1291
|
def __init__(self, datatype='success_probabilities', defaultfit='full', asymptote='std', rtype='EI',
|
1049
|
-
seed=(0.8, 0.95), bootstrap_samples=200, depths='all',
|
1292
|
+
seed=(0.8, 0.95), bootstrap_samples=200, depths='all', name=None):
|
1050
1293
|
"""
|
1051
1294
|
Initialize an RB protocol for analyzing RB data.
|
1052
1295
|
|
@@ -1109,7 +1352,6 @@ class RandomizedBenchmarking(_vb.SummaryStatistics):
|
|
1109
1352
|
self.rtype = rtype
|
1110
1353
|
self.datatype = datatype
|
1111
1354
|
self.defaultfit = defaultfit
|
1112
|
-
self.square_mean_root = square_mean_root
|
1113
1355
|
if self.datatype == 'energies':
|
1114
1356
|
self.energies = True
|
1115
1357
|
else:
|
@@ -1143,8 +1385,6 @@ class RandomizedBenchmarking(_vb.SummaryStatistics):
|
|
1143
1385
|
if self.datatype not in data.cache:
|
1144
1386
|
summary_data_dict = self._compute_summary_statistics(data, energy = self.energies)
|
1145
1387
|
data.cache.update(summary_data_dict)
|
1146
|
-
#print('data cache updated')
|
1147
|
-
#print(data.cache)
|
1148
1388
|
src_data = data.cache[self.datatype]
|
1149
1389
|
data_per_depth = src_data
|
1150
1390
|
|
@@ -1170,17 +1410,9 @@ class RandomizedBenchmarking(_vb.SummaryStatistics):
|
|
1170
1410
|
adj_sps = []
|
1171
1411
|
for depth in depths:
|
1172
1412
|
percircuitdata = circuitdata_per_depth[depth]
|
1173
|
-
|
1174
|
-
if self.square_mean_root:
|
1175
|
-
#print(percircuitdata)
|
1176
|
-
adj_sps.append(_np.nanmean(_np.sqrt(percircuitdata))**2)
|
1177
|
-
#print(adj_sps)
|
1178
|
-
else:
|
1179
|
-
adj_sps.append(_np.nanmean(percircuitdata)) # average [adjusted] success probabilities or energies
|
1413
|
+
adj_sps.append(_np.nanmean(percircuitdata)) # average [adjusted] success probabilities or energies
|
1180
1414
|
|
1181
|
-
#print(adj_sps)
|
1182
1415
|
# Don't think this needs changed
|
1183
|
-
#print(asymptote)
|
1184
1416
|
full_fit_results, fixed_asym_fit_results = _rbfit.std_least_squares_fit(
|
1185
1417
|
depths, adj_sps, nqubits, seed=self.seed, asymptote=asymptote,
|
1186
1418
|
ftype='full+FA', rtype=self.rtype)
|
@@ -1200,10 +1432,8 @@ class RandomizedBenchmarking(_vb.SummaryStatistics):
|
|
1200
1432
|
failcount_faf = 0
|
1201
1433
|
|
1202
1434
|
#Store bootstrap "cache" dicts (containing summary keys) as a list under data.cache
|
1203
|
-
#print(len(data.cache['bootstraps']))
|
1204
1435
|
if 'bootstraps' not in data.cache or len(data.cache['bootstraps']) < self.bootstrap_samples:
|
1205
1436
|
# TIM - finite counts always True here?
|
1206
|
-
#print('adding bootstrap')
|
1207
1437
|
self._add_bootstrap_qtys(data.cache, self.bootstrap_samples, finitecounts=True)
|
1208
1438
|
bootstrap_caches = data.cache['bootstraps'] # if finitecounts else 'infbootstraps'
|
1209
1439
|
|
@@ -1397,6 +1627,147 @@ class RandomizedBenchmarkingResults(_proto.ProtocolResults):
|
|
1397
1627
|
data = _proto.ProtocolData(self.data.edesign, self.data.dataset)
|
1398
1628
|
cpy = RandomizedBenchmarkingResults(data, self.protocol, self.fits, self.depths, self.defaultfit)
|
1399
1629
|
return cpy
|
1630
|
+
|
1631
|
+
|
1632
|
+
class InterleavedRandomizedBenchmarking(_proto.Protocol):
|
1633
|
+
"""
|
1634
|
+
The interleaved randomized benchmarking protocol.
|
1635
|
+
|
1636
|
+
This object itself utilizes the RandomizedBenchmarking protocol to
|
1637
|
+
perform the analysis for the standard CRB and interleaved RB subexperiments
|
1638
|
+
that constitute the IRB process. As such, this class takes as input
|
1639
|
+
the subset of RandomizedBenchmarking's arguments relevant for CRB.
|
1640
|
+
"""
|
1641
|
+
|
1642
|
+
def __init__(self, defaultfit='full', asymptote='std', rtype='EI', seed=(0.8, 0.95),
|
1643
|
+
bootstrap_samples=200, depths='all', name=None):
|
1644
|
+
"""
|
1645
|
+
Initialize an RB protocol for analyzing RB data.
|
1646
|
+
|
1647
|
+
Parameters
|
1648
|
+
----------
|
1649
|
+
defaultfit: 'A-fixed' or 'full'
|
1650
|
+
The summary data is fit to A + Bp^m with A fixed and with A as a fit parameter.
|
1651
|
+
If 'A-fixed' then the default results displayed are those from fitting with A
|
1652
|
+
fixed, and if 'full' then the default results displayed are those where A is a
|
1653
|
+
fit parameter.
|
1654
|
+
|
1655
|
+
asymptote : 'std' or float, optional
|
1656
|
+
The summary data is fit to A + Bp^m with A fixed and with A has a fit parameter,
|
1657
|
+
with the default results returned set by `defaultfit`. This argument specifies the
|
1658
|
+
value used when 'A' is fixed. If left as 'std', then 'A' defaults to 1/2^n if
|
1659
|
+
`datatype` is `success_probabilities` and to 1/4^n if `datatype` is
|
1660
|
+
`adjusted_success_probabilities`.
|
1661
|
+
|
1662
|
+
rtype : 'EI' or 'AGI', optional
|
1663
|
+
The RB error rate definition convention. 'EI' results in RB error rates that are associated
|
1664
|
+
with the entanglement infidelity, which is the error probability with stochastic Pauli errors.
|
1665
|
+
'AGI' results in RB error rates that are associated with the average gate infidelity.
|
1666
|
+
|
1667
|
+
seed : list, optional
|
1668
|
+
Seeds for the fit of B and p (A is seeded to the asymptote defined by `asympote`).
|
1669
|
+
|
1670
|
+
bootstrap_samples : float, optional
|
1671
|
+
The number of samples for generating bootstrapped error bars.
|
1672
|
+
|
1673
|
+
depths: list or 'all'
|
1674
|
+
If not 'all', a list of depths to use (data at other depths is discarded).
|
1675
|
+
|
1676
|
+
name : str, optional
|
1677
|
+
The name of this protocol, also used to (by default) name the
|
1678
|
+
results produced by this protocol. If None, the class name will
|
1679
|
+
be used.
|
1680
|
+
"""
|
1681
|
+
super().__init__(name)
|
1682
|
+
self.seed = seed
|
1683
|
+
self.depths = depths
|
1684
|
+
self.bootstrap_samples = bootstrap_samples
|
1685
|
+
self.asymptote = asymptote
|
1686
|
+
self.rtype = rtype
|
1687
|
+
self.datatype = 'success_probabilities'
|
1688
|
+
self.defaultfit = defaultfit
|
1689
|
+
|
1690
|
+
def run(self, data, memlimit=None, comm=None):
|
1691
|
+
"""
|
1692
|
+
Run this protocol on `data`.
|
1693
|
+
|
1694
|
+
Parameters
|
1695
|
+
----------
|
1696
|
+
data : ProtocolData
|
1697
|
+
The input data.
|
1698
|
+
|
1699
|
+
memlimit : int, optional
|
1700
|
+
A rough per-processor memory limit in bytes.
|
1701
|
+
|
1702
|
+
comm : mpi4py.MPI.Comm, optional
|
1703
|
+
When not ``None``, an MPI communicator used to run this protocol
|
1704
|
+
in parallel.
|
1705
|
+
|
1706
|
+
Returns
|
1707
|
+
-------
|
1708
|
+
RandomizedBenchmarkingResults
|
1709
|
+
"""
|
1710
|
+
design = data.edesign
|
1711
|
+
assert(isinstance(design, InterleavedRBDesign)), 'This protocol can only be run on InterleavedRBDesign.'
|
1712
|
+
#initialize a RandomizedBenchmarking protocol to use as a helper
|
1713
|
+
#for performing analysis on the two subexperiments.
|
1714
|
+
rb_protocol = RandomizedBenchmarking('success_probabilities', self.defaultfit, self.asymptote, self.rtype,
|
1715
|
+
self.seed, self.bootstrap_samples, self.depths, name=None)
|
1716
|
+
|
1717
|
+
#run the RB protocol on both subdesigns.
|
1718
|
+
crb_results = rb_protocol.run(data['crb'])
|
1719
|
+
icrb_results = rb_protocol.run(data['icrb'])
|
1720
|
+
|
1721
|
+
nqubits = len(design.qubit_labels)
|
1722
|
+
#let the dimension depend on the value of rtype.
|
1723
|
+
dim = 2**nqubits
|
1724
|
+
if self.rtype == 'EI':
|
1725
|
+
dim_prefactor = (dim**2 -1)/(dim**2)
|
1726
|
+
elif self.rtype == 'AGI':
|
1727
|
+
dim_prefactor = (dim -1)/dim
|
1728
|
+
else:
|
1729
|
+
raise ValueError('Only EI and AGI type IRB numbers are currently implemented.')
|
1730
|
+
|
1731
|
+
irb_numbers = dict()
|
1732
|
+
irb_bounds = dict()
|
1733
|
+
#use the crb and icrb results to get the irb number and the bounds.
|
1734
|
+
for fit_key in crb_results.fits.keys():
|
1735
|
+
p_crb = crb_results.fits[fit_key].estimates['p']
|
1736
|
+
p_icrb = icrb_results.fits[fit_key].estimates['p']
|
1737
|
+
irb_numbers[fit_key] = dim_prefactor*(1-(p_icrb/p_crb))
|
1738
|
+
#Magesan paper gives the bounds as the minimum of two quantities.
|
1739
|
+
possible_bound_1 = dim_prefactor * (abs(p_crb - (p_icrb/p_crb)) + (1 - p_crb))
|
1740
|
+
possible_bound_2 = (2*(dim**2-1)*(1-p_crb))/(p_crb*dim**2) + (4*_np.sqrt(1-p_crb)*_np.sqrt(dim**2 - 1))/p_crb
|
1741
|
+
#The value of the possible_bound_2 coming directly from the Magesan paper should be in units of AGI.
|
1742
|
+
#So if we want EI use the standard dimensional conversion factor.
|
1743
|
+
if self.rtype == 'EI':
|
1744
|
+
possible_bound_2 = ((dim + 1)/dim)*possible_bound_2
|
1745
|
+
irb_bounds[fit_key] = min(possible_bound_1, possible_bound_2)
|
1746
|
+
|
1747
|
+
children = {'crb': _proto.ProtocolResultsDir(data['crb'], crb_results),
|
1748
|
+
'icrb': _proto.ProtocolResultsDir(data['icrb'], icrb_results)}
|
1749
|
+
|
1750
|
+
irb_top_results = InterleavedRandomizedBenchmarkingResults(data, self, irb_numbers, irb_bounds)
|
1751
|
+
|
1752
|
+
return _proto.ProtocolResultsDir(data, irb_top_results, children = children)
|
1753
|
+
|
1754
|
+
class InterleavedRandomizedBenchmarkingResults(_proto.ProtocolResults):
|
1755
|
+
"""
|
1756
|
+
Class for storing the results of an interleaved randomized benchmarking experiment.
|
1757
|
+
This subclasses off of ProtocolResultsDir as this class acts primarily as both a container
|
1758
|
+
class for holding the two subexperiment's results, as well as containing some specialized
|
1759
|
+
information regarding the IRB number estimates.
|
1760
|
+
"""
|
1761
|
+
|
1762
|
+
def __init__(self, data, protocol, irb_numbers, irb_bounds):
|
1763
|
+
#msg = 'rb_subexperiment_results should be a dictionary with values corresponding to the'\
|
1764
|
+
# +' standard CRB and interleaved CRB subexperiments used in performing IRB.'
|
1765
|
+
#assert(isinstance(rb_subexperiment_results, dict)), msg
|
1766
|
+
#super().__init__(data, rb_subexperiment_results)
|
1767
|
+
super().__init__(data, protocol)
|
1768
|
+
|
1769
|
+
self.irb_numbers = irb_numbers
|
1770
|
+
self.irb_bounds = irb_bounds
|
1400
1771
|
|
1401
1772
|
|
1402
1773
|
RB = RandomizedBenchmarking
|