Circuits
Represents a quantum |
|
Represents a collection of instances of |
Circuit
- class trueq.Circuit(cycles=None, key=None, results=None)
Represents a quantum
Circuit
to be performed on a device, along with relevant additional information about the circuit.Note
All True-Q™ circuit generation and analysis methods assume that circuits are run by initializing systems independently in the ground state, applying the parallelized gates (referred to as cycles) obtained by iterating over the circuit, measuring the systems in the computational basis, and populating
results
with the results.Specifically, all local gates required to rotate preparations and measurements are already included in
cycles
.A circuit is stored as a list of
Cycle
s. It also has private attributes for ease of use with randomized compiling and standard quantum algorithms.- Parameters:
cycles (
list
) –Cycle
s of the circuit. This is a list of the form, for example,[{(1,): tq.Gate.x, (0, 2): tq.Gate.cz}, ...]
.key (
Key
) – A hashable object used to group similar circuits for analysis. For example,Key(protocol=SRB,n_random_cycles=10)
.results (
Results
|dict
) – Results to add to the circuit on construction, see alsoCircuit.results
.
- copy(keep_results=True)
Returns a copy of this circuit.
- measure_all()
Adds a cycle of measurements at the end of the current circuit.
The cycle will be assigned a marker which is
1
larger than the largest marker currently in the circuit.This adds
Meas
onto each label currently in the circuit.- Returns:
This instance.
- Return type:
- property dim
The dimension of each subsystem, e.g.
2
if this circuit acts on qubits. This property is inherited from its cycles or its results if it has no cycles. If this circuit contains no cycles or results, thenNone
.- Type:
int
|NoneType
- property key
Metadata related to this circuit. This is used in analysis methods of protocols, and for organizing circuits within
CircuitCollection
s.- Type:
- property labels
The sorted union of all system labels acted on by gates in this
Circuit
.- Type:
tuple
- property results
Results from running this
Circuit
on a quantum device; a dictionary whose keys are bitstrings, and whose values are total observations of corresponding bitstrings.Bitstrings are python strings containing \(0\) and \(1\), e.g.,
'0110'
, see Results.The initial value of this property is
{}
, which implies thathas_results
isFalse
.Note that these values will internally be normalized to their sum, and not to \(1\) —for example, with respect to all of our analysis routines, the following results are identical:
{'0': 123, '1': 4} {'0': 1230, '1': 40} {'0': 12300, '1': 400}
- Type:
dict
- append(cycles_or_circuit)
Appends one or more
Cycle
s or anotherCircuit
to this circuit. If another circuit is being appended, itsKey
s andResults
s cannot conflict with this circuit’s keys or results. Dictionaries are automatically converted to cycles.
- prepend(cycles_or_circuit)
Prepends one or more
Cycle
s or anotherCircuit
to this circuit. If another circuit is being prepended, itsKey
s andResults
s cannot conflict with this circuit’s keys or results. Dictionaries are automatically converted to cycles.
- property meas_locs
Returns a list of the locations of all measurements in the Circuit.
The ordering of this list is the same as the expected bit-string order in the circuit’s
Results
s.The order of measurements is decided first by the index of the cycle, e.g.: measurements placed in the first cycle of a circuit are returned before measurements in later cycles. Then the order inside of a cycle is decided by the label on which the measurement is placed, e.g.: measurements placed on label
(0,)
comes before label(5,)
The returned list contains tuples, where the first entry of tuple is the cycle index, and the second entry of the tuple is the label the measurement is on.
import trueq as tq # (Cycle 0: measure qubit 0), (Cycle 1: measure qubits 1 and 5) circ = tq.Circuit([{(0,): tq.Meas()}, {(5,): tq.Meas(), (1,): tq.Meas()}]) # meas_locs returns locations of measurements in the form (cycle, qubit) circ.meas_locs
[(0, 0), (1, 1), (1, 5)]
- Type:
list
oftuple
- property n_meas
The total number of measurement operations in the circuit.
- Type:
int
- draw(interactive=True, filename=None)
Draws the circuit as an SVG. If a filename is provided, writes the SVG to the file.
import trueq as tq # Make an example SRB circuit circuit = tq.make_srb([[0, 5], [1, 2], 3, 4], [3], 1)[0] circuit.draw()
- Parameters:
interactive (
bool
) – Determines if the SVG will be interactive or not.filename (
str
) – A filename to write the SVG output to.
- Return type:
- get_probability(outcome, rcal_data=None, labels=None)
Computes the probabilities of the circuit returning specified ditstrings. The ditstrings are adjusted by the
'compiled_pauli'
(assumed to be identity by default) and'measurement_basis'
(assumed to be all"Z"
by default) of the circuit. These probabilities can be corrected using readout correction data of a given circuit collection. The probabilities of subsystems of the circuits can be calculated by specifying a subset of the labels of the circuit.import trueq as tq # generate a circuit collection and gather readout calibration data rcal_data = tq.make_rcal([0, 1]) sim = tq.Simulator().add_readout_error(0.2) sim.run(rcal_data, n_shots=10000) # define and run the circuit of interest circ = tq.Circuit([{(0,): tq.Gate.x}, {(0, 1): tq.Meas()}]) sim.run(circ, n_shots=1000) # return the probability of an outcome circ.get_probability("10", rcal_data)
array([1.00342234])
- Parameters:
outcome (
Iterable
) – A list of outcomes, e.g.["00", "11"]
, to be estimated. For advanced usage, a list of mixed outcomes and observables, e.g.["0W01", "XY"]
, may be specified to estimate expectation values. Each of the observables should be compatible with this circuit’s'measurement_basis'
, e.g. by default we can estimate"Z"
but not"X"
or"Y"
on a single qubit.rcal_data (
CircuitCollection
) – A circuit collection containing readout calibration circuits used to correct probabilities. By default, this circuit collection is empty. If the circuit collection does not contain compatible readout calibration data, the raw probability will be returned.labels (
Iterable
) – The labels of the circuit of which to return the probability. By default, this targets all labels of a circuit.
- Returns:
The corrected probability of obtaining
outcome
.- Return type:
numpy.ndarray
- same_structure(other)
Determines if this circuit has the same structure as the other circuit, that is if it is identical to another circuit except for the parameters of any
NativeGate
s. See alsosame_structure()
.For example:
import trueq as tq import trueq.compilation as tqc # create a Compiler passes = ( tq.Compiler.NATIVE2Q_PASSES + tq.Compiler.RC_PASSES + tq.Compiler.HARDWARE_PASSES ) compiler = tq.Compiler.basic(entangler=tq.Gate.cz, passes=passes) # define and randomly compile a circuit of interest circuit = tq.Circuit([{0: tq.Gate.h}, {(0, 1): tq.Gate.cx}]).measure_all() rc_circuit1 = compiler.compile(circuit) rc_circuit2 = compiler.compile(circuit) # the two instances of the randomly compiled circuit have the same structure # but are not necessarily equal assert rc_circuit1.same_structure(rc_circuit2)
- Parameters:
other (
Circuit
) – Another circuit to compare to.- Return type:
bool
- to_dict(include_cycles=True)
Returns a dictionary representation of a
Circuit
object. This dictionary representation contains only base Python classes.- Parameters:
include_cycles (
bool
) – Whether to include the cycles in the dictionary representation.- Return type:
dict
- static from_dict(dic)
Returns a
Circuit
constructed from a dictionary representation.- Parameters:
dic (
dict
) – The dictionary representation of the circuit.- Return type:
- to_cirq(metadata=None, passes=None, device=None, join_meas=True)
Converts a
Circuit
into acirq.Circuit
.import trueq as tq # A round trip, to cirq and back circ = tq.Circuit([{(0, 1): tq.Gate.cx}]) cirq_circ = tq.interface.cirq.from_trueq_circ(circ) cirq_circ.to_trueq().draw()
0 1 Key: 1 Labels: (0, 1) Name: Gate.cx Aliases: Gate.cx Gate.cnot Locally Equivalent: CNOT Generators: ZX: -90.00 IX: 90.00 ZI: 90.00 1.00 1.00 1.00 1.00 CX CX Note
By default, arbitrary single-qubit operations are decomposed using the
ZXZ
QubitMode
by default. This may be changed by setting the config to have another mode.If a gate is provided which is not directly equivalent to a single gate in
get_config()
, it is decomposed using theCompiler
.See also
pair_from_trueq_circ
.- Parameters:
circuit (
Circuit
) – The True-Q™ circuit to be converted into a Cirq circuit.metadata (
CirqMetadata
) – Metadata required to accurately reproduce the original Cirq circuit. If this is not provided, measurements are added at the end of the circuit.passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.device (
None
orcirq.Device
) – Acirq.Device
, if no device is provided, an unconstrained device withcirq.GridQubit
is assumed.join_meas (
bool
) – This determines ifMeas
are joined into singlecirq.meas()
objects, or single meas object in parallel in the given moment/cycle.
- Return type:
cirq.Circuit
- to_pyquil(metadata=None, passes=None)
Converts a
Circuit
into apyquil.Program
.import pyquil import trueq as tq circ = tq.Circuit([{(0, 1): tq.Gate.cx}]) ext_circ = tq.interface.pyquil.from_trueq_circ(circ) ext_circ.to_trueq().draw()
0 1 Key: Labels: (0, 1) Name: CNOT Aliases: Gate.cx Gate.cnot Parameters: Locally Equivalent: CNOT Generators: ZX: -90.00 IX: 90.00 ZI: 90.00 1.00 1.00 1.00 1.00 CX CX See also
pair_from_trueq_circ()
.Note
Arbitrary single-qubit operations are decomposed using the
ZXZXZ
QubitMode
by default.If an SU(4) gate is provided which is not directly equivalent to a single gate in
default_config()
, it is decomposed using theCompiler()
.- Parameters:
circ (
Circuit
) – The True-Q™ circuit to be converted into a PyQuil Program.metadata (
PyQuilMetadata
|NoneType
) – Metadata required to accurately reproduce the original PyQuil program. If no metadata is provided, measurements are read into a classical register namedro
.passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
pyquil.Program
- to_qasm(custom_header=None, include_auto_header=True, passes=None)
Converts a
Circuit
into a QASM 2.0 text string.Circuits converted to QASM will use the gate definitions found in the
get_config()
. These definitions will by default be included at the top of the output QASM file (this behavior can be disabled by settinginclude_auto_header=False
). Additional lines in the header can be included by providing a list of strings tocustom_header
, which will be appended as new lines at the top of the file.See also
pair_from_trueq_circ
.Note
Barriers are added into the QASM string when there is a marker change between two sequential
Cycle
s.- Parameters:
circuit (
Circuit
) – The circuit to be converted to QASM.custom_header (
list
) – A list of strings which will be put at the top of the file, with each string being placed on a seperate line.include_auto_header (
bool
) – If theget_config
is not the qelib1 config, then QASM requires all gates present to be written as combinations ofU3
andCNOT
gates (see the docs forQASM
, for more details), this flag determines if these definitions should be included in the header of the QASM file.passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
str
- to_qiskit(metadata=None, passes=None)
Converts a
Circuit
into anqiskit.circuit.quantumcircuit.QuantumCircuit
.See also
pair_from_trueq_circ
.- Parameters:
metadata (
QiskitMetadata
) – Metadata required to accurately reproduce the original Qiskit circuit.passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
qiskit.circuit.quantumcircuit.QuantumCircuit
Circuit Collection
- class trueq.CircuitCollection(circuits=None)
Represents a collection of instances of
Circuit
.- Parameters:
circuits (
list
|Circuit
) – Alist
ofCircuit
s, or a singleCircuit
to initially populate this collection with, orNone
.
- property dim
The dimension of each subsystem, e.g.
2
if the circuits in this collection act on qubits. This property is inherited from its circuits. If this collection contains no circuits, thenNone
.- Type:
int
|NoneType
- append(circuit)
Appends one or more
Circuit
s to the collection.- Parameters:
circuit (
Circuit
|Iterable
) – An instance ofCircuit
, or any iterable ofCircuit
objects (including anotherCircuitCollection
).- Returns:
This circuit collection.
- Return type:
- Raises:
ValueError – If the dimension of the circuits to be appended is not compatible with the dimension of the collection.
- shuffle()
Randomly shuffles the order of the
Circuit
s contained in this circuit collection in-place.
- property n_results
The number of experimental
Circuit
s that have been populated with results, an integer between \(0\) andn_circuits
.- Type:
int
- property has_no_results
Whether none of the experimental
Circuit
's have been populated with data.- Type:
bool
- property has_some_results
Whether at least one of the experimental
Circuit
s have been populated with data.- Type:
bool
- property has_all_results
Whether all of the experimental
Circuit
s have been populated with data.- Type:
bool
- save(filename, overwrite=False, include_cycles=True)
Saves this collection to disk in a binary format, including all results. This collection can be reinstantiated at a later time using
trueq.utils.load()
.import trueq as tq circuits = tq.make_srb([0], [4, 20]) tq.Simulator().add_depolarizing(0.01).run(circuits) # save into a temporary folder for this example with tq.utils.temp_folder(): # the extension .tq is arbitrary but recommended circuits.save("my_circuits1.tq") # save discarding all cycle/gate information for a smaller file size circuits.save("my_circuits2.tq", include_cycles=False)
- Parameters:
filename (
str
) – A filename to save the circuit collection as.overwrite (
bool
) – Any existing file will be overwritten if this isTrue
, else saving will raiseFileExistsError
include_cycles (
bool
) – Whether the cycle information in each circuit should be retained. If false, then all circuits will have their cycles stripped in the saved version to save space. Results and other information will be saved so that analysis and plotting will work on a reinstantiated copy.
- fit(labels=None, *, analyze_dim=None, observables=[])
Fits all applicable data found and returns all estimates as an
EstimateCollection
.Fits for a subset of data can be obtained by calling
fit()
on a reducedCircuitCollection
by usingsubset()
:import trueq as tq # make a circuit collection of SRB and XRB circuits circuits = tq.make_srb([[0], [1, 2]], [4, 32]) circuits += tq.make_xrb([[0], [1, 2]], [4, 32]) # run the circuits on a noisy simulator tq.Simulator().add_overrotation(0.04).run(circuits) # fit the results for just SRB circuits.subset(protocol="SRB").fit()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".SRBStreamlined Randomized BenchmarkingCliffords (0,)- Key:
-
- labels: (0,)
- protocol: SRB
- twirl: Cliffords on [0, (1, 2)]
Cliffords (1, 2)- Key:
-
- labels: (1, 2)
- protocol: SRB
- twirl: Cliffords on [0, (1, 2)]
${e}_{F}$The probability of an error acting on the targeted systems during a random gate.3.4e-03 (9.2e-04) 0.0033963605007063524, 0.00091542216818291530.0e+00 (0.0e+00) 0.0, 0.0${p}$Decay parameter of the exponential decay $Ap^m$.1.0e+00 (1.2e-03) 0.9954715193323915, 0.00122056289091055381.0e+00 (0.0e+00) 1.0, 0.0${A}$SPAM parameter of the exponential decay $Ap^m$.9.9e-01 (9.4e-03) 0.9898078819384848, 0.0093836365215123641.0e+00 (0.0e+00) 1.0, 0.0Many protocols have well defined fits for a strict subset of qubits that the protocol was invoked on. For example, if cycle benchmarking acts on a 10 qubit cycle, fitting 6 of these ten qubits returns a valid estimate of the infidelity on those qubits in the context of the entire cycle. The optional argument
labels
allows you to customize such subsets of labels.Certain analysis routines allow optional parameters, see Optional Fitting Arguments.
- Parameters:
labels (
NoneType
|Iterable
) – A list of lists of qubit labels; fits will be produced on each subset. For convenience, isolated labels are treated as a list of length 1, for example,labels = [[0], [1], [2]]
is equivalent tolabels = [0, 1, 2]
. If no labels are provided (None
), they are generated automatically on a protocol-by-protocol basis.analyze_dim (
NoneType
) – A small prime to be used as the qudit dimension during analysis. This can be used to account for leakage levels.observables (
list
) – A list of strings that specify the observables to compute expectation values of. The supported observables include computational basis states, e.g.'000'
, and Pauli/Weyl operators, e.g.'ZIZ'
for qubits or'W01W02W00'
for qudits.
- Return type:
- property plot
An object that stores all plotting functions deemed relevant to this
CircuitCollection
. If one of these functions is called, the data from this circuit collection is analyzed and used.Note
If there is a plotting function that you expected to be present but is not, double check the circuit’s
Key
s to see which types of circuits are present, and also verify that circuits relevant to the plot you want haveresults
entered.- Type:
- batch(max_size, extra_circuits=None, sequencer=None)
Divides the circuits in this collection into a series of batches that are limited in size. This is useful if, for example, your hardware has a finite amount of memory to store circuits with. For this example, we will use True-Q™’s built-in simulator in place of a physical device. In practice, this can be used to batch jobs for submission to hardware, using the modifications suggested in the comments below.
import trueq as tq import trueq.sequencer as tqs # make a bunch of circuits circuits = tq.make_crosstalk_diagnostics([0, 1, 2], [4, 70]) # initialize a simulator to stand in for a physical device my_device = tq.Simulator() # Split collection into batches such that there are no more than 80 # circuits in each batch. For a hardware device, the method run() should be # replaced with a method which runs circuits on the device and returns the # results for each member of the batch, and the content of this for loop # would become batch.results = my_device.run(batch) to set the results # parameter of batch to the returned results. for batch in circuits.batch(80): my_device.run(batch) # we can also set batch size by total number of cycles or gates circuits.batch(tqs.NCycles(1000)) circuits.batch(tqs.NGates(1e6)) # We can riffle the circuits by sequence length. Running on a device, we # again replace the contents of this for loop with # batch.results = my_device.run(batch) to save the results to the circuit for batch in circuits.batch(80, sequencer=tqs.RIFFLER): my_device.run(batch, overwrite=True)
The batcher also supports automatically adding a fixed set of circuits to each batch. For example, we can add readout calibration circuits to each batch:
import trueq as tq circuits = tq.make_crosstalk_diagnostics([0, 1, 2], [4, 70]) ro_circuits = tq.make_rcal([0, 1, 2]) # Initialize a simulator to stand in for a physical device. In practice, all # instances of my_device.run(batch) should be replaced with # batch.results = my_device.run_on_device(batch) for a device called # my_device with a function run_on_device() which runs circuits on hardware # and returns the results. my_device = tq.Simulator() for batch in circuits.batch(80, extra_circuits=ro_circuits): my_device.run(batch)
- Parameters:
max_size (
int
|list
|CircuitRuler
) – The maximum number of circuits per batch, or anyCircuitRuler
such asNCycles
, py:class:~trueq.sequencer.Gates, or py:class:~trueq.sequencer.TotalTime. You can also specify a list ofCircuitRuler
s; every batch will not surpass any of the rulers’ limits.extra_circuits (
CircuitCollection
) – A list of circuits to be placed at the start of every batch. Copies are made of these circuits in every batch.sequencer (
CircuitSequencer
) – Specifies how the circuits should be ordered when batching. This is useful, for example, if you want to riffle long circuits with short sequences within a batch, so that all of your long circuits don’t end up in the same batch, seetrueq.sequencer.RIFFLER
. If no sequencer is given, the existing circuit collection order is used.
- Returns:
A generator of
CircuitCollection
s.- Return type:
generator
- copy(keep_results=True)
Returns a copy of this circuit collection, where each circuit is copied using
Circuit.copy()
. Mutating the new or old circuit collection does not affect the other circuit collection or its circuits.- Parameters:
keep_results – Whether each circuit’s copy should include a copy of its
results
. IfFalse
, the copied circuits will have no results.keep_results –
bool
- Return type:
- keys(**filter)
Returns a
KeySet
of unique keys in thisCircuitCollection
that match the given name/values present in the filter.- Parameters:
**filter – Key/value pairs to be used as a filter.
- Return type:
- similar_keys(*names, invert=False, **filter)
Returns a
generator
over disjointKeySet
s, where all of the keys in each set have equal values for all names appearing in the given names, and have any specific values specified in filter.import trueq as tq circuits = tq.make_srb([0], [4, 10, 50], 30) print("Grouping keys based on matching 'protocol': ") for keys in circuits.similar_keys("protocol"): print(keys) print("\nGrouping keys based on 'protocol' and 'n_random_cycles': ") for keys in circuits.similar_keys("protocol", "n_random_cycles"): print(keys)
Grouping keys based on matching 'protocol': KeySet( Key(compiled_pauli=Weyls('I'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Z'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Y'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Y'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Z'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('X'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('X'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('I'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Y'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('I'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Z'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('X'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2))) Grouping keys based on 'protocol' and 'n_random_cycles': KeySet( Key(compiled_pauli=Weyls('X'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Y'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('I'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Z'), measurement_basis=Weyls('Z'), n_random_cycles=4, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2))) KeySet( Key(compiled_pauli=Weyls('Z'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Y'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('X'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('I'), measurement_basis=Weyls('Z'), n_random_cycles=50, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2))) KeySet( Key(compiled_pauli=Weyls('Z'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('Y'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('X'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)), Key(compiled_pauli=Weyls('I'), measurement_basis=Weyls('Z'), n_random_cycles=10, protocol='SRB', twirl=Twirl({(0,): 'C'}, dim=2)))
- Parameters:
names (
list
) – An iterable of key names.invert (
bool
) – Whether the list of names to use should be those presented, or all names execpt those presented.**filter – Key/value pairs to be used as a filter.
- Return type:
generator
- update_keys(*other, keep=None, remove=None, **kwargs)
Updates every circuit’s
key
in this collection with new keywords/values. If a given key does not have a given keyword, it is added. If it already exists, it is overwritten. See alsocopy()
which this method uses.import trueq as tq circuits = tq.make_srb(0, [4, 10]) # give each circuit a new keyword 'banana' with value 10 circuits.update_keys(banana=10) # change 'n_random_cycles' to 5 for those circuits where it is 4 circuits.subset(n_random_cycles=4).update_keys(n_random_cycles=5) circuits.keys()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".KeySetList of all the keys in the KeySetprotocol The characterization protocol used to generate a circuit.twirl The twirling group used to generate a circuit.n_random_cycles The number of independent random cycles in the circuit.compiled_pauli The n-qubit Pauli operator that was compiled into the circuit immediately before measurement.measurement_basis An n-qubit Pauli operator describing the change-of-basis gates added prior to measurement.banana Key- Key:
-
- banana: 10
- compiled_pauli: Z
- measurement_basis: Z
- n_random_cycles: 5
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 5 Z Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: Y
- measurement_basis: Z
- n_random_cycles: 5
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 5 Y Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: X
- measurement_basis: Z
- n_random_cycles: 5
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 5 X Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: I
- measurement_basis: Z
- n_random_cycles: 5
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 5 I Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: I
- measurement_basis: Z
- n_random_cycles: 10
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 10 I Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: Y
- measurement_basis: Z
- n_random_cycles: 10
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 10 Y Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: Z
- measurement_basis: Z
- n_random_cycles: 10
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 10 Z Z 10 Key- Key:
-
- banana: 10
- compiled_pauli: X
- measurement_basis: Z
- n_random_cycles: 10
- protocol: SRB
- twirl: Cliffords on [0]
SRB Cliffords on [0] 10 X Z 10 - Parameters:
other (
Key
|dict
) – One or more dict-like objects to update the keys with. Updating is applied in the given order. If a name specified in any of these objects already exists after thekeep
orremove
process has taken place, it is updated.keep (
str
|list
) – A string or list of strings specifying the only names to keep during the updates. By default, all names are kept. Only one of the optionskeep
orremove
may be used.remove (
str
|list
) – A string or list of strings specifying names to remove during the updates. By default, no names are removed. Only one of the optionskeep
orremove
may be used.**kwargs – Name-value items to update the keys with. If a name specified here already exists after the
keep
orremove
process has taken place, it is updated.
- Returns:
This circuit collection.
- Return type:
- Raises:
ValueError – If the mutally exclusive
keep
andremove
are both set toTrue
.
- subset(has_results=None, new_collection=True, **filter)
Selects a subset of this collection’s
Circuit
s by matching against a filter. This returns a newCircuitCollection
, with references to the original circuits, i.e. no circuit copies are made. Optionally, by using thenew_collection
flag, the output type can be a generator over circuits that match the filter rather than a new collection object.import trueq as tq circuits = tq.make_srb([0], [4, 32]) circuits.append(tq.make_rcal([0])) # make a new CircuitCollection with only the SRB circuits from the # CircuitCollection defined above srb_circuits = circuits.subset(protocol="SRB") assert srb_circuits.keys().protocol == {"SRB"} # loop over circuits with no results # for efficiency, use new_collection=False to avoid new instantiation for circuit in circuits.subset(has_results=False, new_collection=False): circuit.results = {"0": 1}
- Parameters:
has_results (
NoneType
|bool
) – Whether to filter on circuits which have or do not have results entered. IfTrue
, only circuits with results are included, ifFalse
, only circuits without results are included, and ifNone
(default) all circuits are included.new_collection (
bool
) – Whether to create a newCircuitCollection
and return it. Otherwise, a generator over circuits will be returned, which saves memory.**filter – Key/value pairs to be used as a filter.
- Return type:
generator
|CircuitCollection
- to_dict_list(include_cycles=True)
Returns a list of dictionary representations of the
Circuit
objects in this collection.- Parameters:
include_cycles (
bool
) – Whether to include the cycles in the dictionary representations.- Return type:
list
- static from_dict_list(lst)
Returns a
CircuitCollection
constructed from a list of dictionary representations oftrueq.Circuit
s.- Return type:
- batch_size(ruler)
The size of this collection according to the given method of counting circuit size. For example,
NCycles
,NGates
, orTotalTime
.- Parameters:
ruler (
CircuitRuler
) – A callable that returns the size of a given circuit.- Return type:
int
- property results
A list of the
Results
for every circuit in this collection, where the order of this list matches the order of this collection. This property is also settable, seeCircuit.results
for allowed formats for setting.import trueq as tq circuits = tq.make_srb([0], [4, 100]) print("Circuits start with empty results initially:") print(circuits.results[:5]) # set all results to the same value circuits.results = [{"0": 10, "1": 100}] * len(circuits) print("\nAfter setting the results:") circuits.results[:5]
Circuits start with empty results initially: [Results({}, dim=None), Results({}, dim=None), Results({}, dim=None), Results({}, dim=None), Results({}, dim=None)] After setting the results:
[Results({'0': 10, '1': 100}), Results({'0': 10, '1': 100}), Results({'0': 10, '1': 100}), Results({'0': 10, '1': 100}), Results({'0': 10, '1': 100})]
- Type:
list
- sum_results(decompile_paulis=True, **filter)
Sums together all results in the collection that match the given filter.
import trueq as tq circuits = tq.make_srb([0], [4, 100]) circuits.append(tq.make_xrb([0], [4, 100])) tq.Simulator().add_overrotation(0.05).run(circuits, n_shots=10) print("Sum of all results in the circuit collection:") print(circuits.sum_results()) print("\nTotal number of shots ran for the XRB protocol:") print(circuits.sum_results(protocol="XRB").n_shots) print("\nSum of results where `n_random_cycles=4`:") print(circuits.sum_results(n_random_cycles=4).n_shots)
Sum of all results in the circuit collection: Results({'0': 1406, '1': 994}) Total number of shots ran for the XRB protocol: 1800 Sum of results where `n_random_cycles=4`: 1200
- Parameters:
decompile_paulis (
bool
) – Whether to adjust ditstrings of each circuit’s results by the'compiled_pauli'
key value of the corresponding circuit when summing. In most cases, and especially for randomized compiling, this value should beTrue
.**filter – Key/value pairs to be used as a filter.
- Returns:
The sum of all results.
- Return type: