pygsti.algorithms.randomcircuit

Random circuit sampling functions.

Module Contents

Functions

sample_haar_random_one_qubit_unitary_parameters()

TODO: docstring

sample_compiled_haar_random_one_qubit_gates_zxzxz_circuit(pspec, zname='Gzr', xname='Gxpi2', qubit_labels=None)

TODO: docstring #generate layer of random unitaries and make a series of circuit layers with the compiled versions

sample_random_cz_zxzxz_circuit(pspec, length, qubit_labels=None, two_q_gate_density=0.25, two_q_gate_args_lists={'Gczr': [(str(_np.pi / 2), ), (str(-_np.pi / 2), )]})

TODO: docstring

find_all_sets_of_compatible_two_q_gates(edgelist, n, gatename='Gcnot', aslabel=False)

TODO: docstring

sample_circuit_layer_by_edgegrab(pspec, qubit_labels=None, two_q_gate_density=0.25, one_q_gate_names=None, gate_args_lists=None, rand_state=None)

TODO: docstring

sample_circuit_layer_by_q_elimination(pspec, qubit_labels=None, two_q_prob=0.5, rand_state=None)

Samples a random circuit layer by eliminating qubits one by one.

sample_circuit_layer_by_co2_q_gates(pspec, qubit_labels, co2_q_gates, co2_q_gates_prob='uniform', two_q_prob=1.0, one_q_gate_names='all', rand_state=None)

Samples a random circuit layer using the specified list of "compatible two-qubit gates" (co2_q_gates).

sample_circuit_layer_of_one_q_gates(pspec, qubit_labels=None, one_q_gate_names='all', pdist='uniform', modelname='clifford', rand_state=None)

Samples a random circuit layer containing only 1-qubit gates.

create_random_circuit(pspec, length, qubit_labels=None, sampler='Qelimination', samplerargs=[], addlocal=False, lsargs=[], rand_state=None)

Samples a random circuit of the specified length (or ~ twice this length).

create_direct_rb_circuit(pspec, clifford_compilations, length, qubit_labels=None, sampler='Qelimination', samplerargs=[], addlocal=False, lsargs=[], randomizeout=True, cliffordtwirl=True, conditionaltwirl=True, citerations=20, compilerargs=[], partitioned=False, seed=None)

Generates a "direct randomized benchmarking" (DRB) circuit.

create_clifford_rb_circuit(pspec, clifford_compilations, length, qubit_labels=None, randomizeout=False, citerations=20, compilerargs=[], interleaved_circuit=None, seed=None)

Generates a "Clifford randomized benchmarking" (CRB) circuit.

sample_pauli_layer_as_compiled_circuit(pspec, absolute_compilation, qubit_labels=None, keepidle=False, rand_state=None)

Samples a uniformly random n-qubit Pauli and converts it to the gate-set of pspec.

sample_one_q_clifford_layer_as_compiled_circuit(pspec, absolute_compilation, qubit_labels=None, rand_state=None)

Samples a uniformly random layer of 1-qubit Cliffords.

create_mirror_rb_circuit(pspec, absolute_compilation, length, qubit_labels=None, sampler='Qelimination', samplerargs=[], localclifford=True, paulirandomize=True, seed=None)

Generates a "mirror randomized benchmarking" (MRB) circuit.

create_random_germ(pspec, depths, interacting_qs_density, qubit_labels, rand_state=None)

TODO: docstring

create_random_germpower_circuits(pspec, depths, interacting_qs_density, qubit_labels, fixed_versus_depth=False, rand_state=None)

TODO: docstring

create_random_germpower_mirror_circuits(pspec, absolute_compilation, depths, qubit_labels=None, localclifford=True, paulirandomize=True, interacting_qs_density=1 / 8, fixed_versus_depth=False, seed=None)

TODO: docstring

pygsti.algorithms.randomcircuit.sample_haar_random_one_qubit_unitary_parameters()

