:py:mod:`pygsti.protocols.vb` ============================= .. py:module:: pygsti.protocols.vb .. autoapi-nested-parse:: Volumetric Benchmarking Protocol objects Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: pygsti.protocols.vb.ByDepthDesign pygsti.protocols.vb.BenchmarkingDesign pygsti.protocols.vb.PeriodicMirrorCircuitDesign pygsti.protocols.vb.SummaryStatistics pygsti.protocols.vb.ByDepthSummaryStatistics pygsti.protocols.vb.SummaryStatisticsResults .. py:class:: ByDepthDesign(depths, circuit_lists, qubit_labels=None, remove_duplicates=True) Bases: :py:obj:`pygsti.protocols.protocol.CircuitListsDesign` Experiment design that holds circuits organized by depth. Parameters ---------- depths : list or tuple A sequence of integers specifying the circuit depth associated with each element of `circuit_lists`. circuit_lists : list or tuple The circuits to include in this experiment design. Each element is a list of :class:`Circuits` specifying the circuits at the corresponding depth. qubit_labels : tuple, optional The qubits that this experiment design applies to. If None, the line labels of the first circuit is used. remove_duplicates : bool, optional Whether to remove duplicates when automatically creating all the circuits that need data. Create a new CircuitListsDesign object. Parameters ---------- circuit_lists : list or PlaquetteGridCircuitStructure A list whose elements are themselves lists of :class:`Circuit` objects, specifying the data that needs to be taken. Alternatively, a single :class:`PlaquetteGridCircuitStructure` object containing a sequence of circuits lists, each at a different "x" value (usually the maximum circuit depth). all_circuits_needing_data : list, 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_labels : tuple, optional The qubits that this experiment design applies to. If None, the line labels of the first circuit is used. nested : bool, 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_duplicates : bool, 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 .. py:attribute:: depths .. py:method:: map_qubit_labels(mapper) Creates a new experiment design whose circuits' qubit labels are updated according to a given mapping. Parameters ---------- mapper : dict 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 .. py:method:: truncate_to_lists(list_indices_to_keep) Truncates this experiment design by only keeping a subset of its circuit lists. Parameters ---------- list_indices_to_keep : iterable A list of the (integer) list indices to keep. Returns ------- ByDepthDesign The truncated experiment design. .. py:method:: merge_with(other_edesign, remove_duplicates=True, sort_depths=False) Merge this experiment design with another one and return the result. Parameters ---------- other_edesign: ByDepthDesign The other experiment design to merge Returns ------- ByDepthDesign .. py:class:: BenchmarkingDesign(depths, circuit_lists, ideal_outs, qubit_labels=None, remove_duplicates=False) Bases: :py:obj:`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 ---------- depths : list or tuple A sequence of integers specifying the circuit depth associated with each element of `circuit_lists`. circuit_lists : list or tuple The circuits to include in this experiment design. Each element is a list of :class:`Circuits` specifying the circuits at the corresponding depth. ideal_outs : list 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_labels : tuple, optional The qubits that this experiment design applies to. If None, the line labels of the first circuit is used. remove_duplicates : bool, optional Whether to remove duplicates when automatically creating all the circuits that need data. Create a new CircuitListsDesign object. Parameters ---------- circuit_lists : list or PlaquetteGridCircuitStructure A list whose elements are themselves lists of :class:`Circuit` objects, specifying the data that needs to be taken. Alternatively, a single :class:`PlaquetteGridCircuitStructure` object containing a sequence of circuits lists, each at a different "x" value (usually the maximum circuit depth). all_circuits_needing_data : list, 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_labels : tuple, optional The qubits that this experiment design applies to. If None, the line labels of the first circuit is used. nested : bool, 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_duplicates : bool, 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 .. py:attribute:: paired_with_circuit_attrs :value: 'None' List of attributes which are paired up with circuit lists These will be saved as external files during serialization, and are truncated when circuit lists are truncated. .. py:attribute:: idealout_lists .. py:method:: map_qubit_labels(mapper) Creates a new experiment design whose circuits' qubit labels are updated according to a given mapping. Parameters ---------- mapper : dict 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 .. py:method:: truncate_to_lists(list_indices_to_keep) Truncates this experiment design by only keeping a subset of its circuit lists. Parameters ---------- list_indices_to_keep : iterable A list of the (integer) list indices to keep. Returns ------- BenchmarkingDesign The truncated experiment design. .. py:method:: merge_with(other_edesign, remove_duplicates=True, sort_depths=False) Merge this experiment design with another one and return the result. The returned design will contain the union of the circuits in the two experiment designs being merged, and will contain depth, ideal-output, etc. metadata that is updated appropriately. Parameters ---------- other_edesign: BenchmarkingDesign The other experiment design to merge Returns ------- BenchmarkingDesign .. py:class:: 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: :py:obj:`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 ---------- pspec : QubitProcessorSpec 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. depths : list 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_depth : int The number of (possibly) different MRB circuits sampled at each length. qubit_labels : list, 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. sampler : str 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. samplerargs : list, 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. localclifford : bool, 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). paulirandomize : bool, 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_depth : bool, optional descriptor : str, optional A string describing the generated experiment. Stored in the returned dictionary. Create a new CircuitListsDesign object. Parameters ---------- circuit_lists : list or PlaquetteGridCircuitStructure A list whose elements are themselves lists of :class:`Circuit` objects, specifying the data that needs to be taken. Alternatively, a single :class:`PlaquetteGridCircuitStructure` object containing a sequence of circuits lists, each at a different "x" value (usually the maximum circuit depth). all_circuits_needing_data : list, 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_labels : tuple, optional The qubits that this experiment design applies to. If None, the line labels of the first circuit is used. nested : bool, 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_duplicates : bool, 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 .. py:method:: 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') :classmethod: Create a :class:`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_depth : dict 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_labels : list, 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. sampler : str 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. samplerargs : list, 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. localclifford : bool, 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). paulirandomize : bool, 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_depth : bool, optional descriptor : str, optional A string describing the generated experiment. Stored in the returned dictionary. Returns ------- PeriodicMirrorCircuitDesign .. py:method:: map_qubit_labels(mapper) Creates a new experiment design whose circuits' qubit labels are updated according to a given mapping. Parameters ---------- mapper : dict 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 .. py:class:: SummaryStatistics(name) Bases: :py:obj:`pygsti.protocols.protocol.Protocol` A protocol that can construct "summary" quantities from raw data. Parameters ---------- name : str 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_statistics : tuple Static list of the categories of summary information this protocol can compute. circuit_statistics : tuple Static list of the categories of circuit information this protocol can compute. Create a new Protocol object. Parameters ---------- name : str, 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 .. py:attribute:: summary_statistics :value: "('success_counts', 'total_counts', 'hamming_distance_counts', 'success_probabilities',..." .. py:attribute:: circuit_statistics :value: "('two_q_gate_count', 'depth', 'idealout', 'circuit_index', 'width')" .. py:class:: ByDepthSummaryStatistics(depths='all', statistics_to_compute=('polarization', ), names_to_compute=None, custom_data_src=None, name=None) Bases: :py:obj:`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_compute : tuple, 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_compute : tuple, 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 :class:`ProtocolData` objects. custom_data_src : SuccessFailModel, optional An alternate source of the data counts used to compute the desired summary statistics. Currently this can only be a :class:`SuccessFailModel`. name : str, 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 ---------- name : str, 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 .. py:attribute:: depths :value: "'all'" .. py:attribute:: statistics_to_compute :value: "('polarization',)" .. py:attribute:: names_to_compute :value: "('polarization',)" .. py:attribute:: custom_data_src :value: 'None' .. py:method:: run(data, memlimit=None, comm=None, dscomparator=None) Run this protocol on `data`. Parameters ---------- results : ProtocolResults or ProtocolResultsDir The input results. memlimit : int, optional A rough per-processor memory limit in bytes. comm : mpi4py.MPI.Comm, optional When not ``None``, an MPI communicator used to run this protocol in parallel. dscomparator : DataComparator Special additional comparator object for comparing data sets. Returns ------- SummaryStatisticsResults .. py:class:: SummaryStatisticsResults(data, protocol_instance) Bases: :py:obj:`pygsti.protocols.protocol.ProtocolResults` Summary statistics computed for a set of data. Usually the result of running a :class:`SummaryStatistics` (or derived) protocol. Parameters ---------- data : ProtocolData The experimental data these results are generated from. protocol_instance : Protocol The protocol that generated these results. Initialize an empty SummaryStatisticsResults object. .. py:attribute:: statistics