pygsti.protocols.rb

RB Protocol objects

Module Contents

Classes

CliffordRBDesign

Experiment design for Clifford randomized benchmarking.

DirectRBDesign

Experiment design for Direct randomized benchmarking.

MirrorRBDesign

Experiment design for mirror randomized benchmarking.

BinaryRBDesign

Experiment design for binary randomized benchmarking.

RandomizedBenchmarking

The randomized benchmarking protocol.

RandomizedBenchmarkingResults

The results of running randomized benchmarking.

Attributes

RB

RBResults

class pygsti.protocols.rb.CliffordRBDesign(pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels=None, randomizeout=False, interleaved_circuit=None, citerations=20, compilerargs=(), exact_compilation_key=None, descriptor='A Clifford RB experiment', add_default_protocol=False, seed=None, verbosity=1, num_processes=1)

Bases: pygsti.protocols.vb.BenchmarkingDesign

Experiment design for Clifford randomized benchmarking.

This encapsulates a “Clifford randomized benchmarking” (CRB) experiment. CRB is the RB protocol defined in “Scalable and robust randomized benchmarking of quantum processes”, Magesan et al. PRL 106 180504 (2011). The circuits created by this function will respect the connectivity and gate-set of the device encoded by pspec (see the QubitProcessorSpec object docstring for how to construct the relevant pspec for a device).

Note that this function uses the convention that a depth “l” CRB circuit consists of “l”+2 Clifford gates before compilation.

Parameters

pspecQubitProcessorSpec

The QubitProcessorSpec for the device that the CRB experiment is being generated for, which defines the “native” gate-set and the connectivity of the device. The returned CRB circuits will be over the gates in pspec, and will respect the connectivity encoded by pspec.

clifford_compilationsdict

A dictionary with the potential keys ‘absolute’ and ‘paulieq’ and corresponding class:CompilationRules values. These compilation rules specify how to compile the “native” gates of pspec into Clifford gates.

depthslist of ints

The “CRB depths” of the circuit; a list of integers >= 0. The CRB length is the number of Cliffords in the circuit - 2 before each Clifford is compiled into the native gate-set.

circuits_per_depthint

The number of (possibly) different CRB circuits sampled at each length.

qubit_labelslist, optional

If not None, a list of the qubits that the RB circuits are to be sampled for. This should be all or a subset of the qubits in the device specified by the QubitProcessorSpec pspec. If None, it is assumed that the RB circuit should be over all the qubits. Note that the ordering of this list is the order of the “wires” in the returned circuit, but is otherwise irrelevant. If desired, a circuit that explicitly idles on the other qubits can be obtained by using methods of the Circuit object.

randomizeoutbool, optional

If False, the ideal output of the circuits (the “success” or “survival” outcome) is always the all-zeros bit string. This is probably considered to be the “standard” in CRB. If True, the ideal output a circuit is randomized to a uniformly random bit-string. This setting is useful for, e.g., detecting leakage/loss/measurement-bias etc.

citerationsint, optional

Some of the Clifford compilation algorithms in pyGSTi (including the default algorithm) are randomized, and the lowest-cost circuit is chosen from all the circuit generated in the iterations of the algorithm. This is the number of iterations used. The time required to generate a CRB circuit is linear in citerations * (CRB length + 2). Lower-depth / lower 2-qubit gate count compilations of the Cliffords are important in order to successfully implement CRB on more qubits.

compilerargslist, optional

A list of arguments that are handed to compile_clifford() function, which includes all the optional arguments of compile_clifford() after the iterations option (set by citerations). In order, this list should be values for:

  • algorithm : str. A string that specifies the compilation algorithm. The default in compile_clifford() will always be whatever we consider to be the ‘best’ all-round algorithm.

  • aargs : list. A list of optional arguments for the particular compilation algorithm.

  • costfunction : ‘str’ or function. The cost-function from which the “best” compilation for a Clifford is chosen from all citerations compilations. The default costs a circuit as 10x the num. of 2-qubit gates in the circuit + 1x the depth of the circuit.

  • prefixpaulis : bool. Whether to prefix or append the Paulis on each Clifford.

  • paulirandomize : bool. Whether to follow each layer in the Clifford circuit with a random Pauli on each qubit (compiled into native gates). I.e., if this is True the native gates are Pauli-randomized. When True, this prevents any coherent errors adding (on average) inside the layers of each compiled Clifford, at the cost of increased circuit depth. Defaults to False.

For more information on these options, see the compile_clifford() docstring.

descriptorstr, optional

A string describing the experiment generated, which will be stored in the returned dictionary.

add_default_protocolbool, optional

Whether to add a default RB protocol to the experiment design, which can be run later (once data is taken) by using a DefaultProtocolRunner object.

seedint, optional

A seed to initialize the random number generator used for creating random clifford circuits.

verbosityint, optional

If > 0 the number of circuits generated so far is shown.

Create a new CircuitListsDesign object.

Parameters

circuit_listslist or PlaquetteGridCircuitStructure

A list whose elements are themselves lists of Circuit objects, specifying the data that needs to be taken. Alternatively, a single PlaquetteGridCircuitStructure object containing a sequence of circuits lists, each at a different “x” value (usually the maximum circuit depth).