TODO: docstring

pygsti.algorithms.randomcircuit.sample_compiled_haar_random_one_qubit_gates_zxzxz_circuit(pspec, zname='Gzr', xname='Gxpi2', qubit_labels=None)
TODO: docstring #generate layer of random unitaries and make a series of circuit layers with the compiled versions

of these

pygsti.algorithms.randomcircuit.sample_random_cz_zxzxz_circuit(pspec, length, qubit_labels=None, two_q_gate_density=0.25, two_q_gate_args_lists={'Gczr': [(str(_np.pi / 2),), (str(- _np.pi / 2),)]})

TODO: docstring Generates a forward circuits with benchmark depth d for non-clifford mirror randomized benchmarking. The circuits alternate Haar-random 1q unitaries and layers of Gczr gates

pygsti.algorithms.randomcircuit.find_all_sets_of_compatible_two_q_gates(edgelist, n, gatename='Gcnot', aslabel=False)

TODO: docstring <TODO summary>

Parameters
  • edgelist (<TODO typ>) – <TODO description>

  • n (int) – The number of two-qubit gates to have in the set.

  • gatename (<TODO typ>, optional) – <TODO description>

  • aslabel (<TODO typ>, optional) – <TODO description>

Returns

<TODO typ>

pygsti.algorithms.randomcircuit.sample_circuit_layer_by_edgegrab(pspec, qubit_labels=None, two_q_gate_density=0.25, one_q_gate_names=None, gate_args_lists=None, rand_state=None)

TODO: docstring <TODO summary>

Parameters
  • pspec (<TODO typ>) – <TODO description>

  • qubit_labels (<TODO typ>, optional) – <TODO description>

  • mean_two_q_gates (<TODO typ>, optional) – <TODO description>

  • modelname (<TODO typ>, optional) – <TODO description>

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

<TODO typ>

pygsti.algorithms.randomcircuit.sample_circuit_layer_by_q_elimination(pspec, qubit_labels=None, two_q_prob=0.5, rand_state=None)

Samples a random circuit layer by eliminating qubits one by one.

This sampler works with any connectivity, but the expected number of 2-qubit gates in a layer depends on both the specified 2-qubit gate probability and the exact connectivity graph.

This sampler is the following algorithm: List all the qubits, and repeat the following steps until all qubits are deleted from this list. 1) Uniformly at random pick a qubit from the list, and delete it from the list 2) Flip a coin with bias two_q_prob to be “Heads”. 3) If “Heads” then – if there is one or more 2-qubit gates from this qubit to other qubits still in the list – pick one of these at random. 4) If we haven’t chosen a 2-qubit gate for this qubit (“Tails” or “Heads” but there are no possible 2-qubit gates) then pick a uniformly random 1-qubit gate to apply to this qubit.

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device that the circuit layer is being sampled for. Unless qubit_labels is not None, a circuit layer is sampled over all the qubits in pspec.

  • qubit_labels (list, optional) – If not None, a list of the qubits to sample the circuit layer for. This is a subset of pspec.qubit_labels. If None, the circuit layer is sampled to acton all the qubits in pspec.

  • two_q_prob (float, optional) – If a 2-qubit can is still possible on a qubit at that stage of the sampling, this is the probability a 2-qubit gate is chosen for that qubit. The expected number of 2-qubit gates per layer depend on this quantity and the connectivity graph of the device.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

list of gates – A list of gate Labels that defines a “complete” circuit layer (there is one and only one gate acting on each qubit in pspec or qubit_labels).

pygsti.algorithms.randomcircuit.sample_circuit_layer_by_co2_q_gates(pspec, qubit_labels, co2_q_gates, co2_q_gates_prob='uniform', two_q_prob=1.0, one_q_gate_names='all', rand_state=None)

Samples a random circuit layer using the specified list of “compatible two-qubit gates” (co2_q_gates).

