pygsti.protocols

Sub-package containing protocol objects and related inputs, data, and results

Submodules

Package Contents

Classes

FreeformDataSimulator

Computes arbitrary functions of the state data simulator that also computes user-defined functions

ModelFreeformSimulator

A base class for data simulators that utilize models (probably most of them!).

Circuit

A quantum circuit.

ForwardSimulator

A calculator of circuit outcome probability calculations and their derivatives w.r.t. model parameters.

HasProcessorSpec

Adds to an experiment design a processor_spec attribute

GateSetTomographyDesign

Minimal experiment design needed for GST

StandardGSTDesign

Standard GST experiment design consisting of germ-powers sandwiched between fiducials.

GSTInitialModel

Specification of a starting point for GST.

GSTBadFitOptions

Options for post-processing a GST fit that was unsatisfactory.

GSTObjFnBuilders

Holds the objective-function builders needed for long-sequence GST.

GSTGaugeOptSuite

Holds directives to perform one or more gauge optimizations on a model.

GateSetTomography

The core gate set tomography protocol, which optimizes a parameterized model to (best) fit a data set.

LinearGateSetTomography

The linear gate set tomography protocol.

StandardGST

The standard-practice GST protocol.

ModelEstimateResults

A results object that holds model estimates.

GateSetTomographyCheckpoint

A class for storing intermediate results associated with running

StandardGSTCheckpoint

A class for storing intermediate results associated with running

Circuit

A quantum circuit.

ForwardSimulator

A calculator of circuit outcome probability calculations and their derivatives w.r.t. model parameters.

ModelTest

A protocol that tests how well a model agrees with a given set of data.

ModelTestCheckpoint

A class for storing intermediate results associated with running

Protocol

An analysis routine that is run on experimental data. A generalized notion of a QCVV protocol.

MultiPassProtocol

Runs a (contained) Protocol on all the passes of a multi-pass ProtocolData.

ProtocolRunner

Used to run Protocol objects on an entire tree of data

TreeRunner

Runs specific protocols on specific data-tree paths.

SimpleRunner

Runs a single protocol on every data node that has no sub-nodes (possibly separately for each pass).

DefaultRunner

Run the default protocol at each data-tree node.

ExperimentDesign

An experimental-design specification for one or more QCVV protocols.

CircuitListsDesign

Experiment design specification that is comprised of multiple circuit lists.

CombinedExperimentDesign

An experiment design that combines the specifications of one or more "sub-designs".

SimultaneousExperimentDesign

An experiment design whose circuits are the tensor-products of the circuits from one or more sub-designs.

FreeformDesign

Experiment design holding an arbitrary circuit list and meta data.

ProtocolData

Represents the experimental data needed to run one or more QCVV protocols.

ProtocolResults

Stores the results from running a QCVV protocol on data.

MultiPassResults

Holds the results of a single protocol on multiple "passes" (sets of data, typically taken at different times).

ProtocolResultsDir

Holds a dictionary of ProtocolResults objects.

ProtocolPostProcessor

Similar to a protocol, but runs on an existing ProtocolResults object.

DataSimulator

An analysis routine that is run on an experiment design to produce per-circuit data.

DataCountsSimulator

Simulates data counts for each circuit outcome, producing a simulated data set.

ProtocolCheckpoint

Class for storing checkpointing intermediate progress during

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.

RobustPhaseEstimationDesign

Experimental design for robust phase estimation (RPE).

RobustPhaseEstimation

Robust phase estimation (RPE) protocol

RobustPhaseEstimationResults

Results from the RPE protocol

StabilityAnalysisDesign

Experimental design for stability analysis.

StabilityAnalysis

Stability Analysis protocol

StabilityAnalysisResults

Results from the stability analysis protocol.

ByDepthDesign

Experiment design that holds circuits organized by depth.

BenchmarkingDesign

Experiment design that holds benchmarking data.

PeriodicMirrorCircuitDesign

Experiment design for periodic mirror-circuit benchmarking.

SummaryStatistics

A protocol that can construct "summary" quantities from raw data.

ByDepthSummaryStatistics

A protocol that computes summary statistics for data organized into by-depth circuit lists.

SummaryStatisticsResults

Summary statistics computed for a set of data.

VBDataFrame

A class for storing a DataFrame that contains volumetric benchmarking data, and that

Functions

run_default_protocols(data[, memlimit, comm])

Run the default protocols for the data-tree rooted at data.

polarization_to_success_probability(p, n)

Inverse of success_probability_to_polarization.

success_probability_to_polarization(s, n)

Maps a success probablity s for an n-qubit circuit to

classify_circuit_shape(success_probabilities, ...[, ...])

Utility function for computing "capability regions", as introduced in "Measuring the

Attributes

ROBUST_SUFFIX_LIST

DEFAULT_BAD_FIT_THRESHOLD

GSTDesign

GST

LGST

RB

RBResults

RPEDesign

RPE

RPEResults

class pygsti.protocols.FreeformDataSimulator

Bases: pygsti.protocols.protocol.DataSimulator

Computes arbitrary functions of the state data simulator that also computes user-defined functions of the final states.

abstract compute_freeform_data(circuit)

Computes the simulated free-form data for a single circuit.

Parameters

circuitCircuit

The circuit to compute data for.

Returns

dict

run(edesign, memlimit=None, comm=None)

Run this data simulator on an experiment design.

Parameters

edesignExperimentDesign

The input experiment design.

memlimitint, optional

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional

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

Returns

ProtocolData

apply_fn(series)
apply(df)

Apply this data simulator to a data frame having a Circuit column.

Parameters

dfpandas.DataFrame

The data frame to apply to.

Returns

pandas.DataFrame

class pygsti.protocols.ModelFreeformSimulator(models)

Bases: FreeformDataSimulator

A base class for data simulators that utilize models (probably most of them!).

Holds a dictionary of models and provides basic functionality for computing probabilities, final states, and process matrices corresponding to circuits which make implementing compute_freeform_data() easier.

Parameters

modelsdict

A dictionary whose keys are string labels and values are Model objects, specifying the models used to compute “simluated” data.

compute_process_matrix(model, circuit, include_final_state=False, include_probabilities=False)
compute_process_matrices(circuit, include_final_state=False, include_probabilities=False)
compute_final_state(model, circuit, include_probabilities=False)
compute_final_states(circuit, include_probabilities=False)
compute_circuit_probabilities(model, circuit)
compute_probabilities(circuit, include_probabilities=False)
class pygsti.protocols.Circuit(layer_labels=(), line_labels='auto', num_lines=None, editable=False, stringrep=None, name='', check=True, expand_subcircuits='default', occurrence=None, compilable_layer_indices=None)

Bases: object

A quantum circuit.

A Circuit represents a quantum circuit, consisting of state preparation, gates, and measurement operations. It is composed of some number of “lines”, typically one per qubit, and stores the operations on these lines as a sequence of Label objects, one per circuit layer, whose .sslbls members indicate which line(s) the label belongs on. When a circuit is created with ‘editable=True’, a rich set of operations may be used to construct the circuit in place, after which done_editing() should be called so that the Circuit can be properly hashed as needed.

Parameters

layer_labelsiterable of Labels or str

This argument provides a list of the layer labels specifying the state preparations, gates, and measurements for the circuit. This argument can also be a Circuit or a string, in which case it is parsed as a text-formatted circuit. Internally this will eventually be converted to a list of Label objects, one per layer, but it may be specified using anything that can be readily converted to a Label objects. For example, any of the following are allowed:

  • [‘Gx’,’Gx’] : X gate on each of 2 layers

  • [Label(‘Gx’),Label(‘Gx’)] : same as above

  • [(‘Gx’,0),(‘Gy’,0)] : X then Y on qubit 0 (2 layers)

  • [[(‘Gx’,0),(‘Gx’,1)],[(‘Gy’,0),(‘Gy’,1)]] : parallel X then Y on qubits 0 & 1

line_labelsiterable, optional

The (string valued) label for each circuit line. If ‘auto’, then line_labels is taken to be the list of all state-space labels present within layer_labels. If there are no such labels (e.g. if layer_labels contains just gate names like (‘Gx’,’Gy’)), then the special value ‘*’ is used as a single line label.

num_linesint, optional

Specify this instead of line_labels to set the latter to the integers between 0 and num_lines-1.

editablebool, optional

Whether the created Circuit is created in able to be modified. If True, then you should call done_editing() once the circuit is completely assembled, as this makes the circuit read-only and allows it to be hashed.

stringrepstring, optional

A string representation for the circuit. If None (the default), then this will be generated automatically when needed. One reason you’d want to specify this is if you know of a nice compact string representation that you’d rather use, e.g. “Gx^4” instead of the automatically generated “GxGxGxGx”. If you want to initialize a Circuit entirely from a string representation you can either specify the string in as layer_labels or set layer_labels to None and stringrep to any valid (one-line) circuit string.

namestr, optional

A name for this circuit (useful if/when used as a block within larger circuits).

checkbool, optional

Whether stringrep should be checked against layer_labels to ensure they are consistent, and whether the labels in layer_labels are a subset of line_labels. The only reason you’d want to set this to False is if you’re absolutely sure stringrep and line_labels are consistent and want to save computation time.

expand_subcircuitsbool or “default”

If “default”, then the value of Circuit.default_expand_subcircuits is used. If True, then any sub-circuits (e.g. anything exponentiated like “(GxGy)^4”) will be expanded when it is stored within the created Circuit. If False, then such sub-circuits will be left as-is. It’s typically more robust to expand sub-circuits as this facilitates comparison (e.g. so “GxGx” == “Gx^2”), but in cases when you have massive exponents (e.g. “Gx^8192”) it may improve performance to set expand_subcircuits=False.

occurrencehashable, optional

A value to set as the “occurrence id” for this circuit. This value doesn’t affect the circuit an any way except by affecting it’s hashing and equivalence testing. Circuits with different occurrence ids are not equivalent. Occurrence values effectively allow multiple copies of the same ciruit to be stored in a dictionary or DataSet.

compilable_layer_indicestuple, optional

The circuit-layer indices that may be internally altered (but retaining the same target operation) and/or combined with the following circuit layer by a hardware compiler.when executing this circuit. Layers that are not “compilable” are effectively followed by a barrier which prevents the hardward compiler from restructuring the circuit across the layer boundary.

Attributes

default_expand_subcircuitsbool

By default, expand sub-circuit labels.

line_labelstuple

The line labels (often qubit labels) of this circuit.

layertuptuple

This Circuit’s layers as a standard Python tuple of layer Labels.

tuptuple

This Circuit as a standard Python tuple of layer Labels and line labels.

strstr

The Python string representation of this Circuit.

Creates a new Circuit object, encapsulating a quantum circuit.

You only need to supply the first layer_labels argument, though usually (except for just 1 or 2 qubits) you’ll want to also supply line_labels or num_lines. If you’ll be adding to or altering the circuit before using it, you should set editable=True.

Parameters

layer_labelsiterable of Labels or str

This argument provides a list of the layer labels specifying the state preparations, gates, and measurements for the circuit. This argument can also be a Circuit or a string, in which case it is parsed as a text-formatted circuit. Internally this will eventually be converted to a list of Label objects, one per layer, but it may be specified using anything that can be readily converted to a Label objects. For example, any of the following are allowed:

  • [‘Gx’,’Gx’] : X gate on each of 2 layers

  • [Label(‘Gx’),Label(‘Gx’)] : same as above

  • [(‘Gx’,0),(‘Gy’,0)] : X then Y on qubit 0 (2 layers)

  • [[(‘Gx’,0),(‘Gx’,1)],[(‘Gy’,0),(‘Gy’,1)]] : parallel X then Y on qubits 0 & 1

line_labelsiterable, optional

The (string valued) label for each circuit line. If ‘auto’, then line_labels is taken to be the list of all state-space labels present within layer_labels. If there are no such labels (e.g. if layer_labels contains just gate names like (‘Gx’,’Gy’)), then the special value ‘*’ is used as a single line label.

num_linesint, optional

Specify this instead of line_labels to set the latter to the integers between 0 and num_lines-1.

editablebool, optional

Whether the created Circuit is created in able to be modified. If True, then you should call done_editing() once the circuit is completely assembled, as this makes the circuit read-only and allows it to be hashed.

stringrepstring, optional

A string representation for the circuit. If None (the default), then this will be generated automatically when needed. One reason you’d want to specify this is if you know of a nice compact string representation that you’d rather use, e.g. “Gx^4” instead of the automatically generated “GxGxGxGx”. If you want to initialize a Circuit entirely from a string representation you can either specify the string in as layer_labels or set layer_labels to None and stringrep to any valid (one-line) circuit string.

namestr, optional

A name for this circuit (useful if/when used as a block within larger circuits).

checkbool, optional

Whether stringrep should be checked against layer_labels to ensure they are consistent, and whether the labels in layer_labels are a subset of line_labels. The only reason you’d want to set this to False is if you’re absolutely sure stringrep and line_labels are consistent and want to save computation time.

expand_subcircuitsbool or “default”

If “default”, then the value of Circuit.default_expand_subcircuits is used. If True, then any sub-circuits (e.g. anything exponentiated like “(GxGy)^4”) will be expanded when it is stored within the created Circuit. If False, then such sub-circuits will be left as-is. It’s typically more robust to expand sub-circuits as this facilitates comparison (e.g. so “GxGx” == “Gx^2”), but in cases when you have massive exponents (e.g. “Gx^8192”) it may improve performance to set expand_subcircuits=False.

occurrencehashable, optional

A value to set as the “occurrence id” for this circuit. This value doesn’t affect the circuit an any way except by affecting it’s hashing and equivalence testing. Circuits with different occurrence ids are not equivalent. Occurrence values effectively allow multiple copies of the same ciruit to be stored in a dictionary or DataSet.

compilable_layer_indicestuple, optional

The circuit-layer indices that may be internally altered (but retaining the same target operation) and/or combined with the following circuit layer by a hardware compiler.when executing this circuit. Layers that are not “compilable” are effectively followed by a barrier which prevents the hardward compiler from restructuring the circuit across the layer boundary.

property line_labels

The line labels (often qubit labels) of this circuit.

property name

The name of this circuit.

Note: the name is not a part of the hashed value. The name is used to name the CircuitLabel returned from to_label().

property occurrence

The occurrence id of this circuit.

property layertup

This Circuit’s layers as a standard Python tuple of layer Labels.

Returns

tuple

property tup

This Circuit as a standard Python tuple of layer Labels and line labels.

Returns

tuple

property compilable_layer_indices

Tuple of the layer indices corresponding to “compilable” layers.

property compilable_by_layer

Boolean array indicating whether each layer is “compilable” or not.

property str

The Python string representation of this Circuit.

Returns

str

property layerstr

Just the string representation of the circuit layers (no ‘@<line_labels>’ suffix)

property linesstr

Just the string representation of the circuit’s line labels (the ‘@<line_labels>’ suffix)

property num_lines

The number of lines in this circuit.

Returns

int

property num_layers

The number of circuit layers.

In simple circuits, this is the same as the depth (given by depth()). For circuits containing sub-circuit blocks, this gives the number of top-level layers in this circuit.

Returns

int

property depth

The circuit depth.

This is the number of layers in simple circuits. For circuits containing sub-circuit blocks, this includes the full depth of these blocks. If you just want the number of top-level layers, use num_layers().

Returns

int

property width

The circuit width.

This is the number of qubits on which the circuit acts. This includes qubits that only idle, but are included as part of the circuit according to self.line_labels.

Returns

int

property size

Returns the circuit size.

This is the sum of the sizes of all the gates in the circuit. A gate that acts on n-qubits has a size of n, with the exception of the idle which has a size of 0. Hence, the circuit is given by: size = depth * num_lines - num_1Q_idles.

Returns

int

property duration
property num_multiq_gates

The number of multi-qubit (2+ qubits) gates in the circuit.

(Note that this cannot distinguish between “true” multi-qubit gates and gate that have been defined to act on more than one qubit but that represent some tensor-product gate.)

Returns

int

default_expand_subcircuits = True
classmethod cast(obj)

Convert obj into a Circuit.

Parameters
objobject

Object to convert

Returns

Circuit

classmethod from_tuple(tup)

Creates a Circuit from a tuple

Parameters
tuptuple

The tuple to convert.

Returns

Circuit

to_label(nreps=1)

Construct and return this entire circuit as a CircuitLabel.

Note: occurrence-id information is not stored in a circuit label, so circuits that differ only in their occurence_id will return circuit labels that are equal.

Parameters
nrepsint, optional

The number of times this circuit will be repeated (CircuitLabels support exponentiation and you can specify this here).

Returns

CircuitLabel

repeat(ntimes, expand='default')

Repeat this circuit ntimes times.

Parameters
ntimesint

Number of repetitions.

expandbool or “default”, optional

When False, the returned circuit will contain a CircuitLabel encapsulating the repetitions without explicitly storing them. When True, the returned circuit will be expanded into the ntimes repetitions. “default” means to use the value in the class variable Circuit.default_expand_subcircuits.

copy(editable='auto')

Returns a copy of the circuit.

Parameters
editable{True,False,”auto”}

Whether returned copy is editable. If “auto” is given, then the copy is editable if and only if this Circuit is.

Returns

Circuit

clear()

Removes all the gates in a circuit (preserving the number of lines).

Returns

None

extract_labels(layers=None, lines=None, strict=True)

Get a subregion - a “rectangle” - of this Circuit.

This can be used to select multiple layers and/or lines of this Circuit. The strict argument controls whether gates need to be entirely within the given rectangle or can be intersecting it. If layers is a single integer then a Label is returned (representing a layer or a part of a layer), otherwise a Circuit is returned.

Parameters
layersint, slice, or list/tuple of ints

Which layers to select (the horizontal dimension of the selection rectangle). Layers are always selected by index, and this argument can be a single (integer) index - in which case a Label is returned - or multiple indices as given by a slice or list - in which case a Circuit is returned. Note that, even though we speak of a “rectangle”, layer indices do not need to be contiguous. The special value None selects all layers.

linesstr/int, slice, or list/tuple of strs/ints

Which lines to select (the vertical dimension of the selection rectangle). Lines are selected by their line-labels (elements of the circuit’s .line_labels property), which can be strings and/or integers. A single or multiple line-labels can be specified. If the line labels are integers a slice can be used, otherwise a list or tuple of labels is the only way to select multiple of them. Note that line-labels do not need to be contiguous. The special value None selects all lines.

strictbool, optional

When True, only gates lying completely within the selected region are included in the return value. If a gate straddles the region boundary (e.g. if we select just line 1 and the circuit contains “Gcnot:1:2”) then it is silently not-included in the returned label or circuit. If False, then gates which straddle the region boundary are included. Note that this may result in a Label or Circuit containing more line labels than where requested in the call to extract_labels(…)..

Returns
Label or Circuit

The requested portion of this circuit, given as a Label if layers is a single integer and as a Circuit otherwise. Note: if you want a Circuit when only selecting one layer, set layers to a slice or tuple containing just a single index.

set_labels(lbls, layers=None, lines=None)

Write lbls to the block defined by the layers and lines arguments.

Note that lbls can be anything interpretable as a Label or list of labels.

Parameters
lblsLabel, list/tuple of Labels, or Circuit

When layers is a single integer, lbls should be a single “layer label” of type Label. Otherwise, lbls should be a list or tuple of Label objects with length equal to the number of layers being set. A Circuit may also be used in this case.

layersint, slice, or list/tuple of ints

Which layers to set (the horizontal dimension of the destination rectangle). Layers are always selected by index, and this argument can be a single (integer) index or multiple indices as given by a slice or list. Note that these indices do not need to be contiguous. The special value None stands for all layers.

linesstr/int, slice, or list/tuple of strs/ints

Which lines to set (the vertical dimension of the destination rectangle). Lines are selected by their line-labels, which can be strings and/or integers. A single or multiple line-labels can be specified. If the line labels are integers a slice can be used, otherwise a list or tuple of labels is the only way to specify multiple of them. The line-labels do not need to be contiguous. The special value None stands for all lines, and in this case new lines will be created if there are new state-space labels in lbls (when lines is not None an error is raised instead).

Returns

None

insert_idling_layers(insert_before, num_to_insert, lines=None)

Inserts into this circuit one or more idling (blank) layers, returning a copy.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
insert_beforeint

The layer index to insert the new layers before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

num_to_insertint

The number of new layers to insert.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have new layers (blank circuit space) inserted into them. A single or multiple line-labels can be specified, similarly as in extract_labels(). The default value None stands for all lines.

Returns

Circuit

insert_idling_layers_inplace(insert_before, num_to_insert, lines=None)

Inserts into this circuit one or more idling (blank) layers.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
insert_beforeint

The layer index to insert the new layers before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

num_to_insertint

The number of new layers to insert.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have new layers (blank circuit space) inserted into them. A single or multiple line-labels can be specified, similarly as in extract_labels(). The default value None stands for all lines.

Returns

None

insert_labels_into_layers(lbls, layer_to_insert_before, lines=None)

Inserts into this circuit the contents of lbls into new full or partial layers, returning a copy.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
lblslist/tuple of Labels, or Circuit

The full or partial layer labels to insert. The length of this list, tuple, or circuit determines the number of layers which are inserted.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have lbls inserted into them. Currently this can only be a larger set than the set of line labels present in lbls (in future versions this may allow filtering of lbls). value None stands for all lines.

Returns

Circuit

insert_labels_into_layers_inplace(lbls, layer_to_insert_before, lines=None)

Inserts into this circuit the contents of lbls into new full or partial layers.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
lblslist/tuple of Labels, or Circuit

The full or partial layer labels to insert. The length of this list, tuple, or circuit determines the number of layers which are inserted.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have lbls inserted into them. Currently this can only be a larger set than the set of line labels present in lbls (in future versions this may allow filtering of lbls). value None stands for all lines.

Returns

None

insert_idling_lines(insert_before, line_labels)

Insert one or more idling (blank) lines into this circuit, returning a copy.

Parameters
insert_beforestr or int

The line label to insert new lines before. The special value None inserts lines at the bottom of this circuit.

line_labelslist or tuple

A list or tuple of the new line labels to insert (can be integers and/or strings).

Returns

Circuit

insert_idling_lines_inplace(insert_before, line_labels)

Insert one or more idling (blank) lines into this circuit.

Parameters
insert_beforestr or int

The line label to insert new lines before. The special value None inserts lines at the bottom of this circuit.

line_labelslist or tuple

A list or tuple of the new line labels to insert (can be integers and/or strings).

Returns

None

insert_labels_as_lines_inplace(lbls, layer_to_insert_before=None, line_to_insert_before=None, line_labels='auto')

Inserts into this circuit the contents of lbls into new lines.

By default, lbls is inserted at the beginning of the new lines(s). The layer_to_insert_before argument allows you to insert lbls beginning at a layer of your choice.

Parameters
lblslist/tuple of Labels, or Circuit

A list of layer labels to insert as new lines. The state-space (line) labels within lbls must not overlap with that of this circuit or an error is raised. If lbls contains more layers than this circuit currently has, new layers are added automatically.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The default value of None inserts at the beginning.

line_to_insert_beforestr or int

The line label to insert the new lines before. The default value of None inserts lines at the bottom of the circuit.

line_labelslist, tuple, or “auto”

The labels of the new lines being inserted. If “auto”, then these are inferred from lbls.

Returns

None

insert_labels_as_lines(lbls, layer_to_insert_before=None, line_to_insert_before=None, line_labels='auto')

Inserts into this circuit the contents of lbls into new lines, returning a copy.

By default, lbls is inserted at the beginning of the new lines(s). The layer_to_insert_before argument allows you to insert lbls beginning at a layer of your choice.

Parameters
lblslist/tuple of Labels, or Circuit

A list of layer labels to insert as new lines. The state-space (line) labels within lbls must not overlap with that of this circuit or an error is raised. If lbls contains more layers than this circuit currently has, new layers are added automatically.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The default value of None inserts at the beginning.

line_to_insert_beforestr or int

The line label to insert the new lines before. The default value of None inserts lines at the bottom of the circuit.

line_labelslist, tuple, or “auto”

The labels of the new lines being inserted. If “auto”, then these are inferred from lbls.

Returns

None

clear_labels(layers=None, lines=None, clear_straddlers=False)

Removes all the gates within the given circuit region. Does not reduce the number of layers or lines.

Parameters
layersint, slice, or list/tuple of ints

Defines the horizontal dimension of the region to clear. See extract_labels() for details.

linesstr/int, slice, or list/tuple of strs/ints

Defines the vertical dimension of the region to clear. See extract_labels() for details.

clear_straddlersbool, optional

Whether or not gates which straddle cleared and non-cleared lines should be cleared. If False and straddling gates exist, an error will be raised.

Returns

None

delete_layers(layers=None)

Deletes one or more layers from the circuit.

Parameters
layersint, slice, or list/tuple of ints

The layer index or indices to delete. See extract_labels() for details.

Returns

None

delete_lines(lines, delete_straddlers=False)

Deletes one or more lines from the circuit.

Parameters
linesstr/int, slice, or list/tuple of strs/ints

The line label(s) to delete. See extract_labels() for details.

delete_straddlersbool, optional

Whether or not gates which straddle deleted and non-deleted lines should be removed. If False and straddling gates exist, an error will be raised.

Returns

None

to_pythonstr(op_labels)

Convert this circuit to an “encoded” python string.

In the returned string each operation label is represented as a single character, starting with ‘A’ and continuing down the alphabet. This can be useful for processing operation sequences using python’s string tools (regex in particular).

Parameters
op_labelstuple

An iterable containing at least all the layer-Labels that appear in this Circuit, and which will be mapped to alphabet characters, beginning with ‘A’.

Returns
string

The converted operation sequence.

Examples

(‘Gx’,’Gx’,’Gy’,’Gx’) => “AABA”

classmethod from_pythonstr(python_string, op_labels)

Decode an “encoded string” into a Circuit.

Create a Circuit from a python string where each operation label is represented as a single character, starting with ‘A’ and continuing down the alphabet. This performs the inverse of to_pythonstr().

Parameters
python_stringstring

string whose individual characters correspond to the operation labels of a operation sequence.

op_labelstuple

tuple containing all the operation labels that will be mapped from alphabet characters, beginning with ‘A’.

Returns

Circuit

Examples

“AABA” => (‘Gx’,’Gx’,’Gy’,’Gx’)

serialize(expand_subcircuits=False)

Serialize the parallel gate operations of this Circuit.

Construct a new Circuit whereby all layers containing multiple gates are converted to separate single-gate layers, effectively putting each elementary gate operation into its own layer. Ordering is dictated by the ordering of the compound layer labels.

Parameters
expand_subcircuitsbool

Whether subcircuits should be expanded before performing the serialization. If False, the circuit may contain CircuitLabel layers.

Returns

Circuit

parallelize(can_break_labels=True, adjacent_only=False)

Compress a circuit’s gates by performing them in parallel.

Construct a circuit with the same underlying labels as this one, but with as many gates performed in parallel as possible (with some restrictions - see the Parameters section below). Generally, gates are moved as far left (toward the start) of the circuit as possible.

Parameters
can_break_labelsbool, optional

Whether compound (parallel-gate) labels in this Circuit can be separated during the parallelization process. For example, if can_break_labels=True then “Gx:0[Gy:0Gy:1]” => “[Gx:0Gy:1]Gy:0” whereas if can_break_labels=False the result would remain “Gx:0[Gy:0Gy:1]” because [Gy:0Gy:1] cannot be separated.

adjacent_onlybool, optional

It True, then operation labels are only allowed to move into an adjacent label, that is, they cannot move “through” other operation labels. For example, if adjacent_only=True then “Gx:0Gy:0Gy:1” => “Gx:0[Gy:0Gy:1]” whereas if adjacent_only=False the result would be “[Gx:0Gy:1]Gy:0. Setting this to True is sometimes useful if you want to parallelize a serial string in such a way that subsequently calling .serialize() will give you back the original string.

Returns

Circuit

expand_subcircuits_inplace()

Expands all CircuitLabel labels within this circuit.

This operation is done in place and so can only be performed on an editable Circuit.

Returns

None

expand_subcircuits()

Returns a new circuit with CircuitLabel labels expanded.

Returns

Circuit

factorize_repetitions_inplace()

Attempt to replace repeated sub-circuits with CircuitLabel objects.

More or less the reverse of expand_subcircuits(), this method attempts to collapse repetitions of the same labels into single CircuitLabel labels within this circuit.

This operation is done in place and so can only be performed on an editable Circuit.

Returns

None

insert_layer(circuit_layer, j)

Inserts a single layer into a circuit, returning a copy.

The input layer does not need to contain a gate that acts on every qubit, but it should not contain more than one gate on a qubit.

Parameters
circuit_layerLabel

The layer to insert. A (possibly compound) Label object or something that can be converted into one, e.g. ((‘Gx’,0),(‘Gcnot’,1,2)) or just ‘Gx’.

jint

The layer index (depth) at which to insert the circuit_layer.

Returns

Circuit

insert_layer_inplace(circuit_layer, j)

Inserts a single layer into a circuit.