all_circuits_needing_datalist, optional

A list of all the circuits needing data. By default, This is just the concatenation of the elements of circuit_lists with duplicates removed. The only reason to specify this separately is if you happen to have this list lying around.

qubit_labelstuple, optional

The qubits that this experiment design applies to. If None, the line labels of the first circuit is used.

nestedbool, optional

Whether the elements of circuit_lists are nested, e.g. whether circuit_lists[i] is a subset of circuit_lists[i+1]. This is useful to know because certain operations can be more efficient when it is known that the lists are nested.

remove_duplicatesbool, optional

Whether to remove duplicates when automatically creating all the circuits that need data (this argument isn’t used when all_circuits_needing_data is given).

Returns

CircuitListsDesign

classmethod from_existing_circuits(data_by_depth, qubit_labels=None, randomizeout=False, citerations=20, compilerargs=(), interleaved_circuit=None, descriptor='A Clifford RB experiment', add_default_protocol=False)

Create a CliffordRBDesign from an existing set of sampled RB circuits.

This function serves as an alternative to the usual method of creating a Clifford RB experiment design by sampling a number of circuits randomly. This function takes a list of previously-sampled random circuits and does not sampling internally.

Parameters
data_by_depthdict

A dictionary whose keys are integer depths and whose values are lists of (circuit, ideal_outcome, num_native_gates) tuples giving each RB circuit, its ideal (correct) outcome, and (optionally) the number of native gates in the compiled Cliffords. If only a 2-tuple is passed, i.e. number of native gates is not included, the average_gates_per_clifford() function will not work.

qubit_labelslist, optional

If not None, a list of the qubits that the RB circuits are to be sampled for. This should be all or a subset of the qubits in the device specified by the QubitProcessorSpec pspec. If None, it is assumed that the RB circuit should be over all the qubits. Note that the ordering of this list is the order of the “wires” in the returned circuit, but is otherwise irrelevant. If desired, a circuit that explicitly idles on the other qubits can be obtained by using methods of the Circuit object.

randomizeoutbool, optional

If False, the ideal output of the circuits (the “success” or “survival” outcome) is always the all-zeros bit string. This is probably considered to be the “standard” in CRB. If True, the ideal output a circuit is randomized to a uniformly random bit-string. This setting is useful for, e.g., detecting leakage/loss/measurement-bias etc.

citerationsint, optional

Some of the Clifford compilation algorithms in pyGSTi (including the default algorithm) are randomized, and the lowest-cost circuit is chosen from all the circuit generated in the iterations of the algorithm. This is the number of iterations used. The time required to generate a CRB circuit is linear in citerations * (CRB length + 2). Lower-depth / lower 2-qubit gate count compilations of the Cliffords are important in order to successfully implement CRB on more qubits.

compilerargslist, optional

A list of arguments that are handed to compile_clifford() function, which includes all the optional arguments of compile_clifford() after the iterations option (set by citerations). In order, this list should be values for:

  • algorithm : str. A string that specifies the compilation algorithm. The default in compile_clifford() will always be whatever we consider to be the ‘best’ all-round algorithm.

  • aargs : list. A list of optional arguments for the particular compilation algorithm.

  • costfunction : ‘str’ or function. The cost-function from which the “best” compilation for a Clifford is chosen from all citerations compilations. The default costs a circuit as 10x the num. of 2-qubit gates in the circuit + 1x the depth of the circuit.

  • prefixpaulis : bool. Whether to prefix or append the Paulis on each Clifford.

  • paulirandomize : bool. Whether to follow each layer in the Clifford circuit with a random Pauli on each qubit (compiled into native gates). I.e., if this is True the native gates are Pauli-randomized. When True, this prevents any coherent errors adding (on average) inside the layers of each compiled Clifford, at the cost of increased circuit depth. Defaults to False.

For more information on these options, see the compile_clifford() docstring.

descriptorstr, optional

A string describing the experiment generated, which will be stored in the returned dictionary.

add_default_protocolbool, optional

Whether to add a default RB protocol to the experiment design, which can be run later (once data is taken) by using a DefaultProtocolRunner object.

Returns

CliffordRBDesign

average_native_gates_per_clifford_for_circuit(list_idx, circ_idx)

The average number of native gates per Clifford for a specific circuit

Parameters
list_idx: int

The index of the circuit list (for a given depth)

circ_idx: int

The index of the circuit within the circuit list

Returns
avg_gate_counts: dict

The average number of native gates, native 2Q gates, and native size per Clifford as values with respective label keys

average_native_gates_per_clifford_for_circuit_list(list_idx)

The average number of gates per Clifford for a circuit list

This essentially gives the average number of native gates per Clifford for a given depth (indexed by list index, not depth).

Parameters
list_idx: int

The index of the circuit list (for a given depth)

circ_idx: int

The index of the circuit within the circuit list

Returns
float

The average number of native gates per Clifford

average_native_gates_per_clifford()

The average number of native gates per Clifford for all circuits

Returns
float

The average number of native gates per Clifford

map_qubit_labels(mapper)

Creates a new experiment design whose circuits’ qubit labels are updated according to a given mapping.