That is, the user inputs a list (co2_q_gates) specifying 2-qubit gates that are “compatible” – meaning that they can be implemented simulatenously – and a distribution over the different compatible sets, and a layer is sampled from this via:

1. Pick a set of compatible two-qubit gates from the list co2_q_gates, according to the distribution specified by co2_q_gates_prob. 2. For each 2-qubit gate in the chosen set of compatible gates, with probability two_q_prob add this gate to the layer. 3. Uniformly sample 1-qubit gates for any qubits that don’t yet have a gate on them, from those 1-qubit gates specified by one_q_gate_names.

For example, consider 4 qubits with linear connectivity. a valid co2_q_gates list is co2_q_gates = [[,],[Label(Gcphase,(0,1)),Label(Gcphase,(2,3))]] which consists of an element containing zero 2-qubit gates and an element containing two 2-qubit gates that can be applied in parallel. In this example there are 5 possible sets of compatible 2-qubit gates:

  1. [,] (zero 2-qubit gates)

  2. [Label(Gcphase,(0,1)),] (one of the three 2-qubit gate)

  3. [Label(Gcphase,(1,2)),] (one of the three 2-qubit gate)

  4. [Label(Gcphase,(2,3)),] (one of the three 2-qubit gate)

  5. [Label(Gcphase,(0,1)), Label(Gcphase,(2,3)),] (the only compatible pair of 2-qubit gates).

The list of compatible two-qubit gates co2_q_gates can be any list containing anywhere from 1 to all 5 of these lists.

In order to allow for convenient sampling of some commonly useful distributions, co2_q_gates can be a list of lists of lists of compatible 2-qubit gates (“nested” sampling). In this case, a list of lists of compatible 2-qubit gates is picked according to the distribution co2_q_gates_prob, and then one of the sublists of compatible 2-qubit gates in the selected list is then chosen uniformly at random. For example, this is useful for sampling a layer containing one uniformly random 2-qubit gate with probability p and a layer of 1-qubit gates with probability 1-p. Here, we can specify co2_q_gates as [[],[[the 1st 2Q-gate,],[the 2nd 2Q-gate,], …]] and set two_q_prob=1 and `co2_q_gates_prob = [1-p,p].

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device that the circuit layer is being sampled for. Unless qubit_labels is not None, a circuit layer is sampled over all the qubits in pspec.

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

  • co2_q_gates (list) –

    This is either:

    1. A list of lists of 2-qubit gate Labels that can be applied in parallel.

    2. A list of lists of lists of 2-qubit gate Labels that can be applied in parallel.

    In case (1) each list in co2_q_gates should contain 2-qubit gates, in the form of Labels, that can be applied in parallel and act only on the qubits in pspec if qubit_labels is None, or act only on the qubits in qubit_labels if qubit_labels is not None. The sampler then picks one of these compatible sets of gates (with probability specified by co2_q_gates_prob, and converts this into a circuit layer by applying the 2-qubit gates it contains with the user-specified probability two_q_prob, and augmenting these 2-qubit gates with 1-qubit gates on all other qubits.

    In case (2) a sublist of lists is sampled from co2_q_gates according to co2_q_gates_prob and then we proceed as in case (1) but as though co2_q_gates_prob is the uniform distribution.

  • co2_q_gates_prob (str or list of floats) – If a list, they are unnormalized probabilities to sample each of the elements of co2_q_gates. So it is a list of non-negative floats of the same length as co2_q_gates. If ‘uniform’, then the uniform distribution is used.

  • two_q_prob (float, optional) – The probability for each two-qubit gate to be applied to a pair of qubits, after a set of compatible 2-qubit gates has been chosen. The expected number of 2-qubit gates in a layer is two_q_prob times the expected number of 2-qubit gates in a set of compatible 2-qubit gates sampled according to co2_q_gates_prob.

  • one_q_gate_names ('all' or list of strs, optional) – If not ‘all’, a list of the names of the 1-qubit gates to be sampled from when applying a 1-qubit gate to a qubit. If this is ‘all’, the full set of 1-qubit gate names is extracted from the QubitProcessorSpec.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

list of gates – A list of gate Labels that defines a “complete” circuit layer (there is one and only one gate acting on each qubit).

pygsti.algorithms.randomcircuit.sample_circuit_layer_of_one_q_gates(pspec, qubit_labels=None, one_q_gate_names='all', pdist='uniform', modelname='clifford', rand_state=None)

Samples a random circuit layer containing only 1-qubit gates.

The allowed 1-qubit gates are specified by one_q_gate_names, and the 1-qubit gates are sampled independently and uniformly.

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device that the circuit layer is being sampled for. Unless qubit_labels is not None, a circuit layer is sampled over all the qubits in pspec.

  • qubit_labels (list, optional) – If not None, a list of the qubits to sample the circuit layer for. This is a subset of pspec.qubit_labels. If None, the circuit layer is sampled to acton all the qubits in pspec.

  • one_q_gate_names ('all' or list of strs, optional) – If not ‘all’, a list of the names of the 1-qubit gates to be sampled from when applying a 1-qubit gate to a qubit. If this is ‘all’, the full set of 1-qubit gate names is extracted from the QubitProcessorSpec.

  • pdist ('uniform' or list of floats, optional) – If a list, they are unnormalized probabilities to sample each of the 1-qubit gates in the list one_q_gate_names. If this is not ‘uniform’, then oneQgatename` must not be ‘all’ (it must be a list so that it is unambigious which probability correpsonds to which gate). So if not ‘uniform’, pdist is a list of non-negative floats of the same length as one_q_gate_names. If ‘uniform’, then the uniform distribution over the gates is used.

  • modelname (str, optional) – Only used if one_q_gate_names is ‘all’. Specifies which of the pspec.models to use to extract the model. The clifford default is suitable for Clifford or direct RB, but will not use any non-Clifford gates in the model.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

