pygsti.algorithms.randomcircuit.create_direct_rb_circuit#
- create_direct_rb_circuit(pspec, clifford_compilations, length, qubit_labels=None, sampler='Qelimination', samplerargs=None, addlocal=False, lsargs=None, randomizeout=True, cliffordtwirl=True, conditionaltwirl=True, citerations=20, compilerargs=None, partitioned=False, seed=None)#
Generates a “direct randomized benchmarking” (DRB) circuit.
DRB is the protocol introduced in arXiv:1807.07975 (2018). The length of the “core” circuit is given by length and may be any integer >= 0. 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 preceding circuit to a computational basis state. See arXiv:1807.07975 (2018) for further details.
- Parameters:
pspec (QubitProcessorSpec) – 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_compilation (CompilationRules) – Rules for compiling the “native” gates of pspec into Clifford gates.
length (int) – The “direct RB length” of the circuit, which is closely related to the circuit depth. It must be an integer >= 0. Unless addlocal is True, it 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.
qubit_labels (list, 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.
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 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.
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, 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.
addlocal (bool, optional) – Whether to follow each layer in the “core” circuit, sampled according to sampler with a layer of 1-qubit gates.
lsargs (list, 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.
randomizeout (bool, optional) – If False, the ideal output of the circuit (the “success” or “survival” outcome) is the all-zeros bit string. If True, the ideal output of the circuit is randomized to a uniformly random bit-string. This setting is useful for, e.g., detecting leakage/loss/measurement-bias etc.
cliffordtwirl (bool, optional) – Whether to begin the circuit 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.
conditionaltwirl (bool, 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).
citerations (int, 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 circuit 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.
compilerargs (list, 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.
partitioned (bool, optional) – If False, a single circuit is returned consisting of the full circuit. If True, three circuits are returned in a list 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).
seed (int, optional) – A seed to initialize the random number generator used for creating random clifford circuits.
- Returns:
Circuit or list of Circuits – If partitioned is False, a random DRB circuit sampled as specified. If partitioned is True, 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) [except in the case of cliffordtwirl=False, when it is a list of two circuits].
Tuple – A length-n tuple of integers in [0,1], corresponding to the error-free outcome of the circuit. Always all zeros if randomizeout is False. The ith element of the tuple corresponds to the error-free outcome for the qubit labelled by: the ith element of qubit_labels, if qubit_labels is not None; the ith element of pspec.qubit_labels, otherwise. In both cases, the ith element of the tuple corresponds to the error-free outcome for the qubit on the ith wire of the output circuit.