The input layer does not need to contain a gate that acts on every qubit, but it should not contain more than one gate on a qubit.

Parameters
circuit_layerLabel

The layer to insert. A (possibly compound) Label object or something that can be converted into one, e.g. ((‘Gx’,0),(‘Gcnot’,1,2)) or just ‘Gx’.

jint

The layer index (depth) at which to insert the circuit_layer.

Returns

None

insert_circuit(circuit, j)

Inserts a circuit into this circuit, returning a copy.

The circuit to insert can be over more qubits than this circuit, as long as all qubits that are not part of this circuit are idling. In this case, the idling qubits are all discarded. The circuit to insert can also be on less qubits than this circuit: all other qubits are set to idling. So, the labels of the circuit to insert for all non-idling qubits must be a subset of the labels of this circuit.

Parameters
circuitCircuit

The circuit to be inserted.

jint

The layer index (depth) at which to insert the circuit.

Returns

Circuit

insert_circuit_inplace(circuit, j)

Inserts a circuit into this circuit.

The circuit to insert can be over more qubits than this circuit, as long as all qubits that are not part of this circuit are idling. In this case, the idling qubits are all discarded. The circuit to insert can also be on less qubits than this circuit: all other qubits are set to idling. So, the labels of the circuit to insert for all non-idling qubits must be a subset of the labels of this circuit.

Parameters
circuitCircuit

The circuit to be inserted.

jint

The layer index (depth) at which to insert the circuit.

Returns

None

append_circuit(circuit)

Append a circuit to the end of this circuit, returning a copy.

This circuit must satisfy the requirements of insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be appended.

Returns

Circuit

append_circuit_inplace(circuit)

Append a circuit to the end of this circuit.

This circuit must satisfy the requirements of insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be appended.

Returns

None

prefix_circuit(circuit)

Prefix a circuit to the beginning of this circuit, returning a copy.

This circuit must satisfy the requirements of the insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be prefixed.

Returns

Circuit

prefix_circuit_inplace(circuit)

Prefix a circuit to the beginning of this circuit.

This circuit must satisfy the requirements of the insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be prefixed.

Returns

None

tensor_circuit_inplace(circuit, line_order=None)

The tensor product of this circuit and circuit.

That is, it adds circuit to this circuit as new lines. The line labels of circuit must be disjoint from the line labels of this circuit, as otherwise applying the circuits in parallel does not make sense.

Parameters
circuitA Circuit object

The circuit to be tensored.

line_orderList, optional

A list of all the line labels specifying the order of the circuit in the updated circuit. If None, the lines of circuit are added below the lines of this circuit. Note that, for many purposes, the ordering of lines of the circuit is irrelevant.

Returns

None

tensor_circuit(circuit, line_order=None)

The tensor product of this circuit and circuit, returning a copy.

That is, it adds circuit to this circuit as new lines. The line labels of circuit must be disjoint from the line labels of this circuit, as otherwise applying the circuits in parallel does not make sense.

Parameters
circuitA Circuit object

The circuit to be tensored.

line_orderList, optional

A list of all the line labels specifying the order of the circuit in the updated circuit. If None, the lines of circuit are added below the lines of this circuit. Note that, for many purposes, the ordering of lines of the circuit is irrelevant.

Returns

Circuit

replace_layer_with_circuit_inplace(circuit, j)

Replaces the j-th layer of this circuit with circuit.

Parameters
circuitCircuit

The circuit to insert

jint

The layer index to replace.

Returns

None

replace_layer_with_circuit(circuit, j)

Replaces the j-th layer of this circuit with circuit, returning a copy.

Parameters
circuitCircuit

The circuit to insert

jint

The layer index to replace.

Returns

Circuit

replace_gatename_inplace(old_gatename, new_gatename)

Changes the name of a gate throughout this Circuit.

Note that the name is only a part of the label identifying each gate, and doesn’t include the lines (qubits) a gate acts upon. For example, the “Gx:0” and “Gx:1” labels both have the same name but act on different qubits.

Parameters
old_gatenamestr

The gate name to replace.

new_gatenamestr

The name to replace old_gatename with.

Returns

None

replace_gatename(old_gatename, new_gatename)

Returns a copy of this Circuit except that old_gatename is changed to new_gatename.

Note that the “name” is only a part of the “label” identifying each gate, and doesn’t include the lines (qubits) a gate acts upon. For example, the “Gx:0” and “Gx:1” labels both have the same name but act on different qubits.

Parameters
old_gatenamestr

The gate name to replace.

new_gatenamestr

The name to replace old_gatename with.

Returns

Circuit

replace_gatename_with_idle_inplace(gatename)

Treats a given gatename as an idle gate throughout this Circuit.

This effectively removes this gate name from the circuit, and replaces a layer containing only this gate name with an idle layer.

Parameters
gatenamestr

The gate name to replace.

Returns

None

replace_gatename_with_idle(gatename)

Returns a copy of this Circuit with a given gatename treated as an idle gate.

This effectively removes this gate name from the circuit, and replaces a layer containing only this gate name with an idle layer.

Parameters
gatenamestr

The gate name to replace.

Returns

Circuit

replace_layer(old_layer, new_layer)

Returns a copy of this Circuit except that old_layer is changed to new_layer.

Parameters
old_layerstr or Label

The layer to find.

new_layerstr or Label

The layer to replace found layers with.

Returns

Circuit

replace_layers_with_aliases(alias_dict)

Performs a find and replace using layer aliases.

Returns a copy of this Circuit except that it’s layers that match keys of alias_dict are replaced with the corresponding values.

Parameters
alias_dictdict

A dictionary whose keys are layer Labels (or equivalent tuples or strings), and whose values are Circuits.

Returns

Circuit

change_gate_library(compilation, allowed_filter=None, allow_unchanged_gates=False, depth_compression=True, one_q_gate_relations=None)

Re-express a circuit over a different model.

Parameters
compilationdict or CompilationLibrary.

If a dictionary, the keys are some or all of the gates that appear in the circuit, and the values are replacement circuits that are normally compilations for each of these gates (if they are not, the action of the circuit will be changed). The circuits need not be on all of the qubits, and need only satisfy the requirements of the insert_circuit method. There must be a key for every gate except the self.identity gate, unless allow_unchanged_gates is False. In that case, gate that aren’t a key in this dictionary are left unchanged.

If a CompilationLibrary, this will be queried via the retrieve_compilation_of() method to find compilations for all of the gates in the circuit. So this CompilationLibrary must contain or be able to auto-generate compilations for the requested gates, except when allow_unchanged_gates is True. In that case, gates that a compilation is not returned for are left unchanged.

allowed_filterdict or set, optional

Specifies which gates are allowed to be used when generating compilations from compilation. Can only be not None if compilation is a CompilationLibrary. If a dict, keys must be gate names (like “Gcnot”) and values QubitGraph objects indicating where that gate (if it’s present in the library) may be used. If a set, then it specifies a set of qubits and any gate in the current library that is confined within that set is allowed. If None, then all gates within the library are allowed.

allow_unchanged_gatesbool, optional

Whether to allow some gates to remain unchanged, and therefore to be absent from compilation. When True such gates are left alone; when False an error is raised if any such gates are encountered.

depth_compressionbool, optional

Whether to perform depth compression after changing the gate library. If one_q_gate_relations is None this will only remove idle layers and compress the circuit by moving everything as far forward as is possible without knowledge of the action of any gates other than self.identity. See the depth_compression method for more details. Under most circumstances this should be true; if it is False changing gate library will often result in a massive increase in circuit depth.

one_q_gate_relationsdict, optional

Gate relations for the one-qubit gates in the new gate library, that are used in the depth compression, to cancel / combine gates. E.g., one key-value pair might be (‘Gh’,’Gh’) : ‘I’, to signify that two Hadamards c ompose to the idle gate ‘Gi’. See the depth_compression() method for more details.

Returns

None

map_names_inplace(mapper)

The names of all of the simple labels are updated in-place according to the mapping function mapper.

Parameters
mapperdict or function

A dictionary whose keys are the existing gate name values and whose values are the new names (strings) or a function which takes a single (existing name) argument and returns a new name.

Returns

None

map_state_space_labels_inplace(mapper)

The labels of all of the lines (wires/qubits) are updated according to the mapping function mapper.

Parameters
mapperdict or function

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

Returns

None

map_state_space_labels(mapper)

Creates a new Circuit whose line labels are updated according to the mapping function mapper.

Parameters
mapperdict or function

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

Returns

Circuit

reorder_lines_inplace(order)

Reorders the lines (wires/qubits) of the circuit.

Note that the ordering of the lines is unimportant for most purposes.

Parameters
orderlist

A list containing all of the circuit line labels (self.line_labels) in the order that the should be converted to.

Returns

None

reorder_lines(order)

Reorders the lines (wires/qubits) of the circuit, returning a copy.

Note that the ordering of the lines is unimportant for most purposes.

Parameters
orderlist

A list containing all of the circuit line labels (self.line_labels) in the order that the should be converted to.

Returns

Circuit

idling_lines(idle_layer_labels=None)

Returns the line labels corresponding to idling lines.

Parameters
idle_layer_labelsiterable, optional

A list or tuple of layer-labels that should be treated as idle operations, so their presence will not disqualify a line from being “idle”. E.g. [“Gi”] will cause “Gi” layers to be considered idle layers.

Returns

tuple

delete_idling_lines_inplace(idle_layer_labels=None)

Removes from this circuit all lines that are idling at every layer.

Parameters
idle_layer_labelsiterable, optional

A list or tuple of layer-labels that should be treated as idle operations, so their presence will not disqualify a line from being “idle”. E.g. [“Gi”] will cause “Gi” layers to be considered idle layers.

Returns

None

delete_idling_lines(idle_layer_labels=None)

Removes from this circuit all lines that are idling at every layer, returning a copy.

Parameters
idle_layer_labelsiterable, optional

A list or tuple of layer-labels that should be treated as idle operations, so their presence will not disqualify a line from being “idle”. E.g. [“Gi”] will cause “Gi” layers to be considered idle layers.

Returns

Circuit

replace_with_idling_line_inplace(line_label, clear_straddlers=True)

Converts the specified line to an idling line, by removing all its gates.

If there are any multi-qubit gates acting on this line, this function will raise an error when clear_straddlers=False.

Parameters
line_labelstr or int

The label of the line to convert to an idling line.

clear_straddlersbool, optional

Whether or not gates which straddle the line_label should also be cleared. If False and straddling gates exist, an error will be raised.

Returns

None

reverse_inplace()

Reverses the order of the circuit.

Returns

None

delete_idle_layers_inplace()

Deletes all layers in this circuit that contain no gate operations.

One of the steps of the depth_compression() method.

Returns
bool

False if the circuit is unchanged, and True otherwise.

compress_depth_inplace(one_q_gate_relations=None, verbosity=0)

Compresses the depth of this circuit using very simple re-write rules.

  1. If one_q_gate_relations is provided, all sequences of 1-qubit gates in the circuit are compressed as far as is possible using only the pair-wise combination rules provided by this dict (see below).

  2. All gates are shifted forwarded as far as is possible without any knowledge of what any of the gates are.

  3. All idle-only layers are deleted.

Parameters
one_q_gate_relationsdict

Keys that are pairs of strings, corresponding to 1-qubit gate names, with values that are a single string, also corresponding to a 1-qubit gate name. Whenever a 1-qubit gate with name name1 is followed in the circuit by a 1-qubit gate with name2 then, if one_q_gate_relations[name1,name2] = name3, name1 -> name3 and name2 -> self.identity, the identity name in the circuit. Moreover, this is still implemented when there are self.identity gates between these 1-qubit gates, and it is implemented iteratively in the sense that if there is a sequence of 1-qubit gates with names name1, name2, name3, … and there are relations for all of (name1,name2) -> name12, (name12,name3) -> name123 etc then the entire sequence of 1-qubit gates will be compressed into a single possibly non-idle 1-qubit gate followed by idle gates in place of the previous 1-qubit gates.

If a QubitProcessorSpec object has been created for the gates/device in question, the QubitProcessorSpec.oneQgate_relations is the appropriate (and auto-generated) one_q_gate_relations.

Note that this function will not compress sequences of 1-qubit gates that cannot be compressed by independently inspecting sequential non-idle pairs (as would be the case with, for example, Gxpi Gzpi Gxpi Gzpi, if the relation did not know that (Gxpi,Gzpi) -> Gypi, even though the sequence is the identity).

verbosityint, optional

If > 0, information about the depth compression is printed to screen.

Returns

None

layer(j)

Returns a tuple of the components, i.e. the (non-identity) gates, in the layer at depth j.

These are the .components of the Label returned by indexing this Circuit (using square brackets) with j, i.e. this returns this_circuit[j].components.

Parameters
jint

The index (depth) of the layer to be returned

Returns

tuple

layer_label(j)

Returns the layer, as a Label, at depth j.

This label contains as components all the (non-identity) gates in the layer..

Parameters
jint

The index (depth) of the layer to be returned

Returns

Label

layer_with_idles(j, idle_gate_name='I')

Returns a tuple of the components of the layer at depth j, with idle_gate_name at empty circuit locations.

This effectively places an explicit idle_gate_name gates wherever there is an implied identity operation in the circuit.

Parameters
jint

The index (depth) of the layer to be returned

idle_gate_namestr, optional

The idle gate name to use. Note that state space (qubit) labels will be added to this name to form a Label.

Returns

tuple

layer_label_with_idles(j, idle_gate_name='I')

Returns the layer, as a Label, at depth j, with idle_gate_name at empty circuit locations.

This effectively places an explicit idle_gate_name gates wherever there is an implied identity operation in the circuit.

Parameters
jint

The index (depth) of the layer to be returned

idle_gate_namestr, optional

The idle gate name to use. Note that state space (qubit) labels will be added to this name to form a Label.

Returns

Label

two_q_gate_count()

The number of two-qubit gates in the circuit.

(Note that this cannot distinguish between “true” 2-qubit gates and gate that have been defined to act on two qubits but that represent some tensor-product gate.)

Returns

int

num_nq_gates(nq)

The number of nq-qubit gates in the circuit.

(Note that this cannot distinguish between “true” nq-qubit gates and gate that have been defined to act on nq qubits but that represent some tensor-product gate.)

Parameters
nqint

The qubit-count of the gates to count. For example, if nq == 3, this function returns the number of 3-qubit gates.

Returns

int

format_display_str(width=80)

Formats a string for displaying this circuit suject to a maximum width.

Parameters
widthint, optional

The maximum width in characters. If the circuit is longer than this width it is wrapped using multiple lines (like a musical score).

Returns

str

convert_to_cirq(qubit_conversion, wait_duration=None, gatename_conversion=None, idle_gate_name='Gi')

Converts this circuit to a Cirq circuit.

Parameters
qubit_conversiondict

Mapping from qubit labels (e.g. integers) to Cirq qubit objects.

wait_durationcirq.Duration, optional

If no gatename_conversion dict is given, the idle operation is not converted to a gate. If wait_diration is specified and gatename_conversion is not specified, then the idle operation will be converted to a cirq.WaitGate with the specified duration.

gatename_conversiondict, optional

If not None, a dictionary that converts the gatenames in the circuit to the Cirq gates that will appear in the Cirq circuit. If only standard pyGSTi names are used (e.g., ‘Gh’, ‘Gp’, ‘Gcnot’, ‘Gcphase’, etc) this dictionary need not be specified, and an automatic conversion to the standard Cirq names will be implemented.

idle_gate_namestr, optional

Name to use for idle gates. Defaults to ‘Gi’

Returns

A Cirq Circuit object.

classmethod from_cirq(circuit, qubit_conversion=None, cirq_gate_conversion=None, remove_implied_idles=True, global_idle_replacement_label='auto')

Converts and instantiates a pyGSTi Circuit object from a Cirq Circuit object.

Parameters
circuitcirq Circuit

The cirq Circuit object to parse into a pyGSTi circuit.

qubit_conversiondict, optional (default None)

A dictionary specifying a mapping between cirq qubit objects and pyGSTi qubit labels (either integers or strings). If None, then a default mapping is created.

cirq_gate_conversiondict, optional (default None)

If specified a dictionary with keys given by cirq gate objects, and values given by pygsti gate names which overrides the built-in conversion dictionary used by default.

remove_implied_idlesbool, optional (default True)

A flag indicating whether to remove explicit idles that are part of a circuit layer containing other explicitly specified gates (i.e., whether to abide by the normal pyGSTi implicit idle convention).

global_idle_replacement_labelstring or Label or None, optional (default ‘auto’)

An option specified for the handling of global idle layers. If None, no replacement of global idle layers is performed and a verbatim conversion from the cirq layer is performed. If the string ‘auto’, then the behavior is to replace global idle layers with the gate label Label(()), which is the special syntax for the global idle layer, stylized typically as ‘[]’. If another string then replace with a gate label with the specified name acting on all of the qubits appearing in the cirq circuit. If a Label object, use this directly, this does not check for compatibility so it is up to the user to ensure the labels are compatible.

Returns
pygsti_circuit

A pyGSTi Circuit instance equivalent to the specified Cirq one.

convert_to_quil(num_qubits=None, gatename_conversion=None, qubit_conversion=None, readout_conversion=None, block_between_layers=True, block_idles=True, gate_declarations=None)

Converts this circuit to a quil string.

Parameters
num_qubitsint, optional

The number of qubits for the quil file. If None, then this is assumed to equal the number of line labels in this circuit.

gatename_conversiondict, optional

A dictionary mapping gate names contained in this circuit to the corresponding gate names used in the rendered quil. If None, a standard set of conversions is used (see standard_gatenames_quil_conversions()).

qubit_conversiondict, optional

If not None, a dictionary converting the qubit labels in the circuit to the desired qubit labels in the quil output. Can be left as None if the qubit labels are either (1) integers, or (2) of the form ‘Qi’ for integer i. In this case they are converted to integers (i.e., for (1) the mapping is trivial, for (2) the mapping strips the ‘Q’).

readout_conversiondict, optional

If not None, a dictionary converting the qubit labels mapped through qubit_conversion to the bit labels for readot. E.g. Suppose only qubit 2 (on Rigetti hardware) is in use. Then the pyGSTi string will have only one qubit (labeled 0); it will get remapped to 2 via qubit_conversion={0:2}. At the end of the quil circuit, readout should go recorded in bit 0, so readout_conversion = {0:0}. (That is, qubit with pyGSTi label 0 gets read to Rigetti bit 0, even though that qubit has Rigetti label 2.)

block_between_layersbool, optional

When True, add in a barrier after every circuit layer. Including such “pragma” blocks can be important for QCVV testing, as this can help reduce the “behind-the-scenes” compilation (beyond necessary conversion to native instructions) experience by the circuit.

block_idlesbool, optional

In the special case of global idle gates, pragma-block barriers are inserted even when block_between_layers=False. Set block_idles=False to disable this behavior, whcih typically results in global idle gates being removed by the compiler.

gate_declarationsdict, optional

If not None, a dictionary that provides unitary maps for particular gates that are not already in the quil syntax.

Returns
str

A quil string.

convert_to_openqasm(num_qubits=None, standard_gates_version='u3', gatename_conversion=None, qubit_conversion=None, block_between_layers=True, block_between_gates=False, include_delay_on_idle=True, gateargs_map=None)

Converts this circuit to an openqasm string.

Parameters
num_qubitsint, optional

The number of qubits for the openqasm file. If None, then this is assumed to equal the number of line labels in this circuit.

versionstring, optional

Either ‘u3’ or ‘x-sx-rz’. Specifies the naming convention for the QASM gates. With ‘u3’, all single-qubit gates are specified in terms of the ‘u3’ gate, used by IBM and QisKit until ~2021 (see the qasm_u3 function). With ‘x-sx-rz’, all single-gates are specified in terms of ‘x’ (an x pi rotation), ‘sx’ (an x pi/2 rotation) and ‘rz’ (a parameterized rotation around z by an angle theta).

gatename_conversiondict, optional

If not None, a dictionary that converts the gatenames in the circuit to the gatenames that will appear in the openqasm output. If only standard pyGSTi names are used (e.g., ‘Gh’, ‘Gp’, ‘Gcnot’, ‘Gcphase’, etc) this dictionary need not be specified, and an automatic conversion to the standard openqasm names will be implemented.

qubit_conversiondict, optional

If not None, a dictionary converting the qubit labels in the circuit to the desired qubit labels in the openqasm output. Can be left as None if the qubit labels are either (1) integers, or (2) of the form ‘Qi’ for integer i. In this case they are converted to integers (i.e., for (1) the mapping is trivial, for (2) the mapping strips the ‘Q’).

block_between_layersbool, optional

When True, add in a barrier after every circuit layer. Including such barriers can be important for QCVV testing, as this can help reduce the “behind-the-scenes” compilation (beyond necessary conversion to native instructions) experience by the circuit.

block_between_gates: bool, optional

When True, add in a barrier after every gate (effectively serializing the circuit). Defaults to False.

include_delay_on_idle: bool, optional

When True, includes a delay operation on implicit idles in each layer, as per Qiskit’s OpenQASM 2.0 convention after the deprecation of the id operation. Defaults to True, which is commensurate with legacy usage of this function. However, this can now be set to False to avoid this behaviour if generating actually valid OpenQASM (with no opaque delay instruction) is desired.

gateargs_mapdict, optional

If not None, a dict that maps strings (representing pyGSTi standard gate names) to functions that map the parameters of a pyGSTi gate to a string to be combined with the QASM name to specify the specific gate, in QASM. If only standard pyGSTi names are used (e.g., ‘Gh’, ‘Gzr’, ‘Gczr, etc) or none of the gates are parameterized, this dictionary need not be specified, and an automatic conversion to the standard openqasm format will be implemented.

Returns
str

An openqasm string.

simulate(model, return_all_outcomes=False)

Compute the outcome probabilities of this Circuit using model as a model for the gates.

The order of the outcome strings (e.g., ‘0100’) is w.r.t. to the ordering of the qubits in the circuit. That is, the ith element of the outcome string corresponds to the qubit with label self.line_labels[i].

Parameters
modelModel

A description of the gate and SPAM operations corresponding to the labels stored in this Circuit. If this model is over more qubits than the circuit, the output will be the probabilities for the qubits in the circuit marginalized, if possible over the other qubits. But, the simulation is over the full set of qubits in the model, and so the time taken for the simulation scales with the number of qubits in the model. For models where “spectator” qubits do not affect the qubits in this circuit (such as with perfect gates), more efficient simulations will be obtained by first creating a model only over the qubits in this circuit.

return_all_outcomesbool, optional

Whether to include outcomes in the returned dictionary that have zero probability. When False, the threshold for discarding an outcome as z ero probability is 10^-12.

Returns
probsdictionary

A dictionary with keys equal to all (return_all_outcomes is True) or possibly only some (return_all_outcomes is False) of the possible outcomes, and values that are float probabilities.

done_editing()

Make this circuit read-only, so that it can be hashed (e.g. used as a dictionary key).

This is done automatically when attempting to hash a Circuit for the first time, so there’s calling this function can usually be skipped (but it’s good for code clarity).

Returns

None

expand_instruments_and_separate_povm(model, observed_outcomes=None)

Creates a dictionary of SeparatePOVMCircuit objects from expanding the instruments of this circuit.

Each key of the returned dictionary replaces the instruments in this circuit with a selection of their members. (The size of the resulting dictionary is the product of the sizes of each instrument appearing in this circuit when observed_outcomes is None). Keys are stored as SeparatePOVMCircuit objects so it’s easy to keep track of which POVM outcomes (effects) correspond to observed data. This function is, for the most part, used internally to process a circuit before computing its outcome probabilities.

Parameters
modelModel

The model used to provide necessary details regarding the expansion, including:

  • default SPAM layers

  • definitions of instrument-containing layers

  • expansions of individual instruments and POVMs

Returns
OrderedDict

A dict whose keys are SeparatePOVMCircuit objects and whose values are tuples of the outcome labels corresponding to this circuit, one per POVM effect held in the key.

class pygsti.protocols.ForwardSimulator(model=None)

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

A calculator of circuit outcome probability calculations and their derivatives w.r.t. model parameters.

Some forward simulators may also be used to perform operation-product calculations.

This functionality exists in a class separate from Model to allow for additional model classes (e.g. ones which use entirely different – non-gate-local – parameterizations of operation matrices and SPAM vectors) access to these fundamental operations. It also allows for the easier addition of new forward simulators.

Note: a model holds or “contains” a forward simulator instance to perform its computations, and a forward simulator holds a reference to its parent model, so we need to make sure the forward simulator doesn’t serialize the model or we have a circular reference.

Parameters

modelModel, optional

The model this forward simulator will use to compute circuit outcome probabilities.

property model
Castable
classmethod cast(obj: ForwardSimulator, num_qubits=None)

num_qubits only used if obj == ‘auto’

probs(circuit, outcomes=None, time=None, resource_alloc=None)

Construct a dictionary containing the outcome probabilities for a single circuit.

Parameters
circuitCircuit or tuple of operation labels

The sequence of operation labels specifying the circuit.

outcomeslist or tuple

A sequence of outcomes, which can themselves be either tuples (to include intermediate measurements) or simple strings, e.g. ‘010’. If None, only non-zero outcome probabilities will be reported.

timefloat, optional

The start time at which circuit is evaluated.

resource_allocResourceAllocation, optional

The resources available for computing circuit outcome probabilities.

Returns
probsOutcomeLabelDict

A dictionary with keys equal to outcome labels and values equal to probabilities. If no target outcomes provided, only non-zero probabilities will be reported.

dprobs(circuit, resource_alloc=None)

Construct a dictionary containing outcome probability derivatives for a single circuit.

Parameters
circuitCircuit or tuple of operation labels

The sequence of operation labels specifying the circuit.

resource_allocResourceAllocation, optional

The resources available for computing circuit outcome probability derivatives.

Returns
dprobsOutcomeLabelDict

A dictionary with keys equal to outcome labels and values equal to an array containing the (partial) derivatives of the outcome probability with respect to all model parameters.

hprobs(circuit, resource_alloc=None)

Construct a dictionary containing outcome probability Hessians for a single circuit.

Parameters
circuitCircuit or tuple of operation labels

The sequence of operation labels specifying the circuit.

resource_allocResourceAllocation, optional

The resources available for computing circuit outcome probability Hessians.

Returns
hprobsOutcomeLabelDict

A dictionary with keys equal to outcome labels and values equal to a 2D array that is the Hessian matrix for the corresponding outcome probability (with respect to all model parameters).

create_layout(circuits, dataset=None, resource_alloc=None, array_types=(), derivative_dimensions=None, verbosity=0)

Constructs an circuit-outcome-probability-array (COPA) layout for circuits and dataset.

Parameters
circuitslist

The circuits whose outcome probabilities should be computed.

datasetDataSet

The source of data counts that will be compared to the circuit outcome probabilities. The computed outcome probabilities are limited to those with counts present in dataset.

resource_allocResourceAllocation

A available resources and allocation information. These factors influence how the layout (evaluation strategy) is constructed.

array_typestuple, optional

A tuple of string-valued array types, as given by CircuitOutcomeProbabilityArrayLayout.allocate_local_array(). These types determine what types of arrays we anticipate computing using this layout (and forward simulator). These are used to check available memory against the limit (if it exists) within resource_alloc. The array types also determine the number of derivatives that this layout is able to compute. So, for example, if you ever want to compute derivatives or Hessians of element arrays then array_types must contain at least one ‘ep’ or ‘epp’ type, respectively or the layout will not allocate needed intermediate storage for derivative-containing types. If you don’t care about accurate memory limits, use (‘e’,) when you only ever compute probabilities and never their derivatives, and (‘e’,’ep’) or (‘e’,’ep’,’epp’) if you need to compute Jacobians or Hessians too.

derivative_dimensionstuple, optional

A tuple containing, optionally, the parameter-space dimension used when taking first and second derivatives with respect to the cirucit outcome probabilities. This should have minimally 1 or 2 elements when array_types contains ‘ep’ or ‘epp’ types, respectively. If array_types contains either of these strings and derivative_dimensions is None on input then we automatically set derivative_dimensions based on self.model.

verbosityint or VerbosityPrinter

Determines how much output to send to stdout. 0 means no output, higher integers mean more output.

Returns

CircuitOutcomeProbabilityArrayLayout

bulk_probs(circuits, clip_to=None, resource_alloc=None, smartc=None)

Construct a dictionary containing the probabilities for an entire list of circuits.

Parameters
circuitslist of Circuits

The list of circuits. May also be a CircuitOutcomeProbabilityArrayLayout object containing pre-computed quantities that make this function run faster.

clip_to2-tuple, optional

(min,max) to clip return value if not None.

resource_allocResourceAllocation, optional

A resource allocation object describing the available resources and a strategy for partitioning them.

smartcSmartCache, optional

A cache object to cache & use previously cached values inside this function.

Returns
probsdictionary

A dictionary such that probs[circuit] is an ordered dictionary of outcome probabilities whose keys are outcome labels.

bulk_dprobs(circuits, resource_alloc=None, smartc=None)