Parameters
mapperdict or function

A dictionary whose keys are the existing self.qubit_labels values and whose value are the new labels, or a function which takes a single (existing qubit-label) argument and returns a new qubit-label.

Returns

CliffordRBDesign

class pygsti.protocols.rb.DirectRBDesign(pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels=None, sampler='edgegrab', samplerargs=None, addlocal=False, lsargs=(), randomizeout=False, cliffordtwirl=True, conditionaltwirl=True, citerations=20, compilerargs=(), partitioned=False, descriptor='A DRB experiment', add_default_protocol=False, seed=None, verbosity=1, num_processes=1)

Bases: pygsti.protocols.vb.BenchmarkingDesign

Experiment design for Direct randomized benchmarking.

This encapsulates a “direct randomized benchmarking” (DRB) experiments. DRB was a protocol introduced in arXiv:1807.07975 (2018).

An n-qubit DRB circuit consists of (1) a circuit the prepares a uniformly random stabilizer state; (2) a length-l circuit (specified by length) consisting of circuit layers sampled according to some user-specified distribution (specified by sampler), (3) a circuit that maps the output of the preceeding circuit to a computational basis state. See arXiv:1807.07975 (2018) for further details.

Parameters

pspecQubitProcessorSpec

The QubitProcessorSpec for the device that the circuit is being sampled for, which defines the “native” gate-set and the connectivity of the device. The returned DRB circuit will be over the gates in pspec, and will respect the connectivity encoded by pspec. Note that pspec is always handed to the sampler, as the first argument of the sampler function (this is only of importance when not using an in-built sampler for the “core” of the DRB circuit). Unless qubit_labels is not None, the circuit is sampled over all the qubits in pspec.

clifford_compilationsdict

A dictionary with the potential keys ‘absolute’ and ‘paulieq’ and corresponding CompilationRules values. These compilation rules specify how to compile the “native” gates of pspec into Clifford gates.

depthsint