list of gates – A list of gate Labels that defines a “complete” circuit layer (there is one and only one gate acting on each qubit).

pygsti.algorithms.randomcircuit.create_random_circuit(pspec, length, qubit_labels=None, sampler='Qelimination', samplerargs=[], addlocal=False, lsargs=[], rand_state=None)

Samples a random circuit of the specified length (or ~ twice this length).

The created circuit’s layers are independently sampled according to the specified sampling distribution.

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device that the circuit is being sampled for. This is always handed to the sampler, as the first argument of the sampler function. Unless qubit_labels is not None, the circuit is sampled over all the qubits in pspec.

  • length (int) – If addlocal is False, this is the length of the sampled circuit. If addlocal is True the length of the circuits 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 gates (with the sampling specified by lsargs)

  • 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: {‘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. If this 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. For some in-built samplers this is not optional.

  • addlocal (bool, optional) – If False, the circuit sampled is of length length and each layer is independently sampled according to the sampler specified by sampler. If True, the circuit sampled is of length 2*`length`+1 where: the zeroth + all even layers are consisting of independently random 1-qubit gates (with the sampling specified by lsargs); the odd-indexed layers are independently sampled according to sampler. So length`+1 layers consist only of 1-qubit gates, and `length layers are sampled according to sampler.

  • lsargs (list, optional) – A list of arguments that are handed to the 1-qubit gate layers sampler rb.sampler.circuit_layer_of_oneQgates for the alternating 1-qubit-only layers that are included in the circuit if addlocal is True. This argument is not used if addlocal is false. Note that pspec is used as the first, and only required, argument of rb.sampler.circuit_layer_of_oneQgates. If lsargs = [] then all available 1-qubit gates are uniformly sampled from. To uniformly sample from only a subset of the available 1-qubit gates (e.g., the Paulis to Pauli-frame-randomize) then lsargs should be a 1-element list consisting of a list of the relevant gate names (e.g., lsargs = [‘Gi, ‘Gxpi, ‘Gypi’, ‘Gzpi’]).

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A random circuit of length length (if not addlocal) or length 2*`length`+1 (if addlocal) with layers independently sampled using the specified sampling distribution.

pygsti.algorithms.randomcircuit.create_direct_rb_circuit(pspec, clifford_compilations, length, qubit_labels=None, sampler='Qelimination', samplerargs=[], addlocal=False, lsargs=[], randomizeout=True, cliffordtwirl=True, conditionaltwirl=True, citerations=20, compilerargs=[], 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 preceeding 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) – Wether 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 partioned is False, a random DRB circuit sampled as specified. If partioned 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.

pygsti.algorithms.randomcircuit.create_clifford_rb_circuit(pspec, clifford_compilations, length, qubit_labels=None, randomizeout=False, citerations=20, compilerargs=[], interleaved_circuit=None, seed=None)

Generates a “Clifford randomized benchmarking” (CRB) circuit.

CRB is the current-standard RB protocol defined in “Scalable and robust randomized benchmarking of quantum processes”, Magesan et al. PRL 106 180504 (2011). This consists of a circuit of length`+1 uniformly random n-qubit Clifford gates followed by the unique inversion Clifford, with all the Cliffords compiled into the “native” gates of a device as specified by `pspec. The circuit output by this function will respect the connectivity of the device, as encoded into pspec (see the QubitProcessorSpec object docstring for how to construct the relevant pspec).

Note the convention that the the output Circuit consists of length+2 Clifford gates, rather than the more usual convention of defining the “CRB length” to be the number of Clifford gates - 1. This is for consistency with the other RB functions in pyGSTi: in all RB-circuit-generating functions in pyGSTi length zero corresponds to the minimum-length circuit allowed by the protocol. Note that changing the “RB depths” by a constant additive factor is irrelevant for fitting purposes (except that it changes the obtained “SPAM” fit parameter).

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 CRB circuit will be over the gates in pspec, and will respect the connectivity encoded by pspec.

  • clifford_compilations (dict) – 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.

  • length (int) – The “CRB length” of the circuit – an integer >= 0 – which is the number of Cliffords in the circuit - 2 before each Clifford is compiled into the native gate-set.

  • 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. If desired, a circuit that explicitly idles on the other qubits can be obtained by using methods of the Circuit object.

  • randomizeout (bool, optional) – If False, the ideal output of the circuit (the “success” or “survival” outcome) is the all-zeros bit string. This is probably considered to be the “standard” in CRB. 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.

  • citerations (int, 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 * (`length`+2). Lower-depth / lower 2-qubit gate count compilations of the Cliffords are important in order to successfully implement CRB on more qubits.

  • compilerargs (list, 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:

    • algorithmstr. A string that specifies the compilation algorithm. The default in

      compile_clifford() will always be whatever we consider to be the ‘best’ all-round algorith,

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

    • paulirandomizebool. 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.

  • seed (int, optional) – A seed to initialize the random number generator used for creating random clifford circuits.

Returns

  • Circuit – A random CRB circuit over the “native” gate-set specified.

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

pygsti.algorithms.randomcircuit.sample_pauli_layer_as_compiled_circuit(pspec, absolute_compilation, qubit_labels=None, keepidle=False, rand_state=None)

Samples a uniformly random n-qubit Pauli and converts it to the gate-set of pspec.

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • qubit_labels (list, optional) – If not None, a list of a subset of the qubits from pspec that the pauli circuit should act on.

  • keepidle (bool, optional) – Whether to always have the circuit at-least depth 1.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit corresponding to a uniformly random n-qubit Pauli, converted to the native gate-set of pspec.

pygsti.algorithms.randomcircuit.sample_one_q_clifford_layer_as_compiled_circuit(pspec, absolute_compilation, qubit_labels=None, rand_state=None)

Samples a uniformly random layer of 1-qubit Cliffords.

Create a uniformly random layer of 1-qubit Cliffords on all the qubits, and then converts it to the native gate-set of pspec. That is, an independent and uniformly random 1-qubit Clifford is sampled for each qubit.

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • qubit_labels (list, optional) – If not None, a list of a subset of the qubits from pspec that the circuit should act on.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit corresponding to an independent, uniformly random 1-qubit Clifford gate on each qubit.

pygsti.algorithms.randomcircuit.create_mirror_rb_circuit(pspec, absolute_compilation, length, qubit_labels=None, sampler='Qelimination', samplerargs=[], localclifford=True, paulirandomize=True, seed=None)

Generates a “mirror randomized benchmarking” (MRB) circuit.

This is specific to the case of Clifford gates and can be performed, optionally, with Pauli-randomization and Clifford-twirling. This RB method is currently in development; this docstring will be updated in the future with further information on this technique.

To implement mirror RB it is necessary for U^(-1) to in the gate-set for every U in the gate-set.

Parameters
  • pspec (QubitProcessorSpec) – The QubitProcessorSpec for the device that the circuit is being sampled for. The pspec is always handed to the sampler, as the first argument of the sampler function.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • length (int) –

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

    • If localclifford and paulirandomize are False, this is the depth of the sampled circuit. 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 the circuits 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 the circuits 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 the circuits 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.

  • 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

  • seed (int, optional) – A seed to initialize the random number generator used for creating random clifford circuits.

Returns

  • Circuit

    A random MRB circuit, sampled as specified, of depth:

    • length, if not paulirandomize and not local clifford.

    • 2*`length`+1 if paulirandomize and not local clifford.

    • length + X, if not paulirandomize and local clifford, where X is a random variable that accounts for the depth from the layers of random 1-qubit Cliffords (X = 2 if the 1 qubit Clifford gates are “native” gates in the QubitProcessorSpec).

    • 2*`length`+1 + X, if paulirandomize and local clifford, where X is a random variable that accounts for the depth from the layers of random 1-qubit Cliffords (X = 2 if the 1 qubit Clifford gates are “native” gates in the QubitProcessorSpec).

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

pygsti.algorithms.randomcircuit.create_random_germ(pspec, depths, interacting_qs_density, qubit_labels, rand_state=None)

TODO: docstring <TODO summary>

Parameters
  • pspec (<TODO typ>) – <TODO description>

  • depths (<TODO typ>) – <TODO description>

  • interacting_qs_density (<TODO typ>) – <TODO description>

  • qubit_labels (<TODO typ>) – <TODO description>

Returns

<TODO typ>

pygsti.algorithms.randomcircuit.create_random_germpower_circuits(pspec, depths, interacting_qs_density, qubit_labels, fixed_versus_depth=False, rand_state=None)

TODO: docstring <TODO summary>

Parameters
  • pspec (<TODO typ>) – <TODO description>

  • depths (<TODO typ>) – <TODO description>

  • interacting_qs_density (<TODO typ>) – <TODO description>

  • qubit_labels (<TODO typ>) – <TODO description>

  • fixed_versus_depth (<TODO typ>, optional) – <TODO description>

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

pygsti.algorithms.randomcircuit.create_random_germpower_mirror_circuits(pspec, absolute_compilation, depths, qubit_labels=None, localclifford=True, paulirandomize=True, interacting_qs_density=1 / 8, fixed_versus_depth=False, seed=None)

TODO: docstring length : consistent with RB length.

Parameters
  • pspec (<TODO typ>) – <TODO description>

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • depths (<TODO typ>) – <TODO description>

  • qubit_labels (<TODO typ>, optional) – <TODO description>

  • localclifford (<TODO typ>, optional) – <TODO description>

  • paulirandomize (<TODO typ>, optional) – <TODO description>

  • interacting_qs_density (<TODO typ>, optional) – <TODO description>

  • fixed_versus_depth (<TODO typ>, optional) – <TODO description>

Returns

<TODO typ>