Construct a dictionary containing the probability derivatives for an entire list of circuits.

Parameters
circuitslist of Circuits

The list of circuits. May also be a CircuitOutcomeProbabilityArrayLayout object containing pre-computed quantities that make this function run faster.

resource_allocResourceAllocation, optional

A resource allocation object describing the available resources and a strategy for partitioning them.

smartcSmartCache, optional

A cache object to cache & use previously cached values inside this function.

Returns
dprobsdictionary

A dictionary such that dprobs[circuit] is an ordered dictionary of derivative arrays (one element per differentiated parameter) whose keys are outcome labels

bulk_hprobs(circuits, resource_alloc=None, smartc=None)

Construct a dictionary containing the probability Hessians for an entire list of circuits.

Parameters
circuitslist of Circuits

The list of circuits. May also be a CircuitOutcomeProbabilityArrayLayout object containing pre-computed quantities that make this function run faster.

resource_allocResourceAllocation, optional

A resource allocation object describing the available resources and a strategy for partitioning them.

smartcSmartCache, optional

A cache object to cache & use previously cached values inside this function.

Returns
hprobsdictionary

A dictionary such that hprobs[circuit] is an ordered dictionary of Hessian arrays (a square matrix with one row/column per differentiated parameter) whose keys are outcome labels

bulk_fill_probs(array_to_fill, layout)

Compute the outcome probabilities for a list circuits.

This routine fills a 1D array, array_to_fill with circuit outcome probabilities as dictated by a CircuitOutcomeProbabilityArrayLayout (“COPA layout”) object, which is usually specifically tailored for efficiency.

The array_to_fill array must have length equal to the number of elements in layout, and the meanings of each element are given by layout.

Parameters
array_to_fillnumpy ndarray

an already-allocated 1D numpy array of length equal to the total number of computed elements (i.e. len(layout)).

layoutCircuitOutcomeProbabilityArrayLayout

A layout for array_to_fill, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

Returns

None

bulk_fill_dprobs(array_to_fill, layout, pr_array_to_fill=None)

Compute the outcome probability-derivatives for an entire tree of circuits.

This routine fills a 2D array, array_to_fill with circuit outcome probabilities as dictated by a CircuitOutcomeProbabilityArrayLayout (“COPA layout”) object, which is usually specifically tailored for efficiency.

The array_to_fill array must have length equal to the number of elements in layout, and the meanings of each element are given by layout.

Parameters
array_to_fillnumpy ndarray

an already-allocated 2D numpy array of shape (len(layout), Np), where Np is the number of model parameters being differentiated with respect to.

layoutCircuitOutcomeProbabilityArrayLayout

A layout for array_to_fill, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

pr_mx_to_fillnumpy array, optional

when not None, an already-allocated length-len(layout) numpy array that is filled with probabilities, just as in bulk_fill_probs().

Returns

None

bulk_fill_hprobs(array_to_fill, layout, pr_array_to_fill=None, deriv1_array_to_fill=None, deriv2_array_to_fill=None)

Compute the outcome probability-Hessians for an entire list of circuits.

Similar to bulk_fill_probs(…), but fills a 3D array with the Hessians for each circuit outcome probability.

Parameters
array_to_fillnumpy ndarray

an already-allocated numpy array of shape (len(layout),M1,M2) where M1 and M2 are the number of selected model parameters (by wrt_filter1 and wrt_filter2).

layoutCircuitOutcomeProbabilityArrayLayout

A layout for array_to_fill, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

pr_mx_to_fillnumpy array, optional

when not None, an already-allocated length-len(layout) numpy array that is filled with probabilities, just as in bulk_fill_probs().

deriv1_array_to_fillnumpy array, optional

when not None, an already-allocated numpy array of shape (len(layout),M1) that is filled with probability derivatives, similar to bulk_fill_dprobs() (see array_to_fill for a definition of M1).

deriv2_array_to_fillnumpy array, optional

when not None, an already-allocated numpy array of shape (len(layout),M2) that is filled with probability derivatives, similar to bulk_fill_dprobs() (see array_to_fill for a definition of M2).

Returns

None

iter_hprobs_by_rectangle(layout, wrt_slices_list, return_dprobs_12=False)

Iterates over the 2nd derivatives of a layout’s circuit probabilities one rectangle at a time.

This routine can be useful when memory constraints make constructing the entire Hessian at once impractical, and as it only computes a subset of the Hessian’s rows and colums (a “rectangle”) at once. For example, the Hessian of a function of many circuit probabilities can often be computed rectangle-by-rectangle and without the need to ever store the entire Hessian at once.

Parameters
layoutCircuitOutcomeProbabilityArrayLayout

A layout for generated arrays, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

wrt_slices_listlist

A list of (rowSlice,colSlice) 2-tuples, each of which specify a “rectangle” of the Hessian to compute. Iterating over the output of this function iterates over these computed rectangles, in the order given by wrt_slices_list. rowSlice and colSlice must by Python slice objects.

return_dprobs_12boolean, optional

If true, the generator computes a 2-tuple: (hessian_col, d12_col), where d12_col is a column of the matrix d12 defined by: d12[iSpamLabel,iOpStr,p1,p2] = dP/d(p1)*dP/d(p2) where P is is the probability generated by the sequence and spam label indexed by iOpStr and iSpamLabel. d12 has the same dimensions as the Hessian, and turns out to be useful when computing the Hessian of functions of the probabilities.

Returns
rectangle_generator

A generator which, when iterated, yields the 3-tuple (rowSlice, colSlice, hprobs) or (rowSlice, colSlice, hprobs, dprobs12) (the latter if return_dprobs_12 == True). rowSlice and colSlice are slices directly from wrt_slices_list. hprobs and dprobs12 are arrays of shape E x B x B’, where:

  • E is the length of layout elements

  • B is the number of parameter rows (the length of rowSlice)

  • B’ is the number of parameter columns (the length of colSlice)

If mx, dp1, and dp2 are the outputs of bulk_fill_hprobs() (i.e. args mx_to_fill, deriv1_mx_to_fill, and deriv2_mx_to_fill), then:

  • hprobs == mx[:,rowSlice,colSlice]

  • dprobs12 == dp1[:,rowSlice,None] * dp2[:,None,colSlice]

pygsti.protocols.ROBUST_SUFFIX_LIST = ['.robust', '.Robust', '.robust+', '.Robust+']
pygsti.protocols.DEFAULT_BAD_FIT_THRESHOLD = 2.0
class pygsti.protocols.HasProcessorSpec(processorspec_filename_or_obj)

Bases: object

Adds to an experiment design a processor_spec attribute

Parameters

processorspec_filename_or_objQuditProcessorSpec or str

The processor API used by this experiment design.

abstract create_target_model(gate_type='auto', prep_type='auto', povm_type='auto')

Deprecated function.

class pygsti.protocols.GateSetTomographyDesign(processorspec_filename_or_obj, circuit_lists, all_circuits_needing_data=None, qubit_labels=None, nested=False, remove_duplicates=True)

Bases: pygsti.protocols.protocol.CircuitListsDesign, HasProcessorSpec

Minimal experiment design needed for GST

Parameters

processorspec_filename_or_objQuditProcessorSpec or str

The processor API used by this experiment design.

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 in circuit_lists typically with duplicates removed.

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).

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

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

GateSetTomographyDesign

class pygsti.protocols.StandardGSTDesign(processorspec_filename_or_obj, prep_fiducial_list_or_filename, meas_fiducial_list_or_filename, germ_list_or_filename, max_lengths, germ_length_limits=None, fiducial_pairs=None, keep_fraction=1, keep_seed=None, include_lgst=True, nest=True, circuit_rules=None, op_label_aliases=None, dscheck=None, action_if_missing='raise', qubit_labels=None, verbosity=0, add_default_protocol=False)

Bases: GateSetTomographyDesign

Standard GST experiment design consisting of germ-powers sandwiched between fiducials.

Parameters

processorspec_filename_or_objQuditProcessorSpec or str

The processor API used by this experiment design.

prep_fiducial_list_or_filenamelist or str

A list of preparation fiducial Circuit objects or the path to a filename containing them.

meas_fiducial_list_or_filenamelist or str

A list of measurement fiducial Circuit objects or the path to a filename containing them.

germ_list_or_filenamelist or str

A list of germ Circuit objects or the path to a filename containing them.

max_lengthslist

List of integers, one per LSGST iteration, which set truncation lengths for repeated germ strings. The list of circuits for the i-th LSGST iteration includes the repeated germs truncated to the L-values up to and including the i-th one.

germ_length_limitsdict, optional

A dictionary limiting the max-length values used for specific germs. Keys are germ sequences and values are integers. For example, if this argument is {(‘Gx’,): 4} and max_length_list = [1,2,4,8,16], then the germ (‘Gx’,) is only repeated using max-lengths of 1, 2, and 4 (whereas other germs use all the values in max_length_list).

fiducial_pairslist of 2-tuples or dict, optional

Specifies a subset of all fiducial string pairs (prepStr, effectStr) to be used in the circuit lists. If a list, each element of fid_pairs is a (iPrepStr, iEffectStr) 2-tuple of integers, each indexing a string within prep_strs and effect_strs, respectively, so that prepStr = prep_strs[iPrepStr] and effectStr = effect_strs[iEffectStr]. If a dictionary, keys are germs (elements of germ_list) and values are lists of 2-tuples specifying the pairs to use for that germ.

keep_fractionfloat, optional

The fraction of fiducial pairs selected for each germ-power base string. The default includes all fiducial pairs. Note that for each germ-power the selected pairs are different random sets of all possible pairs (unlike fid_pairs, which specifies the same fiducial pairs for all same-germ base strings). If fid_pairs is used in conjuction with keep_fraction, the pairs specified by fid_pairs are always selected, and any additional pairs are randomly selected.

keep_seedint, optional

The seed used for random fiducial pair selection (only relevant when keep_fraction < 1).

include_lgstboolean, optional

If true, then the starting list (only applicable when nest == True) is the list of LGST strings rather than the empty list. This means that when nest == True, the LGST sequences will be included in all the lists.

nestboolean, optional

If True, the GST circuit lists are “nested”, meaning that each successive list of circuits contains all the gate strings found in previous lists (and usually some additional new ones). If False, then the returned circuit list for maximum length == L contains only those circuits specified in the description above, and not those for previous values of L.

circuit_ruleslist, optional

A list of (find,replace) 2-tuples which specify circuit-label replacement rules. Both find and replace are tuples of operation labels (or Circuit objects).

op_label_aliasesdictionary, optional

Dictionary whose keys are operation label “aliases” and whose values are tuples corresponding to what that operation label should be expanded into before querying the dataset. This information is stored within the returned circuit structures. Defaults to the empty dictionary (no aliases defined) e.g. op_label_aliases[‘Gx^3’] = (‘Gx’,’Gx’,’Gx’)

dscheckDataSet, optional

A data set which filters the circuits used for GST. When a standard-GST circuit is missing from this DataSet, action is taken according to action_if_missing.

action_if_missing{“raise”,”drop”}, optional

The action to take when a desired circuit is missing from dscheck (only relevant when dscheck is not None). “raise” causes a ValueError to be raised; “drop” causes the missing sequences to be dropped from the returned set.

qubit_labelstuple, optional

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

verbosityint, optional

The level of output to print to stdout.

add_default_protocolbool, optional

Whether a default StandardGST protocol should be added to this experiment design. Setting this to True makes it easy to analyze the data (after it’s gathered) corresponding to this design via a DefaultRunner.

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

copy_with_maxlengths(max_lengths, germ_length_limits=None, dscheck=None, action_if_missing='raise', verbosity=0)

Copies this GST experiment design to one with the same data except a different set of maximum lengths.

Parameters
max_lengths_to_keeplist

A list of the maximum lengths that should be present in the returned experiment design.

germ_length_limitsdict, optional

A dictionary limiting the max-length values to keep for specific germs. Keys are germ sequences and values are integers. If None, then the current length limits are used.

dscheckDataSet, optional

A data set which filters the circuits used for GST. When a standard-GST circuit is missing from this DataSet, action is taken according to action_if_missing.

action_if_missing{“raise”,”drop”}, optional

The action to take when a desired circuit is missing from dscheck (only relevant when dscheck is not None). “raise” causes a ValueError to be raised; “drop” causes the missing sequences to be dropped from the returned set.

Returns

StandardGSTDesign

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

StandardGSTDesign

class pygsti.protocols.GSTInitialModel(model=None, target_model=None, starting_point=None, depolarize_start=0, randomize_start=0, lgst_gaugeopt_tol=1e-06, contract_start_to_cptp=False)

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

Specification of a starting point for GST.

Parameters

modelModel, optional

The model to start at, given explicitly.

starting_point{“target”, “User-supplied-Model”, “LGST”, “LGST-if-possible”}, optional

The starting point type. If None, then defaults to “User-supplied-Model” if model is given, otherwise to “target”.

depolarize_startfloat, optional

Amount to depolarize the starting model just prior to running GST.

randomize_startfloat, optional

Amount to randomly kick the starting model just prior to running GST.

lgst_gaugeopt_tolfloat, optional

Gauge-optimization tolerance for the post-LGST gauge optimization that is performed when starting_point == “LGST” or possibly when “starting_point == “LGST-if-possible”.

contract_start_to_cptpbool, optional

Whether the Model should be forced (“contracted”) to being CPTP just prior to running GST.

classmethod cast(obj)

Cast obj to a GSTInitialModel object.

Parameters
objobject

object to cast. Can be a GSTInitialModel (naturally) or a Model.

Returns

GSTInitialModel

retrieve_model(edesign, gaugeopt_target, dataset, comm)

Retrieve the starting-point Model used to seed a long-sequence GST run.

Parameters
edesignExperimentDesign

The experiment design containing the circuits being used, the qubit labels, and (possibly) a target model (for use when starting_point == “target”) and fiducial circuits (for LGST).

gaugeopt_targetModel

The gauge-optimization target, i.e. distance to this model is the objective function within the post-LGST gauge-optimization step.

datasetDataSet

Data used to execute LGST when needed.

commmpi4py.MPI.Comm

A MPI communicator to divide workload amoung multiple processors.

Returns

Model

class pygsti.protocols.GSTBadFitOptions(threshold=DEFAULT_BAD_FIT_THRESHOLD, actions=(), wildcard_budget_includes_spam=True, wildcard_L1_weights=None, wildcard_primitive_op_labels=None, wildcard_initial_budget=None, wildcard_methods=('neldermead',), wildcard_inadmissable_action='print', wildcard1d_reference='diamond distance')

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

Options for post-processing a GST fit that was unsatisfactory.

Parameters

thresholdfloat, optional

A threshold, given in number-of-standard-deviations, below which a GST fit is considered satisfactory (and no “bad-fit” processing is needed).

actionstuple, optional

