Protocols

trueq.make_cb

Generates a CircuitCollection to estimate the process fidelity of a cycle using cycle benchmarking (CB).

trueq.make_crosstalk_diagnostics

Generates a CircuitCollection to measure the discrepancy between gate quality while applying gates simultaneously versus while applying gates in an isolated way to each individual system.

trueq.make_irb

Generates a CircuitCollection to estimate the process fidelity of specific gates using (simultaneous) interleaved randomized benchmarking (IRB).

trueq.make_knr

Generates a CircuitCollection to estimate the probabilities of all errors acting on all sets of subsystems targeted by a combination of k gates using k-body noise reconstruction (KNR).

trueq.make_qcap

Generates a CircuitCollection to measure the quantum capacity (QCAP) bound of any circuit whose immutable cycles are contained in cycles.

trueq.make_rcal

Generates a CircuitCollection to measure the readout errors on the provided system labels.

trueq.make_sc

Generates a CircuitCollection to optimize the fidelity of a cycle using stochastic calibration (SC).

trueq.make_srb

Generates a CircuitCollection to estimate the process fidelity of random gates from a group using (simultaneous) streamlined randomized benchmarking (SRB).

trueq.make_xrb

Generates a CircuitCollection to study how coherent the errors in random gates are using (simultaneous) extended randomized benchmarking (XRB).

trueq.qcap_bound

Computes the quantum capacity (QCAP) bound of the given circuit.

trueq.randomly_compile

Randomly compiles the given circuit into many new random circuits which implement the same algorithm.

Make CB

trueq.make_cb(cycle, n_random_cycles, n_circuits=30, n_decays=20, targeted_errors=None, twirling_group=None, propagate_correction=False)

Generates a CircuitCollection to estimate the process fidelity of a cycle using cycle benchmarking (CB). See also the CB guide.

import trueq as tq

# generate a circuit collection to run CB on the 0th qubit, with 30 circuits,
# for each length in [4, 20] and each with 3 randomly chosen Pauli decay strings
circuits = tq.make_cb({0: tq.Gate.x}, [4, 20], 30, 3)