The set of “direct RB depths” for the circuits. The DRB depths must be integers >= 0. Unless addlocal is True, the DRB length is the depth of the “core” random circuit, sampled according to sampler, specified in step (2) above. If addlocal is True, each layer in the “core” circuit sampled according to “sampler` is followed by a layer of 1-qubit gates, with sampling specified by lsargs (and the first layer is proceeded by a layer of 1-qubit gates), and so the circuit of step (2) is length 2*`length` + 1.

circuits_per_depthint

The number of (possibly) different DRB circuits sampled at each length.

qubit_labelslist, optional

If not None, a list of the qubits to sample the circuit for. This is a subset of pspec.qubit_labels. If None, the circuit is sampled to act on all the qubits in pspec.

samplerstr or function, optional

If a string, this should be one of: {‘edgegrab’, pairingQs’, ‘Qelimination’, ‘co2Qgates’, ‘local’}. Except for ‘local’, this corresponds to sampling layers according to the sampling function in rb.sampler named circuit_layer_by_* (with * replaced by ‘sampler’). For ‘local’, this corresponds to sampling according to rb.sampler.circuit_layer_of_oneQgates [which is not a valid form of sampling for n-qubit DRB, but is not explicitly forbidden in this function]. If sampler is a function, it should be a function that takes as the first argument a QubitProcessorSpec, and returns a random circuit layer as a list of gate Label objects. Note that the default ‘Qelimination’ is not necessarily the most useful in-built sampler, but it is the only sampler that requires no parameters beyond the QubitProcessorSpec and works for arbitrary connectivity devices. See the docstrings for each of these samplers for more information.

samplerargslist, optional

A list of arguments that are handed to the sampler function, specified by sampler. The first argument handed to the sampler is pspec, the second argument is qubit_labels, and samplerargs lists the remaining arguments handed to the sampler. This is not optional for some choices of sampler.

addlocalbool, optional

Whether to follow each layer in the “core” circuits, sampled according to sampler with a layer of 1-qubit gates.

lsargslist, optional

Only used if addlocal is True. A list of optional arguments handed to the 1Q gate layer sampler circuit_layer_by_oneQgate(). Specifies how to sample 1Q-gate layers.

randomizeoutbool, optional

If False, the ideal output of the circuits (the “success” or “survival” outcome) is the all-zeros bit string. If True, the ideal output of each circuit is randomized to a uniformly random bit-string. This setting is useful for, e.g., detecting leakage/loss/measurement-bias etc.

cliffordtwirlbool, optional

Wether to begin the circuits with a sequence that generates a random stabilizer state. For standard DRB this should be set to True. There are a variety of reasons why it is better to have this set to True.

conditionaltwirlbool, optional

DRB only requires that the initial/final sequences of step (1) and (3) create/measure a uniformly random / particular stabilizer state, rather than implement a particular unitary. step (1) and (3) can be achieved by implementing a uniformly random Clifford gate and the unique inversion Clifford, respectively. This is implemented if conditionaltwirl is False. However, steps (1) and (3) can be implemented much more efficiently than this: the sequences of (1) and (3) only need to map a particular input state to a particular output state, if conditionaltwirl is True this more efficient option is chosen – this is option corresponds to “standard” DRB. (the term “conditional” refers to the fact that in this case we essentially implementing a particular Clifford conditional on a known input).

citerationsint, optional

Some of the stabilizer state / Clifford compilation algorithms in pyGSTi (including the default algorithms) are randomized, and the lowest-cost circuit is chosen from all the circuits generated in the iterations of the algorithm. This is the number of iterations used. The time required to generate a DRB circuit is linear in citerations. Lower-depth / lower 2-qubit gate count compilations of steps (1) and (3) are important in order to successfully implement DRB on as many qubits as possible.

compilerargslist, optional

A list of arguments that are handed to the compile_stabilier_state/measurement()functions (or the compile_clifford() function if conditionaltwirl `is False). This includes all the optional arguments of these functions *after* the `iterations option (set by citerations). For most purposes the default options will be suitable (or at least near-optimal from the compilation methods in-built into pyGSTi). See the docstrings of these functions for more information.

partitionedbool, optional

If False, each circuit is returned as a single full circuit. If True, each circuit is returned as a list of three circuits consisting of: (1) the stabilizer-prep circuit, (2) the core random circuit, (3) the pre-measurement circuit. In that case the full circuit is obtained by appended (2) to (1) and then (3) to (1).

descriptorstr, optional

A description of the experiment being generated. Stored in the output dictionary.

add_default_protocolbool, optional

Whether to add a default RB protocol to the experiment design, which can be run later (once data is taken) by using a DefaultProtocolRunner object.

seedint, optional

A seed to initialize the random number generator used for creating random clifford circuits.

verbosityint, optional

If > 0 the number of circuits generated so far is shown.

Create a new CircuitListsDesign object.

Parameters

circuit_listslist or PlaquetteGridCircuitStructure

A list whose elements are themselves lists of Circuit objects, specifying the data that needs to be taken. Alternatively, a single PlaquetteGridCircuitStructure object containing a sequence of circuits lists, each at a different “x” value (usually the maximum circuit depth).

all_circuits_needing_datalist, optional

A list of all the circuits needing data. By default, This is just the concatenation of the elements of circuit_lists with duplicates removed. The only reason to specify this separately is if you happen to have this list lying around.

qubit_labelstuple, optional

The qubits that this experiment design applies to. If None, the line labels of the first circuit is used.

nestedbool, optional

Whether the elements of circuit_lists are nested, e.g. whether circuit_lists[i] is a subset of circuit_lists[i+1]. This is useful to know because certain operations can be more efficient when it is known that the lists are nested.

remove_duplicatesbool, optional

Whether to remove duplicates when automatically creating all the circuits that need data (this argument isn’t used when all_circuits_needing_data is given).

Returns

CircuitListsDesign

classmethod from_existing_circuits(circuits_and_idealouts_by_depth, qubit_labels=None, sampler='edgegrab', samplerargs=None, addlocal=False, lsargs=(), randomizeout=False, cliffordtwirl=True, conditionaltwirl=True, citerations=20, compilerargs=(), partitioned=False, descriptor='A DRB experiment', add_default_protocol=False)

Create a DirectRBDesign from an existing set of sampled RB circuits.

This function serves as an alternative to the usual method of creating a direct RB experiment design by sampling a number of circuits randomly. This function takes a list of previously-sampled random circuits and does not sampling internally.

Parameters
circuits_and_idealouts_by_depthdict

A dictionary whose keys are integer depths and whose values are lists of (circuit, ideal_outcome) 2-tuples giving each RB circuit and its ideal (correct) outcome.

qubit_labelslist, optional

If not None, a list of the qubits to sample the circuit for. This is a subset of pspec.qubit_labels. If None, the circuit is sampled to act on all the qubits in pspec.

samplerstr or function, optional

If a string, this should be one of: {‘edgegrab’, pairingQs’, ‘Qelimination’, ‘co2Qgates’, ‘local’}. Except for ‘local’, this corresponds to sampling layers according to the sampling function in rb.sampler named circuit_layer_by_* (with * replaced by ‘sampler’). For ‘local’, this corresponds to sampling according to rb.sampler.circuit_layer_of_oneQgates [which is not a valid form of sampling for n-qubit DRB, but is not explicitly forbidden in this function]. If sampler is a function, it should be a function that takes as the first argument a QubitProcessorSpec, and returns a random circuit layer as a list of gate Label objects. Note that the default ‘Qelimination’ is not necessarily the most useful in-built sampler, but it is the only sampler that requires no parameters beyond the QubitProcessorSpec and works for arbitrary connectivity devices. See the docstrings for each of these samplers for more information.

samplerargslist, optional

A list of arguments that are handed to the sampler function, specified by sampler. Defaults to [0.25, ]. The first argument handed to the sampler is pspec, the second argument is qubit_labels, and samplerargs lists the remaining arguments handed to the sampler. This is not optional for some choices of sampler.

addlocalbool, optional

Whether to follow each layer in the “core” circuits, sampled according to sampler with a layer of 1-qubit gates.

lsargslist, optional

Only used if addlocal is True. A list of optional arguments handed to the 1Q gate layer sampler circuit_layer_by_oneQgate(). Specifies how to sample 1Q-gate layers.

randomizeoutbool, optional

If False, the ideal output of the circuits (the “success” or “survival” outcome) is the all-zeros bit string. If True, the ideal output of each circuit is randomized to a uniformly random bit-string. This setting is useful for, e.g., detecting leakage/loss/measurement-bias etc.

cliffordtwirlbool, optional

Wether to begin the circuits with a sequence that generates a random stabilizer state. For standard DRB this should be set to True. There are a variety of reasons why it is better to have this set to True.

conditionaltwirlbool, optional

DRB only requires that the initial/final sequences of step (1) and (3) create/measure a uniformly random / particular stabilizer state, rather than implement a particular unitary. step (1) and (3) can be achieved by implementing a uniformly random Clifford gate and the unique inversion Clifford, respectively. This is implemented if conditionaltwirl is False. However, steps (1) and (3) can be implemented much more efficiently than this: the sequences of (1) and (3) only need to map a particular input state to a particular output state, if conditionaltwirl is True this more efficient option is chosen – this is option corresponds to “standard” DRB. (the term “conditional” refers to the fact that in this case we essentially implementing a particular Clifford conditional on a known input).

citerationsint, optional

Some of the stabilizer state / Clifford compilation algorithms in pyGSTi (including the default algorithms) are randomized, and the lowest-cost circuit is chosen from all the circuits generated in the iterations of the algorithm. This is the number of iterations used. The time required to generate a DRB circuit is linear in citerations. Lower-depth / lower 2-qubit gate count compilations of steps (1) and (3) are important in order to successfully implement DRB on as many qubits as possible.

compilerargslist, optional

A list of arguments that are handed to the compile_stabilier_state/measurement()functions (or the compile_clifford() function if conditionaltwirl `is False). This includes all the optional arguments of these functions *after* the `iterations option (set by citerations). For most purposes the default options will be suitable (or at least near-optimal from the compilation methods in-built into pyGSTi). See the docstrings of these functions for more information.

partitionedbool, optional

If False, each circuit is returned as a single full circuit. If True, each circuit is returned as a list of three circuits consisting of: (1) the stabilizer-prep circuit, (2) the core random circuit, (3) the pre-measurement circuit. In that case the full circuit is obtained by appended (2) to (1) and then (3) to (1).

descriptorstr, optional

A description of the experiment being generated. Stored in the output dictionary.

add_default_protocolbool, optional

Whether to add a default RB protocol to the experiment design, which can be run later (once data is taken) by using a DefaultProtocolRunner object.

Returns

DirectRBDesign

map_qubit_labels(mapper)

Creates a new experiment design whose circuits’ qubit labels are updated according to a given mapping.

Parameters
mapperdict or function

A dictionary whose keys are the existing self.qubit_labels values and whose value are the new labels, or a function which takes a single (existing qubit-label) argument and returns a new qubit-label.

Returns

DirectRBDesign

class pygsti.protocols.rb.MirrorRBDesign(pspec, depths, circuits_per_depth, qubit_labels=None, circuit_type='clifford', clifford_compilations=None, sampler='edgegrab', samplerargs=(0.25,), localclifford=True, paulirandomize=True, descriptor='A mirror RB experiment', add_default_protocol=False, seed=None, num_processes=1, verbosity=1)

Bases: pygsti.protocols.vb.BenchmarkingDesign

Experiment design for mirror randomized benchmarking.

Encapsulates a “mirror randomized benchmarking” (MRB) experiment, for the case of Clifford gates and with the option of Pauli randomization and local Clifford twirling. To implement mirror RB it is necessary for U^(-1) to in the gate set for every gate U in the gate set.

THIS METHOD IS IN DEVELOPEMENT. DO NOT EXPECT THAT THIS FUNCTION WILL BEHAVE THE SAME IN FUTURE RELEASES OF PYGSTI!

Parameters

pspecQubitProcessorSpec

The QubitProcessorSpec for the device that the experiment is being generated for. The pspec is always handed to the sampler, as the first argument of the sampler function.

clifford_compilationsdict

A dictionary with the potential keys ‘absolute’ and ‘paulieq’ and corresponding CompilationRules values. These compilation rules specify how to compile the “native” gates of pspec into Clifford gates.

depthslist of ints

The “mirror RB depths” of the circuits, which is closely related to the circuit depth. A MRB length must be an even integer, and can be zero.

  • If localclifford and paulirandomize are False, the depth of a sampled circuit = the MRB length. The first length/2 layers are all sampled independently according to the sampler specified by sampler. The remaining half of the circuit is the “inversion” circuit that is determined by the first half.

  • If paulirandomize is True and localclifford is False, the depth of a circuit is 2*length+1 with odd-indexed layers sampled according to the sampler specified by sampler, and the the zeroth layer + the even-indexed layers consisting of random 1-qubit Pauli gates.

  • If paulirandomize and localclifford are True, the depth of a circuit is 2*length+1 + X where X is a random variable (between 0 and normally <= ~12-16) that accounts for the depth from the layer of random 1-qubit Cliffords at the start and end of the circuit.

  • If paulirandomize is False and localclifford is True, the depth of a circuit is length + X where X is a random variable (between 0 and normally <= ~12-16) that accounts for the depth from the layer of random 1-qubit Cliffords at the start and end of the circuit.

circuits_per_depthint

The number of (possibly) different MRB circuits sampled at each length.

qubit_labelslist, optional

If not None, a list of the qubits that the RB circuit is to be sampled for. This should be all or a subset of the qubits in the device specified by the QubitProcessorSpec pspec. If None, it is assumed that the RB circuit should be over all the qubits. Note that the ordering of this list is the order of the “wires” in the returned circuit, but is otherwise irrelevant.

samplerstr or function, optional

If a string, this should be one of: {‘edgegrab’, ‘Qelimination’, ‘co2Qgates’, ‘local’}. Except for ‘local’, this corresponds to sampling layers according to the sampling function in rb.sampler named circuit_layer_by* (with * replaced by ‘sampler’). For ‘local’, this corresponds to sampling according to rb.sampler.circuit_layer_of_oneQgates [which is not a valid option for n-qubit MRB – it results in sim. 1-qubit MRB – but it is not explicitly forbidden by this function]. If sampler is a function, it should be a function that takes as the first argument a QubitProcessorSpec, and returns a random circuit layer as a list of gate Label objects. Note that the default ‘Qelimination’ is not necessarily the most useful in-built sampler, but it is the only sampler that requires no parameters beyond the QubitProcessorSpec and works for arbitrary connectivity devices. See the docstrings for each of these samplers for more information.

samplerargslist, optional

A list of arguments that are handed to the sampler function, specified by sampler. The first argument handed to the sampler is pspec and samplerargs lists the remaining arguments handed to the sampler.

localcliffordbool, optional

Whether to start the circuit with uniformly random 1-qubit Cliffords and all of the qubits (compiled into the native gates of the device).

paulirandomizebool, optional

Whether to have uniformly random Pauli operators on all of the qubits before and after all of the layers in the “out” and “back” random circuits. At length 0 there is a single layer of random Pauli operators (in between two layers of 1-qubit Clifford gates if localclifford is True); at length l there are 2l+1 Pauli layers as there are

descriptorstr, optional

A string describing the generated experiment. Stored in the returned dictionary.

add_default_protocolbool, optional

Whether to add a default RB protocol to the experiment design, which can be run later (once data is taken) by using a DefaultProtocolRunner object.

Create a new CircuitListsDesign object.

Parameters

circuit_listslist or PlaquetteGridCircuitStructure

A list whose elements are themselves lists of Circuit objects, specifying the data that needs to be taken. Alternatively, a single PlaquetteGridCircuitStructure object containing a sequence of circuits lists, each at a different “x” value (usually the maximum circuit depth).

all_circuits_needing_datalist, optional

A list of all the circuits needing data. By default, This is just the concatenation of the elements of circuit_lists with duplicates removed. The only reason to specify this separately is if you happen to have this list lying around.

qubit_labelstuple, optional

The qubits that this experiment design applies to. If None, the line labels of the first circuit is used.

nestedbool, optional

Whether the elements of circuit_lists are nested, e.g. whether circuit_lists[i] is a subset of circuit_lists[i+1]. This is useful to know because certain operations can be more efficient when it is known that the lists are nested.

remove_duplicatesbool, optional

Whether to remove duplicates when automatically creating all the circuits that need data (this argument isn’t used when all_circuits_needing_data is given).

Returns

CircuitListsDesign

classmethod from_existing_circuits(circuits_and_idealouts_by_depth, qubit_labels=None, circuit_type='clifford', sampler='edgegrab', samplerargs=(0.25,), localclifford=True, paulirandomize=True, descriptor='A mirror RB experiment', add_default_protocol=False)

Create a MirrorRBDesign from an existing set of sampled RB circuits.

This function serves as an alternative to the usual method of creating a mirror RB experiment design by sampling a number of circuits randomly. This function takes a list of previously-sampled random circuits and does not sampling internally.

Parameters
circuits_and_idealouts_by_depthdict

A dictionary whose keys are integer depths and whose values are lists of (circuit, ideal_outcome) 2-tuples giving each RB circuit and its ideal (correct) outcome.

See init docstring for details on all other parameters.

Returns

MirrorRBDesign

map_qubit_labels(mapper)

Creates a new experiment design whose circuits’ qubit labels are updated according to a given mapping.

Parameters
mapperdict or function

A dictionary whose keys are the existing self.qubit_labels values and whose value are the new labels, or a function which takes a single (existing qubit-label) argument and returns a new qubit-label.

Returns

MirrorRBDesign

class pygsti.protocols.rb.BinaryRBDesign(pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels=None, layer_sampling='mixed1q2q', sampler='edgegrab', samplerargs=None, addlocal=False, lsargs=(), descriptor='A BiRB experiment', add_default_protocol=False, seed=None, verbosity=1, num_processes=1)

Bases: pygsti.protocols.vb.BenchmarkingDesign

Experiment design for binary randomized benchmarking.

Encapsulates a “binary randomized benchmarking” (BiRB) experiment.

Parameters

pspecQubitProcessorSpec

The QubitProcessorSpec for the device that the experiment is being generated for. The pspec is always handed to the sampler, as the first argument of the sampler function.

clifford_compilation: CompilationRules

Rules for exactly (absolutely) compiling the “native” gates of pspec into Clifford gates.

depthslist of ints

The “benchmark depth” of the circuit, which is the number of randomly sampled layers of gates in the core circuit. The full BiRB circuit has depth=length+2.

circuits_per_depthint

The number of (possibly) different MRB circuits sampled at each length.

qubit_labelslist, optional

If not None, a list of the qubits that the RB circuit is to be sampled for. This should be all or a subset of the qubits in the device specified by the QubitProcessorSpec pspec. If None, it is assumed that the RB circuit should be over all the qubits. Note that the ordering of this list is the order of the ``wires’’ in the returned circuit, but is otherwise irrelevant.

layer_sampling: str, optional
Determines the structure of the randomly sampled layers of gates:

1. ‘mixed1q2q’: Layers contain radomly-sampled two-qubit gates and randomly-sampled single-qubit gates on all remaining qubits. 2. ‘alternating1q2q’: Each layer consists of radomly-sampled two-qubit gates, with all other qubits idling, followed by randomly sampled single-qubit gates on all qubits.

samplerstr or function, optional

If a string, this should be one of: {‘edgegrab’, ‘Qelimination’, ‘co2Qgates’, ‘local’}. Except for ‘local’, this corresponds to sampling layers according to the sampling function in rb.sampler named circuit_layer_by* (with * replaced by ‘sampler’). For ‘local’, this corresponds to sampling according to rb.sampler.circuit_layer_of_oneQgates [which is not a valid option for n-qubit MRB – it results in sim. 1-qubit MRB – but it is not explicitly forbidden by this function]. If sampler is a function, it should be a function that takes as the first argument a QubitProcessorSpec, and returns a random circuit layer as a list of gate Label objects. Note that the default ‘Qelimination’ is not necessarily the most useful in-built sampler, but it is the only sampler that requires no parameters beyond the QubitProcessorSpec and works for arbitrary connectivity devices. See the docstrings for each of these samplers for more information.

samplerargslist, optional

A list of arguments that are handed to the sampler function, specified by sampler. The first argument handed to the sampler is pspec and samplerargs lists the remaining arguments handed to the sampler.

descriptorstr, optional

A string describing the generated experiment. Stored in the returned dictionary.

add_default_protocolbool, optional

Whether to add a default RB protocol to the experiment design, which can be run later (once data is taken) by using a DefaultProtocolRunner object.

Create a new CircuitListsDesign object.

Parameters

circuit_listslist or PlaquetteGridCircuitStructure

A list whose elements are themselves lists of Circuit objects, specifying the data that needs to be taken. Alternatively, a single PlaquetteGridCircuitStructure object containing a sequence of circuits lists, each at a different “x” value (usually the maximum circuit depth).

all_circuits_needing_datalist, optional

A list of all the circuits needing data. By default, This is just the concatenation of the elements of circuit_lists with duplicates removed. The only reason to specify this separately is if you happen to have this list lying around.

qubit_labelstuple, optional

The qubits that this experiment design applies to. If None, the line labels of the first circuit is used.

nestedbool, optional

Whether the elements of circuit_lists are nested, e.g. whether circuit_lists[i] is a subset of circuit_lists[i+1]. This is useful to know because certain operations can be more efficient when it is known that the lists are nested.

remove_duplicatesbool, optional

Whether to remove duplicates when automatically creating all the circuits that need data (this argument isn’t used when all_circuits_needing_data is given).

Returns

CircuitListsDesign

class pygsti.protocols.rb.RandomizedBenchmarking(datatype='success_probabilities', defaultfit='full', asymptote='std', rtype='EI', seed=(0.8, 0.95), bootstrap_samples=200, depths='all', square_mean_root=False, name=None)

Bases: pygsti.protocols.vb.SummaryStatistics

The randomized benchmarking protocol.

This same analysis protocol is used for Clifford, Direct and Mirror RB. The standard Mirror RB analysis is obtained by setting datatype = adjusted_success_probabilities.

Parameters

datatype: ‘success_probabilities’, ‘adjusted_success_probabilities’, or ‘energies’, optional

The type of summary data to extract, average, and the fit to an exponential decay. If ‘success_probabilities’ then the summary data for a circuit is the frequency that the target bitstring is observed, i.e., the success probability of the circuit. If ‘adjusted_success_probabilties’ then the summary data for a circuit is S = sum_{k = 0}^n (-1/2)^k h_k where h_k is the frequency at which the output bitstring is a Hamming distance of k from the target bitstring, and n is the number of qubits. This datatype is used in Mirror RB, but can also be used in Clifford and Direct RB. If ‘energies’, then the summary data is Pauli operator measurement results. This datatype is only used for Binary RB.

defaultfit: ‘A-fixed’ or ‘full’

The summary data is fit to A + Bp^m with A fixed and with A as a fit parameter. If ‘A-fixed’ then the default results displayed are those from fitting with A fixed, and if ‘full’ then the default results displayed are those where A is a fit parameter.

asymptote‘std’ or float, optional

The summary data is fit to A + Bp^m with A fixed and with A has a fit parameter, with the default results returned set by defaultfit. This argument specifies the value used when ‘A’ is fixed. If left as ‘std’, then ‘A’ defaults to 1/2^n if datatype is success_probabilities and to 1/4^n if datatype is adjusted_success_probabilities.

rtype‘EI’ or ‘AGI’, optional

The RB error rate definition convention. ‘EI’ results in RB error rates that are associated with the entanglement infidelity, which is the error probability with stochastic Pauli errors. ‘AGI’ results in RB error rates that are associated with the average gate infidelity.

seedlist, optional

Seeds for the fit of B and p (A is seeded to the asymptote defined by asympote).

bootstrap_samplesfloat, optional

The number of samples for generating bootstrapped error bars.

depths: list or ‘all’

If not ‘all’, a list of depths to use (data at other depths is discarded).

namestr, optional

The name of this protocol, also used to (by default) name the results produced by this protocol. If None, the class name will be used.

Initialize an RB protocol for analyzing RB data.

Parameters

datatype: ‘success_probabilities’, ‘adjusted_success_probabilities’, or ‘energies’, optional

The type of summary data to extract, average, and the fit to an exponential decay. If ‘success_probabilities’ then the summary data for a circuit is the frequency that the target bitstring is observed, i.e., the success probability of the circuit. If ‘adjusted_success_probabilties’ then the summary data for a circuit is S = sum_{k = 0}^n (-1/2)^k h_k where h_k is the frequency at which the output bitstring is a Hamming distance of k from the target bitstring, and n is the number of qubits. This datatype is used in Mirror RB, but can also be used in Clifford and Direct RB. If ‘energies’, then the summary data is Pauli operator measurement results. This datatype is only used for Binary RB.

defaultfit: ‘A-fixed’ or ‘full’

The summary data is fit to A + Bp^m with A fixed and with A as a fit parameter. If ‘A-fixed’ then the default results displayed are those from fitting with A fixed, and if ‘full’ then the default results displayed are those where A is a fit parameter.

asymptote‘std’ or float, optional

The summary data is fit to A + Bp^m with A fixed and with A has a fit parameter, with the default results returned set by defaultfit. This argument specifies the value used when ‘A’ is fixed. If left as ‘std’, then ‘A’ defaults to 1/2^n if datatype is success_probabilities and to 1/4^n if datatype is adjusted_success_probabilities.

rtype‘EI’ or ‘AGI’, optional

The RB error rate definition convention. ‘EI’ results in RB error rates that are associated with the entanglement infidelity, which is the error probability with stochastic Pauli errors. ‘AGI’ results in RB error rates that are associated with the average gate infidelity.

seedlist, optional

Seeds for the fit of B and p (A is seeded to the asymptote defined by asympote).

bootstrap_samplesfloat, optional

The number of samples for generating bootstrapped error bars.

depths: list or ‘all’

If not ‘all’, a list of depths to use (data at other depths is discarded).

namestr, optional

The name of this protocol, also used to (by default) name the results produced by this protocol. If None, the class name will be used.

seed
depths
bootstrap_samples
asymptote
rtype
datatype
defaultfit
square_mean_root
run(data, memlimit=None, comm=None)

Run this protocol on data.

Parameters
dataProtocolData

The input data.

memlimitint, optional

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional

When not None, an MPI communicator used to run this protocol in parallel.

Returns

RandomizedBenchmarkingResults

class pygsti.protocols.rb.RandomizedBenchmarkingResults(data, protocol_instance, fits, depths, defaultfit)

Bases: pygsti.protocols.protocol.ProtocolResults

The results of running randomized benchmarking.

Parameters

dataProtocolData

The experimental data these results are generated from.

protocol_instanceProtocol

The protocol that generated these results.

fitsdict

A dictionary of RB fit parameters.

depthslist or tuple

A sequence of the depths used in the RB experiment. The x-values of the RB fit curve.

defaultfitstr

The default key within fits to plot when calling plot().

Initialize an empty RandomizedBenchmarkingResults object.

depths
rtype
fits
defaultfit
plot(fitkey=None, decay=True, success_probabilities=True, size=(8, 5), ylim=None, xlim=None, legend=True, title=None, figpath=None)

Plots RB data and, optionally, a fitted exponential decay.

Parameters
fitkeydict key, optional

The key of the self.fits dictionary to plot the fit for. If None, will look for a ‘full’ key (the key for a full fit to A + Bp^m if the standard analysis functions are used) and plot this if possible. It otherwise checks that there is only one key in the dict and defaults to this. If there are multiple keys and none of them are ‘full’, fitkey must be specified when decay is True.

decaybool, optional

Whether to plot a fit, or just the data.

success_probabilitiesbool, optional

Whether to plot the success probabilities distribution, as a violin plot. (as well as the average success probabilities at each length).

sizetuple, optional

The figure size

ylimtuple, optional

The y-axis range.

xlimtuple, optional

The x-axis range.

legendbool, optional

Whether to show a legend.

titlestr, optional

A title to put on the figure.

figpathstr, optional

If specified, the figure is saved with this filename.

Returns

None

copy()

Creates a copy of this RandomizedBenchmarkingResults object.

Returns

RandomizedBenchmarkingResults

pygsti.protocols.rb.RB
pygsti.protocols.rb.RBResults