Actions to take when a GST fit is unsatisfactory. Allowed actions include:

  • ‘wildcard’: Find an admissable wildcard model.

  • ‘wildcard1d’: Fits a single parameter wildcard model in which the amount of wildcard error added to an operation is proportional to the diamond distance between that operation and the target.

  • ‘robust’: scale data according out “robust statistics v1” algorithm,

    where we drastically scale down (reduce) the data due to especially poorly fitting circuits. Namely, if a circuit’s log-likelihood ratio exceeds the 95% confidence region about its expected value (the # of degrees of freedom in the circuits outcomes), then the data is scaled by the expected_value / actual_value, so that the new value exactly matches what would be expected. Ideally there are only a few of these “outlier” circuits, which correspond errors in the measurement apparatus.

  • ‘Robust’: same as ‘robust’, but re-optimize the final objective function

    (usually the log-likelihood) after performing the scaling to get the final estimate.

  • ‘robust+’: scale data according out “robust statistics v2” algorithm,

    which performs the v1 algorithm (see ‘robust’ above) and then further rescales all the circuit data to achieve the desired chi2 distribution of per-circuit goodness-of-fit values without reordering these values.

  • ‘Robust+’: same as ‘robust+’, but re-optimize the final objective function

    (usually the log-likelihood) after performing the scaling to get the final estimate.

  • ‘do nothing’: do not perform any additional actions. Used to help avoid

    the need for special cases when working with multiple types of bad-fit actions.

wildcard_budget_includes_spambool, optional

Include a SPAM budget within the wildcard budget used to process the “wildcard” action.

wildcard_L1_weightsnp.array, optional

An array of weights affecting the L1 penalty term used to select a feasible wildcard error vector w_i that minimizes sum_i weight_i* |w_i| (a weighted L1 norm). Elements of this array must correspond to those of the wildcard budget being optimized, typically the primitive operations of the estimated model - but to get the order right you should specify wildcard_primitive_op_labels to be sure. If None, then all weights are assumed to be 1.

wildcard_primitive_op_labels: list, optional

The primitive operation labels used to construct the PrimitiveOpsWildcardBudget that is optimized. If None, equal to model.primitive_op_labels + model.primitive_instrument_labels where model is the estimated model, with ‘SPAM’ at the end if wildcard_budget_includes_spam is True. When specified, should contain a subset of the default values.

wildcard_methods: tuple, optional

A list of the methods to use to optimize the wildcard error vector. Default is (“neldermead”,). Options include “neldermead”, “barrier”, “cvxopt”, “cvxopt_smoothed”, “cvxopt_small”, and “cvxpy_noagg”. So many methods exist because different convex solvers behave differently (unfortunately). Leave as the default as a safe option, but “barrier” is pretty reliable and much faster than “neldermead”, and is a good option so long as it runs.

wildcard_inadmissable_action: {“print”, “raise”}, optional

What to do when an inadmissable wildcard error vector is found. The default just prints this information and continues, while “raise” raises a ValueError. Often you just want this information printed so that when the wildcard analysis fails in this way it doesn’t cause the rest of an analysis to abort.

classmethod cast(obj)

Cast obj to a GSTBadFitOptions object.

Parameters
objobject

Object to cast. Can be a GSTBadFitOptions (naturally) or a dictionary of constructor arguments.

Returns

GSTBadFitOptions

class pygsti.protocols.GSTObjFnBuilders(iteration_builders, final_builders=())

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

Holds the objective-function builders needed for long-sequence GST.

Parameters

iteration_builderslist or tuple

A list of ObjectiveFunctionBuilder objects used (sequentially) on each GST iteration.

final_builderslist or tuple, optional

A list of ObjectiveFunctionBuilder objects used (sequentially) on the final GST iteration.

classmethod cast(obj)

Cast obj to a GSTObjFnBuilders object.

Parameters
objobject

Object to cast. Can be a GSTObjFnBuilders (naturally), a dictionary of create_from() arguments (or None), or a list or tuple of the (iteration_builders, final_builders) constructor arguments.

Returns

GSTObjFnBuilders

classmethod create_from(objective='logl', freq_weighted_chi2=False, always_perform_mle=False, only_perform_mle=False)

Creates a common GSTObjFnBuilders object from several arguments.

Parameters
objective{‘logl’, ‘chi2’}, optional

Whether to create builders for maximum-likelihood or minimum-chi-squared GST.

freq_weighted_chi2bool, optional

Whether chi-squared objectives use frequency-weighting. If you’re not sure what this is, leave it as False.

always_perform_mlebool, optional

Perform a ML-GST step on each iteration (usually this is only done for the final iteration).

only_perform_mlebool, optional

Only perform a ML-GST step on each iteration, i.e. do not perform any chi2 minimization to “seed” the ML-GST step.

Returns

GSTObjFnBuilders

class pygsti.protocols.GSTGaugeOptSuite(gaugeopt_suite_names=None, gaugeopt_argument_dicts=None, gaugeopt_target=None)

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

Holds directives to perform one or more gauge optimizations on a model.

Usually this gauge optimization is done after fitting a parameterized model to data (e.g. after GST), as the data cannot (by definition) prefer any particular gauge choice.

Parameters

gaugeopt_suite_namesstr or list of strs, optional

Names one or more gauge optimization suites to perform. A string or list of strings (see below) specifies built-in sets of gauge optimizations. The built-in suites are:

  • “single” : performs only a single “best guess” gauge optimization.

  • “varySpam” : varies spam weight and toggles SPAM penalty (0 or 1).

  • “varySpamWt” : varies spam weight but no SPAM penalty.

  • “varyValidSpamWt” : varies spam weight with SPAM penalty == 1.

  • “toggleValidSpam” : toggles spame penalty (0 or 1); fixed SPAM wt.

  • “unreliable2Q” : adds branch to a spam suite that weights 2Q gates less

  • “none”no gauge optimizations are performed. When passed individually

    (not in a list with other suite names) then this results in an empty GSTGaugeOptSuite object (w/gaugeopt_suite_names set to None).

gaugeopt_argument_dictsdict, optional

A dictionary whose string-valued keys label different gauge optimizations (e.g. within a resulting Estimate object). Each corresponding value can be either a dictionary of arguments to gaugeopt_to_target() or a list of such dictionaries which then describe the different stages of a multi-stage gauge optimization.

gaugeopt_targetModel, optional

If not None, a model to be used as the “target” for gauge- optimization (only). This argument is useful when you want to gauge optimize toward something other than the ideal target gates given by the target model, which are used as the default when gaugeopt_target is None.

classmethod cast(obj)
is_empty()

Whether this suite is completely empty, i.e., contains NO gauge optimization instructions.

This is a useful check before constructing quantities needed by gauge optimization, e.g. a target model, which can just be skipped when no gauge optimization will be performed.

Returns

bool

to_dictionary(model, unreliable_ops=(), verbosity=0)

Converts this gauge optimization suite into a raw dictionary of dictionaries.

Constructs a dictionary of gauge-optimization parameter dictionaries based on “gauge optimization suite” name(s).

This essentially renders the gauge-optimization directives within this object in an “expanded” form for either running gauge optimization (e.g. within a GateSetTomography.run() call) or for constructing the would-be gauge optimization call arguments so they can be slightly modeified before passing them in as the actual gauge-optimization suite used in an analysis (the resulting dictionary can be used to initialize a new GSTGaugeOptSuite object via the gaugeopt_argument_dicts argument.

Parameters
modelModel

A model which specifies the dimension (i.e. parameterization) of the gauge-optimization and the basis. Typically the model that is optimized or the ideal model using the same parameterization and having the correct default-gauge-group as the model that is optimized.

unreliable_opstuple, optional

A tuple of gate (or circuit-layer) labels that count as “unreliable operations”. Typically these are the multi-qubit (2-qubit) gates.

verbosityint

The verbosity to attach to the various gauge optimization parameter dictionaries.

Returns
dict

A dictionary whose keys are the labels of the different gauge optimizations to perform and whose values are the corresponding dictionaries of arguments to gaugeopt_to_target() (or lists of such dictionaries for a multi-stage gauge optimization).

class pygsti.protocols.GateSetTomography(initial_model=None, gaugeopt_suite='stdgaugeopt', objfn_builders=None, optimizer=None, badfit_options=None, verbosity=2, name=None)

Bases: pygsti.protocols.protocol.Protocol

The core gate set tomography protocol, which optimizes a parameterized model to (best) fit a data set.

Parameters

initial_modelModel or GSTInitialModel, optional

The starting-point Model.

gaugeopt_suiteGSTGaugeOptSuite, optional

Specifies which gauge optimizations to perform on each estimate. Can also be any object that can be cast to a GSTGaugeOptSuite object, such as a string or list of strings (see below) specifying built-in sets of gauge optimizations. This object also optionally stores an alternate target model for gauge optimization. This model is used as the “target” for gauge- optimization (only), and is useful when you want to gauge optimize toward something other than the ideal target gates.

objfn_buildersGSTObjFnBuilders, optional

The objective function(s) to optimize. Can also be anything that can be cast to a GSTObjFnBuilders object.

optimizerOptimizer, optional

The optimizer to use. Can also be anything that can be cast to a Optimizer.

badfit_optionsGSTBadFitOptions, optional

Options specifying what post-processing actions should be performed if the GST fit is unsatisfactory. Can also be anything that can be cast to a GSTBadFitOptions object.

verbosityint, optional

The ‘verbosity’ option is an integer specifying the level of detail printed to stdout during the calculation.

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.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

run(data, memlimit=None, comm=None, checkpoint=None, checkpoint_path=None, disable_checkpointing=False, simulator: pygsti.forwardsims.ForwardSimulator.Castable | None = None)

Run this protocol on data.

Parameters
dataProtocolData

The input data.

memlimitint, optional (default None)

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional (default None)

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

checkpointGateSetTomographyCheckpoint, optional (default None)

If specified use a previously generated checkpoint object to restart or warm start this run part way through.

checkpoint_pathstr, optional (default None)

A string for the path/name to use for writing intermediate checkpoint files to disk. Format is {path}/{name}, without inclusion of the json file extension. This {path}/{name} combination will have the latest completed iteration number appended to it before writing it to disk. If none, the value of {name} will be set to the name of the protocol being run.

disable_checkpointingbool, optional (default False)

When set to True checkpoint objects will not be constructed and written to disk during the course of this protocol. It is strongly recommended that this be kept set to False without good reason to disable the checkpoints.

simulatorForwardSimulator.Castable or None
Ignored if None. If not None, then we call

fwdsim = ForwardSimulator.cast(simulator),

and we set the .sim attribute of every Model we encounter to fwdsim.

Returns

ModelEstimateResults

class pygsti.protocols.LinearGateSetTomography(target_model=None, gaugeopt_suite='stdgaugeopt', badfit_options=None, verbosity=2, name=None)

Bases: pygsti.protocols.protocol.Protocol

The linear gate set tomography protocol.

Parameters

target_modelModel, optional

The target (ideal) model.

gaugeopt_suiteGSTGaugeOptSuite, optional

Specifies which gauge optimizations to perform on each estimate. Can also be any object that can be cast to a GSTGaugeOptSuite object, such as a string or list of strings (see below) specifying built-in sets of gauge optimizations. This object also optionally stores an alternate target model for gauge optimization. This model is used as the “target” for gauge- optimization (only), and is useful when you want to gauge optimize toward something other than the ideal target gates.

badfit_optionsGSTBadFitOptions, optional

Options specifying what post-processing actions should be performed if the LGST fit is unsatisfactory. Can also be anything that can be cast to a GSTBadFitOptions object.

verbosityint, optional

The ‘verbosity’ option is an integer specifying the level of detail printed to stdout during the calculation.

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.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

check_if_runnable(data)

Raises a ValueError if LGST cannot be run on data

Parameters
dataProtocolData

The experimental data to test for LGST-compatibility.

Returns

None

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

ModelEstimateResults

class pygsti.protocols.StandardGST(modes=('full TP', 'CPTPLND', 'Target'), gaugeopt_suite='stdgaugeopt', target_model=None, models_to_test=None, objfn_builders=None, optimizer=None, badfit_options=None, verbosity=2, name=None)

Bases: pygsti.protocols.protocol.Protocol

The standard-practice GST protocol.

Parameters

modesstr, optional

A comma-separated list of modes which dictate what types of analyses are performed. Currently, these correspond to different types of parameterizations/constraints to apply to the estimated model. The default value is usually fine. Allowed values are:

  • “full” : full (completely unconstrained)

  • “TP” : TP-constrained

  • “CPTPLND” : Lindbladian CPTP-constrained

  • “H+S” : Only Hamiltonian + Stochastic errors allowed (CPTP)

  • “S” : Only Stochastic errors allowed (CPTP)

  • “Target” : use the target (ideal) gates as the estimate

  • <model> : any key in the models_to_test argument

gaugeopt_suiteGSTGaugeOptSuite, optional

Specifies which gauge optimizations to perform on each estimate. Can also be any object that can be cast to a GSTGaugeOptSuite object, such as a string or list of strings (see below) specifying built-in sets of gauge optimizations. This object also optionally stores an alternate target model for gauge optimization. This model is used as the “target” for gauge- optimization (only), and is useful when you want to gauge optimize toward something other than the ideal target gates.

target_modelModel, optional (default None)

If specified use this Model as the target model. Depending on other specified keyword arguments this model may be used as the target for the purposes of gauge optimization, report generation/analysis, and initial seeding for optimization. (For almost all of these it may be the case that other keyword argument values override this for certain tasks).

models_to_testdict, optional

A dictionary of Model objects representing (gate-set) models to test against the data. These Models are essentially hypotheses for which (if any) model generated the data. The keys of this dictionary can (and must, to actually test the models) be used within the comma- separate list given by the modes argument.

objfn_buildersGSTObjFnBuilders, optional

The objective function(s) to optimize. Can also be anything that can be cast to a GSTObjFnBuilders object. Applies to all modes.

optimizerOptimizer, optional

The optimizer to use. Can also be anything that can be case to a Optimizer. Applies to all modes.

badfit_optionsGSTBadFitOptions, optional

Options specifying what post-processing actions should be performed if the GST fit is unsatisfactory. Can also be anything that can be cast to a GSTBadFitOptions object. Applies to all modes.

verbosityint, optional

The ‘verbosity’ option is an integer specifying the level of detail printed to stdout during the calculation.

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.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

run(data, memlimit=None, comm=None, checkpoint=None, checkpoint_path=None, disable_checkpointing=False, simulator: pygsti.forwardsims.ForwardSimulator.Castable | None = 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.

checkpointStandardGSTCheckpoint, optional (default None)

If specified use a previously generated checkpoint object to restart or warm start this run part way through.

checkpoint_pathstr, optional (default None)

A string for the path/name to use for writing intermediate checkpoint files to disk. Format is {path}/{name}, without inclusion of the json file extension. This {path}/{name} combination will have the latest completed iteration number appended to it before writing it to disk. If none, the value of {name} will be set to the name of the protocol being run.

disable_checkpointingbool, optional (default False)

When set to True checkpoint objects will not be constructed and written to disk during the course of this protocol. It is strongly recommended that this be kept set to False without good reason to disable the checkpoints.

simulatorForwardSimulator.Castable or None
Ignored if None. If not None, then we call

fwdsim = ForwardSimulator.cast(simulator),

and we set the .sim attribute of every Model we encounter to fwdsim.

Returns

ProtocolResults

class pygsti.protocols.ModelEstimateResults(data, protocol_instance, init_circuits=True)

Bases: pygsti.protocols.protocol.ProtocolResults

A results object that holds model estimates.

Parameters

dataProtocolData

The experimental data these results are generated from.

protocol_instanceProtocol

The protocol that generated these results.

init_circuitsbool, optional

Whether self.circuit_lists should be initialized or not. (In special cases, this can be disabled for speed.)

Attributes

datasetDataSet

The underlying data set.

Initialize an empty Results object.

property dataset

The underlying data set.

classmethod from_dir(dirname, name, preloaded_data=None, quick_load=False)

Initialize a new ModelEstimateResults object from dirname / results / name.

Parameters
dirnamestr

The root directory name (under which there is are ‘edesign’, ‘data’, and ‘results’ subdirectories).

namestr

The sub-directory name of the particular results object to load (there can be multiple under a given root dirname). This is the name of a subdirectory of dirname / results.

preloaded_dataProtocolData, optional

In the case that the ProtocolData object for dirname is already loaded, it can be passed in here. Otherwise leave this as None and it will be loaded.

quick_loadbool, optional

Setting this to True skips the loading of data and experiment-design components that may take a long time to load. This can be useful all the information of interest lies only within the results object.

Returns

ModelEstimateResults

to_nameddict()

Convert these results into nested NamedDict objects.

Returns

NamedDict

add_estimates(results, estimates_to_add=None)

Add some or all of the estimates from results to this Results object.

Parameters
resultsResults

The object to import estimates from. Note that this object must contain the same data set and gate sequence information as the importing object or an error is raised.

estimates_to_addlist, optional

A list of estimate keys to import from results. If None, then all the estimates contained in results are imported.

Returns

None

rename_estimate(old_name, new_name)

Rename an estimate in this Results object.

Ordering of estimates is not changed.

Parameters
old_namestr

The labels of the estimate to be renamed

new_namestr

The new name for the estimate.

Returns

None

add_estimate(estimate, estimate_key='default')

Add a set of Model estimates to this Results object.

Parameters
estimateEstimate

The estimate to add.

estimate_keystr, optional

The key or label used to identify this estimate.

Returns

None

add_model_test(target_model, themodel, estimate_key='test', gaugeopt_keys='auto', verbosity=2, simulator: pygsti.forwardsims.ForwardSimulator.Castable | None = None)

Add a new model-test (i.e. non-optimized) estimate to this Results object.

Parameters
target_modelModel

The target model used for comparison to the model.

themodelModel

The “model” model whose fit to the data and distance from target_model are assessed.

estimate_keystr, optional

The key or label used to identify this estimate.

gaugeopt_keyslist, optional

A list of gauge-optimization keys to add to the estimate. All of these keys will correspond to trivial gauge optimizations, as the model model is assumed to be fixed and to have no gauge degrees of freedom. The special value “auto” creates gauge-optimized estimates for all the gauge optimization labels currently in this Results object.

verbosityint, optional

Level of detail printed to stdout.

simulatorForwardSimulator.Castable or None
Ignored if None. If not None, then we call

fwdsim = ForwardSimulator.cast(simulator),

and we set the .sim attribute of every Model we encounter to fwdsim.

Returns

None

view(estimate_keys, gaugeopt_keys=None)

Creates a shallow copy of this Results object containing only the given estimate.

This function an also filter based on gauge-optimization keys, only keeping a subset of those available.

Parameters
estimate_keysstr or list

Either a single string-value estimate key or a list of such keys.

gaugeopt_keysstr or list, optional

Either a single string-value gauge-optimization key or a list of such keys. If None, then all gauge-optimization keys are retained.

Returns

Results

copy()

Creates a copy of this ModelEstimateResults object.

Returns

ModelEstimateResults

class pygsti.protocols.GateSetTomographyCheckpoint(mdl_list=None, last_completed_iter=-1, last_completed_circuit_list=None, final_objfn=None, name=None, parent=None)

Bases: pygsti.protocols.protocol.ProtocolCheckpoint

A class for storing intermediate results associated with running a GateSetTomography protocol’s run method to allow for restarting that method partway through.

Parameters

mdl_listlist of models, optional (default None)

Current list of models for each of the completed iterations of the protocol.

last_completed_iterint, optional (default -1)

Index of the last iteration what was successfully completed.

last_completed_circuit_listlist of Circuit objects, CircuitList or equivalent, optional (default None)

A list of Circuit objects corresponding to the last iteration successfully completed.

final_objfnModelDatasetCircuitStore, optional (Default None)

A ModelDatasetCircuitStore object corresponding to the final evaluated objective function. Not currently serialized or used during the warmstarting, so purely informational and may not always be initialized.

namestr, optional (default None)

An optional name for the checkpoint. Note this is not necessarily the name used in the automatic generation of filenames when written to disk.

parentProtocolCheckpoint, optional (default None)

When specified this checkpoint object is treated as the child of another ProtocolCheckpoint object that acts as the parent. When present, the parent’s write method supersedes the child objects and is called when calling write on the child. Currently only used in the implementation of StandardGSTCheckpoint.

class pygsti.protocols.StandardGSTCheckpoint(modes=None, children=None, name=None)

Bases: pygsti.protocols.protocol.ProtocolCheckpoint

A class for storing intermediate results associated with running a StandardGST protocol’s run method to allow for restarting that method partway through. This class acts as a container class for some set of child GateSetTomographyCheckpoint and ModelTestCheckpoint objects for each of the sub-protocols run in the course of the StandardGST protocol.

Parameters

modeslist of str, optional (default None)

A list of strings corresponding to the mode labels being run in the StandardGST protocol object that generated this checkpoint.

childrendict, optional (default None)

A dictionary whose keys correspond to modes (i.e. the same elements as the modes kwarg) and whose values are either GateSetTomographyCheckpoint or ModelTestCheckpoint objects, depending on whichever is appropriate for that mode.

namestr, optional (default None)

An optional name for the checkpoint. Note this is not necessarily the name used in the automatic generation of filenames when written to disk.

property children
pygsti.protocols.GSTDesign
pygsti.protocols.GST
pygsti.protocols.LGST
class pygsti.protocols.Circuit(layer_labels=(), line_labels='auto', num_lines=None, editable=False, stringrep=None, name='', check=True, expand_subcircuits='default', occurrence=None, compilable_layer_indices=None)

Bases: object

A quantum circuit.

A Circuit represents a quantum circuit, consisting of state preparation, gates, and measurement operations. It is composed of some number of “lines”, typically one per qubit, and stores the operations on these lines as a sequence of Label objects, one per circuit layer, whose .sslbls members indicate which line(s) the label belongs on. When a circuit is created with ‘editable=True’, a rich set of operations may be used to construct the circuit in place, after which done_editing() should be called so that the Circuit can be properly hashed as needed.

Parameters

layer_labelsiterable of Labels or str

This argument provides a list of the layer labels specifying the state preparations, gates, and measurements for the circuit. This argument can also be a Circuit or a string, in which case it is parsed as a text-formatted circuit. Internally this will eventually be converted to a list of Label objects, one per layer, but it may be specified using anything that can be readily converted to a Label objects. For example, any of the following are allowed:

  • [‘Gx’,’Gx’] : X gate on each of 2 layers

  • [Label(‘Gx’),Label(‘Gx’)] : same as above

  • [(‘Gx’,0),(‘Gy’,0)] : X then Y on qubit 0 (2 layers)

  • [[(‘Gx’,0),(‘Gx’,1)],[(‘Gy’,0),(‘Gy’,1)]] : parallel X then Y on qubits 0 & 1

line_labelsiterable, optional

The (string valued) label for each circuit line. If ‘auto’, then line_labels is taken to be the list of all state-space labels present within layer_labels. If there are no such labels (e.g. if layer_labels contains just gate names like (‘Gx’,’Gy’)), then the special value ‘*’ is used as a single line label.

num_linesint, optional

Specify this instead of line_labels to set the latter to the integers between 0 and num_lines-1.

editablebool, optional

Whether the created Circuit is created in able to be modified. If True, then you should call done_editing() once the circuit is completely assembled, as this makes the circuit read-only and allows it to be hashed.

stringrepstring, optional

A string representation for the circuit. If None (the default), then this will be generated automatically when needed. One reason you’d want to specify this is if you know of a nice compact string representation that you’d rather use, e.g. “Gx^4” instead of the automatically generated “GxGxGxGx”. If you want to initialize a Circuit entirely from a string representation you can either specify the string in as layer_labels or set layer_labels to None and stringrep to any valid (one-line) circuit string.

namestr, optional

A name for this circuit (useful if/when used as a block within larger circuits).

checkbool, optional

Whether stringrep should be checked against layer_labels to ensure they are consistent, and whether the labels in layer_labels are a subset of line_labels. The only reason you’d want to set this to False is if you’re absolutely sure stringrep and line_labels are consistent and want to save computation time.

expand_subcircuitsbool or “default”

If “default”, then the value of Circuit.default_expand_subcircuits is used. If True, then any sub-circuits (e.g. anything exponentiated like “(GxGy)^4”) will be expanded when it is stored within the created Circuit. If False, then such sub-circuits will be left as-is. It’s typically more robust to expand sub-circuits as this facilitates comparison (e.g. so “GxGx” == “Gx^2”), but in cases when you have massive exponents (e.g. “Gx^8192”) it may improve performance to set expand_subcircuits=False.

occurrencehashable, optional

A value to set as the “occurrence id” for this circuit. This value doesn’t affect the circuit an any way except by affecting it’s hashing and equivalence testing. Circuits with different occurrence ids are not equivalent. Occurrence values effectively allow multiple copies of the same ciruit to be stored in a dictionary or DataSet.

compilable_layer_indicestuple, optional

The circuit-layer indices that may be internally altered (but retaining the same target operation) and/or combined with the following circuit layer by a hardware compiler.when executing this circuit. Layers that are not “compilable” are effectively followed by a barrier which prevents the hardward compiler from restructuring the circuit across the layer boundary.

Attributes

default_expand_subcircuitsbool

By default, expand sub-circuit labels.

line_labelstuple

The line labels (often qubit labels) of this circuit.

layertuptuple

This Circuit’s layers as a standard Python tuple of layer Labels.

tuptuple

This Circuit as a standard Python tuple of layer Labels and line labels.

strstr

The Python string representation of this Circuit.

Creates a new Circuit object, encapsulating a quantum circuit.

You only need to supply the first layer_labels argument, though usually (except for just 1 or 2 qubits) you’ll want to also supply line_labels or num_lines. If you’ll be adding to or altering the circuit before using it, you should set editable=True.

Parameters

layer_labelsiterable of Labels or str

This argument provides a list of the layer labels specifying the state preparations, gates, and measurements for the circuit. This argument can also be a Circuit or a string, in which case it is parsed as a text-formatted circuit. Internally this will eventually be converted to a list of Label objects, one per layer, but it may be specified using anything that can be readily converted to a Label objects. For example, any of the following are allowed:

  • [‘Gx’,’Gx’] : X gate on each of 2 layers

  • [Label(‘Gx’),Label(‘Gx’)] : same as above

  • [(‘Gx’,0),(‘Gy’,0)] : X then Y on qubit 0 (2 layers)

  • [[(‘Gx’,0),(‘Gx’,1)],[(‘Gy’,0),(‘Gy’,1)]] : parallel X then Y on qubits 0 & 1

line_labelsiterable, optional

The (string valued) label for each circuit line. If ‘auto’, then line_labels is taken to be the list of all state-space labels present within layer_labels. If there are no such labels (e.g. if layer_labels contains just gate names like (‘Gx’,’Gy’)), then the special value ‘*’ is used as a single line label.

num_linesint, optional

Specify this instead of line_labels to set the latter to the integers between 0 and num_lines-1.

editablebool, optional

Whether the created Circuit is created in able to be modified. If True, then you should call done_editing() once the circuit is completely assembled, as this makes the circuit read-only and allows it to be hashed.

stringrepstring, optional

A string representation for the circuit. If None (the default), then this will be generated automatically when needed. One reason you’d want to specify this is if you know of a nice compact string representation that you’d rather use, e.g. “Gx^4” instead of the automatically generated “GxGxGxGx”. If you want to initialize a Circuit entirely from a string representation you can either specify the string in as layer_labels or set layer_labels to None and stringrep to any valid (one-line) circuit string.

namestr, optional

A name for this circuit (useful if/when used as a block within larger circuits).

checkbool, optional

Whether stringrep should be checked against layer_labels to ensure they are consistent, and whether the labels in layer_labels are a subset of line_labels. The only reason you’d want to set this to False is if you’re absolutely sure stringrep and line_labels are consistent and want to save computation time.

expand_subcircuitsbool or “default”

If “default”, then the value of Circuit.default_expand_subcircuits is used. If True, then any sub-circuits (e.g. anything exponentiated like “(GxGy)^4”) will be expanded when it is stored within the created Circuit. If False, then such sub-circuits will be left as-is. It’s typically more robust to expand sub-circuits as this facilitates comparison (e.g. so “GxGx” == “Gx^2”), but in cases when you have massive exponents (e.g. “Gx^8192”) it may improve performance to set expand_subcircuits=False.

occurrencehashable, optional

A value to set as the “occurrence id” for this circuit. This value doesn’t affect the circuit an any way except by affecting it’s hashing and equivalence testing. Circuits with different occurrence ids are not equivalent. Occurrence values effectively allow multiple copies of the same ciruit to be stored in a dictionary or DataSet.

compilable_layer_indicestuple, optional

The circuit-layer indices that may be internally altered (but retaining the same target operation) and/or combined with the following circuit layer by a hardware compiler.when executing this circuit. Layers that are not “compilable” are effectively followed by a barrier which prevents the hardward compiler from restructuring the circuit across the layer boundary.

property line_labels

The line labels (often qubit labels) of this circuit.

property name

The name of this circuit.

Note: the name is not a part of the hashed value. The name is used to name the CircuitLabel returned from to_label().

property occurrence

The occurrence id of this circuit.

property layertup

This Circuit’s layers as a standard Python tuple of layer Labels.

Returns

tuple

property tup

This Circuit as a standard Python tuple of layer Labels and line labels.

Returns

tuple

property compilable_layer_indices

Tuple of the layer indices corresponding to “compilable” layers.

property compilable_by_layer

Boolean array indicating whether each layer is “compilable” or not.

property str

The Python string representation of this Circuit.

Returns

str

property layerstr

Just the string representation of the circuit layers (no ‘@<line_labels>’ suffix)

property linesstr

Just the string representation of the circuit’s line labels (the ‘@<line_labels>’ suffix)

property num_lines

The number of lines in this circuit.

Returns

int

property num_layers

The number of circuit layers.

In simple circuits, this is the same as the depth (given by depth()). For circuits containing sub-circuit blocks, this gives the number of top-level layers in this circuit.

Returns

int

property depth

The circuit depth.

This is the number of layers in simple circuits. For circuits containing sub-circuit blocks, this includes the full depth of these blocks. If you just want the number of top-level layers, use num_layers().

Returns

int

property width

The circuit width.

This is the number of qubits on which the circuit acts. This includes qubits that only idle, but are included as part of the circuit according to self.line_labels.

Returns

int

property size

Returns the circuit size.

This is the sum of the sizes of all the gates in the circuit. A gate that acts on n-qubits has a size of n, with the exception of the idle which has a size of 0. Hence, the circuit is given by: size = depth * num_lines - num_1Q_idles.

Returns

int

property duration
property num_multiq_gates

The number of multi-qubit (2+ qubits) gates in the circuit.

(Note that this cannot distinguish between “true” multi-qubit gates and gate that have been defined to act on more than one qubit but that represent some tensor-product gate.)

Returns

int

default_expand_subcircuits = True
classmethod cast(obj)

Convert obj into a Circuit.

Parameters
objobject

Object to convert

Returns

Circuit

classmethod from_tuple(tup)

Creates a Circuit from a tuple

Parameters
tuptuple

The tuple to convert.

Returns

Circuit

to_label(nreps=1)

Construct and return this entire circuit as a CircuitLabel.

Note: occurrence-id information is not stored in a circuit label, so circuits that differ only in their occurence_id will return circuit labels that are equal.

Parameters
nrepsint, optional

The number of times this circuit will be repeated (CircuitLabels support exponentiation and you can specify this here).

Returns

CircuitLabel

repeat(ntimes, expand='default')

Repeat this circuit ntimes times.

Parameters
ntimesint

Number of repetitions.

expandbool or “default”, optional

When False, the returned circuit will contain a CircuitLabel encapsulating the repetitions without explicitly storing them. When True, the returned circuit will be expanded into the ntimes repetitions. “default” means to use the value in the class variable Circuit.default_expand_subcircuits.

copy(editable='auto')

Returns a copy of the circuit.

Parameters
editable{True,False,”auto”}

Whether returned copy is editable. If “auto” is given, then the copy is editable if and only if this Circuit is.

Returns

Circuit

clear()

Removes all the gates in a circuit (preserving the number of lines).

Returns

None

extract_labels(layers=None, lines=None, strict=True)

Get a subregion - a “rectangle” - of this Circuit.

This can be used to select multiple layers and/or lines of this Circuit. The strict argument controls whether gates need to be entirely within the given rectangle or can be intersecting it. If layers is a single integer then a Label is returned (representing a layer or a part of a layer), otherwise a Circuit is returned.

Parameters
layersint, slice, or list/tuple of ints

Which layers to select (the horizontal dimension of the selection rectangle). Layers are always selected by index, and this argument can be a single (integer) index - in which case a Label is returned - or multiple indices as given by a slice or list - in which case a Circuit is returned. Note that, even though we speak of a “rectangle”, layer indices do not need to be contiguous. The special value None selects all layers.

linesstr/int, slice, or list/tuple of strs/ints

Which lines to select (the vertical dimension of the selection rectangle). Lines are selected by their line-labels (elements of the circuit’s .line_labels property), which can be strings and/or integers. A single or multiple line-labels can be specified. If the line labels are integers a slice can be used, otherwise a list or tuple of labels is the only way to select multiple of them. Note that line-labels do not need to be contiguous. The special value None selects all lines.

strictbool, optional

When True, only gates lying completely within the selected region are included in the return value. If a gate straddles the region boundary (e.g. if we select just line 1 and the circuit contains “Gcnot:1:2”) then it is silently not-included in the returned label or circuit. If False, then gates which straddle the region boundary are included. Note that this may result in a Label or Circuit containing more line labels than where requested in the call to extract_labels(…)..

Returns
Label or Circuit

The requested portion of this circuit, given as a Label if layers is a single integer and as a Circuit otherwise. Note: if you want a Circuit when only selecting one layer, set layers to a slice or tuple containing just a single index.

set_labels(lbls, layers=None, lines=None)

Write lbls to the block defined by the layers and lines arguments.

Note that lbls can be anything interpretable as a Label or list of labels.

Parameters
lblsLabel, list/tuple of Labels, or Circuit

When layers is a single integer, lbls should be a single “layer label” of type Label. Otherwise, lbls should be a list or tuple of Label objects with length equal to the number of layers being set. A Circuit may also be used in this case.

layersint, slice, or list/tuple of ints

Which layers to set (the horizontal dimension of the destination rectangle). Layers are always selected by index, and this argument can be a single (integer) index or multiple indices as given by a slice or list. Note that these indices do not need to be contiguous. The special value None stands for all layers.

linesstr/int, slice, or list/tuple of strs/ints

Which lines to set (the vertical dimension of the destination rectangle). Lines are selected by their line-labels, which can be strings and/or integers. A single or multiple line-labels can be specified. If the line labels are integers a slice can be used, otherwise a list or tuple of labels is the only way to specify multiple of them. The line-labels do not need to be contiguous. The special value None stands for all lines, and in this case new lines will be created if there are new state-space labels in lbls (when lines is not None an error is raised instead).

Returns

None

insert_idling_layers(insert_before, num_to_insert, lines=None)

Inserts into this circuit one or more idling (blank) layers, returning a copy.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
insert_beforeint

The layer index to insert the new layers before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

num_to_insertint

The number of new layers to insert.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have new layers (blank circuit space) inserted into them. A single or multiple line-labels can be specified, similarly as in extract_labels(). The default value None stands for all lines.

Returns

Circuit

insert_idling_layers_inplace(insert_before, num_to_insert, lines=None)

Inserts into this circuit one or more idling (blank) layers.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
insert_beforeint

The layer index to insert the new layers before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

num_to_insertint

The number of new layers to insert.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have new layers (blank circuit space) inserted into them. A single or multiple line-labels can be specified, similarly as in extract_labels(). The default value None stands for all lines.

Returns

None

insert_labels_into_layers(lbls, layer_to_insert_before, lines=None)

Inserts into this circuit the contents of lbls into new full or partial layers, returning a copy.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
lblslist/tuple of Labels, or Circuit

The full or partial layer labels to insert. The length of this list, tuple, or circuit determines the number of layers which are inserted.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have lbls inserted into them. Currently this can only be a larger set than the set of line labels present in lbls (in future versions this may allow filtering of lbls). value None stands for all lines.

Returns

Circuit

insert_labels_into_layers_inplace(lbls, layer_to_insert_before, lines=None)

Inserts into this circuit the contents of lbls into new full or partial layers.

By default, complete layer(s) are inserted. The lines argument allows you to insert partial layers (on only a subset of the lines).

Parameters
lblslist/tuple of Labels, or Circuit

The full or partial layer labels to insert. The length of this list, tuple, or circuit determines the number of layers which are inserted.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The special value None inserts at the end.

linesstr/int, slice, or list/tuple of strs/ints, optional

Which lines should have lbls inserted into them. Currently this can only be a larger set than the set of line labels present in lbls (in future versions this may allow filtering of lbls). value None stands for all lines.

Returns

None

insert_idling_lines(insert_before, line_labels)

Insert one or more idling (blank) lines into this circuit, returning a copy.

Parameters
insert_beforestr or int

The line label to insert new lines before. The special value None inserts lines at the bottom of this circuit.

line_labelslist or tuple

A list or tuple of the new line labels to insert (can be integers and/or strings).

Returns

Circuit

insert_idling_lines_inplace(insert_before, line_labels)

Insert one or more idling (blank) lines into this circuit.

Parameters
insert_beforestr or int

The line label to insert new lines before. The special value None inserts lines at the bottom of this circuit.

line_labelslist or tuple

A list or tuple of the new line labels to insert (can be integers and/or strings).

Returns

None

insert_labels_as_lines_inplace(lbls, layer_to_insert_before=None, line_to_insert_before=None, line_labels='auto')

Inserts into this circuit the contents of lbls into new lines.

By default, lbls is inserted at the beginning of the new lines(s). The layer_to_insert_before argument allows you to insert lbls beginning at a layer of your choice.

Parameters
lblslist/tuple of Labels, or Circuit

A list of layer labels to insert as new lines. The state-space (line) labels within lbls must not overlap with that of this circuit or an error is raised. If lbls contains more layers than this circuit currently has, new layers are added automatically.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The default value of None inserts at the beginning.

line_to_insert_beforestr or int

The line label to insert the new lines before. The default value of None inserts lines at the bottom of the circuit.

line_labelslist, tuple, or “auto”

The labels of the new lines being inserted. If “auto”, then these are inferred from lbls.

Returns

None

insert_labels_as_lines(lbls, layer_to_insert_before=None, line_to_insert_before=None, line_labels='auto')

Inserts into this circuit the contents of lbls into new lines, returning a copy.

By default, lbls is inserted at the beginning of the new lines(s). The layer_to_insert_before argument allows you to insert lbls beginning at a layer of your choice.

Parameters
lblslist/tuple of Labels, or Circuit

A list of layer labels to insert as new lines. The state-space (line) labels within lbls must not overlap with that of this circuit or an error is raised. If lbls contains more layers than this circuit currently has, new layers are added automatically.

layer_to_insert_beforeint

The layer index to insert lbls before. Can be from 0 (insert at the beginning) to len(self)-1 (insert at end), and negative indexing can be used to insert relative to the last layer. The default value of None inserts at the beginning.

line_to_insert_beforestr or int

The line label to insert the new lines before. The default value of None inserts lines at the bottom of the circuit.

line_labelslist, tuple, or “auto”

The labels of the new lines being inserted. If “auto”, then these are inferred from lbls.

Returns

None

clear_labels(layers=None, lines=None, clear_straddlers=False)

Removes all the gates within the given circuit region. Does not reduce the number of layers or lines.

Parameters
layersint, slice, or list/tuple of ints

Defines the horizontal dimension of the region to clear. See extract_labels() for details.

linesstr/int, slice, or list/tuple of strs/ints

Defines the vertical dimension of the region to clear. See extract_labels() for details.

clear_straddlersbool, optional

Whether or not gates which straddle cleared and non-cleared lines should be cleared. If False and straddling gates exist, an error will be raised.

Returns

None

delete_layers(layers=None)

Deletes one or more layers from the circuit.

Parameters
layersint, slice, or list/tuple of ints

The layer index or indices to delete. See extract_labels() for details.

Returns

None

delete_lines(lines, delete_straddlers=False)

Deletes one or more lines from the circuit.

Parameters
linesstr/int, slice, or list/tuple of strs/ints

The line label(s) to delete. See extract_labels() for details.

delete_straddlersbool, optional

Whether or not gates which straddle deleted and non-deleted lines should be removed. If False and straddling gates exist, an error will be raised.

Returns

None

to_pythonstr(op_labels)

Convert this circuit to an “encoded” python string.

In the returned string each operation label is represented as a single character, starting with ‘A’ and continuing down the alphabet. This can be useful for processing operation sequences using python’s string tools (regex in particular).

Parameters
op_labelstuple

An iterable containing at least all the layer-Labels that appear in this Circuit, and which will be mapped to alphabet characters, beginning with ‘A’.

Returns
string

The converted operation sequence.

Examples

(‘Gx’,’Gx’,’Gy’,’Gx’) => “AABA”

classmethod from_pythonstr(python_string, op_labels)

Decode an “encoded string” into a Circuit.

Create a Circuit from a python string where each operation label is represented as a single character, starting with ‘A’ and continuing down the alphabet. This performs the inverse of to_pythonstr().

Parameters
python_stringstring

string whose individual characters correspond to the operation labels of a operation sequence.

op_labelstuple

tuple containing all the operation labels that will be mapped from alphabet characters, beginning with ‘A’.

Returns

Circuit

Examples

“AABA” => (‘Gx’,’Gx’,’Gy’,’Gx’)

serialize(expand_subcircuits=False)

Serialize the parallel gate operations of this Circuit.

Construct a new Circuit whereby all layers containing multiple gates are converted to separate single-gate layers, effectively putting each elementary gate operation into its own layer. Ordering is dictated by the ordering of the compound layer labels.

Parameters
expand_subcircuitsbool

Whether subcircuits should be expanded before performing the serialization. If False, the circuit may contain CircuitLabel layers.

Returns

Circuit

parallelize(can_break_labels=True, adjacent_only=False)

Compress a circuit’s gates by performing them in parallel.

Construct a circuit with the same underlying labels as this one, but with as many gates performed in parallel as possible (with some restrictions - see the Parameters section below). Generally, gates are moved as far left (toward the start) of the circuit as possible.

Parameters
can_break_labelsbool, optional

Whether compound (parallel-gate) labels in this Circuit can be separated during the parallelization process. For example, if can_break_labels=True then “Gx:0[Gy:0Gy:1]” => “[Gx:0Gy:1]Gy:0” whereas if can_break_labels=False the result would remain “Gx:0[Gy:0Gy:1]” because [Gy:0Gy:1] cannot be separated.

adjacent_onlybool, optional

It True, then operation labels are only allowed to move into an adjacent label, that is, they cannot move “through” other operation labels. For example, if adjacent_only=True then “Gx:0Gy:0Gy:1” => “Gx:0[Gy:0Gy:1]” whereas if adjacent_only=False the result would be “[Gx:0Gy:1]Gy:0. Setting this to True is sometimes useful if you want to parallelize a serial string in such a way that subsequently calling .serialize() will give you back the original string.

Returns

Circuit

expand_subcircuits_inplace()

Expands all CircuitLabel labels within this circuit.

This operation is done in place and so can only be performed on an editable Circuit.

Returns

None

expand_subcircuits()

Returns a new circuit with CircuitLabel labels expanded.

Returns

Circuit

factorize_repetitions_inplace()

Attempt to replace repeated sub-circuits with CircuitLabel objects.

More or less the reverse of expand_subcircuits(), this method attempts to collapse repetitions of the same labels into single CircuitLabel labels within this circuit.

This operation is done in place and so can only be performed on an editable Circuit.

Returns

None

insert_layer(circuit_layer, j)

Inserts a single layer into a circuit, returning a copy.

The input layer does not need to contain a gate that acts on every qubit, but it should not contain more than one gate on a qubit.

Parameters
circuit_layerLabel

The layer to insert. A (possibly compound) Label object or something that can be converted into one, e.g. ((‘Gx’,0),(‘Gcnot’,1,2)) or just ‘Gx’.

jint

The layer index (depth) at which to insert the circuit_layer.

Returns

Circuit

insert_layer_inplace(circuit_layer, j)

Inserts a single layer into a circuit.

The input layer does not need to contain a gate that acts on every qubit, but it should not contain more than one gate on a qubit.

Parameters
circuit_layerLabel

The layer to insert. A (possibly compound) Label object or something that can be converted into one, e.g. ((‘Gx’,0),(‘Gcnot’,1,2)) or just ‘Gx’.

jint

The layer index (depth) at which to insert the circuit_layer.

Returns

None

insert_circuit(circuit, j)

Inserts a circuit into this circuit, returning a copy.

The circuit to insert can be over more qubits than this circuit, as long as all qubits that are not part of this circuit are idling. In this case, the idling qubits are all discarded. The circuit to insert can also be on less qubits than this circuit: all other qubits are set to idling. So, the labels of the circuit to insert for all non-idling qubits must be a subset of the labels of this circuit.

Parameters
circuitCircuit

The circuit to be inserted.

jint

The layer index (depth) at which to insert the circuit.

Returns

Circuit

insert_circuit_inplace(circuit, j)

Inserts a circuit into this circuit.

The circuit to insert can be over more qubits than this circuit, as long as all qubits that are not part of this circuit are idling. In this case, the idling qubits are all discarded. The circuit to insert can also be on less qubits than this circuit: all other qubits are set to idling. So, the labels of the circuit to insert for all non-idling qubits must be a subset of the labels of this circuit.

Parameters
circuitCircuit

The circuit to be inserted.

jint

The layer index (depth) at which to insert the circuit.

Returns

None

append_circuit(circuit)

Append a circuit to the end of this circuit, returning a copy.

This circuit must satisfy the requirements of insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be appended.

Returns

Circuit

append_circuit_inplace(circuit)

Append a circuit to the end of this circuit.

This circuit must satisfy the requirements of insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be appended.

Returns

None

prefix_circuit(circuit)

Prefix a circuit to the beginning of this circuit, returning a copy.

This circuit must satisfy the requirements of the insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be prefixed.

Returns

Circuit

prefix_circuit_inplace(circuit)

Prefix a circuit to the beginning of this circuit.

This circuit must satisfy the requirements of the insert_circuit(). See that method for more details.

Parameters
circuitA Circuit object

The circuit to be prefixed.

Returns

None

tensor_circuit_inplace(circuit, line_order=None)

The tensor product of this circuit and circuit.

That is, it adds circuit to this circuit as new lines. The line labels of circuit must be disjoint from the line labels of this circuit, as otherwise applying the circuits in parallel does not make sense.

Parameters
circuitA Circuit object

The circuit to be tensored.

line_orderList, optional

A list of all the line labels specifying the order of the circuit in the updated circuit. If None, the lines of circuit are added below the lines of this circuit. Note that, for many purposes, the ordering of lines of the circuit is irrelevant.

Returns

None

tensor_circuit(circuit, line_order=None)

The tensor product of this circuit and circuit, returning a copy.

That is, it adds circuit to this circuit as new lines. The line labels of circuit must be disjoint from the line labels of this circuit, as otherwise applying the circuits in parallel does not make sense.

Parameters
circuitA Circuit object

The circuit to be tensored.

line_orderList, optional

A list of all the line labels specifying the order of the circuit in the updated circuit. If None, the lines of circuit are added below the lines of this circuit. Note that, for many purposes, the ordering of lines of the circuit is irrelevant.

Returns

Circuit

replace_layer_with_circuit_inplace(circuit, j)

Replaces the j-th layer of this circuit with circuit.

Parameters
circuitCircuit

The circuit to insert

jint

The layer index to replace.

Returns

None

replace_layer_with_circuit(circuit, j)

Replaces the j-th layer of this circuit with circuit, returning a copy.

Parameters
circuitCircuit

The circuit to insert

jint

The layer index to replace.

Returns

Circuit

replace_gatename_inplace(old_gatename, new_gatename)

Changes the name of a gate throughout this Circuit.

Note that the name is only a part of the label identifying each gate, and doesn’t include the lines (qubits) a gate acts upon. For example, the “Gx:0” and “Gx:1” labels both have the same name but act on different qubits.

Parameters
old_gatenamestr

The gate name to replace.

new_gatenamestr

The name to replace old_gatename with.

Returns

None

replace_gatename(old_gatename, new_gatename)

Returns a copy of this Circuit except that old_gatename is changed to new_gatename.

Note that the “name” is only a part of the “label” identifying each gate, and doesn’t include the lines (qubits) a gate acts upon. For example, the “Gx:0” and “Gx:1” labels both have the same name but act on different qubits.

Parameters
old_gatenamestr

The gate name to replace.

new_gatenamestr

The name to replace old_gatename with.

Returns

Circuit

replace_gatename_with_idle_inplace(gatename)

Treats a given gatename as an idle gate throughout this Circuit.

This effectively removes this gate name from the circuit, and replaces a layer containing only this gate name with an idle layer.

Parameters
gatenamestr

The gate name to replace.

Returns

None

replace_gatename_with_idle(gatename)

Returns a copy of this Circuit with a given gatename treated as an idle gate.

This effectively removes this gate name from the circuit, and replaces a layer containing only this gate name with an idle layer.

Parameters
gatenamestr

The gate name to replace.

Returns

Circuit

replace_layer(old_layer, new_layer)

Returns a copy of this Circuit except that old_layer is changed to new_layer.

Parameters
old_layerstr or Label

The layer to find.

new_layerstr or Label

The layer to replace found layers with.

Returns

Circuit

replace_layers_with_aliases(alias_dict)

Performs a find and replace using layer aliases.

Returns a copy of this Circuit except that it’s layers that match keys of alias_dict are replaced with the corresponding values.

Parameters
alias_dictdict

A dictionary whose keys are layer Labels (or equivalent tuples or strings), and whose values are Circuits.

Returns

Circuit

change_gate_library(compilation, allowed_filter=None, allow_unchanged_gates=False, depth_compression=True, one_q_gate_relations=None)

Re-express a circuit over a different model.

Parameters
compilationdict or CompilationLibrary.

If a dictionary, the keys are some or all of the gates that appear in the circuit, and the values are replacement circuits that are normally compilations for each of these gates (if they are not, the action of the circuit will be changed). The circuits need not be on all of the qubits, and need only satisfy the requirements of the insert_circuit method. There must be a key for every gate except the self.identity gate, unless allow_unchanged_gates is False. In that case, gate that aren’t a key in this dictionary are left unchanged.

If a CompilationLibrary, this will be queried via the retrieve_compilation_of() method to find compilations for all of the gates in the circuit. So this CompilationLibrary must contain or be able to auto-generate compilations for the requested gates, except when allow_unchanged_gates is True. In that case, gates that a compilation is not returned for are left unchanged.

allowed_filterdict or set, optional

Specifies which gates are allowed to be used when generating compilations from compilation. Can only be not None if compilation is a CompilationLibrary. If a dict, keys must be gate names (like “Gcnot”) and values QubitGraph objects indicating where that gate (if it’s present in the library) may be used. If a set, then it specifies a set of qubits and any gate in the current library that is confined within that set is allowed. If None, then all gates within the library are allowed.

allow_unchanged_gatesbool, optional

Whether to allow some gates to remain unchanged, and therefore to be absent from compilation. When True such gates are left alone; when False an error is raised if any such gates are encountered.

depth_compressionbool, optional

Whether to perform depth compression after changing the gate library. If one_q_gate_relations is None this will only remove idle layers and compress the circuit by moving everything as far forward as is possible without knowledge of the action of any gates other than self.identity. See the depth_compression method for more details. Under most circumstances this should be true; if it is False changing gate library will often result in a massive increase in circuit depth.

one_q_gate_relationsdict, optional

Gate relations for the one-qubit gates in the new gate library, that are used in the depth compression, to cancel / combine gates. E.g., one key-value pair might be (‘Gh’,’Gh’) : ‘I’, to signify that two Hadamards c ompose to the idle gate ‘Gi’. See the depth_compression() method for more details.

Returns

None

map_names_inplace(mapper)

The names of all of the simple labels are updated in-place according to the mapping function mapper.

Parameters
mapperdict or function

A dictionary whose keys are the existing gate name values and whose values are the new names (strings) or a function which takes a single (existing name) argument and returns a new name.

Returns

None

map_state_space_labels_inplace(mapper)

The labels of all of the lines (wires/qubits) are updated according to the mapping function mapper.

Parameters
mapperdict or function

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

Returns

None

map_state_space_labels(mapper)

Creates a new Circuit whose line labels are updated according to the mapping function mapper.

Parameters
mapperdict or function

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

Returns

Circuit

reorder_lines_inplace(order)

Reorders the lines (wires/qubits) of the circuit.

Note that the ordering of the lines is unimportant for most purposes.

Parameters
orderlist

A list containing all of the circuit line labels (self.line_labels) in the order that the should be converted to.

Returns

None

reorder_lines(order)

Reorders the lines (wires/qubits) of the circuit, returning a copy.

Note that the ordering of the lines is unimportant for most purposes.

Parameters
orderlist

A list containing all of the circuit line labels (self.line_labels) in the order that the should be converted to.

Returns

Circuit

idling_lines(idle_layer_labels=None)

Returns the line labels corresponding to idling lines.

Parameters
idle_layer_labelsiterable, optional

A list or tuple of layer-labels that should be treated as idle operations, so their presence will not disqualify a line from being “idle”. E.g. [“Gi”] will cause “Gi” layers to be considered idle layers.

Returns

tuple

delete_idling_lines_inplace(idle_layer_labels=None)

Removes from this circuit all lines that are idling at every layer.

Parameters
idle_layer_labelsiterable, optional

A list or tuple of layer-labels that should be treated as idle operations, so their presence will not disqualify a line from being “idle”. E.g. [“Gi”] will cause “Gi” layers to be considered idle layers.

Returns

None

delete_idling_lines(idle_layer_labels=None)

Removes from this circuit all lines that are idling at every layer, returning a copy.

Parameters
idle_layer_labelsiterable, optional

A list or tuple of layer-labels that should be treated as idle operations, so their presence will not disqualify a line from being “idle”. E.g. [“Gi”] will cause “Gi” layers to be considered idle layers.

Returns

Circuit

replace_with_idling_line_inplace(line_label, clear_straddlers=True)

Converts the specified line to an idling line, by removing all its gates.

If there are any multi-qubit gates acting on this line, this function will raise an error when clear_straddlers=False.

Parameters
line_labelstr or int

The label of the line to convert to an idling line.

clear_straddlersbool, optional

Whether or not gates which straddle the line_label should also be cleared. If False and straddling gates exist, an error will be raised.

Returns

None

reverse_inplace()

Reverses the order of the circuit.

Returns

None

delete_idle_layers_inplace()

Deletes all layers in this circuit that contain no gate operations.

One of the steps of the depth_compression() method.

Returns
bool

False if the circuit is unchanged, and True otherwise.

compress_depth_inplace(one_q_gate_relations=None, verbosity=0)

Compresses the depth of this circuit using very simple re-write rules.

  1. If one_q_gate_relations is provided, all sequences of 1-qubit gates in the circuit are compressed as far as is possible using only the pair-wise combination rules provided by this dict (see below).

  2. All gates are shifted forwarded as far as is possible without any knowledge of what any of the gates are.

  3. All idle-only layers are deleted.

Parameters
one_q_gate_relationsdict

Keys that are pairs of strings, corresponding to 1-qubit gate names, with values that are a single string, also corresponding to a 1-qubit gate name. Whenever a 1-qubit gate with name name1 is followed in the circuit by a 1-qubit gate with name2 then, if one_q_gate_relations[name1,name2] = name3, name1 -> name3 and name2 -> self.identity, the identity name in the circuit. Moreover, this is still implemented when there are self.identity gates between these 1-qubit gates, and it is implemented iteratively in the sense that if there is a sequence of 1-qubit gates with names name1, name2, name3, … and there are relations for all of (name1,name2) -> name12, (name12,name3) -> name123 etc then the entire sequence of 1-qubit gates will be compressed into a single possibly non-idle 1-qubit gate followed by idle gates in place of the previous 1-qubit gates.

If a QubitProcessorSpec object has been created for the gates/device in question, the QubitProcessorSpec.oneQgate_relations is the appropriate (and auto-generated) one_q_gate_relations.

Note that this function will not compress sequences of 1-qubit gates that cannot be compressed by independently inspecting sequential non-idle pairs (as would be the case with, for example, Gxpi Gzpi Gxpi Gzpi, if the relation did not know that (Gxpi,Gzpi) -> Gypi, even though the sequence is the identity).

verbosityint, optional

If > 0, information about the depth compression is printed to screen.

Returns

None

layer(j)

Returns a tuple of the components, i.e. the (non-identity) gates, in the layer at depth j.

These are the .components of the Label returned by indexing this Circuit (using square brackets) with j, i.e. this returns this_circuit[j].components.

Parameters
jint

The index (depth) of the layer to be returned

Returns

tuple

layer_label(j)

Returns the layer, as a Label, at depth j.

This label contains as components all the (non-identity) gates in the layer..

Parameters
jint

The index (depth) of the layer to be returned

Returns

Label

layer_with_idles(j, idle_gate_name='I')

Returns a tuple of the components of the layer at depth j, with idle_gate_name at empty circuit locations.

This effectively places an explicit idle_gate_name gates wherever there is an implied identity operation in the circuit.

Parameters
jint

The index (depth) of the layer to be returned

idle_gate_namestr, optional

The idle gate name to use. Note that state space (qubit) labels will be added to this name to form a Label.

Returns

tuple

layer_label_with_idles(j, idle_gate_name='I')

Returns the layer, as a Label, at depth j, with idle_gate_name at empty circuit locations.

This effectively places an explicit idle_gate_name gates wherever there is an implied identity operation in the circuit.

Parameters
jint

The index (depth) of the layer to be returned

idle_gate_namestr, optional

The idle gate name to use. Note that state space (qubit) labels will be added to this name to form a Label.

Returns

Label

two_q_gate_count()

The number of two-qubit gates in the circuit.

(Note that this cannot distinguish between “true” 2-qubit gates and gate that have been defined to act on two qubits but that represent some tensor-product gate.)

Returns

int

num_nq_gates(nq)

The number of nq-qubit gates in the circuit.

(Note that this cannot distinguish between “true” nq-qubit gates and gate that have been defined to act on nq qubits but that represent some tensor-product gate.)

Parameters
nqint

The qubit-count of the gates to count. For example, if nq == 3, this function returns the number of 3-qubit gates.

Returns

int

format_display_str(width=80)

Formats a string for displaying this circuit suject to a maximum width.

Parameters
widthint, optional

The maximum width in characters. If the circuit is longer than this width it is wrapped using multiple lines (like a musical score).

Returns

str

convert_to_cirq(qubit_conversion, wait_duration=None, gatename_conversion=None, idle_gate_name='Gi')

Converts this circuit to a Cirq circuit.

Parameters
qubit_conversiondict

Mapping from qubit labels (e.g. integers) to Cirq qubit objects.

wait_durationcirq.Duration, optional

If no gatename_conversion dict is given, the idle operation is not converted to a gate. If wait_diration is specified and gatename_conversion is not specified, then the idle operation will be converted to a cirq.WaitGate with the specified duration.

gatename_conversiondict, optional

If not None, a dictionary that converts the gatenames in the circuit to the Cirq gates that will appear in the Cirq circuit. If only standard pyGSTi names are used (e.g., ‘Gh’, ‘Gp’, ‘Gcnot’, ‘Gcphase’, etc) this dictionary need not be specified, and an automatic conversion to the standard Cirq names will be implemented.

idle_gate_namestr, optional

Name to use for idle gates. Defaults to ‘Gi’

Returns

A Cirq Circuit object.

classmethod from_cirq(circuit, qubit_conversion=None, cirq_gate_conversion=None, remove_implied_idles=True, global_idle_replacement_label='auto')

Converts and instantiates a pyGSTi Circuit object from a Cirq Circuit object.

Parameters
circuitcirq Circuit

The cirq Circuit object to parse into a pyGSTi circuit.

qubit_conversiondict, optional (default None)

A dictionary specifying a mapping between cirq qubit objects and pyGSTi qubit labels (either integers or strings). If None, then a default mapping is created.

cirq_gate_conversiondict, optional (default None)

If specified a dictionary with keys given by cirq gate objects, and values given by pygsti gate names which overrides the built-in conversion dictionary used by default.

remove_implied_idlesbool, optional (default True)

A flag indicating whether to remove explicit idles that are part of a circuit layer containing other explicitly specified gates (i.e., whether to abide by the normal pyGSTi implicit idle convention).

global_idle_replacement_labelstring or Label or None, optional (default ‘auto’)

An option specified for the handling of global idle layers. If None, no replacement of global idle layers is performed and a verbatim conversion from the cirq layer is performed. If the string ‘auto’, then the behavior is to replace global idle layers with the gate label Label(()), which is the special syntax for the global idle layer, stylized typically as ‘[]’. If another string then replace with a gate label with the specified name acting on all of the qubits appearing in the cirq circuit. If a Label object, use this directly, this does not check for compatibility so it is up to the user to ensure the labels are compatible.

Returns
pygsti_circuit

A pyGSTi Circuit instance equivalent to the specified Cirq one.

convert_to_quil(num_qubits=None, gatename_conversion=None, qubit_conversion=None, readout_conversion=None, block_between_layers=True, block_idles=True, gate_declarations=None)

Converts this circuit to a quil string.

Parameters
num_qubitsint, optional

The number of qubits for the quil file. If None, then this is assumed to equal the number of line labels in this circuit.

gatename_conversiondict, optional

A dictionary mapping gate names contained in this circuit to the corresponding gate names used in the rendered quil. If None, a standard set of conversions is used (see standard_gatenames_quil_conversions()).

qubit_conversiondict, optional

If not None, a dictionary converting the qubit labels in the circuit to the desired qubit labels in the quil output. Can be left as None if the qubit labels are either (1) integers, or (2) of the form ‘Qi’ for integer i. In this case they are converted to integers (i.e., for (1) the mapping is trivial, for (2) the mapping strips the ‘Q’).

readout_conversiondict, optional

If not None, a dictionary converting the qubit labels mapped through qubit_conversion to the bit labels for readot. E.g. Suppose only qubit 2 (on Rigetti hardware) is in use. Then the pyGSTi string will have only one qubit (labeled 0); it will get remapped to 2 via qubit_conversion={0:2}. At the end of the quil circuit, readout should go recorded in bit 0, so readout_conversion = {0:0}. (That is, qubit with pyGSTi label 0 gets read to Rigetti bit 0, even though that qubit has Rigetti label 2.)

block_between_layersbool, optional

When True, add in a barrier after every circuit layer. Including such “pragma” blocks can be important for QCVV testing, as this can help reduce the “behind-the-scenes” compilation (beyond necessary conversion to native instructions) experience by the circuit.

block_idlesbool, optional

In the special case of global idle gates, pragma-block barriers are inserted even when block_between_layers=False. Set block_idles=False to disable this behavior, whcih typically results in global idle gates being removed by the compiler.

gate_declarationsdict, optional

If not None, a dictionary that provides unitary maps for particular gates that are not already in the quil syntax.

Returns
str

A quil string.

convert_to_openqasm(num_qubits=None, standard_gates_version='u3', gatename_conversion=None, qubit_conversion=None, block_between_layers=True, block_between_gates=False, include_delay_on_idle=True, gateargs_map=None)

Converts this circuit to an openqasm string.

Parameters
num_qubitsint, optional

The number of qubits for the openqasm file. If None, then this is assumed to equal the number of line labels in this circuit.

versionstring, optional

Either ‘u3’ or ‘x-sx-rz’. Specifies the naming convention for the QASM gates. With ‘u3’, all single-qubit gates are specified in terms of the ‘u3’ gate, used by IBM and QisKit until ~2021 (see the qasm_u3 function). With ‘x-sx-rz’, all single-gates are specified in terms of ‘x’ (an x pi rotation), ‘sx’ (an x pi/2 rotation) and ‘rz’ (a parameterized rotation around z by an angle theta).

gatename_conversiondict, optional

If not None, a dictionary that converts the gatenames in the circuit to the gatenames that will appear in the openqasm output. If only standard pyGSTi names are used (e.g., ‘Gh’, ‘Gp’, ‘Gcnot’, ‘Gcphase’, etc) this dictionary need not be specified, and an automatic conversion to the standard openqasm names will be implemented.

qubit_conversiondict, optional

If not None, a dictionary converting the qubit labels in the circuit to the desired qubit labels in the openqasm output. Can be left as None if the qubit labels are either (1) integers, or (2) of the form ‘Qi’ for integer i. In this case they are converted to integers (i.e., for (1) the mapping is trivial, for (2) the mapping strips the ‘Q’).

block_between_layersbool, optional

When True, add in a barrier after every circuit layer. Including such barriers can be important for QCVV testing, as this can help reduce the “behind-the-scenes” compilation (beyond necessary conversion to native instructions) experience by the circuit.

block_between_gates: bool, optional

When True, add in a barrier after every gate (effectively serializing the circuit). Defaults to False.

include_delay_on_idle: bool, optional

When True, includes a delay operation on implicit idles in each layer, as per Qiskit’s OpenQASM 2.0 convention after the deprecation of the id operation. Defaults to True, which is commensurate with legacy usage of this function. However, this can now be set to False to avoid this behaviour if generating actually valid OpenQASM (with no opaque delay instruction) is desired.

gateargs_mapdict, optional

If not None, a dict that maps strings (representing pyGSTi standard gate names) to functions that map the parameters of a pyGSTi gate to a string to be combined with the QASM name to specify the specific gate, in QASM. If only standard pyGSTi names are used (e.g., ‘Gh’, ‘Gzr’, ‘Gczr, etc) or none of the gates are parameterized, this dictionary need not be specified, and an automatic conversion to the standard openqasm format will be implemented.

Returns
str

An openqasm string.

simulate(model, return_all_outcomes=False)

Compute the outcome probabilities of this Circuit using model as a model for the gates.

The order of the outcome strings (e.g., ‘0100’) is w.r.t. to the ordering of the qubits in the circuit. That is, the ith element of the outcome string corresponds to the qubit with label self.line_labels[i].

Parameters
modelModel

A description of the gate and SPAM operations corresponding to the labels stored in this Circuit. If this model is over more qubits than the circuit, the output will be the probabilities for the qubits in the circuit marginalized, if possible over the other qubits. But, the simulation is over the full set of qubits in the model, and so the time taken for the simulation scales with the number of qubits in the model. For models where “spectator” qubits do not affect the qubits in this circuit (such as with perfect gates), more efficient simulations will be obtained by first creating a model only over the qubits in this circuit.

return_all_outcomesbool, optional

Whether to include outcomes in the returned dictionary that have zero probability. When False, the threshold for discarding an outcome as z ero probability is 10^-12.

Returns
probsdictionary

A dictionary with keys equal to all (return_all_outcomes is True) or possibly only some (return_all_outcomes is False) of the possible outcomes, and values that are float probabilities.

done_editing()

Make this circuit read-only, so that it can be hashed (e.g. used as a dictionary key).

This is done automatically when attempting to hash a Circuit for the first time, so there’s calling this function can usually be skipped (but it’s good for code clarity).

Returns

None

expand_instruments_and_separate_povm(model, observed_outcomes=None)

Creates a dictionary of SeparatePOVMCircuit objects from expanding the instruments of this circuit.

Each key of the returned dictionary replaces the instruments in this circuit with a selection of their members. (The size of the resulting dictionary is the product of the sizes of each instrument appearing in this circuit when observed_outcomes is None). Keys are stored as SeparatePOVMCircuit objects so it’s easy to keep track of which POVM outcomes (effects) correspond to observed data. This function is, for the most part, used internally to process a circuit before computing its outcome probabilities.

Parameters
modelModel

The model used to provide necessary details regarding the expansion, including:

  • default SPAM layers

  • definitions of instrument-containing layers

  • expansions of individual instruments and POVMs

Returns
OrderedDict

A dict whose keys are SeparatePOVMCircuit objects and whose values are tuples of the outcome labels corresponding to this circuit, one per POVM effect held in the key.

class pygsti.protocols.ForwardSimulator(model=None)

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

A calculator of circuit outcome probability calculations and their derivatives w.r.t. model parameters.

Some forward simulators may also be used to perform operation-product calculations.

This functionality exists in a class separate from Model to allow for additional model classes (e.g. ones which use entirely different – non-gate-local – parameterizations of operation matrices and SPAM vectors) access to these fundamental operations. It also allows for the easier addition of new forward simulators.

Note: a model holds or “contains” a forward simulator instance to perform its computations, and a forward simulator holds a reference to its parent model, so we need to make sure the forward simulator doesn’t serialize the model or we have a circular reference.

Parameters

modelModel, optional

The model this forward simulator will use to compute circuit outcome probabilities.

property model
Castable
classmethod cast(obj: ForwardSimulator, num_qubits=None)

num_qubits only used if obj == ‘auto’

probs(circuit, outcomes=None, time=None, resource_alloc=None)

Construct a dictionary containing the outcome probabilities for a single circuit.

Parameters
circuitCircuit or tuple of operation labels

The sequence of operation labels specifying the circuit.

outcomeslist or tuple

A sequence of outcomes, which can themselves be either tuples (to include intermediate measurements) or simple strings, e.g. ‘010’. If None, only non-zero outcome probabilities will be reported.

timefloat, optional

The start time at which circuit is evaluated.

resource_allocResourceAllocation, optional

The resources available for computing circuit outcome probabilities.

Returns
probsOutcomeLabelDict

A dictionary with keys equal to outcome labels and values equal to probabilities. If no target outcomes provided, only non-zero probabilities will be reported.

dprobs(circuit, resource_alloc=None)

Construct a dictionary containing outcome probability derivatives for a single circuit.

Parameters
circuitCircuit or tuple of operation labels

The sequence of operation labels specifying the circuit.

resource_allocResourceAllocation, optional

The resources available for computing circuit outcome probability derivatives.

Returns
dprobsOutcomeLabelDict

A dictionary with keys equal to outcome labels and values equal to an array containing the (partial) derivatives of the outcome probability with respect to all model parameters.

hprobs(circuit, resource_alloc=None)

Construct a dictionary containing outcome probability Hessians for a single circuit.

Parameters
circuitCircuit or tuple of operation labels

The sequence of operation labels specifying the circuit.

resource_allocResourceAllocation, optional

The resources available for computing circuit outcome probability Hessians.

Returns
hprobsOutcomeLabelDict

A dictionary with keys equal to outcome labels and values equal to a 2D array that is the Hessian matrix for the corresponding outcome probability (with respect to all model parameters).

create_layout(circuits, dataset=None, resource_alloc=None, array_types=(), derivative_dimensions=None, verbosity=0)

Constructs an circuit-outcome-probability-array (COPA) layout for circuits and dataset.

Parameters
circuitslist

The circuits whose outcome probabilities should be computed.

datasetDataSet

The source of data counts that will be compared to the circuit outcome probabilities. The computed outcome probabilities are limited to those with counts present in dataset.

resource_allocResourceAllocation

A available resources and allocation information. These factors influence how the layout (evaluation strategy) is constructed.

array_typestuple, optional

A tuple of string-valued array types, as given by CircuitOutcomeProbabilityArrayLayout.allocate_local_array(). These types determine what types of arrays we anticipate computing using this layout (and forward simulator). These are used to check available memory against the limit (if it exists) within resource_alloc. The array types also determine the number of derivatives that this layout is able to compute. So, for example, if you ever want to compute derivatives or Hessians of element arrays then array_types must contain at least one ‘ep’ or ‘epp’ type, respectively or the layout will not allocate needed intermediate storage for derivative-containing types. If you don’t care about accurate memory limits, use (‘e’,) when you only ever compute probabilities and never their derivatives, and (‘e’,’ep’) or (‘e’,’ep’,’epp’) if you need to compute Jacobians or Hessians too.

derivative_dimensionstuple, optional

A tuple containing, optionally, the parameter-space dimension used when taking first and second derivatives with respect to the cirucit outcome probabilities. This should have minimally 1 or 2 elements when array_types contains ‘ep’ or ‘epp’ types, respectively. If array_types contains either of these strings and derivative_dimensions is None on input then we automatically set derivative_dimensions based on self.model.

verbosityint or VerbosityPrinter

Determines how much output to send to stdout. 0 means no output, higher integers mean more output.

Returns

CircuitOutcomeProbabilityArrayLayout

bulk_probs(circuits, clip_to=None, resource_alloc=None, smartc=None)

Construct a dictionary containing the probabilities for an entire list of circuits.

Parameters
circuitslist of Circuits

The list of circuits. May also be a CircuitOutcomeProbabilityArrayLayout object containing pre-computed quantities that make this function run faster.

clip_to2-tuple, optional

(min,max) to clip return value if not None.

resource_allocResourceAllocation, optional

A resource allocation object describing the available resources and a strategy for partitioning them.

smartcSmartCache, optional

A cache object to cache & use previously cached values inside this function.

Returns
probsdictionary

A dictionary such that probs[circuit] is an ordered dictionary of outcome probabilities whose keys are outcome labels.

bulk_dprobs(circuits, resource_alloc=None, smartc=None)

Construct a dictionary containing the probability derivatives for an entire list of circuits.

Parameters
circuitslist of Circuits

The list of circuits. May also be a CircuitOutcomeProbabilityArrayLayout object containing pre-computed quantities that make this function run faster.

resource_allocResourceAllocation, optional

A resource allocation object describing the available resources and a strategy for partitioning them.

smartcSmartCache, optional

A cache object to cache & use previously cached values inside this function.

Returns
dprobsdictionary

A dictionary such that dprobs[circuit] is an ordered dictionary of derivative arrays (one element per differentiated parameter) whose keys are outcome labels

bulk_hprobs(circuits, resource_alloc=None, smartc=None)

Construct a dictionary containing the probability Hessians for an entire list of circuits.

Parameters
circuitslist of Circuits

The list of circuits. May also be a CircuitOutcomeProbabilityArrayLayout object containing pre-computed quantities that make this function run faster.

resource_allocResourceAllocation, optional

A resource allocation object describing the available resources and a strategy for partitioning them.

smartcSmartCache, optional

A cache object to cache & use previously cached values inside this function.

Returns
hprobsdictionary

A dictionary such that hprobs[circuit] is an ordered dictionary of Hessian arrays (a square matrix with one row/column per differentiated parameter) whose keys are outcome labels

bulk_fill_probs(array_to_fill, layout)

Compute the outcome probabilities for a list circuits.

This routine fills a 1D array, array_to_fill with circuit outcome probabilities as dictated by a CircuitOutcomeProbabilityArrayLayout (“COPA layout”) object, which is usually specifically tailored for efficiency.

The array_to_fill array must have length equal to the number of elements in layout, and the meanings of each element are given by layout.

Parameters
array_to_fillnumpy ndarray

an already-allocated 1D numpy array of length equal to the total number of computed elements (i.e. len(layout)).

layoutCircuitOutcomeProbabilityArrayLayout

A layout for array_to_fill, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

Returns

None

bulk_fill_dprobs(array_to_fill, layout, pr_array_to_fill=None)

Compute the outcome probability-derivatives for an entire tree of circuits.

This routine fills a 2D array, array_to_fill with circuit outcome probabilities as dictated by a CircuitOutcomeProbabilityArrayLayout (“COPA layout”) object, which is usually specifically tailored for efficiency.

The array_to_fill array must have length equal to the number of elements in layout, and the meanings of each element are given by layout.

Parameters
array_to_fillnumpy ndarray

an already-allocated 2D numpy array of shape (len(layout), Np), where Np is the number of model parameters being differentiated with respect to.

layoutCircuitOutcomeProbabilityArrayLayout

A layout for array_to_fill, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

pr_mx_to_fillnumpy array, optional

when not None, an already-allocated length-len(layout) numpy array that is filled with probabilities, just as in bulk_fill_probs().

Returns

None

bulk_fill_hprobs(array_to_fill, layout, pr_array_to_fill=None, deriv1_array_to_fill=None, deriv2_array_to_fill=None)

Compute the outcome probability-Hessians for an entire list of circuits.

Similar to bulk_fill_probs(…), but fills a 3D array with the Hessians for each circuit outcome probability.

Parameters
array_to_fillnumpy ndarray

an already-allocated numpy array of shape (len(layout),M1,M2) where M1 and M2 are the number of selected model parameters (by wrt_filter1 and wrt_filter2).

layoutCircuitOutcomeProbabilityArrayLayout

A layout for array_to_fill, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

pr_mx_to_fillnumpy array, optional

when not None, an already-allocated length-len(layout) numpy array that is filled with probabilities, just as in bulk_fill_probs().

deriv1_array_to_fillnumpy array, optional

when not None, an already-allocated numpy array of shape (len(layout),M1) that is filled with probability derivatives, similar to bulk_fill_dprobs() (see array_to_fill for a definition of M1).

deriv2_array_to_fillnumpy array, optional

when not None, an already-allocated numpy array of shape (len(layout),M2) that is filled with probability derivatives, similar to bulk_fill_dprobs() (see array_to_fill for a definition of M2).

Returns

None

iter_hprobs_by_rectangle(layout, wrt_slices_list, return_dprobs_12=False)

Iterates over the 2nd derivatives of a layout’s circuit probabilities one rectangle at a time.

This routine can be useful when memory constraints make constructing the entire Hessian at once impractical, and as it only computes a subset of the Hessian’s rows and colums (a “rectangle”) at once. For example, the Hessian of a function of many circuit probabilities can often be computed rectangle-by-rectangle and without the need to ever store the entire Hessian at once.

Parameters
layoutCircuitOutcomeProbabilityArrayLayout

A layout for generated arrays, describing what circuit outcome each element corresponds to. Usually given by a prior call to create_layout().

wrt_slices_listlist

A list of (rowSlice,colSlice) 2-tuples, each of which specify a “rectangle” of the Hessian to compute. Iterating over the output of this function iterates over these computed rectangles, in the order given by wrt_slices_list. rowSlice and colSlice must by Python slice objects.

return_dprobs_12boolean, optional

If true, the generator computes a 2-tuple: (hessian_col, d12_col), where d12_col is a column of the matrix d12 defined by: d12[iSpamLabel,iOpStr,p1,p2] = dP/d(p1)*dP/d(p2) where P is is the probability generated by the sequence and spam label indexed by iOpStr and iSpamLabel. d12 has the same dimensions as the Hessian, and turns out to be useful when computing the Hessian of functions of the probabilities.

Returns
rectangle_generator

A generator which, when iterated, yields the 3-tuple (rowSlice, colSlice, hprobs) or (rowSlice, colSlice, hprobs, dprobs12) (the latter if return_dprobs_12 == True). rowSlice and colSlice are slices directly from wrt_slices_list. hprobs and dprobs12 are arrays of shape E x B x B’, where:

  • E is the length of layout elements

  • B is the number of parameter rows (the length of rowSlice)

  • B’ is the number of parameter columns (the length of colSlice)

If mx, dp1, and dp2 are the outputs of bulk_fill_hprobs() (i.e. args mx_to_fill, deriv1_mx_to_fill, and deriv2_mx_to_fill), then:

  • hprobs == mx[:,rowSlice,colSlice]

  • dprobs12 == dp1[:,rowSlice,None] * dp2[:,None,colSlice]

class pygsti.protocols.ModelTest(model_to_test, target_model=None, gaugeopt_suite=None, objfn_builder=None, badfit_options=None, set_trivial_gauge_group=True, verbosity=2, name=None)

Bases: pygsti.protocols.protocol.Protocol

A protocol that tests how well a model agrees with a given set of data.

Parameters

model_to_testModel

The model to compare with data when run() is called.

target_modelModel, optional

The ideal or desired model of perfect operations. It is often useful to bundle this together with model_to_test so that comparison metrics can be easily computed.

gaugeopt_suiteGSTGaugeOptSuite, optional

Specifies which gauge optimizations to perform on each estimate. Can also be any object that can be cast to a GSTGaugeOptSuite object, such as a string or list of strings (see below) specifying built-in sets of gauge optimizations. This object also optionally stores an alternate target model for gauge optimization. This model is used as the “target” for gauge- optimization (only), and is useful when you want to gauge optimize toward something other than the ideal target gates.

objfn_builderObjectiveFunctionBuilder

The objective function (builder) that is used to compare the model to data, i.e. the objective function that defines this model test.

badfit_optionsGSTBadFitOptions

Options specifing what constitutes a “bad fit” (or “failed test”) and what additional actions to take if and when this occurs.

set_trivial_gauge_groupbool, optional

A convenience flag that updates the default gauge group of model_to_test to the trivial gauge group before performing the test, so that no actual gauge optimization is performed (even if gaugeopt_suite is non-None).

verbosityint, optional

Level of detail printed to stdout.

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.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

classmethod create_objective_builder(obj)

Creates objective function builders from obj that are commonly used in model tests.

Parameters
objobject

If obj is already an ObjectiveFunctionBuilder it is used directly. A dictionary is assumed to hold arguments of ObjectiveFunctionBuilder.simple(). A list or tuple is assumed to hold positional arguments of ObjectiveFunctionBuilder.__init__().

Returns

ObjectiveFunctionBuilder

run(data, memlimit=None, comm=None, checkpoint=None, checkpoint_path=None, disable_checkpointing=False, simulator: pygsti.forwardsims.ForwardSimulator.Castable | None = 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.

checkpointModelTestCheckpoint, optional (default None)

If specified use a previously generated checkpoint object to restart or warm start this run part way through.

checkpoint_pathstr, optional (default None)

A string for the path/name to use for writing intermediate checkpoint files to disk. Format is {path}/{name}, without inclusion of the json file extension. This {path}/{name} combination will have the latest completed iteration number appended to it before writing it to disk. If none, the value of {name} will be set to the name of the protocol being run.

disable_checkpointingbool, optional (default False)

When set to True checkpoint objects will not be constructed and written to disk during the course of this protocol. It is strongly recommended that this be kept set to False without good reason to disable the checkpoints.

simulatorForwardSimulator.Castable or None
Ignored if None. If not None, then we call

fwdsim = ForwardSimulator.cast(simulator),

and we set the .sim attribute of every Model we encounter to fwdsim.

Returns

ModelEstimateResults

class pygsti.protocols.ModelTestCheckpoint(last_completed_iter=-1, last_completed_circuit_list=None, objfn_vals=None, chi2k_distributed_vals=None, name=None, parent=None)

Bases: pygsti.protocols.protocol.ProtocolCheckpoint

A class for storing intermediate results associated with running a ModelTest protocol’s run method to allow for restarting that method partway through.

Parameters

last_completed_iterint, optional (default -1)

Index of the last iteration what was successfully completed.

last_completed_circuit_listlist of Circuit objects, CircuitList or equivalent, optional (default None)

A list of Circuit objects corresponding to the last iteration successfully completed.

objfn_valslist, optional (default None)

A list of the current objective function values for each iteration/circuit list evaluated during the ModelTest protocol.

chi2k_distributed_valslist, optional (default None)
A list of the current objective function values for each iteration/circuit list

evaluated during the ModelTest protocol rescaled so as to have an expected chi-squared distribution under the null hypothesis of Wilks’ theorem.

namestr, optional (default None)

An optional name for the checkpoint. Note this is not necessarily the name used in the automatic generation of filenames when written to disk.

parentProtocolCheckpoint, optional (default None)

When specified this checkpoint object is treated as the child of another ProtocolCheckpoint object that acts as the parent. When present, the parent’s write method supersedes the child objects and is called when calling write on the child. Currently only used in the implementation of StandardGSTCheckpoint.

class pygsti.protocols.Protocol(name=None)

Bases: pygsti.baseobjs.mongoserializable.MongoSerializable

An analysis routine that is run on experimental data. A generalized notion of a QCVV protocol.

A Protocol object represents things like, but not strictly limited to, QCVV protocols. This class is essentially a serializable run function that takes as input a ProtocolData object and returns a ProtocolResults object. This function describes the working of the “protocol”.

Parameters

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.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

collection_name = 'pygsti_protocols'
classmethod from_dir(dirname, quick_load=False)

Initialize a new Protocol object from dirname.

quick_loadbool, optional

Setting this to True skips the loading of components that may take a long time to load.

Parameters
dirnamestr

The directory name.

quick_loadbool, optional

Setting this to True skips the loading of components that may take a long time to load.

Returns

Protocol

abstract 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

ProtocolResults

write(dirname)

Write this protocol to a directory.

Parameters
dirnamestr

The directory name to write. This directory will be created if needed, and the files in an existing directory will be overwritten.

Returns

None

setup_nameddict(final_dict)

Initializes a set of nested NamedDict dictionaries describing this protocol.

This function is used by ProtocolResults objects when they’re creating nested dictionaries of their contents. This function returns a set of nested, single (key,val)-pair named-dictionaries which describe the particular attributes of this Protocol object named within its self._nameddict_attributes tuple. The final nested dictionary is set to be final_dict, which allows additional result quantities to easily be added.

Parameters
final_dictNamedDict

the final-level (innermost-nested) NamedDict in the returned nested dictionary.

Returns

NamedDict

class pygsti.protocols.MultiPassProtocol(protocol, name=None)

Bases: Protocol

Runs a (contained) Protocol on all the passes of a multi-pass ProtocolData.

A simple protocol that runs a “sub-protocol” on the passes of a ProtocolData containing a MultiDataSet. The sub-protocol therefore doesn’t need to know how to deal with multiple data passes. Instances of this class essentially act as wrappers around other protocols enabling them to handle multi-pass data.

Parameters

protocolProtocol

The protocol to run on each pass.

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.

Create a new MultiPassProtocol object.

Parameters

protocolProtocol

The protocol to run on each pass.

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.

Returns

MultiPassProtocol

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

MultiPassResults

class pygsti.protocols.ProtocolRunner

Bases: object

Used to run Protocol objects on an entire tree of data

This class provides a way of combining multiple calls to Protocol.run(), potentially running multiple protocols on different data. From the outside, a ProtocolRunner object behaves similarly, and can often be used interchangably, with a Protocol object. It posesses a run method that takes a ProtocolData as input and returns a ProtocolResultsDir that can contain multiple ProtocolResults objects within it.

abstract run(data, memlimit=None, comm=None)

Run all the protocols specified by this protocol-runner 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-runner in parallel.

Returns

ProtocolResultsDir

class pygsti.protocols.TreeRunner(protocol_dict)

Bases: ProtocolRunner

Runs specific protocols on specific data-tree paths.

Parameters

protocol_dictdict

A dictionary of Protocol objects whose keys are paths (tuples of strings) specifying where in the data-tree that protocol should be run.

Create a new TreeRunner object, which runs specific protocols on specific data-tree paths.

Parameters

protocol_dictdict

A dictionary of Protocol objects whose keys are paths (tuples of strings) specifying where in the data-tree that protocol should be run.

Returns

TreeRunner

run(data, memlimit=None, comm=None)

Run all the protocols specified by this protocol-runner 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-runner in parallel.

Returns

ProtocolResultsDir

class pygsti.protocols.SimpleRunner(protocol, protocol_can_handle_multipass_data=False, edesign_type='all')

Bases: ProtocolRunner

Runs a single protocol on every data node that has no sub-nodes (possibly separately for each pass).

Parameters

protocolProtocol

The protocol to run.

protocol_can_handle_multipass_databool, optional

Whether protocol is able to process multi-pass data, or if MultiPassProtocol objects should be created implicitly.

edesign_typetype or ‘all’

Only run protocol on leaves with this type. (If ‘all’, then no filtering is performed.)

Create a new SimpleRunner object, which runs a single protocol on every ‘leaf’ of the data-tree.

Parameters

protocolProtocol

The protocol to run.

protocol_can_handle_multipass_databool, optional

Whether protocol is able to process multi-pass data, or if MultiPassProtocol objects should be created implicitly.

edesign_typetype or ‘all’

Only run protocol on leaves with this type. (If ‘all’, then no filtering is performed.)

Returns

SimpleRunner

run(data, memlimit=None, comm=None)

Run all the protocols specified by this protocol-runner 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-runner in parallel.

Returns

ProtocolResultsDir

class pygsti.protocols.DefaultRunner(run_passes_separately=False)

Bases: ProtocolRunner

Run the default protocol at each data-tree node.

(Default protocols are given within ExperimentDesign objects.)

Parameters

run_passes_separatelybool, optional

If True, then when multi-pass data is encountered it is split into passes before handing it off to the protocols. Set this to True when the default protocols being run expect single-pass data.

Create a new DefaultRunner object, which runs the default protocol at each data-tree node. (Default protocols are given within ExperimentDesign objects.)

Parameters

run_passes_separatelybool, optional

If True, then when multi-pass data is encountered it is split into passes before handing it off to the protocols. Set this to True when the default protocols being run expect single-pass data.

Returns

DefaultRunner

run(data, memlimit=None, comm=None)

Run all the protocols specified by this protocol-runner 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-runner in parallel.

Returns

ProtocolResultsDir

class pygsti.protocols.ExperimentDesign(circuits=None, qubit_labels=None, children=None, children_dirs=None)

Bases: pygsti.protocols.treenode.TreeNode, pygsti.baseobjs.mongoserializable.MongoSerializable

An experimental-design specification for one or more QCVV protocols.

The quantities needed to define the experiments required to run a Protocol. Minimally, a ExperimentDesign object holds a list of Circuit`s that need to be run.  Typically, a :class:`ExperimentDesign object also contains information used to interpret these circuits, either by describing how they are constructed from smaller pieces or how they are drawn from a distribution.

It’s important to note that a ExperimentDesign does not contain all the inputs needed to run any particular QCVV protocol (e.g. there may be additional parameters specified when creating a Protocol object, and it may be the case that the data described by a single ExperimentDesign can be used by muliple protocols). Rather, a ExperimentDesign specifies what is necessary to acquire and interpret the data needed for one or more QCVV protocols.

Parameters

circuitslist of Circuits, optional

A list of the circuits needing data. If None, then the list is empty.

qubit_labelstuple or “multiple”, optional

The qubits that this experiment design applies to. These should also be the line labels of circuits. If None, the concatenation of the qubit labels of any child experiment designs is used, or, if there are no child designs, the line labels of the first circuit is used. The special “multiple” value means that different circuits act on different qubit lines.

childrendict, optional

A dictionary of whose values are child ExperimentDesign objects and whose keys are the names used to identify them in a “path”.

children_dirsdict, optional

A dictionary whose values are directory names and keys are child names (the same as the keys of children). If None, then the keys of children must be strings and are used as directory names. Directory names are used when saving the object (via write()).

child_categorystr, optional

The category that describes the children of this object. This is used as a heading for the keys of children.

Create a new ExperimentDesign object, which holds a set of circuits (needing data).

Parameters

circuitslist of Circuits, optional

A list of the circuits needing data. If None, then the list is empty.

qubit_labelstuple or “multiple”, optional

The qubits that this experiment design applies to. These should also be the line labels of circuits. If None, the concatenation of the qubit labels of any child experiment designs is used, or, if there are no child designs, the line labels of the first circuit is used. The special “multiple” value means that different circuits act on different qubit lines.

childrendict, optional

A dictionary of whose values are child ExperimentDesign objects and whose keys are the names used to identify them in a “path”.

children_dirsdict, optional

A dictionary whose values are directory names and keys are child names (the same as the keys of children). If None, then the keys of children must be strings and are used as directory names. Directory names are used when saving the object (via write()).

Returns

ExperimentDesign

collection_name = 'pygsti_experiment_designs'
classmethod from_dir(dirname, parent=None, name=None, quick_load=False)

Initialize a new ExperimentDesign object from dirname.

Parameters
dirnamestr

The root directory name (under which there is a ‘edesign’ subdirectory).

parentExperimentDesign, optional

The parent design object, if there is one. Primarily used internally - if in doubt, leave this as None.

namestr, optional

The sub-name of the design object being loaded, i.e. the key of this data object beneath parent. Only used when parent is not None.

quick_loadbool, optional

Setting this to True skips the loading of the potentially long circuit lists. This can be useful when loading takes a long time and all the information of interest lies elsewhere, e.g. in an encompassing results object.

Returns

ExperimentDesign

classmethod from_edesign(edesign)

Create an ExperimentDesign out of an existing experiment design.

Parameters
edesignExperimentDesign

The experiment design to convert (use as a base).

Returns

ExperimentDesign

set_actual_circuits_executed(actual_circuits)

Sets a list of circuits that will actually be executed.

This list must be parallel, and corresponding circuits must be logically equivalent, to those in self.all_circuits_needing_data. For example, when the circuits in this design are run simultaneously with other circuits, the circuits in this design may need to be padded with idles.

Parameters
actual_circuitslist

A list of Circuit objects that must be the same length as self.all_circuits_needing_data.

Returns

None

add_default_protocol(default_protocol_instance)

Add a “default” protocol to this experiment design.

Default protocols are a way of designating protocols you mean to run on the the data corresponding to an experiment design before that data has been taken. Use a DefaultRunner object to run (all) the default protocols of the experiment designs within a ProtocolData object.

Note that default protocols are indexed by their names, and so when adding multiple default protocols they need to have distinct names (usually given to the protocol when it is constructed).

Parameters
default_protocol_instanceProtocol

The protocol to add. This protocol’s name is used to index it.

Returns

None

truncate_to_circuits(circuits_to_keep)

Builds a new experiment design containing only the specified circuits.

Parameters
circuits_to_keeplist

A list of the circuits to keep.

Returns

ExperimentDesign

truncate_to_available_data(dataset)

Builds a new experiment design containing only those circuits present in dataset.

Parameters
datasetDataSet

The dataset to filter based upon.

Returns

ExperimentDesign

truncate_to_design(other_design)

Truncates this experiment design by only keeping the circuits also in other_design

Parameters
other_designExperimentDesign

The experiment design to compare with.

Returns
ExperimentDesign

The truncated experiment design.

write(dirname=None, parent=None)

Write this experiment design to a directory.

Parameters
dirnamestr

The root directory to write into. This directory will have an ‘edesign’ subdirectory, which will be created if needed and overwritten if present. If None, then the path this object was loaded from is used (if this object wasn’t loaded from disk, an error is raised).

parentExperimentDesign, optional

The parent experiment design, when a parent is writing this design as a sub-experiment-design. Otherwise leave as None.

Returns

None

setup_nameddict(final_dict)

Initializes a set of nested NamedDict dictionaries describing this design.

This function is used by ProtocolResults objects when they’re creating nested dictionaries of their contents. This function returns a set of nested, single (key,val)-pair named-dictionaries which describe the particular attributes of this ExperimentDesign object named within its self._nameddict_attributes tuple. The final nested dictionary is set to be final_dict, which allows additional result quantities to easily be added.

Parameters
final_dictNamedDict

the final-level (innermost-nested) NamedDict in the returned nested dictionary.

Returns

NamedDict

promote_to_combined(name='**0')

Promote this experiment design to be a combined experiment design.

Wraps this experiment design in a new CombinedExperimentDesign whose only sub-design is this one, and returns the combined design.

Parameters
namestr, optional

The sub-design-name of this experiment design within the created combined experiment design.

Returns

CombinedExperimentDesign

promote_to_simultaneous()

Promote this experiment design to be a simultaneous experiment design.

Wraps this experiment design in a new SimultaneousExperimentDesign whose only sub-design is this one, and returns the simultaneous design.

Returns

SimultaneousExperimentDesign

map_qubit_labels(mapper)

Creates a new ExperimentDesign 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

ExperimentDesign

class pygsti.protocols.CircuitListsDesign(circuit_lists, all_circuits_needing_data=None, qubit_labels=None, nested=False, remove_duplicates=True)

Bases: ExperimentDesign

Experiment design specification that is comprised of multiple circuit lists.

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).

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_edesign(edesign)

Create a CircuitListsDesign out of an existing experiment design.

If edesign already is a circuit lists experiment design, it will just be returned (not a copy of it).

Parameters
edesignExperimentDesign

The experiment design to convert (use as a base).

Returns

CircuitListsDesign

truncate_to_lists(list_indices_to_keep)

Truncates this experiment design by only keeping a subset of its circuit lists.

Parameters
list_indices_to_keepiterable

A list of the (integer) list indices to keep.

Returns
CircuitListsDesign

The truncated experiment design.

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

CircuitListsDesign

class pygsti.protocols.CombinedExperimentDesign(sub_designs, all_circuits=None, qubit_labels=None, sub_design_dirs=None, interleave=False)

Bases: ExperimentDesign

An experiment design that combines the specifications of one or more “sub-designs”.

The sub-designs are preserved as children under the CombinedExperimentDesign instance, creating a “data-tree” structure. The CombinedExperimentDesign object itself simply merges all of the circuit lists.

Parameters

sub_designsdict or list

A dictionary of other ExperimentDesign objects whose keys are names for each sub-edesign (used for directories and to index the sub-edesigns from this experiment design). If a list is given instead, a default names of the form “ **<number> “ are used.

all_circuitslist, optional

A list of Circuit`s, specifying all the circuits needing data.  This can include additional circuits that are not in any of `sub_designs. By default, the union of all the circuits in the sub-designs is used.

qubit_labelstuple, optional

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

sub_design_dirsdict, optional

A dictionary whose values are directory names and keys are sub-edesign names (the same as the keys of sub_designs). If None, then the keys of sub_designs must be strings and are used as directory names. Directory names are used when saving the object (via write()).

interleavebool, optional

Whether the circuits of the sub_designs should be interleaved to form the circuit ordering of this experiment design.

Create a new CombinedExperimentDesign object.

Parameters

sub_designsdict or list

A dictionary of other ExperimentDesign objects whose keys are names for each sub-edesign (used for directories and to index the sub-edesigns from this experiment design). If a list is given instead, a default names of the form “ **<number> “ are used.

all_circuitslist, optional

A list of Circuit`s, specifying all the circuits needing data.  This can include additional circuits that are not in any of `sub_designs. By default, the union of all the circuits in the sub-designs is used.

qubit_labelstuple, optional

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

sub_design_dirsdict, optional

A dictionary whose values are directory names and keys are sub-edesign names (the same as the keys of sub_designs). If None, then the keys of sub_designs must be strings and are used as directory names. Directory names are used when saving the object (via write()).

interleavebool, optional

Whether the circuits of the sub_designs should be interleaved to form the circuit ordering of this experiment design.

Returns

CombinedExperimentDesign

classmethod from_edesign(edesign, name)

Create a combined experiment design out of an existing experiment design.

This makes edesign the one and only member of a new combined experiment design, even in edesign is already a CombinedExperimentDesign.

Parameters
edesignExperimentDesign

The experiment design to convert (use as a base).

namestr

The sub-name of edesign within the returned combined experiment design.

Returns

CombinedExperimentDesign

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

CombinedExperimentDesign

class pygsti.protocols.SimultaneousExperimentDesign(edesigns, tensored_circuits=None, qubit_labels=None)

Bases: ExperimentDesign

An experiment design whose circuits are the tensor-products of the circuits from one or more sub-designs.

The sub-ExperimentDesign objects must act on disjoint sets of qubits. The sub-designs are preserved as children under the SimultaneousExperimentDesign instance, creating a “data-tree” structure.

Parameters

edesignslist

A list of ExperimentDesign objects whose circuits are to occur simultaneously.

tensored_circuitslist, optional

A list of all the circuits for this experiment design. By default, these are the circuits of those in edesigns tensored together. Typically this is left as the default.

qubit_labelstuple, optional

The qubits that this experiment design applies to. If None, the concatenated qubit labels of edesigns are used (this is usually what you want).

categorystr, optional

The category name for the qubit-label-tuples correspoding to the elements of edesigns.

Create a new SimultaneousExperimentDesign object.

Parameters

edesignslist

A list of ExperimentDesign objects whose circuits are to occur simultaneously.

tensored_circuitslist, optional

A list of all the circuits for this experiment design. By default, these are the circuits of those in edesigns tensored together. Typically this is left as the default.

qubit_labelstuple, optional

The qubits that this experiment design applies to. If None, the concatenated qubit labels of edesigns are used (this is usually what you want).

Returns

SimultaneousExperimentDesign

classmethod from_edesign(edesign)

Create a simultaneous experiment design out of an existing experiment design.

This makes edesign the one and only member of a new simultanieous experiment design, even in edesign is already a SimultaneousExperimentDesign.

Parameters
edesignExperimentDesign

The experiment design to convert (use as a base).

Returns

SimultaneousExperimentDesign

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

SimultaneousExperimentDesign

class pygsti.protocols.FreeformDesign(circuits, qubit_labels=None)

Bases: ExperimentDesign

Experiment design holding an arbitrary circuit list and meta data.

Parameters

circuitslist or dict

A list of the circuits needing data. If None, then the list is empty.

qubit_labelstuple, optional

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

Create a new ExperimentDesign object, which holds a set of circuits (needing data).

Parameters

circuitslist of Circuits, optional

A list of the circuits needing data. If None, then the list is empty.

qubit_labelstuple or “multiple”, optional

The qubits that this experiment design applies to. These should also be the line labels of circuits. If None, the concatenation of the qubit labels of any child experiment designs is used, or, if there are no child designs, the line labels of the first circuit is used. The special “multiple” value means that different circuits act on different qubit lines.

childrendict, optional

A dictionary of whose values are child ExperimentDesign objects and whose keys are the names used to identify them in a “path”.

children_dirsdict, optional

A dictionary whose values are directory names and keys are child names (the same as the keys of children). If None, then the keys of children must be strings and are used as directory names. Directory names are used when saving the object (via write()).

Returns

ExperimentDesign

classmethod from_dataframe(df, qubit_labels=None)

Create a FreeformDesign from a pandas dataframe.

Parameters
dfpandas.Dataframe

A dataframe containing a “Circuit” column and possibly others.

qubit_labelstuple, optional

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

Returns

FreeformDesign

classmethod from_edesign(edesign)

Create a FreeformDesign out of an existing experiment design.

If edesign already is a free-form experiment design, it will just be returned (not a copy of it).

Parameters
edesignExperimentDesign

The experiment design to convert (use as a base).

Returns

FreeformDesign

to_dataframe(pivot_valuename=None, pivot_value='Value', drop_columns=False)
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

FreeformDesign

class pygsti.protocols.ProtocolData(edesign, dataset=None, cache=None)

Bases: pygsti.protocols.treenode.TreeNode, pygsti.baseobjs.mongoserializable.MongoSerializable

Represents the experimental data needed to run one or more QCVV protocols.

This class contains a ProtocolIput, which describes a set of circuits, and a DataSet (or MultiDataSet) that holds data for these circuits. These members correspond to the .edesign and .dataset attributes.

Parameters

edesignExperimentDesign

The experiment design describing what circuits this object contains data for. If None, then an unstructured ExperimentDesign is created containing the circuits present in dataset.

datasetDataSet or MultiDataSet, optional

The data counts themselves.

cachedict, optional

A cache of values which holds values derived only from the experiment design and data in this object.

Attributes

passesdict

A dictionary of the data on a per-pass basis (works even it there’s just one pass).

Create a new ProtocolData object.

Parameters

edesignExperimentDesign

The experiment design describing what circuits this object contains data for. If None, then an unstructured ExperimentDesign is created containing the circuits present in dataset.

datasetDataSet or MultiDataSet, optional

The data counts themselves.

cachedict, optional

A cache of values which holds values derived only from the experiment design and data in this object.

Returns

ProtocolData

property passes

A dictionary of the data on a per-pass basis (works even it there’s just one pass).

Returns

dict

collection_name = 'pygsti_protocol_data'
CACHE_COLLECTION_NAME = 'pygsti_protocol_data_caches'
classmethod from_dir(dirname, parent=None, name=None, preloaded_edesign=None, quick_load=False, record_zero_counts=True)

Initialize a new ProtocolData object from dirname.

Parameters
dirnamestr

The root directory name (under which there are ‘edesign’ and ‘data’ subdirectories).

parentProtocolData, optional

The parent data object, if there is one. This is needed for sub-data objects which reference/inherit their parent’s dataset. Primarily used internally - if in doubt, leave this as None.

namestr, optional

The sub-name of the object being loaded, i.e. the key of this data object beneath parent. Only used when parent is not None.

preloaded_edesignExperimentDesign, optional

In the case that the ExperimentDesign object for dirname is already loaded, it can be passed in here. Otherwise leave this as None and it will be loaded.

quick_loadbool, optional

Setting this to True skips the loading of components that may take a long time, e.g. the actual raw data set(s). This can be useful when loading takes a long time and all the information of interest lies elsewhere, e.g. in an encompassing results object.

record_zero_countsbool, optional

Whether zero-counts are actually recorded (stored) in the datasets held within this ProtocolData object.

Returns

ProtocolData

copy()

Make a copy of this object.

Returns

ProtocolData

is_multipass()

Whether this protocol data contains multiple passes.

More accurately, whether the .dataset of this object is a MultiDataSet.

Returns

bool

prune_tree(paths, paths_are_sorted=False)

Prune the tree rooted here to include only the given paths, discarding all else.

Returns a new ProtocolData object with a subset of the data-tree paths contained under this one.

Parameters
pathslist

A list of the paths to keep. Each path is a tuple of keys, delineating a path in the data-tree.

paths_are_sortedbool, optional

Whether paths has already been sorted lexographically.

Returns

ProtocolData

write(dirname=None, parent=None, edesign_already_written=False)

Write this protocol data to a directory.

Parameters
dirnamestr

The root directory to write into. This directory will have ‘edesign’ and ‘data’ subdirectories, which will be created if needed and overwritten if present. If None, then the path this object was loaded from is used (if this object wasn’t loaded from disk, an error is raised).

parentProtocolData, optional

The parent protocol data, when a parent is writing this data as a sub-protocol-data object. Otherwise leave as None.

edesign_already_writtenbool, optional

If True, the experiment design within this data object is not written to disk, and it is left to the caller to ensure the experiment design is saved.

Returns

None

setup_nameddict(final_dict)

Initializes a set of nested NamedDict dictionaries describing this data.

This function is used by ProtocolResults objects when they’re creating nested dictionaries of their contents. The final nested dictionary is set to be final_dict, which allows additional result quantities to easily be added.

Parameters
final_dictNamedDict

the final-level (innermost-nested) NamedDict in the returned nested dictionary.

Returns

NamedDict

to_dataframe(pivot_valuename=None, pivot_value=None, drop_columns=False)

Create a Pandas dataframe with this data.

Parameters
pivot_valuenamestr, optional

If not None, the resulting dataframe is pivoted using pivot_valuename as the column whose values name the pivoted table’s column names. If None and pivot_value is not None,`”ValueName”` is used.

pivot_valuestr, optional

If not None, the resulting dataframe is pivoted such that values of the pivot_value column are rearranged into new columns whose names are given by the values of the pivot_valuename column. If None and pivot_valuename is not None,`”Value”` is used.

drop_columnsbool or list, optional

A list of column names to drop (prior to performing any pivot). If True appears in this list or is given directly, then all constant-valued columns are dropped as well. No columns are dropped when drop_columns == False.

Returns

pandas.DataFrame

class pygsti.protocols.ProtocolResults(data, protocol_instance)

Bases: pygsti.baseobjs.mongoserializable.MongoSerializable

Stores the results from running a QCVV protocol on data.

A ProtocolResults object Contains a ProtocolData object and stores the results of running a Protcocol on this data.

Parameters

dataProtocolData

The input data from which these results are derived.

protocol_instanceProtocol

The protocol that created these results.

Create a new ProtocolResults object.

Parameters

dataProtocolData

The input data from which these results are derived.

protocol_instanceProtocol

The protocol that created these results.

Returns

ProtocolResults

collection_name = 'pygsti_results'
classmethod from_dir(dirname, name, preloaded_data=None, quick_load=False)

Initialize a new ProtocolResults object from dirname / results / name.

Parameters
dirnamestr

The root directory name (under which there is are ‘edesign’, ‘data’, and ‘results’ subdirectories).

namestr

The sub-directory name of the particular results object to load (there can be multiple under a given root dirname). This is the name of a subdirectory of dirname / results.

preloaded_dataProtocolData, optional

In the case that the ProtocolData object for dirname is already loaded, it can be passed in here. Otherwise leave this as None and it will be loaded.

quick_loadbool, optional

Setting this to True skips the loading of data and experiment-design components that may take a long time to load. This can be useful all the information of interest lies only within the results object.

Returns

ProtocolResults

write(dirname=None, data_already_written=False)

Write these protocol results to a directory.

Parameters
dirnamestr

The root directory to write into. This directory will have ‘edesign’, ‘data’, and ‘results/<myname>’ subdirectories, which will path be created if needed and overwritten if present. If None, then the this object was loaded from is used (if this object wasn’t loaded from disk, an error is raised).

data_already_writtenbool, optional

Set this to True if you’re sure the .data ProtocolData object within this results object has already been written to dirname. Leaving this as the default is a safe option.

Returns

None

to_nameddict()

Convert these results into nested NamedDict objects.

Returns

NamedDict

to_dataframe(pivot_valuename=None, pivot_value=None, drop_columns=False)

Convert these results into Pandas dataframe.

Parameters
pivot_valuenamestr, optional

If not None, the resulting dataframe is pivoted using pivot_valuename as the column whose values name the pivoted table’s column names. If None and pivot_value is not None,`”ValueName”` is used.

pivot_valuestr, optional

If not None, the resulting dataframe is pivoted such that values of the pivot_value column are rearranged into new columns whose names are given by the values of the pivot_valuename column. If None and pivot_valuename is not None,`”Value”` is used.

drop_columnsbool or list, optional

A list of column names to drop (prior to performing any pivot). If True appears in this list or is given directly, then all constant-valued columns are dropped as well. No columns are dropped when drop_columns == False.

Returns

DataFrame

class pygsti.protocols.MultiPassResults(data, protocol_instance)

Bases: ProtocolResults

Holds the results of a single protocol on multiple “passes” (sets of data, typically taken at different times).

The results of each pass are held as a separate ProtcolResults object within the .passes attribute.

Parameters

dataProtocolData

The input data from which these results are derived.

protocol_instanceProtocol

The protocol that created these results.

Initialize an empty MultiPassResults object, which contain a dictionary of sub-results one per “pass”. Usually these sub-results are obtained by running protocol_instance on each data set within data.

Parameters

dataProtocolData

The input data from which these results are derived.

protocol_instanceProtocol

The protocol that created these results.

Returns

MultiPassResults

classmethod from_dir(dirname, name, preloaded_data=None, quick_load=False)

Initialize a new MultiPassResults object from dirname / results / name.

Parameters
dirnamestr

The root directory name (under which there is are ‘edesign’, ‘data’, and ‘results’ subdirectories).

namestr

The sub-directory name of the particular results object to load (there can be multiple under a given root dirname). This is the name of a subdirectory of dirname / results.

preloaded_dataProtocolData, optional

In the case that the ProtocolData object for dirname is already loaded, it can be passed in here. Otherwise leave this as None and it will be loaded.

quick_loadbool, optional

Setting this to True skips the loading of data and experiment-design components that may take a long time to load. This can be useful all the information of interest lies only within the results object.

Returns

ProtocolResults

to_nameddict()

Create a NamedDict of the results within this object.

Returns

NamedDict

copy()

Make a copy of this object.

Returns

MultiPassResults

class pygsti.protocols.ProtocolResultsDir(data, protocol_results=None, children=None)

Bases: pygsti.protocols.treenode.TreeNode, pygsti.baseobjs.mongoserializable.MongoSerializable

Holds a dictionary of ProtocolResults objects.

It contains a ProtocolData object and is rooted at the_model corresponding node of the data-tree. It contains links to child-ProtocolResultsDir objects representing sub-directories.

This container object holds two things:

  1. A .for_protocol dictionary of ProtocolResults corresponding to different protocols (keys are protocol names).

  2. Child ProtocolResultsDir objects, obtained by indexing this object directly using the name of the sub-directory.

Parameters

dataProtocolData

The data from which all the Results objects in this ProtocolResultsDir are derived.

protocol_resultsProtocolResults, optional

An initial (single) results object to add. The name of the results object is used as its key within the .for_protocol dictionary. If None, then an empty results directory is created.

childrendict, optional

A dictionary of the ProtocolResultsDir objects that are sub-directories beneath this one. If None, then children are automatically created based upon the tree given by data. (To avoid creating any children, you can pass an empty dict here.)

Create a new ProtocolResultsDir object.

This container object holds two things:

  1. A .for_protocol dictionary of ProtocolResults corresponding to different protocols (keys are protocol names).

  2. Child ProtocolResultsDir objects, obtained by indexing this object directly using the name of the sub-directory.

Parameters

dataProtocolData

The data from which all the Results objects in this ProtocolResultsDir are derived.

protocol_resultsProtocolResults or dict, optional

An initial dictionary of ProtocolResults objects to add, or a single results object. The name(s) of the results object(s) must be used as keys (and will used as its key for a single results object). This beccomes the created object’s .for_protocol dictionary. If None, then an empty results directory is created.

childrendict, optional

A dictionary of the ProtocolResultsDir objects that are sub-directories beneath this one. If None, then children are automatically created based upon the tree given by data. (To avoid creating any children, you can pass an empty dict here.)

Returns

ProtocolResultsDir

collection_name = 'pygsti_results_directories'
classmethod from_dir(dirname, parent=None, name=None, preloaded_data=None, quick_load=False)

Initialize a new ProtocolResultsDir object from dirname.

Parameters
dirnamestr

The root directory name (under which there are ‘edesign’ and ‘data’, and possibly ‘results’, subdirectories).

parentProtocolResultsDir, optional

The parent results-directory object that is loading the returned object as a sub-results. This is used internally when loading a ProtocolResultsDir that represents a node of the data-tree with children.

namestr, optional

The name of this result within parent. This is only used when parent is not None.

preloaded_dataProtocolData, optional

In the case that the ProtocolData object for dirname is already loaded, it can be passed in here. Otherwise leave this as None and it will be loaded.

quick_loadbool, optional

Setting this to True skips the loading of data and experiment-design components that may take a long time to load. This can be useful all the information of interest lies only within the contained results objects.

Returns

ProtcolResultsDir

add_results(for_protocol_name, results)

Add a new results object to this results directory node.

The added results object must share this result directory’s data, i.e., its .data attribute must match the .data of this directory. This requirement is usually met because the results have been created by running a protocol on this directory’s .data. The results object is stored in the .for_protocol[for_protocol_name] attribute of this directory.

Parameters
for_protocol_namestr

Name of the protocol to be added.

resultsProtocolResults

The results object to be added

Returns

None

write(dirname=None, parent=None, data_already_written=False)

Write this “protocol results directory” to a directory.

Parameters
dirnamestr

The root directory to write into. This directory will have ‘edesign’, ‘data’, and ‘results’ subdirectories, which will be created if needed and overwritten if present. If None, then the path this object was loaded from is used (if this object wasn’t loaded from disk, an error is raised).

parentProtocolResultsDir, optional

The parent protocol results directory, when a parent is writing this results dir as a sub-results-dir. Otherwise leave as None.

data_already_writtenbool, optional

If True, the data object within this results directory is not written to disk, and it is left to the caller to ensure the data object is saved.

Returns

None

to_nameddict()

Convert the results in this object into nested NamedDict objects.

Returns

NamedDict

to_dataframe(pivot_valuename=None, pivot_value=None, drop_columns=False)

Convert these results into Pandas dataframe.

Parameters
pivot_valuenamestr, optional

If not None, the resulting dataframe is pivoted using pivot_valuename as the column whose values name the pivoted table’s column names. If None and pivot_value is not None,`”ValueName”` is used.

pivot_valuestr, optional

If not None, the resulting dataframe is pivoted such that values of the pivot_value column are rearranged into new columns whose names are given by the values of the pivot_valuename column. If None and pivot_valuename is not None,`”Value”` is used.

drop_columnsbool or list, optional

A list of column names to drop (prior to performing any pivot). If True appears in this list or is given directly, then all constant-valued columns are dropped as well. No columns are dropped when drop_columns == False.

Returns

DataFrame

pygsti.protocols.run_default_protocols(data, memlimit=None, comm=None)

Run the default protocols for the data-tree rooted at data.

Parameters

dataProtocolData

the data to run default protocols on.

memlimitint, optional

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional

When not None, an MPI communicator used to run the protocols in parallel.

Returns

ProtocolResultsDir

class pygsti.protocols.ProtocolPostProcessor(name)

Bases: object

Similar to a protocol, but runs on an existing ProtocolResults object.

Running a ProtocolPostProcessor produces a new (or updated) ProtocolResults object.

Parameters

namestr

The name of this post-processor.

Create a new ProtocolPostProcessor object.

Parameters

namestr

The name of this post-processor.

Returns

ProtocolPostProcessor

classmethod from_dir(dirname, quick_load=False)

Initialize a new ProtocolPostProcessor object from dirname.

Parameters
dirnamestr

The directory name.

quick_loadbool, optional

Setting this to True skips the loading of components that may take a long time to load.

Returns

ProtocolPostProcessor

abstract run(results, memlimit=None, comm=None)

Run this post-processor on results.

Parameters
resultsProtocolResults

The input results.

memlimitint, optional

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional

When not None, an MPI communicator used to run this post-processor in parallel.

Returns

ProtocolResults

write(dirname)

Write this protocol post-processor to a directory.

Parameters
dirnamestr

The directory to write into.

Returns

None

class pygsti.protocols.DataSimulator

Bases: object

An analysis routine that is run on an experiment design to produce per-circuit data.

A DataSimulator fundamentally simulates a model to create data, taking an ExperimentDesign as input and producing a ProtocolData object as output.

The produced data may consist of data counts for some/all of the circuit outcomes, and thus result in a ProtocolData containsing a normal DataSet. Alternatively, a data simulator may compute arbitrary quantities to be associated with the circuits, resulting in a ProtocolData containsing a normal FreeformDataSet.

abstract run(edesign, memlimit=None, comm=None)

Run this data simulator on an experiment design.

Parameters

edesignExperimentDesign

The input experiment design.

memlimitint, optional

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional

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

Returns

ProtocolData

class pygsti.protocols.DataCountsSimulator(model, num_samples=1000, sample_error='multinomial', seed=None, rand_state=None, alias_dict=None, collision_action='aggregate', record_zero_counts=True, times=None)

Bases: DataSimulator

Simulates data counts for each circuit outcome, producing a simulated data set.

This object can also be used to compute the outcome probabilities for each circuit outcome instead of sampled counts by setting sample_error=”none”.

Parameters

modelModel

The model to simulate.

num_samplesint or list of ints or None, optional

The simulated number of samples for each circuit. This only has effect when sample_error == "binomial" or "multinomial". If an integer, all circuits have this number of total samples. If a list, integer elements specify the number of samples for the corresponding circuit. If None, then model_or_dataset must be a DataSet, and total counts are taken from it (on a per-circuit basis).

sample_errorstring, optional

What type of sample error is included in the counts. Can be:

  • “none” - no sample error: counts are floating point numbers such that the exact probabilty can be found by the ratio of count / total.

  • “clip” - no sample error, but clip probabilities to [0,1] so, e.g., counts are always positive.

  • “round” - same as “clip”, except counts are rounded to the nearest integer.

  • “binomial” - the number of counts is taken from a binomial distribution. Distribution has parameters p = (clipped) probability of the circuit and n = number of samples. This can only be used when there are exactly two SPAM labels in model_or_dataset.

  • “multinomial” - counts are taken from a multinomial distribution. Distribution has parameters p_k = (clipped) probability of the gate string using the k-th SPAM label and n = number of samples.

seedint, optional

If not None, a seed for numpy’s random number generator, which is used to sample from the binomial or multinomial distribution.

rand_statenumpy.random.RandomState

A RandomState object to generate samples from. Can be useful to set instead of seed if you want reproducible distribution samples across multiple random function calls but you don’t want to bother with manually incrementing seeds between those calls.

alias_dictdict, optional

A dictionary mapping single operation labels into tuples of one or more other operation labels which translate the given circuits before values are computed using model_or_dataset. The resulting Dataset, however, contains the un-translated circuits as keys.

collision_action{“aggregate”, “keepseparate”}

Determines how duplicate circuits are handled by the resulting DataSet. Please see the constructor documentation for DataSet.

record_zero_countsbool, optional

Whether zero-counts are actually recorded (stored) in the returned DataSet. If False, then zero counts are ignored, except for potentially registering new outcome labels.

timesiterable, optional

When not None, a list of time-stamps at which data should be sampled. num_samples samples will be simulated at each time value, meaning that each circuit in circuit_list will be evaluated with the given time value as its start time.

run(edesign, memlimit=None, comm=None)

Run this data simulator on an experiment design.

Parameters
edesignExperimentDesign

The input experiment design.

memlimitint, optional

A rough per-processor memory limit in bytes.

commmpi4py.MPI.Comm, optional

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

Returns

ProtocolData

class pygsti.protocols.ProtocolCheckpoint(name, parent=None)

Bases: pygsti.baseobjs.nicelyserializable.NicelySerializable

Class for storing checkpointing intermediate progress during the running of a protocol in order to enable restarting subsequent runs of the protocol from that point.

Parameters

namestr

Name of the protocol associated with this checkpoint.

parentProtocolCheckpoint, optional (default None)

When specified this checkpoint object is treated as the child of another ProtocolCheckpoint object that acts as the parent. When present, the parent’s write method supersedes the child objects and is called when calling write on the child. Currently only used in the implementation of StandardGSTCheckpoint.

write(path)

Writes this object to a file.

Parameters
pathstr or Path

The name of the file that is written.

format_kwargsdict, optional

Additional arguments specific to the format being used. For example, the JSON format accepts indent as an argument because json.dump does.

Returns

None

class pygsti.protocols.CliffordRBDesign(pspec, clifford_compilations, depths, circuits_per_depth, qubit_labels=None, randomizeout=False, interleaved_circuit=None, citerations=20, compilerargs=(), 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(circuits_and_idealouts_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
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 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

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.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.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.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.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.

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.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.

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
pygsti.protocols.RBResults
class pygsti.protocols.RobustPhaseEstimationDesign(gate, req_lengths, sin_prep, sin_meas, sin_outcomes_pos, sin_outcomes_neg, cos_prep, cos_meas, cos_outcomes_pos, cos_outcomes_neg, *, qubit_labels=None, req_counts=None)

Bases: pygsti.protocols.protocol.CircuitListsDesign

Experimental design for robust phase estimation (RPE).

Produces an Experiment Design to test the phase that develops on a target gate, by applying it req_lengths times to a states prepared by sin_prep and cos_prep circuits, and then measured in the computational basis after (respective) action by sin_meas and cos_meas circuits. outcomes_pos and outcomes_neg determine which of those computational basis states count towards each of the probabilities

P^{γ’γ}_{Ns} = |<γ’ y| U^N |γ x>|² = |<γ’ x| U^N |-γ y>|² = (1 ± sin(θ))/2 P^{γ’γ}_{Nc} = |<γ’ x| U^N |γ x>|² = |<γ’ y| U^N | γ y>|² = (1 ± cos(θ))/2

(Computational basis state measurements in neither of these sets are silently dropped.)

In the above, the +x refers to the |E_0> + |E_1> combination of eigenstates of U, not of computational basis states. For instance, if U is rotation in the X basis, then cos_prep and cos_meas could be simply the identity:

|± U> = |0> ± |1>

where |±U> are the eigenstates of U, so that, in the notation of the above,

|+x> = |+U> + |-U> = |0>

The circuit would then calculate

P^+_{Nc} = |<+x| U^N | +x>|²

provided that cos_outcomes_pos = [0] and cos_outcomes_neg = [1].

Parameters

gate<TODO typ>

<TODO description>

req_lengths<TODO typ>

<TODO description>

sin_prep<TODO typ>

<TODO description>

sin_meas<TODO typ>

<TODO description>

sin_outcomes_pos<TODO typ>

<TODO description>

sin_outcomes_neg<TODO typ>

<TODO description>

cos_prep<TODO typ>

<TODO description>

cos_meas<TODO typ>

<TODO description>

cos_outcomes_pos<TODO typ>

<TODO description>

cos_outcomes_neg<TODO typ>

<TODO description>

Produces an Experiment Design to test the phase that develops on a target gate, by applying it req_lengths times to a states prepared by sin_prep and cos_prep circuits, and then measured in the computational basis after (respective) action by sin_meas and cos_meas circuits. outcomes_pos and outcomes_neg determine which of those computational basis states count towards each of the probabilities

P^{γ’γ}_{Ns} = |<γ’ y| U^N |γ x>|² = |<γ’ x| U^N |-γ y>|² = (1 ± sin(θ))/2 P^{γ’γ}_{Nc} = |<γ’ x| U^N |γ x>|² = |<γ’ y| U^N | γ y>|² = (1 ± cos(θ))/2

(Computational basis state measurements in neither of these sets are silently dropped.)

In the above, the +x refers to the |E_0> + |E_1> combination of eigenstates of U, not of computational basis states. For instance, if U is rotation in the X basis, then cos_prep and cos_meas could be simply the identity:

|± U> = |0> ± |1>

where |±U> are the eigenstates of U, so that, in the notation of the above,

|+x> = |+U> + |-U> = |0>

The circuit would then calculate

P^+_{Nc} = |<+x| U^N | +x>|²

provided that cos_outcomes_pos = [0] and cos_outcomes_neg = [1].

class pygsti.protocols.RobustPhaseEstimation(name=None)

Bases: pygsti.protocols.protocol.Protocol

Robust phase estimation (RPE) protocol

Create a new Protocol object.

Parameters

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.

Returns

Protocol

parse_dataset(design, dataset)

<TODO summary>

Parameters
design<TODO typ>

<TODO description>

dataset<TODO typ>

<TODO description>

compute_raw_angles(measured)

Determine the raw angles from the count data.

This corresponds to the angle of U^N, i.e., it is N times the phase of U.

Parameters
measured<TODO typ>

<TODO description>

Returns

<TODO typ>

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

RobustPhaseEstimationResults

class pygsti.protocols.RobustPhaseEstimationResults(data, protocol_instance, angle_estimates)

Bases: pygsti.protocols.protocol.ProtocolResults

Results from the RPE protocol

Parameters

data<TODO typ>

<TODO description>

protocol_instance<TODO typ>

<TODO description>

angle_estimates<TODO typ>

<TODO description>

Attributes

angle_estimate<TODO typ>

<TODO description>

measured_counts<TODO typ>

<TODO description>

raw_angles<TODO typ>

<TODO description>

Produce an RPE results object, providing access to
  • angle_estimates for each generation, and

  • the RPE-estimated angle, angle_estimate, from the last generation

property angle_estimate

<TODO summary>

property measured_counts

<TODO summary>

property raw_angles

<TODO summary>

pygsti.protocols.RPEDesign
pygsti.protocols.RPE
pygsti.protocols.RPEResults
class pygsti.protocols.StabilityAnalysisDesign(circuits, qubit_labels=None)

Bases: pygsti.protocols.protocol.ExperimentDesign

Experimental design for stability analysis.

Parameters

circuitslist

The list of circuits to perform the stability analysis on. These can be anything.

qubit_labelstuple or “multiple”, optional

The qubits that this experiment design applies to. These should also be the line labels of circuits.

Create a new ExperimentDesign object, which holds a set of circuits (needing data).

Parameters

circuitslist of Circuits, optional

A list of the circuits needing data. If None, then the list is empty.

qubit_labelstuple or “multiple”, optional

The qubits that this experiment design applies to. These should also be the line labels of circuits. If None, the concatenation of the qubit labels of any child experiment designs is used, or, if there are no child designs, the line labels of the first circuit is used. The special “multiple” value means that different circuits act on different qubit lines.

childrendict, optional

A dictionary of whose values are child ExperimentDesign objects and whose keys are the names used to identify them in a “path”.

children_dirsdict, optional

A dictionary whose values are directory names and keys are child names (the same as the keys of children). If None, then the keys of children must be strings and are used as directory names. Directory names are used when saving the object (via write()).

Returns

ExperimentDesign

class pygsti.protocols.StabilityAnalysis(significance=0.05, transform='auto', marginalize='auto', mergeoutcomes=None, constnumtimes='auto', ids=False, frequencies='auto', freqpointers=None, freqstest=None, tests='auto', inclass_correction=None, betweenclass_weighting='auto', estimator='auto', modelselector=None, verbosity=1, name=None)

Bases: pygsti.protocols.protocol.Protocol

Stability Analysis protocol

Parameters

dsDataSet or MultiDataSet

A DataSet containing time-series data to be analyzed for signs of instability.

significancefloat, optional

The global significance level. With defaults for all other inputs (a wide range of non-default options), the family-wise error rate of the set of all hypothesis tests performed is controlled to this value.

transformstr, optional

The type of transform to use in the spectral analysis. Options are:

  • ‘auto’: An attempt is made to choose the best transform given the “meta-data” of the data,

    e.g., the variability in the time-step between data points. For beginners, ‘auto’ is the best option. If you are familiar with the underlying methods, the meta-data of the input, and the relative merits of the different transform, then it is probably better to choose this yourself – as the auto-selection is not hugely sophisticated.

  • ‘dct’The Type-II Discrete Cosine Transform (with an orthogonal normalization). This is

    the only tested option, and it is our recommended option when the data is approximately equally-spaced, i.e., the time-step between each “click” for each circuit is almost a constant. (the DCT transform implicitly assumes that this time-step is exactly constant)

  • ‘dft’The discrete Fourier transform (with an orthogonal normalization).

    This is an experimental feature, and the results are unreliable with this transform

  • ‘lsp’The Lomb-Scargle periodogram.

    This is an experimental feature, and the code is untested with this transform

marginalizestr or bool, optional

True, False or ‘auto’. Whether or not to marginalize multi-qubit data, to look for instability in the marginalized probability distribution over the two outcomes for each qubit. Cannot be set to True if mergeoutcomes is not None.

mergeoutcomesNone or Dict, optional

If not None, a dictionary of outcome-merging dictionaries. Each dictionary contained as a value of mergeoutcomes is used to create a new DataSet, where the values have been merged according to that dictionary (see the aggregate_dataset_outcomes() function inside datasetconstructions.py). The corresponding key is used as the key for that DataSet, when it is stored in a MultiDataSet, and the instability analysis is implemented on each DataSet. This is a more general data coarse-grainin option than marginalize.

constnumtimesstr or bool, optional

True, False or ‘auto’. If True then data is discarded from the end of the “clickstream” for each circuit until all circuits have the same length clickstream, i.e., the same number of data aquisition times. If ‘auto’ then it is set to True or False depending on the meta-data of the data and the type of transform being used.

ids: True or False, optional

Whether the multiple DataSets should be treat as generated from independent random variables. If the input is a DataSet and marginalize is False and mergeoutcomes is None then this input is irrelevant: there is only ever one DataSet being analyzed. But in general multiple DataSets are concurrently analyzed. This is irrelevant for independent analyses of the DataSets, but the analysis is capable of also implementing a joint analysis of the DataSets. This joint analysis is only valid on the assumption of independent DataSets, and so this analysis will not be permitted unless ids is set to True. Note that the set of N marginalized data from N-qubit circuits are generally not independent – even if the circuits contain no 2-qubit gates then crosstalk can causes dependencies. However, as long as the dependencies are weak then settings this to True is likely ok.

frequencies‘auto’ or list, optional

The frequencies that the power spectra are calculated for. If ‘auto’ these are automatically determined from the meta-data of the time-series data (e.g., using the mean time between data points) and the transform being used. If not ‘auto’, then a list of lists, where each list is a set of frequencies that are the frequencies corresponding to one or more power spectra. The frequencies that should be paired to a given power spectrum are specified by freqpointers.

These frequencies (whether automatically calculated or explicitly input) have a fundmentally different meaning depending on whether the transform is time-stamp aware (here, the LSP) or not (here, the DCT and DFT).

Time-stamp aware transforms take the frequencies to calculate powers at as an input, so the specified frequencies are, explicitly, the frequencies associated with the powers. The task of choosing the frequencies amounts to picking the best set of frequencies at which to interogate the true probability trajectory for components. As there are complex factors involved in this choice that the code has no way of knowing, sometimes it is best to choose them yourself. E.g., if different frequencies are used for different circuits it isn’t possible to (meaningfully) averaging power spectra across circuits, but this might be preferable if the time-step is sufficiently different between different circuits – it depends on your aims.

For time-stamp unaware transforms, these frequencies should be the frequencies that, given that we’re implementing the, e.g., DCT, the generated power spectrum is implicitly with respect to. In the case of data on a fixed time-grid, i.e., equally spaced data, then there is a precise set of frequencies implicit in the transform (which will be accurately extracted with frequencies set to auto). Otherwise, these frequencies are explicitly at least slightly ad hoc, and choosing these frequencies amounts to choosing those frequencies that “best” approximate the properties being interogatted with fitting each, e.g., DCT basis function to the (timestamp-free) data. The ‘auto’ option bases there frequencies solely on the mean time step and the number of times, and is a decent option when the time stamps are roughly equally spaced for each circuit.

These frequencies should be in units of 1/t where ‘t’ is the unit of the time stamps.

freqpointersdict, optional

Specifies which frequencies correspond to which power spectra. The keys are power spectra labels, and the values are integers that point to the index of frequencies (a list of lists) that the relevant frquencies are found at. Whenever a power spectra is not included in freqpointers then this defaults to 0. So if frequencies is specified and is a list containing a single list (of frequencies) then freqpointers can be left as the empty dictionary.

freqstestNone or list, optional

If not not None, a list of the frequency indices at which to test the powers. Leave as None to perform comprehensive testing of the power spectra.

tests‘auto’ or tuple, optional

Specifies the set of hypothesis tests to perform. If ‘auto’ then an set of tests is automatically chosen. This set of tests will be suitable for most purposes, but sometimes it is useful to override this. If a tuple, the elements are “test classes”, that specifies a set of hypothesis tests to run, and each test class is itself specified by a tuple. The tests specified by each test class in this tuple are all implemented. A test class is a tuple containing some subset of ‘dataset’, ‘circuit’ and ‘outcome’, which specifies a set of power spectra. Specifically, a power spectra has been calculated for the clickstream for every combination of eachinput DataSet (e.g., there are multiple DataSets if there has been marginalization of multi-qubit data), each Circuit in the DataSet, and each possible outcome in the DataSet. For each of “dataset”, “circuit” and “outcome” not included in a tuple defining a test class, the coresponding “axis” of the 3-dimensional array of spectra is averaged over, and these spectra are then tested. So the tuple () specifies the “test class” whereby we test the power spectrum obtained by averaging all power spectra; the tuple (‘dataset’,’circuit’) specifies the “test class” whereby we average only over outcomes, obtaining a single power spectrum for each DataSet and Circuit combination, which we test.

The default option for “tests” is appropriate for most circumstances, and it consists of (), (‘dataset’) and (‘dataset’, ‘circuit’) with duplicates removed (e.g., if there is a single DataSet then () is equivalent to (‘dataset’)).

inclass_correctiondict, optional

A dictionary with keys ‘dataset’, ‘circuit’, ‘outcome’ and ‘spectrum’, and values that specify the type of multi-test correction used to account for the multiple tests being implemented. This specifies how the statistically significance is maintained within the tests implemented in a single “test class”.

betweenclass_weighting‘auto’ or dict, optional

The weighting to use to maintain statistical significance between the different classes of test being implemented. If ‘auto’ then a standard Bonferroni correction is used.

estimatorstr, optional

The name of the estimator to use. This is the method used to estimate the parameters of a parameterized model for each probability trajectory, after that parameterized model has been selected with the model selection methods. Allowed values are:

  • ‘auto’. The estimation method is chosen automatically, default to the fast method that is also

    reasonably reliable.

  • ‘filter’. Performs a type of signal filtering: implements the transform used for generating power

    spectra (e.g., the DCT), sets the amplitudes to zero for all freuquencies that the model selection has not included in the model, inverts the transform, and then performs some minor post-processing to guarantee probabilities within [0, 1]. This method is less statically well-founded than ‘mle’, but it is faster and typically gives similar results. This method is not an option for non-invertable transforms, such as the Lomb-Scargle periodogram.

  • ‘mle’. Implements maximum likelihood estimation, on the parameterized model chosen by the model

    selection. The most statistically well-founded option, but can be slower than ‘filter’ and relies on numerical optimization.

modelselectortuple, optional

The model selection method. If not None, a “test class” tuple, specifying which test results to use to decide which frequencies are significant for each circuit, to then construct a parameterized model for each probability trajectory. This can be typically set to None, and it will be chosen automatically. But if you wish to use specific test results for the model selection then this should be set.

verbosityint, optional

The amount of print-to-screen

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.

Implements instability (“drift”) detection and characterization on timeseries data from any set of quantum circuits on any number of qubits. This uses the StabilityAnalyzer object, and directly accessing that object allows for some more complex analyzes to be performed. That object also offers a more step-by-step analysis procedure, which may be helpful for exploring the optional arguments of this analysis.

Parameters

dsDataSet or MultiDataSet

A DataSet containing time-series data to be analyzed for signs of instability.

significancefloat, optional

The global significance level. With defaults for all other inputs (a wide range of non-default options), the family-wise error rate of the set of all hypothesis tests performed is controlled to this value.

transformstr, optional

The type of transform to use in the spectral analysis. Options are:

  • ‘auto’: An attempt is made to choose the best transform given the “meta-data” of the data,

    e.g., the variability in the time-step between data points. For beginners, ‘auto’ is the best option. If you are familiar with the underlying methods, the meta-data of the input, and the relative merits of the different transform, then it is probably better to choose this yourself – as the auto-selection is not hugely sophisticated.

  • ‘dct’The Type-II Discrete Cosine Transform (with an orthogonal normalization). This is

    the only tested option, and it is our recommended option when the data is approximately equally-spaced, i.e., the time-step between each “click” for each circuit is almost a constant. (the DCT transform implicitly assumes that this time-step is exactly constant)

  • ‘dft’The discrete Fourier transform (with an orthogonal normalization).

    This is an experimental feature, and the results are unreliable with this transform

  • ‘lsp’The Lomb-Scargle periodogram.

    This is an experimental feature, and the code is untested with this transform

marginalizestr or bool, optional

True, False or ‘auto’. Whether or not to marginalize multi-qubit data, to look for instability in the marginalized probability distribution over the two outcomes for each qubit. Cannot be set to True if mergeoutcomes is not None.

mergeoutcomesNone or Dict, optional

If not None, a dictionary of outcome-merging dictionaries. Each dictionary contained as a value of mergeoutcomes is used to create a new DataSet, where the values have been merged according to that dictionary (see the aggregate_dataset_outcomes() function inside datasetconstructions.py). The corresponding key is used as the key for that DataSet, when it is stored in a MultiDataSet, and the instability analysis is implemented on each DataSet. This is a more general data coarse-grainin option than marginalize.

constnumtimesstr or bool, optional

True, False or ‘auto’. If True then data is discarded from the end of the “clickstream” for each circuit until all circuits have the same length clickstream, i.e., the same number of data aquisition times. If ‘auto’ then it is set to True or False depending on the meta-data of the data and the type of transform being used.

ids: True or False, optional

Whether the multiple DataSets should be treat as generated from independent random variables. If the input is a DataSet and marginalize is False and mergeoutcomes is None then this input is irrelevant: there is only ever one DataSet being analyzed. But in general multiple DataSets are concurrently analyzed. This is irrelevant for independent analyses of the DataSets, but the analysis is capable of also implementing a joint analysis of the DataSets. This joint analysis is only valid on the assumption of independent DataSets, and so this analysis will not be permitted unless ids is set to True. Note that the set of N marginalized data from N-qubit circuits are generally not independent – even if the circuits contain no 2-qubit gates then crosstalk can causes dependencies. However, as long as the dependencies are weak then settings this to True is likely ok.

frequencies‘auto’ or list, optional

The frequencies that the power spectra are calculated for. If ‘auto’ these are automatically determined from the meta-data of the time-series data (e.g., using the mean time between data points) and the transform being used. If not ‘auto’, then a list of lists, where each list is a set of frequencies that are the frequencies corresponding to one or more power spectra. The frequencies that should be paired to a given power spectrum are specified by freqpointers.

These frequencies (whether automatically calculated or explicitly input) have a fundmentally different meaning depending on whether the transform is time-stamp aware (here, the LSP) or not (here, the DCT and DFT).

Time-stamp aware transforms take the frequencies to calculate powers at as an input, so the specified frequencies are, explicitly, the frequencies associated with the powers. The task of choosing the frequencies amounts to picking the best set of frequencies at which to interogate the true probability trajectory for components. As there are complex factors involved in this choice that the code has no way of knowing, sometimes it is best to choose them yourself. E.g., if different frequencies are used for different circuits it isn’t possible to (meaningfully) averaging power spectra across circuits, but this might be preferable if the time-step is sufficiently different between different circuits – it depends on your aims.

For time-stamp unaware transforms, these frequencies should be the frequencies that, given that we’re implementing the, e.g., DCT, the generated power spectrum is implicitly with respect to. In the case of data on a fixed time-grid, i.e., equally spaced data, then there is a precise set of frequencies implicit in the transform (which will be accurately extracted with frequencies set to auto). Otherwise, these frequencies are explicitly at least slightly ad hoc, and choosing these frequencies amounts to choosing those frequencies that “best” approximate the properties being interogatted with fitting each, e.g., DCT basis function to the (timestamp-free) data. The ‘auto’ option bases there frequencies solely on the mean time step and the number of times, and is a decent option when the time stamps are roughly equally spaced for each circuit.

These frequencies should be in units of 1/t where ‘t’ is the unit of the time stamps.

freqpointersdict, optional

Specifies which frequencies correspond to which power spectra. The keys are power spectra labels, and the values are integers that point to the index of frequencies (a list of lists) that the relevant frquencies are found at. Whenever a power spectra is not included in freqpointers then this defaults to 0. So if frequencies is specified and is a list containing a single list (of frequencies) then freqpointers can be left as the empty dictionary.

freqstestNone or list, optional

If not not None, a list of the frequency indices at which to test the powers. Leave as None to perform comprehensive testing of the power spectra.

tests‘auto’ or tuple, optional

Specifies the set of hypothesis tests to perform. If ‘auto’ then an set of tests is automatically chosen. This set of tests will be suitable for most purposes, but sometimes it is useful to override this. If a tuple, the elements are “test classes”, that specifies a set of hypothesis tests to run, and each test class is itself specified by a tuple. The tests specified by each test class in this tuple are all implemented. A test class is a tuple containing some subset of ‘dataset’, ‘circuit’ and ‘outcome’, which specifies a set of power spectra. Specifically, a power spectra has been calculated for the clickstream for every combination of eachinput DataSet (e.g., there are multiple DataSets if there has been marginalization of multi-qubit data), each Circuit in the DataSet, and each possible outcome in the DataSet. For each of “dataset”, “circuit” and “outcome” not included in a tuple defining a test class, the coresponding “axis” of the 3-dimensional array of spectra is averaged over, and these spectra are then tested. So the tuple () specifies the “test class” whereby we test the power spectrum obtained by averaging all power spectra; the tuple (‘dataset’,’circuit’) specifies the “test class” whereby we average only over outcomes, obtaining a single power spectrum for each DataSet and Circuit combination, which we test.

The default option for “tests” is appropriate for most circumstances, and it consists of (), (‘dataset’) and (‘dataset’, ‘circuit’) with duplicates removed (e.g., if there is a single DataSet then () is equivalent to (‘dataset’)).

inclass_correctiondict, optional

A dictionary with keys ‘dataset’, ‘circuit’, ‘outcome’ and ‘spectrum’, and values that specify the type of multi-test correction used to account for the multiple tests being implemented. This specifies how the statistically significance is maintained within the tests implemented in a single “test class”.

betweenclass_weighting‘auto’ or dict, optional

The weighting to use to maintain statistical significance between the different classes of test being implemented. If ‘auto’ then a standard Bonferroni correction is used.

estimatorstr, optional

The name of the estimator to use. This is the method used to estimate the parameters of a parameterized model for each probability trajectory, after that parameterized model has been selected with the model selection methods. Allowed values are:

  • ‘auto’. The estimation method is chosen automatically, default to the fast method that is also

    reasonably reliable.

  • ‘filter’. Performs a type of signal filtering: implements the transform used for generating power

    spectra (e.g., the DCT), sets the amplitudes to zero for all freuquencies that the model selection has not included in the model, inverts the transform, and then performs some minor post-processing to guarantee probabilities within [0, 1]. This method is less statically well-founded than ‘mle’, but it is faster and typically gives similar results. This method is not an option for non-invertable transforms, such as the Lomb-Scargle periodogram.

  • ‘mle’. Implements maximum likelihood estimation, on the parameterized model chosen by the model

    selection. The most statistically well-founded option, but can be slower than ‘filter’ and relies on numerical optimization.

modelselectortuple, optional

The model selection method. If not None, a “test class” tuple, specifying which test results to use to decide which frequencies are significant for each circuit, to then construct a parameterized model for each probability trajectory. This can be typically set to None, and it will be chosen automatically. But if you wish to use specific test results for the model selection then this should be set.

verbosityint, optional

The amount of print-to-screen

Returns

StabilityAnalysis

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

StabilityAnalysisResults

class pygsti.protocols.StabilityAnalysisResults(data, protocol_instance, stabilityanalyzer)

Bases: pygsti.protocols.protocol.ProtocolResults

Results from the stability analysis protocol.

NOTE Currently, this object just wraps a pygsti.extras.drift.StabilityAnalyzer object, which historically performed stability analysis. In the future, this object will likely take over the function of StabilityAnalyzer.

Parameters

dataProtocolData

The experimental data these results are generated from.

protocol_instanceProtocol

The protocol that generated these results.

stabilityanalyzerpygsti.extras.drift.StabilityAnalyzer

An object holding the stability analysis results. This will likely be updated in the future.

Initialize an empty Results object.

class pygsti.protocols.ByDepthDesign(depths, circuit_lists, qubit_labels=None, remove_duplicates=True)

Bases: pygsti.protocols.protocol.CircuitListsDesign

Experiment design that holds circuits organized by depth.

Parameters

depthslist or tuple

A sequence of integers specifying the circuit depth associated with each element of circuit_lists.

circuit_listslist or tuple

The circuits to include in this experiment design. Each element is a list of Circuits specifying the circuits at the corresponding depth.

qubit_labelstuple, optional

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

remove_duplicatesbool, optional

Whether to remove duplicates when automatically creating all the circuits that need data.

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

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

ByDepthDesign

class pygsti.protocols.BenchmarkingDesign(depths, circuit_lists, ideal_outs, qubit_labels=None, remove_duplicates=False)

Bases: ByDepthDesign

Experiment design that holds benchmarking data.

By “benchmarking data” we mean definite-outcome circuits organized by depth along with their corresponding ideal outcomes.

Parameters

depthslist or tuple

A sequence of integers specifying the circuit depth associated with each element of circuit_lists.

circuit_listslist or tuple

The circuits to include in this experiment design. Each element is a list of Circuits specifying the circuits at the corresponding depth.

ideal_outslist or tuple

The ideal circuit outcomes corresponding to the circuits in circuit_lists. Each element of ideal_outs is a list (with the same length as the corresponding circuits_lists element) of outcome labels.

qubit_labelstuple, optional

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

remove_duplicatesbool, optional

Whether to remove duplicates when automatically creating all the circuits that need data.

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

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

ByDepthDesign

class pygsti.protocols.PeriodicMirrorCircuitDesign(pspec, depths, circuits_per_depth, qubit_labels=None, clifford_compilations=None, sampler='edgegrab', samplerargs=(0.125,), localclifford=True, paulirandomize=True, fixed_versus_depth=False, descriptor='A random germ mirror circuit experiment', seed=None)

Bases: BenchmarkingDesign

Experiment design for periodic mirror-circuit benchmarking.

THIS METHOD IS IN DEVELOPEMENT. DO NOT EXPECT THAT THIS FUNCTION WILL BEHAVE THE SAME IN FUTURE RELEASES OF PYGSTI! THE DOCSTRINGS SHOULD ALSO NOT BE TRUSTED – MANY (MAYBE ALL) OF THEM ARE COPIED FROM THE MIRRORBDESIGN OBJECT AND SO SOME BITS ARE WRONG OR NOT APPLICABLE.

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.

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: {‘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 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

fixed_versus_depthbool, optional

<TODO description>

descriptorstr, optional

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

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=(0.125,), localclifford=True, paulirandomize=True, fixed_versus_depth=False, descriptor='A random germ mirror circuit experiment')

Create a PeriodicMirrorCircuitDesign 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.

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: {‘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 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

fixed_versus_depthbool, optional

<TODO description>

descriptorstr, optional

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

Returns

PeriodicMirrorCircuitDesign

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

PeriodicMirrorCircuitDesign

class pygsti.protocols.SummaryStatistics(name)

Bases: pygsti.protocols.protocol.Protocol

A protocol that can construct “summary” quantities from raw data.

Parameters

namestr

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.

Attributes

summary_statisticstuple

Static list of the categories of summary information this protocol can compute.

circuit_statisticstuple

Static list of the categories of circuit information this protocol can compute.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

summary_statistics = ('success_counts', 'total_counts', 'hamming_distance_counts', 'success_probabilities',...
circuit_statistics = ('two_q_gate_count', 'depth', 'idealout', 'circuit_index', 'width')
class pygsti.protocols.ByDepthSummaryStatistics(depths='all', statistics_to_compute=('polarization',), names_to_compute=None, custom_data_src=None, name=None)

Bases: SummaryStatistics

A protocol that computes summary statistics for data organized into by-depth circuit lists. Parameters ———- depths : list or “all”, optional

A sequence of the depths to compute summary statistics for or the special “all” value which means “all the depths in the data”. If data being processed does not contain a given value in depths, it is just ignored.

statistics_to_computetuple, optional

A sequence of the statistic names to compute. Allowed names are:

‘success_counts’, ‘total_counts’, ‘hamming_distance_counts’, ‘success_probabilities’, ‘polarization’, ‘adjusted_success_probabilities’, ‘two_q_gate_count’, ‘depth’, ‘idealout’, ‘circuit_index’, and ‘width’.

names_to_computetuple, optional

A sequence of user-defined names for the statistics in statistics_to_compute. If None, then the statistic names themselves are used. These names are the column names produced by calling to_dataframe on this protocol’s results, so can be useful to name the computed statistics differently from the statistic name itself to distinguish it from the same statistic run on other data, when you want to combine data frames generated from multiple ProtocolData objects.

custom_data_srcSuccessFailModel, optional

An alternate source of the data counts used to compute the desired summary statistics. Currently this can only be a SuccessFailModel.

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.

Create a new Protocol object.

Parameters

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.

Returns

Protocol

run(data, memlimit=None, comm=None, dscomparator=None)

Run this protocol on data. Parameters ———- results : ProtocolResults or ProtocolResultsDir

The input results.

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.

dscomparatorDataComparator

Special additional comparator object for comparing data sets.

Returns

SummaryStatisticsResults

class pygsti.protocols.SummaryStatisticsResults(data, protocol_instance)

Bases: pygsti.protocols.protocol.ProtocolResults

Summary statistics computed for a set of data.

Usually the result of running a SummaryStatistics (or derived) protocol.

Parameters

dataProtocolData

The experimental data these results are generated from.

protocol_instanceProtocol

The protocol that generated these results.

Initialize an empty SummaryStatisticsResults object.

pygsti.protocols.polarization_to_success_probability(p, n)

Inverse of success_probability_to_polarization.

pygsti.protocols.success_probability_to_polarization(s, n)

Maps a success probablity s for an n-qubit circuit to the polarization, defined by p = (s - 1/2^n)/(1 - 1/2^n)

pygsti.protocols.classify_circuit_shape(success_probabilities, total_counts, threshold, significance=0.05)

Utility function for computing “capability regions”, as introduced in “Measuring the Capabilities of Quantum Computers” arXiv:2008.11294.

Returns an integer that classifies the input list of success probabilities (SPs) as either

  • “success”: all SPs above the specified threshold, specified by the int 2.

  • “indeterminate”: some SPs are above and some are below the threshold, specified by the int 1.

  • “fail”: all SPs are below the threshold, specified by the int 0.

This classification is based on a hypothesis test whereby the null hypothesis is “success” or “fail”. That is, the set of success probabilities are designated to be “indeterminate” only if there is statistically significant evidence that at least one success probabilities is above the threshold, and at least one is below. The details of this hypothesis testing are given in the Section 8.B.5 in the Supplement of arXiv:2008.11294.

Parameters

success_probabilitieslist

List of success probabilities, should all be in [0,1].

total_countslist

The number of samples from which the success probabilities where computed.

thresholdfloat

The threshold for designating a success probability as “success”.

significancefloat, optional

The statistical significance for the hypothesis test.

Returns

int in (2, 1, 0), corresponding to (“success”, “indeterminate”, “fail”) classifications. If the SPs list is length 0 then NaN is returned, and if it contains only NaN elements then 0 is returned. Otherwise, all NaN elements are ignored.

class pygsti.protocols.VBDataFrame(df, x_axis='Depth', y_axis='Width', x_values=None, y_values=None, edesign=None)

Bases: object

A class for storing a DataFrame that contains volumetric benchmarking data, and that has methods for manipulating that data and creating volumetric-benchmarking-like plots.

Initialize a VBDataFrame object.

Parameters

dfPandas DataFrame

A DataFrame that contains the volumetric benchmarking data. This sort of DataFrame can be created using ByBepthSummaryStatics protocols and the to_dataframe() method of the created results object.

x_axisstring, optional

A VBDataFrame is intended to create volumetric-benchmarking-like plots where performance is plotted on an (x, y) grid. This specifies what the x-axis of these plots should be. It should be a column label in the DataFrame.

y_axisstring, optional

A VBDataFrame is intended to create volumetric-benchmarking-like plots where performance is plotted on an (x, y) grid. This specifies what the y-axis of these plots should be. It should be a column label in the DataFrame.

x_values : string or None, optional

x_values : string or None, optional

edesignExperimentDesign or None, optional

The ExperimentDesign that corresponds to the data in the dataframe. This is not currently used by any methods in the VBDataFrame.

select_column_value(column_label, column_value)

Filters the dataframe, by discarding all rows of the dataframe for which the column labelled column_label does not have column_value.

Parameters
column_labelstring

The label of the column whose value is to be filtered on.

column_valuevaried

The value of the column.

Returns
VBDataFrame

A new VBDataFrame that has had the filtering applied to its dataframe.

filter_data(column_label, metric='polarization', statistic='mean', indep_x=True, threshold=1 / _np.e, verbosity=0)

Filters the dataframe, by selecting the “best” value at each (x, y) (typically corresponding to circuit shape) for the column specified by column_label. Returns a VBDataFrame whose data that contains only one value for the column labelled by column_label for each (x, y).

Parameters
column_labelstring

The label of the column whose “best” value at each circuit shape is to be selected. For example, this could be “Qubits”, to select only the data for the best qubit subset at each circuit shape.

metricstring, optional

The data to be used as the figure-of-merit for performance at each (x, y). Must be a column of the dataframe.

statisticsstring, optional

The statistic to apply to the data specified by metric the data at (x, y) into a scalar. Allowed values are: - ‘max’ - ‘min’ - ‘mean’

indep_xbool, optional

If True, then an independent value, for the column, is selected at each (x, y) value. If False, then the same value for the column is selected for every x value for a given y.

thresholdfloat, optional.

Does nothing if indep_x is True. If indep_x is False, then ‘metric’ and ‘statistic’ are not enough to uniquely decide which column value is best. In this case, the value is chosen that, for each y in (x,y), maximizes the x value at which the figure-of-merit (as specified by the metric and statistic) drops below the threshold. If there are multiple values that drop below the threshold at the same x (or the figure-of-merit never drops below the threshold for multiple values), then value with the larger figure-of-merit at that x is chosen.

Returns
VBDataFrame

A new VBDataFrame that has had the filtering applied to its dataframe.

vb_data(metric='polarization', statistic='mean', lower_cutoff=0.0, no_data_action='discard')

Converts the data into a dictionary, for plotting in a volumetric benchmarking plot. For each (x, y) value (as specified by the axes of this VBDataFrame, and typically circuit shape), pools all of the data specified by metric with that (x, y) and computes the statistic on that data defined by statistic.

Parameters
metricstring, optional

The type of data. Must be a column of the dataframe.

statisticsstring, optional

The statistic on the data to be computed at each value of (x, y). Options are:

  • ‘max’: the maximum

  • ‘min’: the minimum.

  • ‘mean’: the mean.

  • ‘monotonic_max’: the maximum of all the data with (x, y) values that are that large or larger

  • ‘monotonic_min’: the minimum of all the data with (x, y) values that are that small or smaller

All these options ignore nan values.

lower_cutofffloat, optional

The value to cutoff the statistic at: takes the maximum of the calculated static and this value.

no_data_action: string, optional

Sets what to do when there is no data, or only NaN data, at an (x, y) value:

  • If ‘discard’ then when there is no data, or only NaN data, for an (x,y) value then this (x,y) value will not be a key in the returned dictionary

  • If ‘nan’ then when there is no data, or only NaN data, for an (x,y) value then this (x,y) value will be a key in the returned dictionary and its value will be NaN.

  • If ‘min’ then when there is no data, or only NaN data, for an (x,y) value then this (x,y) value will be a key in the returned dictionary and its value will be the minimal value allowed for this statistic, as specified by lower_cutoff.

Returns
dict

A dictionary where the keys are (x,y) tuples (typically circuit shapes) and the values are the VB data at that (x, y).

capability_regions(metric='polarization', threshold=1 / _np.e, significance=0.05, monotonic=True, nan_data_action='discard')

Computes a “capability region” from the data, as introduced in “Measuring the Capabilities of Quantum Computers” arXiv:2008.11294. Classifies each (x,y) value (as specified by the x and y axes of the VBDataFrame, which are typically width and depth) as either “success” (the int 2), “indeterminate” (the int 1), “fail” (the int 0), or “no data” (NaN).

Parameters
metricstring, optional

The type of data. Must be ‘polarization’ or ‘success_probability’, and this must be a column in the dataframe.

thresholdfloat, optional

The threshold for “success”.

significancefloat, optional

The statistical significance for the hypothesis tests that are used to classify each circuit shape.

monotonicbool, optional

If True, makes the region monotonic, i,e, if (x’,y’) > (x,y) then the classification for (x’,y’) is less/worse than for (x,y).

no_data_actionstring, optional

If ‘discard’ then when there is no data, for an (x,y) value then this (x,y) value will not be a key in the returned dictionary. Otherwise the value will be NaN.

Returns
dict

A dictionary where the keys are (x,y) tuples (typically circuit shapes) and the values are in (2, 1, 0, NaN).