# draw the first circuit
circuits[0].draw()
0 Key: cycle: Cycle((0,): Gate.x, immutable=True) twirl: (('P', 0),) protocol: CB analyze_decays: ('I', 'X', 'Z') compiled_pauli: X n_random_cycles: 4 measurement_basis: X Labels: (0,) Name: Gate.cliff13 Aliases: Gate.cliff13 Generators: Z: 127.28 X: -127.28 0.71 -0.71 -0.71 -0.71 13 Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: -180.00 1.00 -1.00 Y Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.cliff7 Aliases: Gate.cliff7 Generators: Y: -270.00 -0.71 0.71 -0.71 -0.71 7 Imm Labels: (0,) Name: Meas() M
Parameters
  • cycle (Cycle | dict) – The cycle to benchmark or an argument to instantiate the cycle.

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [4, 20].

  • n_circuits (int) – The number of circuits for each number of random cycles.

  • n_decays (int) – An integer specifying the total number of randomly chosen Pauli decay strings used to measure the process infidelity or the probability of each error. Warning: Setting this value lower than min(20, 4 ** n_qubits - 1) may result in a biased estimate of the process fidelity, and setting this value lower than min(40, 4 ** n_qubits - 1) may result in a biased estimate of the probability for non-identity errors.

  • targeted_errors (Iterable) – A list of Pauli strings, e.g. ["ZIZIZ", "XYXYX"] that specify which errors to target. By default, the Pauli I * n_qubits is used to estimate the probability of no error, i.e. the process fidelity.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be one of "P" (Pauli), "C" (Clifford), "SU" (special unitary), or "I" (Identity). The twirling group will be the tensor product of the specified group on the keys of the cycle to be benchmarked. A mixture of groups on different labels can be specified by an iterable of groups and labels, for example, [["P", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified elements of labels will be set to "P". Warning: "I" is provided as a convenience method for expert users to identify coherent errors and/or crosstalk even though an exponential decay is not expected.

  • propagate_correction (bool) – Whether to propagate correction gates to the end of the circuit or compile them in to neighbouring cycles. Warning: can result in arbitrary two-qubit gates at the end of the circuit!

Returns

A collection of CB circuits.

Return type

CircuitCollection

Crosstalk Diagnostics

trueq.make_crosstalk_diagnostics(labels, n_random_cycles, n_circuits=30, subsets=None, include_xrb=True, twirling_group=None)

Generates a CircuitCollection to measure the discrepancy between gate quality while applying gates simultaneously versus while applying gates in an isolated way to each individual system. See also the CTD guide.

This discrepancy is assessed by running SRB simultaneously on the specified systems, as well as running it on each system in turn. Optionally, and True by default, the coherence of crosstalk errors is assessed using XRB. Therefore, this function is equivalent to concatenating the circuits from multiple calls to make_srb() (and optionally make_xrb()) with different label configurations.

import trueq as tq

# generate a circuit collection to run crosstalk diagnostics in single qubit
# mode for qubits 5, 6, 7, and 8
circuits = tq.make_crosstalk_diagnostics([5, 6, 7, 8], [4, 100])

# reduce the number of circuits to perform by excluding XRB circuits
# this means we cannot distinguish between coherent errors (due to static
# crosstalk) and incoherent errors (due to fluctuating crosstalk)
circuits = tq.make_crosstalk_diagnostics(
    [5, 6, 7, 8], [4, 100], include_xrb=False
)

# we can also twirl some pairs of systems using entangling gates
circuits = tq.make_crosstalk_diagnostics(
    [5, [6, 7], 8], [4, 100], include_xrb=False
)

# using the subsets option, we can customize exactly which subsets of the full
# simultaneous twirl are performed in isolation. Here, the default value would
# have resulted in subsets [[5],[6],[[7, 8]]]
circuits = tq.make_crosstalk_diagnostics(
    [5, 6, [7, 8]], [4, 100], include_xrb=False, subsets=[[5], [5, 6], [[7, 8]]]
)
Parameters
  • labels (Iterable) – A list of which sets of system labels are to be twirled together in each circuit, e.g. [3, [1, 2], 4].

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for at each n_random_cycles for each protocol.

  • subsets (Iterable) – A list of subsets of the given labels to be used. The default value of None results in each subset being a member of the given labels. See the last example above.

  • include_xrb (bool) – Whether to include XRB circuits in the output.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be either "C" (Clifford) or "SU" (special unitary). The twirling group will be the tensor product of the specified group on the labels to be benchmarked. A mixture of groups on different labels can be specified by an iterable of groups and labels such as [["SU", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified labels will be set to "C".

Returns

A collection of circuits to diagnose crosstalk.

Return type

CircuitCollection

Make IRB

trueq.make_irb(cycle, n_random_cycles, n_circuits=30, twirling_group=None, propagate_correction=False)

Generates a CircuitCollection to estimate the process fidelity of specific gates using (simultaneous) interleaved randomized benchmarking (IRB). See also the IRB guide.

import trueq as tq

# generate a circuit collection to run single qubit IRB on an X gate acting on
# qubit 0, with 30 random circuits for each circuit length in [5, 40, 60, 100]
circuits = tq.make_irb({0: tq.Gate.x}, [5, 40, 60, 100], 30)

# next, generate circuits to run IRB on a cycle with an X gate acting on qubit 0
# and a CZ gate on qubits (2, 3), with 20 random circuits at each circuit length
circuits = tq.make_irb({0: tq.Gate.x, (2, 3): tq.Gate.cz}, [2, 100], 20)

# finding the Pauli matrix compiled into the first circuit
print(circuits[0].key.compiled_pauli)

# draw the first circuit
circuits[0].draw()
IYI
0 2 3 Key: cycle: Cycle((0,): Gate.x, (2, 3): Gate.cz, immutable=True) twirl: (('C', 0), ('C', 2, 3)) protocol: IRB compiled_pauli: IYI n_random_cycles: 2 Labels: (0,) Name: Gate.cliff5 Aliases: Gate.cliff5 Generators: X: 90.00 0.71 -0.71j -0.71j 0.71 5 Labels: (2, 3) Name: Gate(IX, IY, ...) Locally Equivalent: iSWAP Generators: ZI: -60.00 ZX: 60.00 XZ: -60.00 IZ: -60.00 ZZ: 60.00 YY: -60.00 YZ: -34.64 ... 0.35 0.35j 0.35 0.35j 0.35 0.35j -0.35 -0.35j -0.35 -0.35j 0.35 0.35j -0.35 -0.35j -0.35 -0.35j -0.35 -0.35j 0.35 0.35j 0.35 0.35j 0.35 0.35j -0.35 -0.35j -0.35 -0.35j 0.35 0.35j -0.35 -0.35j Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2, 3) Name: Gate.cz Aliases: Gate.cz Locally Equivalent: CNOT Generators: IZ: 90.00 ZI: 90.00 ZZ: -90.00 1.00 1.00 1.00 -1.00 CZ CZ Labels: (0,) Name: Gate.cliff23 Aliases: Gate.cliff23 Generators: Z: 69.28 Y: 69.28 X: 69.28 0.50 0.50j 0.50 -0.50j 0.50 0.50j -0.50 0.50j 23 Labels: (2, 3) Name: Gate(IZ, XI, ...) Locally Equivalent: iSWAP Generators: XZ: -90.00 IZ: 63.64 YX: -63.64 ZY: 63.64 XI: 63.64 ZX: 45.00 YY: -45.00 -0.50 -0.50j -0.50 0.50j 0.50 -0.50j -0.50 -0.50j -0.50 -0.50j 0.50 -0.50j -0.50 0.50j -0.50 -0.50j Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2, 3) Name: Gate.cz Aliases: Gate.cz Locally Equivalent: CNOT Generators: IZ: 90.00 ZI: 90.00 ZZ: -90.00 1.00 1.00 1.00 -1.00 CZ CZ Labels: (0,) Name: Gate.cliff11 Aliases: Gate.cliff11 Generators: X: 127.28 Y: -127.28 0.71 0.71j 0.71 -0.71j 11 Labels: (2, 3) Name: Gate(XI, XX, ...) Locally Equivalent: CNOT Generators: ZX: 63.64 YI: -63.64 YX: -63.64 ZI: 63.64 XI: -45.00 XX: 45.00 0.35 -0.35j -0.35 -0.35j 0.35 0.35j 0.35 -0.35j -0.35 -0.35j 0.35 -0.35j 0.35 -0.35j 0.35 0.35j -0.35 0.35j -0.35 -0.35j 0.35 0.35j -0.35 0.35j -0.35 -0.35j -0.35 0.35j -0.35 0.35j 0.35 0.35j Imm Labels: (0,) Name: Meas() M Labels: (2,) Name: Meas() M Labels: (3,) Name: Meas() M

Note

We invert each random sequence up to an independent random Pauli matrix (accessible as shown in the example above) to diagnose errors to that are missed by always returning to the initial state (see arXiv:1901.00535).

Warning

The estimate of the process fidelity obtained by taking the ratio of the process fidelities from IRB and SRB is subject to a large systematic uncertainty that is typically not reported. This systematic uncertainty arises because of the many ways in which the noise in the twirling group can combine with the noise in the interleaved gates. Both the standard interleaved estimate and the systematic uncertainty are automatically computed by fit if the circuit collection contains SRB circuits. The systematic uncertainty can be reduced if the circuit collection also contains XRB circuits.

Parameters
  • cycle (Cycle | dict) – The cycle to benchmark or an argument to instantiate the cycle.

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for each number of random cycles.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be either "C" (Clifford) or "SU" (special unitary). The twirling group will be the tensor product of the specified group on the labels of the cycle to be benchmarked. A mixture of groups on different keys can be specified by an iterable of groups and labels such as [["P", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified keys of the cycle to be benchmarked will be set to "C".

  • propagate_correction (bool) – Whether to propagate correction gates to the end of the circuit or compile them in to neighbouring cycles. Warning: can result in arbitrary two-qubit gates at the end of the circuit!

Returns

A collection of IRB circuits.

Return type

CircuitCollection

Make KNR

trueq.make_knr(cycle, n_random_cycles, n_circuits=30, n_bodies=1, twirling_group=None, propagate_correction=False)

Generates a CircuitCollection to estimate the probabilities of all errors acting on all sets of subsystems targeted by a combination of k gates using k-body noise reconstruction (KNR). See also the KNR guide.

For example, if the input cycle is {0: tq.Gate.id, (1, 3): tq.Gate.cnot, 2: tq.Gate.x} and n_bodies=2, then data will be present to reconstruct any Pauli error rate on the subsystems [0, 1, 3], [0, 2], [1, 2, 3] (and any subsystems thereof, e.g. [1, 2] but not [0, 1, 2]).

import trueq as tq

# generate a circuit collection to reconsturct two-body marginal
# error distributions
# on a 4-qubit device using 30 circuits for each length in [6, 20]
# and for each Pauli subspace in a set of log2(4) subspaces
circuits = tq.make_knr({j: tq.Gate.x for j in range(4)}, [6, 20], 30)

# draw the first circuit
circuits[0].draw()
0 1 2 3 Key: cycle: Cycle((0,): Gate.x, (1,): Gate.x, (2,): Gate.x, (3,): Gate.x, immutable=True) twirl: (('P', 0), ('P', 1), ('P', 2), ('P', 3)) n_bodies: 1 protocol: KNR compiled_pauli: ZZXY n_random_cycles: 6 measurement_basis: XXXZ Labels: (0,) Name: Gate.h Aliases: Gate.h Gate.cliff12 Generators: Z: 127.28 X: 127.28 0.71 0.71 0.71 -0.71 H Labels: (1,) Name: Gate.h Aliases: Gate.h Gate.cliff12 Generators: Z: 127.28 X: 127.28 0.71 0.71 0.71 -0.71 H Labels: (2,) Name: Gate.cliff13 Aliases: Gate.cliff13 Generators: Z: 127.28 X: -127.28 0.71 -0.71 -0.71 -0.71 13 Labels: (3,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID Labels: (1,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID Labels: (3,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Labels: (3,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Labels: (1,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID Labels: (2,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Labels: (3,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (2,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (3,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.cliff7 Aliases: Gate.cliff7 Generators: Y: -270.00 -0.71 0.71 -0.71 -0.71 7 Labels: (1,) Name: Gate.cliff13 Aliases: Gate.cliff13 Generators: Z: 127.28 X: -127.28 0.71 -0.71 -0.71 -0.71 13 Labels: (2,) Name: Gate.cliff13 Aliases: Gate.cliff13 Generators: Z: 127.28 X: -127.28 0.71 -0.71 -0.71 -0.71 13 Labels: (3,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Imm Labels: (0,) Name: Meas() M Labels: (1,) Name: Meas() M Labels: (2,) Name: Meas() M Labels: (3,) Name: Meas() M

Note

The number of returned circuits scales mildly with the number of total systems but exponentially with the value of n_bodies.

Parameters
  • cycle (Cycle | dict) – The cycle to benchmark or an argument to instantiate the cycle.

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for each number of random cycles.

  • n_bodies (int) – A number of gate bodies to reconstruct marginal probability distributions for.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be one of "P" (Pauli), "C" (Clifford), "SU" (special unitary), or "I" (Identity). The twirling group will be the tensor product of the specified group on the keys of the cycle to be benchmarked. A mixture of groups on different labels can be specified by an iterable of groups and labels, for example, [["P", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified elements of labels will be set to "P". Warning: "I" is provided as a convenience method for expert users to identify coherent errors and/or crosstalk even though an exponential decay is not expected.

  • propagate_correction (bool) – Whether to propagate correction gates to the end of the circuit or compile them in to neighbouring cycles. Warning: can result in arbitrary two-qubit gates at the end of the circuit!

Returns

A collection of KNR circuits.

Return type

CircuitCollection

Make RCAL

trueq.make_rcal(labels, stagger=False, independent=True, batch=None)

Generates a CircuitCollection to measure the readout errors on the provided system labels. These circuits contain \(I\) and \(X\) gates. See the RCAL guide for more information.

Parameters
  • labels (Iterable) – A list of the system labels whose readout errors are to be estimated.

  • stagger (bool) – Whether \(X\) gates should appear in separate immutable cycles. If the gates are much worse when applied in parallel, then staggering them will reduce systematic errors, provided that the gate duration multiplied by the number of qubits is much shorter than \(T_1\).

  • independent (bool) – Whether it can be assumed that the readout error is independent over qubits. Under this assumption, only two circuits are required, whereas \(2^n\) circuits are required when this assumption does not hold. Note that if you measure the readout calibration matrix in both independent and non-independent modes, any observed non-independence could potentially be due to gate crosstalk errors.

  • batch (int) – A unique identifier for these calibration circuits. Other circuits which are to be calibrated based on these circuits’ results in particular should set their trueq.Circuit.key batch attribute to the same value.

Return type

trueq.CircuitCollection

Make SC

trueq.make_sc(cycle, n_random_cycles, n_circuits=30, pauli_decays=None, twirling_group=None, propagate_correction=False)

Generates a CircuitCollection to optimize the fidelity of a cycle using stochastic calibration (SC). See also the SC guide.

import trueq as tq

# generate a circuit collection to run SC on the 0th qubit, with 30 circuits,
# for each length in [4, 20] and each with a Pauli decay string "Z"
circuits = tq.make_sc({0: tq.Gate.x}, [4, 20], 30, "Z")

# draw the first circuit
circuits[0].draw()
0 Key: cycle: Cycle((0,): Gate.x, immutable=True) twirl: (('P', 0),) protocol: SC analyze_decays: ('Z',) compiled_pauli: Y n_random_cycles: 4 measurement_basis: Z Labels: (0,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: 180.00 -1.00j 1.00j Y Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 -1.00 -1.00 ID Imm Labels: (0,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 1.00 1.00 X Labels: (0,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 -1.00 -1.00 ID Imm Labels: (0,) Name: Meas() M
Parameters
  • cycle (Cycle | dict) – The cycle to benchmark or an argument to instantiate the cycle.

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for each number of random cycles.

  • pauli_decays (Iterable) – A list of Pauli decay strings, e.g. ["ZIZIZ", "XYXYX"] that specify which elements of the diagonalized channel should be estimated. These should be chosen to anticommute with the Hamiltonian terms of a known noise source to be optimized.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be one of "P" (Pauli), "C" (Clifford), "SU" (special unitary), or "I" (Identity). The twirling group will be the tensor product of the specified group on the keys of the cycle to be benchmarked. A mixture of groups on different labels can be specified by an iterable of groups and labels, for example, [["P", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified elements of labels will be set to "P". Warning: "I" is provided as a convenience method for expert users to identify coherent errors and/or crosstalk even though an exponential decay is not expected.

  • propagate_correction (bool) – Whether to propagate correction gates to the end of the circuit or compile them in to neighbouring cycles. Warning: can result in arbitrary two-qubit gates at the end of the circuit!

Returns

A collection of SC circuits.

Return type

CircuitCollection

Make SRB

trueq.make_srb(labels, n_random_cycles, n_circuits=30, twirling_group=None)

Generates a CircuitCollection to estimate the process fidelity of random gates from a group using (simultaneous) streamlined randomized benchmarking (SRB). See also the SRB guide.

import trueq as tq

# generate a circuit collection to run single qubit SRB on qubit 5
circuits = tq.make_srb([5], [4, 200], 30)

# generate a circuit collection to run simultaneous one-qubit SRB on qubits
# 2 and 7 and two-qubit SRB on the pairs [0, 1] and [4, 9]
circuits = tq.make_srb([[0, 1], 2, 7, [4, 9]], [4, 200], 30)

# finding the Pauli matrix compiled into the first circuit
print(circuits[0].key.compiled_pauli)

# draw the first circuit
circuits[0].draw()
XXXIZI
0 1 2 4 7 9 Key: twirl: (('C', 2), ('C', 7), ('C', 0, 1), ('C', 4, 9)) protocol: SRB compiled_pauli: XXXIZI n_random_cycles: 4 Labels: (0, 1) Name: Gate(IZ, XI, ...) Locally Equivalent: SWAP Generators: XZ: 90.00 ZX: 63.64 YX: 63.64 ZY: -63.64 YY: 63.64 XI: 45.00 IZ: -45.00 -0.35 0.35j 0.35 -0.35j 0.35 -0.35j -0.35 0.35j -0.35 -0.35j 0.35 0.35j -0.35 -0.35j 0.35 0.35j 0.35 -0.35j 0.35 -0.35j -0.35 0.35j -0.35 0.35j 0.35 0.35j 0.35 0.35j 0.35 0.35j 0.35 0.35j Labels: (2,) Name: Gate.cliff18 Aliases: Gate.cliff18 Generators: X: -69.28 Z: -69.28 Y: 69.28 0.50 0.50j -0.50 0.50j 0.50 0.50j 0.50 -0.50j 18 Labels: (4, 9) Name: Gate(XI, XY, ...) Locally Equivalent: iSWAP Generators: XY: 90.00 XI: -69.28 YZ: 69.28 ZZ: -69.28 0.35 0.35j 0.35 -0.35j -0.35 0.35j -0.35 -0.35j 0.35 0.35j 0.35 -0.35j 0.35 -0.35j 0.35 0.35j 0.35 0.35j -0.35 0.35j 0.35 -0.35j -0.35 -0.35j 0.35 0.35j -0.35 0.35j -0.35 0.35j 0.35 0.35j Labels: (7,) Name: Gate.cliff11 Aliases: Gate.cliff11 Generators: X: 127.28 Y: -127.28 0.71 0.71j 0.71 -0.71j 11 Imm Labels: (0, 1) Name: Gate(IX, XX, ...) Locally Equivalent: iSWAP Generators: ZX: -69.28 IX: 69.28 YI: 69.28 YY: -69.28 YZ: 69.28 XX: 69.28 -0.71 -0.71j 0.71 0.71j 0.71 -0.71j 0.71 -0.71j Labels: (2,) Name: Gate.y Aliases: Gate.y Gate.cliff2 Generators: Y: -180.00 1.00 -1.00 Y Labels: (4, 9) Name: Gate(IX, YY, ...) Locally Equivalent: iSWAP Generators: ZX: -90.00 YY: -69.28 YZ: -69.28 IX: 69.28 0.71 -0.71j 0.71 0.71j -0.71 -0.71j 0.71 -0.71j Labels: (7,) Name: Gate.cliff5 Aliases: Gate.cliff5 Generators: X: 90.00 0.71j 0.71 0.71 0.71j 5 Imm Labels: (0, 1) Name: Gate(IX, IY, ...) Locally Equivalent: CNOT Generators: XY: 90.00 IZ: -90.00 YY: -90.00 IX: -90.00 YZ: -45.00 IY: -45.00 ZI: -45.00 ... -0.35 0.35j -0.35 0.35j 0.35 0.35j -0.35 -0.35j -0.35 0.35j 0.35 -0.35j 0.35 0.35j 0.35 0.35j 0.35 -0.35j -0.35 0.35j 0.35 0.35j 0.35 0.35j 0.35 -0.35j 0.35 -0.35j 0.35 0.35j -0.35 -0.35j Labels: (2,) Name: Gate.cliff19 Aliases: Gate.cliff19 Generators: X: -69.28 Y: 69.28 Z: 69.28 0.50 -0.50j -0.50 0.50j 0.50 0.50j 0.50 0.50j 19 Labels: (4, 9) Name: Gate(IX, YI, ...) Locally Equivalent: CNOT Generators: YI: -90.00 YY: 69.28 IX: 69.28 YZ: 69.28 0.71 -0.71j -0.71j 0.71 0.71 -0.71j 0.71j -0.71 Labels: (7,) Name: Gate.cliff6 Aliases: Gate.cliff6 Generators: Y: -90.00 0.71 0.71 -0.71 0.71 6 Imm Labels: (0, 1) Name: Gate(IX, XI, ...) Locally Equivalent: CNOT Generators: YY: -90.00 IX: -90.00 ZY: -90.00 XY: 90.00 XZ: -45.00 YI: 45.00 XI: -45.00 ... -0.71 -0.71j -0.71 0.71j -0.71 0.71j 0.71 0.71j Labels: (2,) Name: Gate.cliff16 Aliases: Gate.cliff16 Generators: Y: -69.28 X: -69.28 Z: -69.28 0.50 0.50j 0.50 0.50j -0.50 0.50j 0.50 -0.50j 16 Labels: (4, 9) Name: Gate(IY, XY, ...) Locally Equivalent: CNOT Generators: YY: 127.28 XY: -127.28 ZX: 69.28 IY: 69.28 ZZ: 69.28 0.71j 0.71 -0.71j 0.71 -0.71j 0.71 0.71j 0.71 Labels: (7,) Name: Gate.x Aliases: Gate.x Gate.cliff1 Generators: X: 180.00 -1.00j -1.00j X Imm Labels: (0, 1) Name: Gate(XZ, YZ, ...) Locally Equivalent: CNOT Generators: XZ: -138.56 YZ: 138.56 ZI: -138.56 -0.50 0.50j -0.50 0.50j -0.50 0.50j 0.50 -0.50j 0.50 0.50j -0.50 -0.50j -0.50 -0.50j -0.50 -0.50j Labels: (2,) Name: Gate.cliff18 Aliases: Gate.cliff18 Generators: X: -69.28 Z: -69.28 Y: 69.28 0.50 0.50j -0.50 0.50j 0.50 0.50j 0.50 -0.50j 18 Labels: (4, 9) Name: Gate(IZ, XI, ...) Locally Equivalent: CNOT Generators: YI: -61.25 ZI: 61.25 IZ: -61.25 YX: -61.25 ZY: 61.25 ZX: 37.85 XI: -37.85 ... 0.50 -0.50 0.50j -0.50j -0.50j -0.50j 0.50 0.50 -0.50 -0.50 0.50j 0.50j -0.50j 0.50j -0.50 0.50 Labels: (7,) Name: Gate.cliff15 Aliases: Gate.cliff15 Generators: Z: 127.28 Y: -127.28 0.71 0.71j -0.71j -0.71 15 Imm Labels: (0,) Name: Meas() M Labels: (1,) Name: Meas() M Labels: (2,) Name: Meas() M Labels: (4,) Name: Meas() M Labels: (7,) Name: Meas() M Labels: (9,) Name: Meas() M

Note

We invert each random sequence up to an independent random Pauli matrix (accessible as shown in the example above) to diagnose errors to that are missed by always returning to the initial state (see arXiv:1901.00535).

Parameters
  • labels (Iterable) – A list of which sets of system labels are to be twirled together in each circuit, e.g. [3, [1, 2], 4].

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for each number of random cycles.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be either "C" (Clifford) or "SU" (special unitary). The twirling group will be the tensor product of the specified group on the labels to be benchmarked. A mixture of groups on different labels can be specified by an iterable of groups and labels such as [["SU", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified labels will be set to "C".

Returns

A collection of SRB circuits.

Return type

CircuitCollection

Make XRB

trueq.make_xrb(labels, n_random_cycles, n_circuits=30, twirling_group=None)

Generates a CircuitCollection to study how coherent the errors in random gates are using (simultaneous) extended randomized benchmarking (XRB). See also the XRB guide.

import trueq as tq

# generate circuit collections to run XRB on a single qubit (qubit 0), with
# 30 random circuits for each length in [4, 50, 500]
circuits = tq.make_xrb([0], [4, 50, 500], 30)

# generate circuit collections to run two-qubit XRB on qubit pair [5, 6], with
# 50 random circuits for each length in [3, 150]
circuits = tq.make_xrb([[5, 6]], [3, 150], 50)

# generate a circuit collection to run simultaneous one-qubit XRB on [5, 6, 7]
# with 30 random circuits for each length in [5, 10, 100]
circuits = tq.make_xrb([5, 6, 7], [5, 10, 100], 30)

# generate a circuit collection to run simultaneous one-qubit XRB on qubit 5,
# and two-qubit XRB on qubits [1, 2], with 15 random circuits for each circuit
# length in [4, 30]
circuits = tq.make_xrb([[1, 2], 5], [4, 30], 15)

# draw the first circuit
circuits[0].draw()
1 2 5 Key: twirl: (('C', 5), ('C', 1, 2)) protocol: XRB seq_label: 3829 n_random_cycles: 4 measurement_basis: YZZ Imm Labels: (1, 2) Name: Gate(IX, XI, ...) Locally Equivalent: CNOT Generators: IX: -180.00 ZX: -69.28 XI: 69.28 YX: 69.28 -0.50 0.50j -0.50j 0.50 0.50j -0.50 0.50 -0.50j 0.50j 0.50 0.50 0.50j 0.50 0.50j 0.50j 0.50 Labels: (5,) Name: Gate.cliff4 Aliases: Gate.cliff4 Generators: X: -90.00 0.71 0.71j 0.71j 0.71 4 Imm Labels: (1, 2) Name: Gate(IX, IY, ...) Locally Equivalent: CNOT Generators: IY: -61.25 YX: -61.25 ZI: 61.25 XY: -61.25 IX: -61.25 IZ: 37.85 YZ: -37.85 ... -0.50j 0.50 0.50j 0.50 0.50j 0.50 0.50j -0.50 -0.50 0.50j 0.50 0.50j -0.50 -0.50j -0.50 0.50j Labels: (5,) Name: Gate.cliff14 Aliases: Gate.cliff14 Generators: Z: 127.28 Y: 127.28 0.71 -0.71j 0.71j -0.71 14 Imm Labels: (1, 2) Name: Gate(IX, IY, ...) Locally Equivalent: iSWAP Generators: IY: -90.00 XI: 90.00 XY: -90.00 XX: 69.28 ZX: -69.28 IX: -69.28 YZ: 69.28 ... -0.35 -0.35j -0.35 0.35j -0.35 -0.35j 0.35 -0.35j -0.35 0.35j -0.35 -0.35j 0.35 -0.35j -0.35 -0.35j 0.35 0.35j 0.35 -0.35j -0.35 -0.35j 0.35 -0.35j -0.35 0.35j -0.35 -0.35j -0.35 0.35j 0.35 0.35j Labels: (5,) Name: Gate.cliff13 Aliases: Gate.cliff13 Generators: X: 127.28 Z: -127.28 -0.71 0.71 0.71 0.71 13 Imm Labels: (1, 2) Name: Gate(XY, XZ, ...) Locally Equivalent: CNOT Generators: XZ: -127.28 XY: 127.28 YX: -90.00 0.50 -0.50j 0.50j -0.50 0.50j -0.50 0.50 -0.50j 0.50j -0.50 -0.50 0.50j 0.50 -0.50j -0.50j 0.50 Labels: (5,) Name: Gate.cliff14 Aliases: Gate.cliff14 Generators: Z: 127.28 Y: 127.28 0.71 -0.71j 0.71j -0.71 14 Imm Labels: (1,) Name: Meas() M Labels: (2,) Name: Meas() M Labels: (5,) Name: Meas() M

Note

If the circuit collection also contains SRB circuits with the same twirl group, then calling fit will also return an estimate e_U of how much the process fidelity of the twirling groups can be improved by correcting static calibration errors.

Parameters
  • labels (Iterable) – A list of which sets of system labels are to be twirled together in each circuit, e.g. [3, [1, 2], 4].

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for each number of random cycles.

  • twirling_group (Iterable) – The twirling group to use in this protocol. This can be either "C" (Clifford) or "SU" (special unitary). The twirling group will be the tensor product of the specified group on the labels to be benchmarked. A mixture of groups on different labels can be specified by an iterable of groups and labels such as [["SU", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified labels will be set to "C".

Returns

A collection of XRB circuits.

Return type

CircuitCollection

QCAP (Quantum Capacity)

trueq.make_qcap(cycles, n_random_cycles, n_circuits=30, n_decays=20)

Generates a CircuitCollection to measure the quantum capacity (QCAP) bound of any circuit whose immutable cycles are contained in cycles. See also the QCAP guide.

The bound can be obtained by calling qcap_bound() on the QCAP circuits once they have been performed and their results have been populated. Note that this function outputs cycle benchmarking circuits, and fit() will report the individual infidelities of the given cycles.

import trueq as tq

# make a circuit to assess
circuit = tq.Circuit([
    {0: tq.Gate.y},
    {(0, 1): tq.Gate.cnot},
    {0: tq.Gate.h, 1: tq.Gate.h},
    {(1, 2): tq.Gate.cnot, (3, 4): tq.Gate.cnot},
    {0: tq.Gate.h, 1: tq.Gate.h},
    {(1, 2): tq.Gate.cnot, (3, 4): tq.Gate.cnot},
    {0: tq.Gate.h, 1: tq.Gate.h},
    {(1, 3): tq.Gate.cnot}
])

# generate a circuit collection to measure the QCAP
circuits = tq.make_qcap(circuit, [0, 16])

# run the circuits on your hardware or simulator
tq.Simulator().add_overrotation(0.05).run(circuits)

# generate the QCAP bound
tq.qcap_bound(circuit, circuits)
QCAP
Quantum Capacity
Paulis
(0, 1, 2, 3, 4)
Key:
  • labels: (0, 1, 2, 3, 4)
  • protocol: QCAP
  • twirl: (('P', 0), ('P', 1), ('P', 2), ('P', 3), ('P', 4))
${e}_{IU}$
The inferred upper bound on the process infidelity of a circuit if it were run under RC.
1.2e-01 (2.9e-03)
0.11567970783231862, 0.002942727472326336

Note

This function is a convenience wrapper of make_cb(). If, for example, different values of n_random_cycles are desired for each cycle, call make_cb() manually for each cycle placing all generated circuits in the same collection. However, it is important to set the twirling_group option to ((P, i) for i in labels) where labels are all the qubit labels involved in the circuit(s) of interest.

Parameters
  • cycles (Iterable | Circuit) – An iterable of Cycles (note that a Circuit is an iterable of cycles). Only the immutable cycles will be considered, and duplicate immutable cycles will be ignored.

  • n_random_cycles (Iterable) – A list of positive integers specifying how many random cycles will be generated during the protocol, e.g. [6, 20].

  • n_circuits (int) – The number of circuits for each random cycle.

  • n_decays (int) – An integer specifying the total number of randomly chosen pauli decay strings used to measure the process infidelity. Warning: Setting this value lower than min(20, 4 ** n_qubits - 1) may result in a biased estimate.

Returns

A collection of QCAP circuits.

Return type

CircuitCollection

trueq.qcap_bound(circuit, fit_or_circuits)

Computes the quantum capacity (QCAP) bound of the given circuit. This scalar quantity is a bound on the circuit performance when the circuit is executed using randomly_compile(). See also the QCAP guide.

Parameters
  • circuit (Circuit) – The circuit you wish to know the QCAP bound of. This will usually be the original circuit that was given to make_qcap(), but can be any circuit whose immutable cycles are a subset of the immutable cycles present in the CB circuits or fits of fit_or_circuits.

  • fit_or_circuits – A circuit collection output by make_qcap() populated with results, or an estimate collection that resulted from calling fit() on such a circuit collection. For efficiency, use the latter format if computing a bound on multiple circuits.

Returns

A bound on the circut performance.

Return type

NormalEstimate

Randomly Compile

trueq.randomly_compile(circuit, n_compilations=30, twirling_group=None, compile_paulis=False, compress=True)

Randomly compiles the given circuit into many new random circuits which implement the same algorithm. Random gates are inserted adjacent to gates in the provided circuit, chosen from the specified twirling group (the Pauli group is used by default). See also the RC guide.

Cycles in the input circuit that are immutable will not be chnaged, while other cycles may have random gates compiled into them.

import trueq as tq

#Define a circuit which applies an X gate on the 0th qubit, a controlled-Z
#gate on qubits 0 and 1, and another X gate on the 0th qubit.
cycle1 = tq.Cycle({0: tq.Gate.x})
cycle2 = tq.Cycle({(0, 1): tq.Gate.cz});
circuit = tq.Circuit((cycle1, cycle2, cycle1))
circuit.measure_all()

#Run randomized compiling on the circuit
compiled_circuit = tq.randomly_compile(circuit)

# draw the first circuit
compiled_circuit[0].draw()
0 1 Key: twirl: (('P', 0), ('P', 1)) protocol: RC n_random_cycles: 1 Labels: (0,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Labels: (1,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Imm Labels: (0, 1) Name: Gate.cz Aliases: Gate.cz Locally Equivalent: CNOT Generators: IZ: 90.00 ZI: 90.00 ZZ: -90.00 1.00 1.00 1.00 -1.00 CZ CZ Labels: (0,) Name: Gate.z Aliases: Gate.z Gate.cliff3 Generators: Z: 180.00 -1.00j 1.00j Z Labels: (1,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID Imm Labels: (0,) Name: Meas() M Labels: (1,) Name: Meas() M

Note

Running randomly_compile() on a circuit several times is likely to return different compiled circuits due to the random nature of the algorithm. The circuit returned will always contain the same number of cycles as the input circuit, and will be logically equivalent, up to a global phase.

Warning

Running randomly_compile() on circuits containing gates acting on multiple systems with a non-Clifford gate will typically result in an error because twirling operations cannot be corrected locally.

Parameters
  • circuit (Circuit) – A circuit to randomly compile.

  • n_compilations (int) – The number of random compilations of the input circuit. Each instance will appear as a new circuit in the returned circuit collection.

  • twirling_group (Iterable) – The twirling group to use. This can be one of "P" (Pauli), "C" (Clifford), "SU" (special unitary), or "I" (Identity). The twirling group will be the tensor product of the specified group on the labels of the circuit to be randomly compiled. A mixture of groups on different labels can be specified by an iterable of groups and labels, for example, [["P", 0], ["C", 1, 2], ["C", 3]], where ["C", 1, 2] specifies the two-qubit Clifford group acting on the labels [1, 2] and ["C", 3] specifies the one-qubit Clifford group acting on the label 3. Any unspecified elements of labels will be set to "P".

  • compile_paulis (bool) – Whether or not to compile a random Pauli gate onto a qubit in the cycle preceding a measurement operation for each Meas operation encountered in the circuit. Which Paulis were compiled in are stored as a string in the key, where the order is first defined by cycle index, and then by sorted labels of each cycle. (default is False).

  • compress (bool) – Whether or not to compress the easy cycles (default is True).

Returns

A circuit collection containing randomly compiled versions of the circuit.

Return type

py:class:~trueq.CircuitCollection