Compilation
Relabels a |
|
Decomposes gates by applying the |
|
Pass which adds randomly-chosen Pauli gates before all measurements in the circuit. |
|
Performs optimal decomposition of two-qubit gates into 0, 1, 2, or 3 CPHASE gates, defined below. |
|
Combines the |
|
Pass that searches |
|
Inserts swaps and decomposes gates of a |
|
A pass which ensures that any |
|
Pass that moves operations forward in time. |
|
Pass that marks cycles which contain multi-qubit gates if none of the existing non-measurement cycles in the circuit have been marked with non-zero values. |
|
Pass that marks cycles which contain multi-qubit gates if none of the existing cycles in the circuit have been marked with non-zero values. |
|
Pass that takes a list of cycles, finds compatabile labels and gates, and merges them to a single gate as much as is possible. |
|
A |
|
An |
|
An |
|
A |
|
An |
|
An |
|
An |
|
An |
|
A pass which decomposes cycles of arbitrary single-qudit gates into alternations of cycles of native gates with diagonal gates. |
|
A |
|
Tracks phase accumulation on each qubit throughout a circuit, and compiles this phase information into parametric gates. |
|
Pass which performs Randomized Compilation (RC) on groups of cycles with matching marker values by adding gates on either side of the cycles, chosen using the provided |
|
Pass which performs Randomized Compilation (RC) on cycles with non-zero markers. |
|
Pass which performs Randomized Compilation (RC) on groups of cycles with matching marker values by adding gates on either side of the cycles. |
|
Pass which relabels all the labels and keys in a |
|
Pass that remarks all the marked cycles. |
|
Pass which removes empty cycles from groups of cycles with matching markers. |
|
Pass that removes single qubit identity gates from one |
|
An |
|
Pass which sets all cycle markers to |
|
Performs optimal decomposition of two-qubit gates into 0, 1, 2, or 3 XY gates, defined below. |
|
Parent class for compiler passes which operates on groups of cycles with matching markers. |
|
Parent class for compiler passes which accept a fixed number of cycles at a time. |
|
Parent class used by |
|
Parent class for all |
|
Abstract base for classes that hold properties about a gate that are relevant to particular decomposition strategies. |
|
Stores the KAK decomposition of a |
|
|
Mixin for decomposition strategies that use a single |
Abstract parent classes that are able to provide a cost heuristic for decomposing gates in terms of other gates, and that also perform the decomposition when requested. |
|
Iterates through a |
|
Decomposes a |
|
Decomposes the provided |
Base Classes
- class trueq.compilation.Compiler(passes)
Substitutes cycles in a
Circuit
using a series ofPass
es.In classical computing this would formally be called a Peephole Optimizer.
An instance of this class stores a list of
Pass
objects which define rules for how to decompose, replace, or removeGate
s (or more generally,Operation
s), while possibly also adding or removing cycles.A simple example is the
RemoveId
pass, which accepts 1 cycle at a time, and removes any identity gates from the cycle, before returning it.In general building a compiler which knows all possible simplification rules would result in an overly complex and rigid tool, and would be difficult to generalize for all hardware implementations. By making the compiler itself very small, and allowing custom rules (passes in this case), very complex compilation instructions can be expressed in a simple and readable fashion.
Each
Pass
object iterates through a circuit in its own way; in the example above, the circuit is iterated over 1 cycle at a time. In general, passes operate on collections of cycles at a time, up to the entire circuit at once. There are two pre-builtPass
child classes which define common methods for iterating over a circuit:NCyclePass
Iterates over a fixed
N
cycles at a time, the majority of default passes are subclassed off of this.
MarkerPass
Iterates over groups of cycles with matching markers.
An example of iteration is merging multiple single qubit gates into a single operation (which is done by the
Merge
pass). This requires multiple cycles to be operated on at any given time, in this case this operation can be performed with a fixed number (2) of cycles at a time. The pass looks for single qubit gates in both of the cycles, and computes the single equivalentGate
, which is put back instead of the two original gates.Here is an example of a set of passes which converts a circuit of
Gate
s into a circuit ofNativeGate
s as defined in aConfig
:from trueq.compilation import * import trueq as tq factories = tq.Config.basic().factories Compiler( [ Justify(), Native2Q(factories=factories), Merge(), RemoveId(), Native1Q(factories=factories), Justify(), ] )
Compiler([Justify, Native2Q, Merge, RemoveId, Native1Q, Justify])
This set of passes performs these operations:
Justify
Move gates preferentially to one side of the circuit. For example, if a circuit contains an
X90
gate at the beginning and 10 empty cycles,Justify
would move theX90
gate to the end of the circuit.Native2Q
Convert all two qubit operations found in the circuit into
NativeGate
s which can be run on hardware as specified by the config object. This pass does NOT decompose the single qubit gates, so in the process it adds single qubit gate objects to some cycles.Merge
This simplifies any neighboring single qubit operations and reduces them to a single gate. Changing the default settings can enable it to merge multi-qubit gates together as well.
RemoveId
Since the merge step may have introduced single qubit gates which could be identity gates, this pass removes all identity gates.
Native1Q
This converts all one-qubit operations into
NativeGate
s which can be run on hardware as specified by the config object.Justify
To leave everything in the ground state for as long as possible, this pass ensures everything is moved as far forward in the circuit as possible.
- Parameters:
passes (
list
) – A list ofPass
es, see above.
- compile(circ)
Sequentially applies all of the passes in the compiler to a given
Circuit
orCircuitCollection
, a newCircuit
orCircuitCollection
instance is returned.import trueq as tq # make a simple one-qubit circuit with four X gates circuit = tq.Circuit([{0: tq.Gate.x}] * 4) # Create a compiler with a Merge pass compiler = tq.Compiler([tq.compilation.Merge()]) # this compiler will merge all four X gates into a single # identity operation compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
- Parameters:
circ (
Circuit
|CircuitCollection
) – A circuit that the pass list should be applied to.- Return type:
- static from_config(config, passes=None)
Gets a
Compiler
which can transpile from arbitrary True-Q™ representation of circuits, into a representation which is compatible with a given config.By default, this performs a standard set of passes to make the circuit compatible with hardware while making the minimum required changes, and can be used as a template for more advanced compiler definitions. See
trueq.compilation.Compiler.HARDWARE_PASSES
for a list of the default passes which are applied.Several other lists of compiler passes are predefined in the compiler. In the example below several of these predefined compiler lists are chained together to randomly compile a circuit containing non-clifford two qubit gates.
import trueq as tq # define the config which defines hardware gates config = tq.Config.basic(mode="ZXZ", entangler=tq.Gate.cnot) # Pick the compiler passes to apply in the specified order. The order below # will decompose the two qubit gates into the two qubit gates specified in # the config (which contains clifford entanglers), then randomly compile, # then convert all gates into hardware compatable gates. passes = ( tq.Compiler.NATIVE2Q_PASSES + tq.Compiler.RC_PASSES + tq.Compiler.HARDWARE_PASSES ) compiler = tq.Compiler.from_config(config, passes=passes) # Build the circuit to apply the passes to circ = tq.Circuit() circ.append({0: tq.Gate.h}) circ.append({(0, 1): tq.Gate.cnot**0.5}) circ.measure_all() compiler.compile(circ)
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".Circuit- Key:
-
- compiled_pauli: YX
- protocol: RC
- twirl: Paulis on [0, 1]
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.z
- Gate.cliff3
- Parameters:
-
- phi = 180.0
- Generators:
-
- 'Z': 180.0
- Matrix:
-
(1): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.z
- Gate.cliff3
- Parameters:
-
- phi = 180.0
- Generators:
-
- 'Z': 180.0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): x(phi)- Name:
-
- x(phi)
- Parameters:
-
- phi = 136.416451
- Generators:
-
- 'X': 136.416
- Matrix:
-
(1): x(phi)- Name:
-
- x(phi)
- Parameters:
-
- phi = 58.715191
- Generators:
-
- 'X': 58.715
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Parameters:
-
- phi = -0.0
- Generators:
-
- 'I': 0
- Matrix:
-
(1): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Parameters:
-
- phi = -0.0
- Generators:
-
- 'I': 0
- Matrix:
-
2- Marker 2
Compilation tools may only recompile cycles with equal markers.(0, 1): cx()- Name:
-
- cx()
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Parameters:
-
- phi = -0.0
- Generators:
-
- 'I': 0
- Matrix:
-
(1): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Parameters:
-
- phi = -0.0
- Generators:
-
- 'I': 0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): x(phi)- Name:
-
- x(phi)
- Parameters:
-
- phi = 135.0
- Generators:
-
- 'X': 135.0
- Matrix:
-
(1): x(phi)- Name:
-
- x(phi)
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Parameters:
-
- phi = 90.0
- Generators:
-
- 'X': 90.0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.cliff8
- Parameters:
-
- phi = -90.0
- Generators:
-
- 'Z': -90.0
- Matrix:
-
(1): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Parameters:
-
- phi = -0.0
- Generators:
-
- 'I': 0
- Matrix:
-
3- Marker 3
Compilation tools may only recompile cycles with equal markers.(0, 1): cx()- Name:
-
- cx()
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.z
- Gate.cliff3
- Parameters:
-
- phi = 180.0
- Generators:
-
- 'Z': 180.0
- Matrix:
-
(1): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Parameters:
-
- phi = -0.0
- Generators:
-
- 'I': 0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): x(phi)- Name:
-
- x(phi)
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Parameters:
-
- phi = 90.0
- Generators:
-
- 'X': 90.0
- Matrix:
-
(1): x(phi)- Name:
-
- x(phi)
- Parameters:
-
- phi = 166.284809
- Generators:
-
- 'X': 166.285
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): z(phi)- Name:
-
- z(phi)
- Parameters:
-
- phi = -91.416451
- Generators:
-
- 'Z': -91.416
- Matrix:
-
(1): z(phi)- Name:
-
- z(phi)
- Aliases:
-
- Gate.z
- Gate.cliff3
- Parameters:
-
- phi = 180.0
- Generators:
-
- 'Z': 180.0
- Matrix:
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0): Meas()- Name:
-
- Meas()
(1): Meas()- Name:
-
- Meas()
- Parameters:
config (
trueq.Config
) – Atrueq.Config
which has 2-qubit gates defined.passes (
tuple
|NoneType
) – A tuple oftrueq.compilation.base.Pass
to be applied in order. These must be uninstantiated classes which must acceptfactories
as a keyword argument, seetrueq.compilation.Compiler.HARDWARE_PASSES
for an example. IfNone
is provided, then the default list is used.
- Return type:
- static basic(entangler=Gate.cx, mode='ZXZXZ', passes=None)
Gets a
Compiler
which is built from a standardConfig
.By default, this performs a standard set of passes, and a config as defined by
trueq.Config.basic()
. Seetrueq.compilation.Compiler.HARDWARE_PASSES
for a list of the default passes which are applied.- Parameters:
entangler (
trueq.Gate
) – A two-qubit gate.mode (
str
) – The single qubit decomposition mode, defaults to'ZXZXZ'
, seetrueq.math.decomposition.QubitMode
for more details.passes (
tuple
|NoneType
) – A tuple oftrueq.compilation.base.Pass
to be applied in order. These must be uninstantiated classes which must acceptfactories
as a keyword argument, seetrueq.compilation.Compiler.HARDWARE_PASSES
for an example. IfNone
is provided, then the default list is used.
- Return type:
- HARDWARE_PASSES = (<class 'trueq.compilation.two_qubit.Native2Q'>, <class 'trueq.compilation.common.Merge'>, <class 'trueq.compilation.one_qubit.Native1Q'>, <class 'trueq.compilation.common.InvolvingRestrictions'>, <class 'trueq.compilation.common.RemoveEmptyCycle'>)
A tuple of compiler passes which decompose all gates into hardware restricted gates while only introducing the minimum number of structural changes to the circuit.
Identity gates are not removed, and are instead compiled into available gates.
Changing this default list changes the behavior of the interfaces to Qiskit, Cirq, and PyQuil, and altering it may break the interface conversions completely.
- SIMPLIFY_PASSES = (functools.partial(<class 'trueq.compilation.common.Merge'>, max_sys=2), <class 'trueq.compilation.common.RemoveId'>, <class 'trueq.compilation.common.Justify'>, <class 'trueq.compilation.common.RemoveEmptyCycle'>)
A set of compiler passes that merge single/two qubit gates, remove identity gates, and remove empty cycles.
Compiler passes obey
marker
s, meaning simplifications will only happen when neighboring cycles have matching markers.These passes do not build into
NativeGate
s.
- RC_PASSES = (<class 'trueq.compilation.common.MarkCycles'>, <class 'trueq.compilation.rc.RCCycle'>, <class 'trueq.compilation.common.CompilePaulis'>, <class 'trueq.compilation.common.Merge'>, <class 'trueq.compilation.common.RemoveEmptyCycle'>)
A tuple of compiler passes that randomly compile a circuit.
This is equivalent to
randomly_compile()
wheren_compilations=1
,twirl="P"
andcompile_paulis=True
. These passes do not introduce anyNativeGate
s.
- NATIVE2Q_PASSES = (<class 'trueq.compilation.two_qubit.Native2Q'>, <class 'trueq.compilation.common.Merge'>, <class 'trueq.compilation.common.RemoveEmptyCycle'>)
A tuple of compiler passes that decompose two-qubit gates into native gates, and merge all single qubit gates together.
Compiler passes obey
marker
s, so single-qubit gates (including those introduced byNative2Q
) will only be merged between neighboring cycles with matching markers.
- class trueq.compilation.base.MarkerPass(factories=None, **_)
Parent class for compiler passes which operates on groups of cycles with matching markers.
The
_apply()
method is implemented to invoke the new abstract method_apply_cycles()
on every consecutive list of cycles in the circuit with an equal marker.- abstract _apply_cycles(cycles)
Accepts any number of
Cycle
s and returns a list of cycles.Cycles returned by this function are put back into the original circuit in place of the cycles passed.
There is no restriction on the number of returned cycles.
- Parameters:
cycles (
list
) – A list ofCycle
s which are to be altered by this pass.- Return type:
list
- class trueq.compilation.base.NCyclePass(factories=None, **_)
Parent class for compiler passes which accept a fixed number of cycles at a time.
This is a convenience parent class which contains the logic of passing a fixed number of cycles
n_input_cycles
at a time to a child class defined method_apply_cycles()
, then taking the returned cycles and re-inserting them into a circuit.The
_apply()
method is implemented to invoke the new abstract method_apply_cycles()
on every consecutive list of cycles with length equal ton_input_cycles
, starting from the beginning of the circuit. At each invocation, the output of_apply_cycles()
is inserted into the circuit before calling it on the next subset of cycles. There is no restriction on the number cycles returned by implementations of_apply_cycles()
.To demonstrate how this class iterates over cycles, here is an implementation of a pass which takes two cycles at a time, prints the gates, and returns the cycles unaltered:
from trueq.compilation.base import NCyclePass from trueq import Gate class Passthrough(NCyclePass): n_input_cycles = 2 def _apply_cycles(self, cycles): print([gate for cycle in cycles for _, gate in cycle]) return cycles Passthrough().apply([{0: Gate.i}, {0: Gate.x}, {0: Gate.y}, {0: Gate.z}])
[Gate.id, Gate.x] [Gate.x, Gate.y] [Gate.y, Gate.z]
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.x- Name:
-
- Gate.x
- Aliases:
-
- Gate.x
- Gate.cliff1
- Generators:
-
- 'X': 180.0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.y- Name:
-
- Gate.y
- Aliases:
-
- Gate.y
- Gate.cliff2
- Generators:
-
- 'Y': 180.0
- Matrix:
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.z- Name:
-
- Gate.z
- Aliases:
-
- Gate.z
- Gate.cliff3
- Generators:
-
- 'Z': 180.0
- Matrix:
-
The circuit in this example has four cycles, each with a single gate. The first two cycles which are passed are the ones containing
I
andX
gates. These are printed, and get put back into the circuit without being altered. The pass then increments forward one index and passes the cycles containingX
andY
. It is important to note that this increments by one, notn_input_cycles
at a time.- abstract _apply_cycles(cycles)
Accepts
n_input_cycles
number ofCycle
s and returns a list of cycles.Cycles returned by this function are put back into the original circuit in place of the cycles passed.
There is no restriction on the number of returned cycles.
- Parameters:
cycles (
list
) – A list containingn_input_cycles
which are to be altered by this pass.- Return type:
list
- abstract property n_input_cycles
The number of cycles
_apply_cycles()
expects.- Type:
int
- class trueq.compilation.base.OperationReplacement
Parent class used by
Pass
es which manipulates a singleOperation
s at a time.The
apply()
accepts a label and operation, and returns a list containing dictionaries. This differs from aPass
in that it only operates on a single operation at a time, whereasPass
es operate on a cycles or circuits.- abstract apply(labels, operation)
Accepts labels and an
Operation
and returns a list of dictionaries, where the dictionary keys are labels and the values areOperation
s.The returned list may contain any number of dictionaries.
- Parameters:
labels (
tuple
) – A tuple containing the qubit labels which the operation acts on.operation (
trueq.Operation
) – The operation to be altered by the replacement.
- Returns:
A list of dictionaries, where the keys are labels, and the values are
trueq.Operation
s.- Return type:
list
- class trueq.compilation.base.Pass(factories=None, **_)
Parent class for all
Compiler
passes that manipulate and return an alteredCircuit
.A pass accepts a circuit to its
apply()
function. This circuit will then be operated on, and some (potentially new) circuit is returned.
Decomposition Strategy
- class trueq.compilation.decomposition_strategy.GateAttr
Abstract base for classes that hold properties about a gate that are relevant to particular decomposition strategies.
These properties may be expensive to compute, and this read-only container can serve as a shared resource.
- class trueq.compilation.decomposition_strategy.KakAttr(a, b, k)
Stores the KAK decomposition of a
Gate
.The KAK decomposition is relatively expensive compared to many compiler operations such as gate multiplication, and this read-only container can serve as a shared resource for the compiler.
The assertion in the following example defines the requirements of the decomposition. In particular the values of
x, y, z = k
are expected to be in degrees, not radians, and such that the correct core arises when passed tofrom_generators()
. Additionally, the Weyl chamber convention used should satisfy \(90 \geq x \geq y \geq |z|\) and \(z>0\) whenever \(x=90\).import trueq as tq g = tq.Gate.random(4) kak = tq.compilation.decomposition_strategy.KakAttr.from_gate(g) x, y, z = kak.k core = tq.Gate.from_generators("XX", x, "YY", y, "ZZ", z) assert g == (kak.a0 & kak.a1) @ core @ (kak.b0 & kak.b1)
- Parameters:
a (
tuple
) – The pair of single qubit gates on the left of the KAK decomposition.b (
tuple
) – The pair of single qubit gates on the right of the KAK decomposition.k (
numpy.ndarray
) – The three angles of the core of the KAK decomposition.
- property a
The pair of single qubit gates on the left of the KAK decomposition.
- Type:
tuple
- property b
The pair of single qubit gates on the right of the KAK decomposition.
- Type:
tuple
- property k_rad
The KAK core angles in radians, including an entry for the II element.
- Type:
numpy.ndarray
- property x_zero
Whether the XX component of the core is approximately zero.
- Type:
bool
- property y_zero
Whether the YY component of the core is approximately zero.
- Type:
bool
- property z_zero
Whether the ZZ component of the core is approximately zero.
- Type:
bool
- property xy_equal
Whether the XX and YY components of the core are approximately equal.
- Type:
bool
- property yz_equal
Whether the XX and ZZ components of the core are approximately equal.
- Type:
bool
- class trueq.compilation.decomposition_strategy.FactoryNoiseTopology(noise_topology, factory=None, scalings=None, special_cases=None)
Mixin for decomposition strategies that use a single
GateFactory
to produce entanglement, and that make use of a label-based cost function to quantify the quality of a decomposition.- Parameters:
noise_topology (
dict
) – A dictionary mapping label tuples to gate quality, which is a number in \([0, 1]\), where 0 indicates perfect quality.factory (
GateFactory
|NoneType
) – The factory used by this strategy.scalings (
list
|NoneType
) – A scaling factor for eachfactory
parameter in case it is equivalent toDEFAULT
up to some scalings. For example, if the default factory has a parameters in terms of degrees but the factory you want is in terms of radians, you can provide a scaling for each parameter to do this conversion.special_cases (
Iterable
) – An iterable ofGate
s and/or zero-parameterGateFactory
s that specify special values of the possibly-parametricfactory
that you may want to treat specially during circuit conversion or scheduling.
- DEFAULT: GateFactory
The default
GateFactory
to use if one is not provided during construction.
- property factory
The factory used by this strategy.
- Type:
- class trueq.compilation.decomposition_strategy.DecompStrategy
Abstract parent classes that are able to provide a cost heuristic for decomposing gates in terms of other gates, and that also perform the decomposition when requested.
- SPEC
The input type to
cost()
anddecompose()
that encapsulates gate properties that shouldn’t be computed more than once.alias of
GateAttr
- abstract cost(labels, gate_spec)
Estimates a cost for performing this kind of decomposition on the provided gate.
The cost is a number in \([0,1]\) where a small number indicates that this is a good strategy, and a value
1
indicates that it is impossible.
- class trueq.compilation.CPhaseStrategy(noise_topology, factory=None, scalings=None, special_cases=None)
Performs optimal decomposition of two-qubit gates into 0, 1, 2, or 3 CPHASE gates, defined below. See
FactoryNoiseTopology
for a description of the constructor arguments.\[\begin{split}\operatorname{CPHASE}(\phi)= \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & \exp(i\phi\pi/90) \end{pmatrix}\end{split}\]- DEFAULT: GateFactory = GateFactory(name='cphase', layers=[Rotation(<matrix>, 'phi')], parameters={'phi': None})
The default
GateFactory
to use if one is not provided during construction.
- cost(labels, gate_spec)
Estimates a cost for performing CPHASE decomposition on the provided gate.
The cost is a number in \([0,1]\) where a small number indicates that this is a good strategy, and a value
1
indicates that it is impossible.- Parameters:
labels (
tuple
) – The labels of the gate to decompose.gate_spec (
GateAttr
) – The gate to decompose, encapsulated as aSPEC
.
- Return type:
float
- decompose(labels, gate_spec)
Decomposes the provided gate into a list (in circuit order) of dictionaries that map labels to gates.
- Parameters:
labels (
tuple
) – The labels of the gate to decompose.gate_spec (
GateAttr
) – The gate to decompose, encapsulated as aSPEC
.
- Return type:
float
- Raises:
CompilationError – If the provided gate on the provided labels cannot be decomposed.
- class trueq.compilation.XYStrategy(noise_topology, factory=None, scalings=None, special_cases=None)
Performs optimal decomposition of two-qubit gates into 0, 1, 2, or 3 XY gates, defined below. See
FactoryNoiseTopology
for a description of the constructor arguments.\[\begin{split}\operatorname{XY}(\phi)= \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos(\phi\pi/180) & i\sin(\phi\pi/180) & 0 \\ 0 & i\sin(\phi\pi/180) & \cos(\phi\pi/180) & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}\end{split}\]- DEFAULT: GateFactory = GateFactory(name='xy', layers=[Rotation(<matrix>, 'phi')], parameters={'phi': None})
The default
GateFactory
to use if one is not provided during construction.
- cost(labels, gate_spec)
Estimates a cost for performing XY decomposition on the provided gate.
The cost is a number in \([0,1]\) where a small number indicates that this is a good strategy, and a value
1
indicates that it is impossible.- Parameters:
labels (
tuple
) – The labels of the gate to decompose.gate_spec (
GateAttr
) – The gate to decompose, encapsulated as aSPEC
.
- Return type:
float
- decompose(labels, gate_spec)
Decomposes the provided gate into a list (in circuit order) of dictionaries that map labels to gates.
- Parameters:
labels (
tuple
) – The labels of the gate to decompose.gate_spec (
GateAttr
) – The gate to decompose, encapsulated as aSPEC
.
- Return type:
float
- Raises:
CompilationError – If the provided gate on the provided labels cannot be decomposed.
- class trueq.compilation.CPhaseXYJointStrategy(cphase_strategy, xy_strategy)
Combines the
CPhaseStrategy
and theXYStrategy
strategies for input gates that can be created using one of each gate.- Parameters:
cphase_strategy (
CPhaseStrategy
) – An instance ofCPhaseStrategy
.xy_strategy (
XYStrategy
) – An instance ofXYStrategy
.
- cost(labels, gate_spec)
Estimates a cost for performing joint CPHASE and XY decomposition on the provided gate.
The cost is a number in \([0,1]\) where a small number indicates that this is a good strategy, and a value
1
indicates that it is impossible.- Parameters:
labels (
tuple
) – The labels of the gate to decompose.gate_spec (
GateAttr
) – The gate to decompose, encapsulated as aSPEC
.
- Return type:
float
- decompose(labels, gate_spec)
Decomposes the provided gate into a list (in circuit order) of dictionaries that map labels to gates.
- Parameters:
labels (
tuple
) – The labels of the gate to decompose.gate_spec (
GateAttr
) – The gate to decompose, encapsulated as aSPEC
.
- Return type:
float
- Raises:
CompilationError – If the provided gate on the provided labels cannot be decomposed.
- class trueq.compilation.BestCostDecomposer(*strategies, cache_size=1024)
Decomposes gates by applying the
DecompStrategy
with the lowest cost.- Parameters:
*strategies – One or more
DecompStrategy
.cache_size (
int
) – The size of the cache used for storingGateAttr
s.
AllocateLabels
- class trueq.compilation.AllocateLabels(graph)
Relabels a
Circuit
to match the labels and topology of aGraph
. When relabeling, it will choose new labels that maximize the the number of valid pairings and minimize the distance between qudit labels.import trueq as tq import trueq.visualization as tqv graph = tqv.Graph.aspen_11(show_labels=True) circ = tq.Circuit( [ {(0, 1): tq.Gate.cx}, {(0, 2): tq.Gate.cx}, {(0, 3): tq.Gate.cx}, {(0, 4): tq.Gate.cx}, ] ) alloc = tq.compilation.AllocateLabels(graph) circ = tq.compilation.Compiler([alloc]).compile(circ) assert circ.key.relabeling == ((0, 1, 2, 3, 4), (26, 11, 25, 27, 10)) circ.draw()
Inspecting the returned circuit, we see that labels
0, 1, 2, 3, 4
of the input circuit got respectively mapped to labels26, 11, 25, 27, 10
, of the Aspen-11 chip. Thus the output circuit has three out of the four input circuits valid under the connectivity of this graph.Note that labels of the target graph that are not assigned in the remapping are not included in
key.relabeling
.- Parameters:
graph (
trueq.visualization.Graph
) – The graph that specifies the qudit layout for this circuit to be relabeled to match.
CompilePaulis
- class trueq.compilation.CompilePaulis(factories=None, **_)
Pass which adds randomly-chosen Pauli gates before all measurements in the circuit. Additionally updates the circuit key with the
compiled_pauli
entry with the appropriate Pauli string.import trueq as tq # make a simple circuit with H gates on each qubit followed by measurements circuit = tq.Circuit([{range(4): tq.Gate.h}]) circuit.measure_all() # create a Compiler with a CompilePaulis pass and apply it to the circuit compiler = tq.Compiler([tq.compilation.CompilePaulis()]) compiled_circ = compiler.compile(circuit) print(compiled_circ.key) compiled_circ
Key(compiled_pauli=Weyls('IZIY'))
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".Circuit- Key:
-
- compiled_pauli: IZIY
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(2): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(3): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
(1): Gate.z- Name:
-
- Gate.z
- Aliases:
-
- Gate.z
- Gate.cliff3
- Generators:
-
- 'Z': 180.0
- Matrix:
-
-
1.00 -1.00
-
(2): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
(3): Gate.y- Name:
-
- Gate.y
- Aliases:
-
- Gate.y
- Gate.cliff2
- Generators:
-
- 'Y': 180.0
- Matrix:
-
-
-1.00 1.00
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0): Meas()- Name:
-
- Meas()
(1): Meas()- Name:
-
- Meas()
(2): Meas()- Name:
-
- Meas()
(3): Meas()- Name:
-
- Meas()
Note
If the circuit’s key already contains a
compiled_pauli
entry, this entry will be updated to account for the new random Paulis which have been inserted.
CycleReplacement
- class trueq.compilation.CycleReplacement(target, replacement, ignore_marker=True, ignore_id=True, **_)
Pass that searches
Circuit
s for a specificCycle
and when found, replaces it with a list of provided cycles.import trueq as tq from trueq.compilation import CycleReplacement old_circuit = tq.Circuit({(0, 1): tq.Gate.cx}) # every time the target cycle is found, insert a new cycle before the target target = tq.Cycle({(0, 1): tq.Gate.cx}) new_cycle = tq.Cycle({0: tq.Gate.from_generators("Z", 4)}) replace_cycle = CycleReplacement(target, replacement=[new_cycle, target]) replace_cycle.apply(old_circuit) # replacements can also be instantiated with dictionaries instead of cycles equiv_replace_list = [{0: tq.Gate.from_generators("Z", 4)}, target] equiv_replace = CycleReplacement({(0, 1): tq.Gate.cx}, equiv_replace_list)
- Parameters:
target (
Cycle
|dict
) – Which cycle to match on.replacement (
list
|Cycle
|dict
) – A cycle or list of cycles to replace thetarget
cycle with.ignore_marker (
bool
) – Whether to apply this pass when the target and a cycle have differing values oftrueq.Cycle.marker
. Default isTrue
.ignore_id (
bool
) – Whether to treat all identity gates as though they are not present when comparing cycles. Default isTrue
.
DeferredSwapper
- class trueq.compilation.DeferredSwapper(graph)
Inserts swaps and decomposes gates of a
Circuit
to obey the connectivity ofGraph
.import trueq as tq import trueq.visualization as tqv graph = tqv.Graph.aspen_11(show_labels=True) circ = tq.Circuit([{(26, 10): tq.Gate.cx}, {(10, 26): tq.Gate.cz}]) swapper = tq.compilation.DeferredSwapper(graph) tq.compilation.Compiler([swapper]).compile(circ).draw()
10 11 26 Key: Labels: (10, 11) Name: Gate.swap Aliases: Gate.swap Locally Equivalent: SWAP Generators: YY: 90.00 XX: 90.00 ZZ: 90.00 1.00 1.00 1.00 1.00 SW SW Labels: (26, 11) 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 Labels: (11, 26) Name: Gate.cz Aliases: Gate.cz Locally Equivalent: CNOT Generators: ZZ: -90.00 ZI: 90.00 IZ: 90.00 1.00 1.00 1.00 -1.00 CZ CZ Labels: (11, 10) Name: Gate.swap Aliases: Gate.swap Locally Equivalent: SWAP Generators: YY: 90.00 XX: 90.00 ZZ: 90.00 1.00 1.00 1.00 1.00 SW SW - Parameters:
graph (
trueq.visualization.Graph
) – The graph that specifies the qudit layout that this circuit must obey.
InvolvingRestrictions
- class trueq.compilation.InvolvingRestrictions(factories, **_)
A pass which ensures that any
NativeGate
which is defined from a list ofGateFactory
s obeys the involving restrictions of theGateFactory
s.Returns a list of
Cycle
s, whose length will not exceed the number of operations inside the original cycle.Satisfying the involving restrictions is done through a greedy algorithm, and there is no guarantee that the final number of cycles will be optimal.
Cycles retain their marker, and marked cycles will be broken into pieces as neccessary.
import trueq as tq # an example config with no initial restrictions config = tq.Config.basic(entangler=tq.Gate.cx) # adding a restriction on cx on (0, 1) so that it can not be at the # same time as gates on qubit (2, ) config.cx.involving[(0, 1)] = (2,) circuit = tq.Circuit([{(0, 1): tq.Gate.cx, (2, 3): tq.Gate.cx, 7: tq.Gate.x}]) passes = (tq.compilation.Native2Q, tq.compilation.InvolvingRestrictions) compiler = tq.Compiler.from_config(config, passes) compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): cx()- Name:
-
- cx()
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
(2, 3): cx()- Name:
-
- cx()
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
(7): Gate.x- Name:
-
- Gate.x
- Aliases:
-
- Gate.x
- Gate.cliff1
- Generators:
-
- 'X': 180.0
- Matrix:
-
-
1.00 1.00
-
Justify
- class trueq.compilation.Justify(factories=None, **_)
Pass that moves operations forward in time.
This class does not move operations between cycles with mismatched markers.
Below is an example where the
X
gate on qubit 1 is moved forward in time to the end of the circuit:import trueq as tq circuit = tq.Circuit() circuit.append({0: tq.Gate.id, 1: tq.Gate.x}) circuit.append({0: tq.Gate.id}) circuit.append({0: tq.Gate.id}) circuit.draw() compiler = tq.Compiler([tq.compilation.Justify()]) compiler.compile(circuit).draw()
0 1 Key: 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: (0,) Name: Gate.id Aliases: Gate.id Gate.i Gate.cliff0 Locally Equivalent: Identity Generators: I: 0.00 1.00 1.00 ID 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
MarkBlocks
- class trueq.compilation.MarkBlocks(marker=None, **_)
Pass that marks cycles which contain multi-qubit gates if none of the existing non-measurement cycles in the circuit have been marked with non-zero values. This pass is similar to
MarkCycles
, except that it uses the same marker for any adjacent cycles that are not separated by single-qubit cycles. By default, markers start at a value one greater than the largest existing marker value, and increment up for every additional block of subsequent cycles containing multi-qubit gates.import trueq as tq # make a simple circuit with two single-qubit gates between blocks of # two-qubit gates circuit = tq.Circuit( [ {0: tq.Gate.h}, {(0, 1): tq.Gate.cx}, {(0, 2): tq.Gate.cz}, {1: tq.Gate.h}, {(0, 1): tq.Gate.cx}, {(1, 2): tq.Gate.cz}, ] ) compiler = tq.Compiler([tq.compilation.MarkBlocks()]) # the first block of two-qubit gate cycles will be marked with "1" and the # second block with "2" compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cx- Name:
-
- Gate.cx
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
2- Marker 2
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cx- Name:
-
- Gate.cx
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
2- Marker 2
Compilation tools may only recompile cycles with equal markers.(1, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
- Parameters:
marker (
int
|NoneType
) – The marker value added to hard cycles. The default valueNone
causes the first block to have marker one greater than the largest marker already present in the circuit, and subsequent blocks to have markers incremented by1
for each block found.
MarkCycles
- class trueq.compilation.MarkCycles(marker=None, **_)
Pass that marks cycles which contain multi-qubit gates if none of the existing cycles in the circuit have been marked with non-zero values. By default, markers start at
1
and increment up for every cycle containing a multi-qubit gate found.import trueq as tq # make a simple circuit with a single-qubit and two two-qubit gates circuit = tq.Circuit( [{0: tq.Gate.h}, {(0, 1): tq.Gate.cx}, {(0, 2): tq.Gate.cz}] ) compiler = tq.Compiler([tq.compilation.MarkCycles()]) # the two-qubit gate cycles will be marked with "1" and "2" compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cx- Name:
-
- Gate.cx
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
2- Marker 2
Compilation tools may only recompile cycles with equal markers.(0, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
# in circuits that already have at least one cycle marked, the MarkCycles pass # does nothing circuit = tq.Circuit( [ {0: tq.Gate.h}, tq.Cycle({(0, 1): tq.Gate.cx}, marker=1), {(0, 2): tq.Gate.cz}, ] ) compiler = tq.Compiler([tq.compilation.MarkCycles(marker=2)]) compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cx- Name:
-
- Gate.cx
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
- Parameters:
marker (
int
|NoneType
) – The marker to be added to cycles containing multi-qubit gates. IfNone
then markers are incremented from1
for each cycle found.
Merge
- class trueq.compilation.Merge(max_sys=1, marker=None, **_)
Pass that takes a list of cycles, finds compatabile labels and gates, and merges them to a single gate as much as is possible.
Gates are automatically split into the smallest number of individual gates possible. For example, if merging results in a two-qubit gate that is the Kronecker product of two single-qubit gates, then it will be broken apart into the two-single qubit gates.
This class will only merge gates if adjacent cycles have the same marker.
import trueq as tq # make a circuit containing 4 X gates in a row, and merge them together circuit = tq.Circuit([{0: tq.Gate.x}] * 4) compiler = tq.Compiler([tq.compilation.Merge()]) compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
- Parameters:
max_sys (
int
) – The maximum number of labels to merge at any given time. If only single qubit merging is desired, then setmax_sys=1
, and so on.marker (
int
|NoneType
) – The cycle marker where this pass will be applied. ifNone
then this pass is applied to all cycles regardless of cycle marker.
Native1Q
- class trueq.compilation.Native1Q(factories, mode='ZXZXZ', **_)
A
NCyclePass
which iteratively attempts to decompose one-qubit gates into gates which are performable by the given list ofGateFactory
s.import trueq as tq from trueq.config import GateFactory # create a circuit with a single H gate circuit = tq.Circuit({0: tq.Gate.h}) # Define GateFactory objects for an X and Z rotation rx = GateFactory.from_hamiltonian("RX", [["X", "theta"]], parameters=["theta"]) rz = GateFactory.from_hamiltonian("RZ", [["Z", "phi"]], parameters=["phi"]) # the following Native1Q pass will decompose this circuit into X and Z gates # using the ZXZ decomposition compiler = tq.Compiler( [tq.compilation.Native1Q(factories=[rx, rz], mode="ZXZ")] ) compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): RZ(phi)- Name:
-
- RZ(phi)
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Parameters:
-
- phi = 90.0
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): RX(theta)- Name:
-
- RX(theta)
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Parameters:
-
- theta = 90.0
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): RZ(phi)- Name:
-
- RZ(phi)
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Parameters:
-
- phi = 90.0
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
Advanced Users:
This pass combines
Parallel
andTryInOrder
to attempt various one-qubit decomposition methods across one-qubit gates in a given cycle. In particular, every one-qubit gate will attempt to be decomposed, in order, by the following replacements, using right-justification if decomposition lengths are ragged:Native1QMode
-Decompose single qubit gates into the mode allowed by the
GateFactory
s.
NativeExact
-See if the gate appears exactly as seen inside of the list of
GateFactory
s.
Native1QRRZ
-Decompose single qubit gates into
R
andZ
gates, as long as the list ofGateFactory
s defines the correct gates.
- Parameters:
factories (
Iterable
) – The iterable ofGateFactory
objects containing target one-qubit gates.mode (
str
) – The single qubit decomposition mode, defaults to'ZXZXZ'
, seetrueq.math.decomposition.QubitMode
for more details.
Native1QRRZ
- class trueq.compilation.Native1QRRZ(factories)
An
OperationReplacement
which decomposes single qubit gates into3
gates \(R(\theta) R(\phi) Z(\gamma)\), where theR
gates are defined by \(Z(\theta) X(90) Z(-\theta)\) in time.This will return either
1
or3
dictionaries.Will throw a
CompilationError
if noGateFactory
can be found in the list which can build anR
gate and aZ
gate. AGateFactory
forR
can be found inr_factory
.import trueq as tq from trueq.config import GateFactory # define GateFactories for the R and Z gates r = GateFactory.from_hamiltonian( "R", [["Z", "-theta"], ["X", 90], ["Z", "theta"]], parameters=["theta"] ) rz = GateFactory.from_hamiltonian("RZ", [["Z", "phi"]], parameters=["phi"]) native1qrrz = tq.compilation.Native1QRRZ(factories=[r, rz]) native1qrrz.apply((0,), tq.Gate.x)
[{(0,): R(theta)}, {(0,): R(theta)}, {(0,): RZ(phi)}]
- Parameters:
factories (
Iterable
) – A iterable containingGateFactory
s which may contain anR
andZ
gates as defined above.
Native1QMode
- class trueq.compilation.Native1QMode(factories, mode='ZXZXZ', **_)
An
OperationReplacement
which expands arbitrary single qubit gates into the decomposition mode provided in a givenConfig
.Basics of operation:
When decomposing a single qubit gate on a given label, this looks through the list of
GateFactory
objects to find one which applies to that qubit. If the found factories are sufficient to build arbitrary single qubit gates according to the target mode. This list of factories is cached against the label.Next, these factories are combined with
QubitMode
to decompose into3
or5
dictionaries ofNativeGate
s.
Returns
1
,3
, or5
dictionaries.import trueq as tq from trueq.config import GateFactory # define GateFactorys for the X and Z gates x90 = GateFactory.from_hamiltonian("X90", [["X", 90]]) rz = GateFactory.from_hamiltonian("RZ", [["Z", "phi"]], parameters=["phi"]) native1qmode = tq.compilation.Native1QMode(factories=[x90, rz]) native1qmode.apply((0,), tq.Gate.h)
[{(0,): RZ(phi)}, {(0,): X90()}, {(0,): RZ(phi)}, {(0,): X90()}, {(0,): RZ(phi)}]
- Parameters:
factories (
Iterable
) – The iterable ofGateFactory
objects containing target one-qubit gates.mode (
str
) – The single qubit decomposition mode, defaults to'ZXZXZ'
, seetrueq.math.decomposition.QubitMode
for more details.
Native2Q
- class trueq.compilation.Native2Q(factories, max_depth=10, tol=1e-12, **_)
A
NCyclePass
which iteratively attempts to decompose two-qubit gates into gates which are performable by the given list ofGateFactory
s.Advanced Users:
This pass combines
Parallel
andTryInOrder
to attempt various two-qubit decomposition methods across two-qubit gates in a given cycle. In particular, every two-qubit gate will attempt to be decomposed, in order, by the following replacements, using right-justification if decomposition lengths are ragged:NativeExact
-See if the gate appears exactly as seen inside of the factory list.
Native2QKAK
-See if the gate is equivalent to a gate inside of the factory list up to single qubit operations.
Native2QCX
-If a
CX
equivalent gate is found in the factory list, build the target gate using a known analytic decomposition.
NativeDecomp
-Use a numerical method to find a decomposition, a very general method.
Walking through an example:
Lets start with a cycle which only contains a single Haar random
SU(4)
, with a factory list that contains aCZ
gate.Each operation is passed to the
TryInOrder
one at a time, theTryInOrder
pass will run through its list of replacements, starting withNativeExact
until no errors occur.Since the target gate is Haar random and the factory list only defines a
CZ
, the first few replacements will fail. The first one which will successfully decompose the random gate in this case will be theNative2QCX
, as the factory list defines aCZ
which is locally equivalent toCX
.This decomposition is then passed back up to the
Native2Q
pass (which is a subclass ofParallel
), where it has no other cycles to be combined with, so it is simply returned as is.See
Parallel
for more details on how cycles are combined in general.import trueq as tq from trueq.config import GateFactory # Create a circuit with a single random SU(4) gate circuit = tq.Circuit({(0, 1): tq.Gate.random(4)}) # define a GateFactory for the CZ gate cz = GateFactory.from_matrix("CZ", tq.Gate.cz.mat) compiler = tq.Compiler([tq.compilation.Native2Q(factories=[cz])]) compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate(Y, X, ...)- Name:
-
- Gate(Y, X, ...)
- Generators:
-
- 'Y': -3.221
- 'X': -15.937
- 'Z': -101.197
- Matrix:
-
-
-0.48 0.87j -0.10 0.07j -0.12 0.02j 0.95 0.29j
-
(1): Gate(Y, X, ...)- Name:
-
- Gate(Y, X, ...)
- Generators:
-
- 'Y': 8.719
- 'X': -138.79
- 'Z': 63.263
- Matrix:
-
-
0.37 -0.28j -0.39 0.80j -0.28 0.84j 0.07 0.46j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): CZ()- Name:
-
- CZ()
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate(Y, X, ...)- Name:
-
- Gate(Y, X, ...)
- Generators:
-
- 'Y': -10.609
- 'X': 89.545
- 'Z': -10.609
- Matrix:
-
-
0.44 0.56j 0.56 -0.44j 0.44 -0.56j 0.56 0.44j
-
(1): Gate(Y)- Name:
-
- Gate(Y)
- Generators:
-
- 'Y': -22.392
- Matrix:
-
-
0.69 -0.69j 0.14 -0.14j -0.14 0.14j 0.69 -0.69j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): CZ()- Name:
-
- CZ()
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.cliff14- Name:
-
- Gate.cliff14
- Aliases:
-
- Gate.cliff14
- Generators:
-
- 'Y': -127.279
- 'Z': -127.279
- Matrix:
-
-
-0.50 0.50j 0.50 0.50j -0.50 -0.50j 0.50 -0.50j
-
(1): Gate(Y)- Name:
-
- Gate(Y)
- Generators:
-
- 'Y': -39.975
- Matrix:
-
-
0.66 -0.66j 0.24 -0.24j -0.24 0.24j 0.66 -0.66j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): CZ()- Name:
-
- CZ()
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate(Y, X, ...)- Name:
-
- Gate(Y, X, ...)
- Generators:
-
- 'Y': -24.451
- 'X': -165.927
- 'Z': -19.137
- Matrix:
-
-
0.14 -0.05j 0.97 0.19j 0.87 0.46j -0.07 -0.13j
-
(1): Gate(Y, X, ...)- Name:
-
- Gate(Y, X, ...)
- Generators:
-
- 'Y': 24.963
- 'X': -14.681
- 'Z': -15.849
- Matrix:
-
-
0.19 0.95j -0.19 -0.16j -0.05 0.24j 0.45 0.86j
-
- Parameters:
factories (
Iterable
) – The iterable ofGateFactory
objects containing target two-qubit gates.max_depth (
int
) – The maximum depth passed to the final numerical decomposition methodNativeDecomp
.tol (
float
) – The minimum process infidelity allowed for decompositions to be considered successful, this may be used to do approximate decompositions.
Native2QCX
- class trueq.compilation.Native2QCX(factories, **_)
An
OperationReplacement
which decomposes anySU(4)
into a gate which is locally equivalent toCNOT
, as long as such a gate exists inside of the givenConfig
.The decomposition methods inside of this
OperationReplacement
are based on:https://arxiv.org/abs/quant-ph/0307177
This pass accepts
1
operation, and will return either5
or7
dictionaries, seeNative2QKAK
if only3
dictionaries are expected.If the target gate is locally equivalent to a gate of the form
trueq.Gate.from_generators("XX", theta, "YY", phi)
for anyphi
ortheta
, then the restrictions on the config defined gate relax from being locally equivalent to aCNOT
to any gate of the formtrueq.Gate.from_generators("XX", 90, "YY", phi)
, which includes iSWAP gates.- Parameters:
factories (
tuple
) – The tuple ofGateFactory
objects.
Native2QKAK
- class trueq.compilation.Native2QKAK(factories, **_)
An
OperationReplacement
which checks if a given operation is a two-qubit gate that is equal to some staticGateFactory
in the provided list ofGateFactory
s up to single qubit operations, and if so, switch theGate
with aNativeGate
built from the factory list plus the approriate single qubit gates.- Parameters:
factories (
Iterable
) – The iterable ofGateFactory
objects containing target gates.
NativeDecomp
- class trueq.compilation.NativeDecomp(depth, factories, tol=1e-12, max_resets=20, **_)
An
OperationReplacement
which attempts to decompose the target gate using the specified number of gates found in the provided list ofGateFactory
s.This is only successful if the provided gate can be decomposed in exactly the depth specified and the decomposition has a process infidelity which is smaller than the
tol
parameter.- Parameters:
depth (
int
) – The number of gates from the factory list to decompose each gate into.factories (
tuple
) – The tuple ofGateFactory
objects.tol (
float
) – The minimum process infidelity allowed for the decomposition to be considered successful.max_resets (
int
) – The number of times to attempt to reset the algorithm.
NativeExact
- class trueq.compilation.NativeExact(factories, tol=1e-12)
An
OperationReplacement
which checks if the specified gate can be generated directly from a single output of a single factory present in theGateFactory
list with an appropriate choice of parameter values, and if so, replaces aGate
with theNativeGate
.For example, suppose we have a factory list
[rz(phi), u3(phi, theta, lambda), x90()]
and encounter aGate.rx(90)
gate. The first operation,rz(phi)
, will be skipped because it can’t make an \(X90\) for any value ofphi
, but theu3(phi, theta, lambda)
factory will be used because it is next in line and it can make any single qubit gate including an \(X90\). The actualx90()
in the factory list will be ignored (even though it is an exact match) because it comes last in the factory list.import trueq as tq from trueq.config import GateFactory rz = GateFactory.from_hamiltonian("RZ", [["Z", "phi"]], parameters=["phi"]) u3 = tq.config.u3_factory x90 = GateFactory.from_hamiltonian("X90", [["X", 90]]) native_exact = tq.compilation.NativeExact(factories=[rz, u3, x90]) native_exact.apply((0,), tq.Gate.rx(90))
[{(0,): U3Gate(theta, phi, ...)}]
- Parameters:
factories (
Iterable
) – An iterable ofGateFactory
s which may be used by the replacement.tol (
float
) – The allowed process infidelity to be considered an exact match.
OneQuditDecomp
- class trueq.compilation.OneQuditDecomp(factories, optimal=False, **_)
A pass which decomposes cycles of arbitrary single-qudit gates into alternations of cycles of native gates with diagonal gates. See
native_cycles()
for details on the form of the cycles of native gates.The native gates are generated by the given factories. These factories should produce gates that perform subspace rotations between adjacent energy levels (i.e. computation basis states). For example, a qubit only has two levels so any factory that produces non-diagonal gates will suffice. For a qutrit, two factories are required: one between \(|0\rangle\leftrightarrow|1\rangle\) and one between \(|0\rangle\leftrightarrow|2\rangle\). If a given qubit label has a choice between applicable factories, the one with fewer free parameters is preferred.
Any non single-qudit gates found in a provided cycle are placed into a new cycle at the end of the decomposition.
Note
This compiler pass is an independent alternative to
Native1Q
and its partners. However, it works for qubits and qudits.In the first example, we show how this class can be easily used to decompose rounds of single qubit gates. The same \(\sqrt{X}\) factory is used for every qubit.
import trueq as tq # Compiler.basic will use the factories z-rotation and RX(90) by default compiler = tq.Compiler.basic(passes=(tq.compilation.OneQuditDecomp,)) # we decompose all single qubit gates in the circuit with guaranteed alignment circuits = tq.make_cb({(0, 1): tq.Gate.cnot}, [2]) compiler.compile(circuits[0])
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".Circuit- Key:
-
- analyze_decays: YY_YX_XY_XX_YZ_YI_XZ_XI_ZY_ZX_IY_IX_ZZ_ZI_IZ_II
- compiled_pauli: II
- cycles: (Cycle((0, 1): Gate.cx),)
- measurement_basis: YY
- n_random_cycles: 2
- protocol: CB
- twirl: Paulis on [0, 1]
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.cliff8- Name:
-
- Gate.cliff8
- Aliases:
-
- Gate.cliff8
- Generators:
-
- 'Z': -90.0
- Matrix:
-
-
-0.71 0.71j 0.71 0.71j
-
(1): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
(1): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
(1): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
(1): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
(1): Gate.cliff8- Name:
-
- Gate.cliff8
- Aliases:
-
- Gate.cliff8
- Generators:
-
- 'Z': -90.0
- Matrix:
-
-
-0.71 0.71j 0.71 0.71j
-
1- Marker 1
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cx- Name:
-
- Gate.cx
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
-1.00 -1.00
-
(1): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 0.71j -0.71 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
(1): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.z- Name:
-
- Gate.z
- Aliases:
-
- Gate.z
- Gate.cliff3
- Generators:
-
- 'Z': 180.0
- Matrix:
-
-
-1.00j 1.00j
-
(1): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
-1.00 -1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
(1): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.z- Name:
-
- Gate.z
- Aliases:
-
- Gate.z
- Gate.cliff3
- Generators:
-
- 'Z': 180.0
- Matrix:
-
-
-1.00j 1.00j
-
(1): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 0.71j -0.71 0.71j
-
2- Marker 2
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cx- Name:
-
- Gate.cx
- Aliases:
-
- Gate.cx
- Gate.cnot
- Likeness:
-
- CNOT
- Generators:
-
- 'ZX': -90.0
- 'IX': 90.0
- 'ZI': 90.0
- Matrix:
-
-
1.00 1.00 1.00 1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.cliff8- Name:
-
- Gate.cliff8
- Aliases:
-
- Gate.cliff8
- Generators:
-
- 'Z': -90.0
- Matrix:
-
-
-0.71 0.71j 0.71 0.71j
-
(1): Gate.cliff8- Name:
-
- Gate.cliff8
- Aliases:
-
- Gate.cliff8
- Generators:
-
- 'Z': -90.0
- Matrix:
-
-
-0.71 0.71j 0.71 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
(1): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
(1): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
(1): sx()- Name:
-
- sx()
- Aliases:
-
- Gate.sx
- Gate.cliff5
- Generators:
-
- 'X': 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
(1): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
0.71 -0.71j 0.71 0.71j
-
3- Marker 3
Compilation tools may only recompile cycles with equal markers.(0): Meas()- Name:
-
- Meas()
(1): Meas()- Name:
-
- Meas()
In the second example, we show a qutrit configuration where each subsystem is assigned fixed rotation values on each subspace.
import trueq as tq import numpy as np # define two factories, one for each subspace, with angles in degrees a = np.pi / 360 fn1 = lambda theta: [ [np.cos(a * theta), -1j * np.sin(a * theta), 0], [-1j * np.sin(a * theta), np.cos(a * theta), 0], [0, 0, 1], ] f1 = tq.config.GateFactory.from_function("f1", fn1, dim=3) fn2 = lambda theta: [ [1, 0, 0], [0, np.cos(a * theta), -1j * np.sin(a * theta)], [0, -1j * np.sin(a * theta), np.cos(a * theta)], ] f2 = tq.config.GateFactory.from_function("f2", fn2, dim=3) # define specific values on certain subsystems f1_params = {0: [68], 1: [94], 2: [71], 3: [86], 4: [90]} f2_params = {0: [65], 1: [94], 2: [-75], 3: [62], 4: [90]} # helper function that returns new factories where free parameters become fixed, # and where it is only allowed to act on one particular label def fixed_factory(factory, label, args): params = {name: val for name, val in zip(factory.free_parameters, args)} return factory.fix_parameters({(label,): ()}, **params) # enter all of the factories into a list. note that we are adding both the # parameterized and fixed factories. this is for demonstration purposes, you # can just enter the fixed or the parametric, as needed. in this case, the # parametric ones will be used as backup if no fixed factory acts on a label # required by a cycle to decompose factories = [f1, f2] factories.extend(fixed_factory(f1, i, args) for i, args in f1_params.items()) factories.extend(fixed_factory(f2, i, args) for i, args in f2_params.items()) # instantiate compiler with only this pass compiler = tq.Compiler([tq.compilation.OneQuditDecomp(factories)]) # make a random cycle on three qutrits and decompose it circuit = tq.Circuit([{label: tq.Gate.random(3) for label in [0, 2, 8]}]) compiler.compile(circuit[0])
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
-0.90 -0.43j -0.97 -0.26j -0.84 -0.55j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.54 0.84j 0.90 0.44j -0.98 -0.19j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
-0.94 0.34j -0.55 -0.83j -0.72 0.69j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 65.0
- Matrix:
-
-
1.00 0.84 -0.54j -0.54j 0.84
-
(2): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = -75.0
- Matrix:
-
-
1.00 0.79 0.61j 0.61j 0.79
-
(8): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
1.00 0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.60 -0.80j 0.60 0.80j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.30 -0.95j 0.30 0.95j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 -0.09 -1.00j -0.09 1.00j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 65.0
- Matrix:
-
-
1.00 0.84 -0.54j -0.54j 0.84
-
(2): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = -75.0
- Matrix:
-
-
1.00 0.79 0.61j 0.61j 0.79
-
(8): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
1.00 0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.81 0.59j 0.81 -0.59j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.74 0.68j 0.74 -0.68j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.71 0.71j 0.71 -0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 65.0
- Matrix:
-
-
1.00 0.84 -0.54j -0.54j 0.84
-
(2): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = -75.0
- Matrix:
-
-
1.00 0.79 0.61j 0.61j 0.79
-
(8): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
1.00 0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.59 -0.81j 0.59 0.81j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.80 -0.60j 0.80 0.60j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 -0.61 -0.79j -0.61 0.79j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 68.0
- Matrix:
-
-
0.83 -0.56j -0.56j 0.83 1.00
-
(2): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 71.0
- Matrix:
-
-
0.81 -0.58j -0.58j 0.81 1.00
-
(8): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.72 -0.69j 0.72 0.69j 1.00
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.63 -0.77j 0.63 0.77j 1.00
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
-0.21 -0.98j -0.21 0.98j 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 68.0
- Matrix:
-
-
0.83 -0.56j -0.56j 0.83 1.00
-
(2): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 71.0
- Matrix:
-
-
0.81 -0.58j -0.58j 0.81 1.00
-
(8): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.83 0.56j 0.83 -0.56j 1.00
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.79 0.61j 0.79 -0.61j 1.00
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 68.0
- Matrix:
-
-
0.83 -0.56j -0.56j 0.83 1.00
-
(2): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 71.0
- Matrix:
-
-
0.81 -0.58j -0.58j 0.81 1.00
-
(8): f1(theta)- Name:
-
- f1(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
0.71 -0.71j -0.71j 0.71 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.80 0.60j 0.80 -0.60j 1.00
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
-0.14 -0.99j -0.14 0.99j 1.00
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
0.88 0.47j 0.88 -0.47j 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 65.0
- Matrix:
-
-
1.00 0.84 -0.54j -0.54j 0.84
-
(2): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = -75.0
- Matrix:
-
-
1.00 0.79 0.61j 0.61j 0.79
-
(8): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
1.00 0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.15 -0.99j 0.15 0.99j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 -0.31 -0.95j -0.31 0.95j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 -0.34 -0.94j -0.34 0.94j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 65.0
- Matrix:
-
-
1.00 0.84 -0.54j -0.54j 0.84
-
(2): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = -75.0
- Matrix:
-
-
1.00 0.79 0.61j 0.61j 0.79
-
(8): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
1.00 0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.73 0.68j 0.73 -0.68j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.68 0.74j 0.68 -0.74j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.71 0.71j 0.71 -0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 65.0
- Matrix:
-
-
1.00 0.84 -0.54j -0.54j 0.84
-
(2): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = -75.0
- Matrix:
-
-
1.00 0.79 0.61j 0.61j 0.79
-
(8): f2(theta)- Name:
-
- f2(theta)
- Parameters:
-
- theta = 90.0
- Matrix:
-
-
1.00 0.71 -0.71j -0.71j 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.99 0.14j 0.99 -0.14j
-
(2): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 1.00 0.02j 1.00 -0.02j
-
(8): Gate() - Name:
-
- Gate(
)
- Gate(
- Matrix:
-
-
1.00 0.71 0.70j 0.71 -0.70j
-
- Parameters:
factories (
Iterable
) – A list ofGateFactory
s.optimal (
bool
) – IfFalse
, the depth of every decomposition will be fixed regardless of which cycle is input (e.g. even for an input cycles containing only identity gates). Otherwise, the depth of the decomposition will be optimal for each given input.
- native_cycles(labels)
Parses the factories owned by this class and returns a list of
Cycle
s such that:All cycles have single-qudit
NativeGate
s on each of thelabels
.Each cycle contains gates that are block diagonal with exactly one 2-by-2 block (in the same location on each gate), with the remaining blocks 1-by-1.
Cycles are sorted by block location, and all
dim-1
possible block locations are present.
- Parameters:
labels (
tuple
) – The labels for which to construct cycles.- Return type:
list
Parallel
- class trueq.compilation.Parallel(replacements=None, **_)
A
NCyclePass
that splits a cycle into individual operations, passes the operations to providedOperationReplacement
s in parallel, and recombines the output into a list of cycles.Note that this pass is not implemented in parallel across cpu cores currently.
Each operation in the input cycle is split and passed to each
OperationReplacement
based upon a dictionary lookup, this dictionary lookup has keys which are labels, and the values are the targetOperationReplacement
. If the given labels are not found in the lookup dictionary, then the operation is passed unaltered to the output cycles. The lookup dictionary can optionally have aNone
key, which signifies a default pass which should be used if the labels are not present in the dictionary.This returns a list of cycles, where the number of cycles is decided by the
OperationReplacement
s provided, and all cycles returned are joined such that they are justified to the latest possible cycle in time.All output cycles maintain the marker of the input cycle.
- Parameters:
replacements (
dict
|OperationReplacement
) – Optional, either a dictionary mapping labels toOperationReplacement
s, or just a singleOperationReplacement
, which is applied to all labels.
PhaseTrack
- class trueq.compilation.PhaseTrack(factories, virtual=None, include_final_virtual=False, **_)
Tracks phase accumulation on each qubit throughout a circuit, and compiles this phase information into parametric gates.
For example, if a device tunes up two gate pulses, \(X90\) and \(XX90\) (the maximally entangling Molmer-Sorensen gate), and implements single-qubit Z-rotations virtually, then this pass will accumulate phases on each qubit based on \(Z(\theta)\) gates it finds, and respectively replace \(X90\) and \(XX90\) gates with parameterized \(X90(\phi)\) gates (i.e. 90 degree nutations about a vector in the X-Y plane) and parameterized \(XX90(\phi_1, \phi_2)\) gates (i.e. the \(XX90\) gate which has been individually phase updated on each qubit). Therefore, pulse sequences can be programmed directly by looping through cycles in a circuit, choosing the pulse shape based on the gate names, and choosing pulse phases based on the parameters of the gates.
See Example: Phase Tracking with the Compiler for detailed usage examples.
Note
This pass may not output a circuit that implements the same unitary as the input because it may be off by z-rotations (as in the example above) prior to measurement. It will, however, produce the same bitstring statistics because a z-rotation prior to a measurement along the z-axis will not affect bitstring populations.
- Parameters:
factories (
Iterable
) – An iterable ofGateFactory
s that contains all the gate factories of interest.virtual (
NoneType
|GateFactory
) – The factory of the virtual gate. By default, the factory list wil be searched for a single-qubit Z-rotation, which will be defined as the virtual gate.include_final_virtual (
bool
) – Whether to apply the cumulative virtual gates prior to preparations, measurements, or at the end of the circuit.
RCCycle
- class trueq.compilation.RCCycle(twirl='P', **_)
Pass which performs Randomized Compilation (RC) on groups of cycles with matching marker values by adding gates on either side of the cycles, chosen using the provided
Twirl
.Use of this class requires a Randomized Compilation license.
Note
Cycles containing twirling gates are inserted before and after blocks of cycles which have non-zero markers. The inserted cycles will have the default marker
0
.Multiple cycles in a row which all contain the same marker value are twirled around as a group, twirls are not inserted between the cycles.
No twirling gates are added around groups of cycles containing
Meas
orPrep
operations.- Parameters:
twirl (
trueq.Twirl
|str
) – TheTwirl
to use. You can also specify a twirling group (default is"P"
) that will be used to automatically instantiate a twirl based on the labels in the given circuit.
RCKak
- class trueq.compilation.RCKak(local=True, **_)
Pass which performs Randomized Compilation (RC) on cycles with non-zero markers. However, in contrast to
RCCycle
, marked cycles may contain non-Clifford multi-qudit gates. Randomizing operations and their corrections may either be applied locally or globally.Use of this class requires a Randomized Compilation license.
Note
Cycles containing randomizing gates are inserted before and after every cycle that has a non-zero marker. The inserted cycles have the default marker
0
.No gates are added around cycles containing
Meas
orPrep
operations.- Parameters:
local (
bool
) – Whether to apply randomizing gates around all gates in a marked cycle or to apply gates to all qubits in the circuit including idling qubits.
RCLocal
- class trueq.compilation.RCLocal(twirling_group='P', **_)
Pass which performs Randomized Compilation (RC) on groups of cycles with matching marker values by adding gates on either side of the cycles. However, in contrast to
RCCycle
, twirling operations and their corrections are only added to labels that the cycles they surround act on; idling qubits are left alone.Use of this class requires a Randomized Compilation license.
Note
Cycles containing twirling gates are inserted before and after blocks of cycles which have non-zero markers. The inserted cycles will have the default marker
0
.Multiple cycles in a row which all contain the same marker value are twirled around as a group, twirls are not inserted between the cycles.
No twirling gates are added around groups of cycles containing
Meas
orPrep
operations.- Parameters:
twirling_group (
str
) – A twirling group string (default is"P"
) that will be used to automatically instantiate a twirl based on each marker block in the circuit.
Relabel
- class trueq.compilation.Relabel(permutation, **_)
Pass which relabels all the labels and keys in a
Circuit
.This searches through and relabels/reorders entries in the following key entries:
analyze_decays
compiled_pauli
cycle
measurement_basis
targeted_errors
twirl
Note that this does not function when the circuit has results present.
import trueq as tq old_circ = tq.Circuit([{0: tq.Gate.x, 1: tq.Gate.y, 2: tq.Gate.z}]) # Swapping the labels on qubit 0 and 1, 2 stays permutation = {0: 1, 1: 0, 2: 2} pat = tq.compilation.Relabel(permutation) tq.compilation.Compiler([pat]).compile(old_circ)
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".Circuit- Key:
-
- relabeling: ((0, 1, 2), (1, 0, 2))
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.y- Name:
-
- Gate.y
- Aliases:
-
- Gate.y
- Gate.cliff2
- Generators:
-
- 'Y': 180.0
- Matrix:
-
-
-1.00j 1.00j
-
(1): Gate.x- Name:
-
- Gate.x
- Aliases:
-
- Gate.x
- Gate.cliff1
- Generators:
-
- 'X': 180.0
- Matrix:
-
-
1.00 1.00
-
(2): Gate.z- Name:
-
- Gate.z
- Aliases:
-
- Gate.z
- Gate.cliff3
- Generators:
-
- 'Z': 180.0
- Matrix:
-
-
1.00 -1.00
-
- Parameters:
permutation (
dict
) – A dictionary where the keys are the current label and the values are the new labels.
RemarkCycles
- class trueq.compilation.RemarkCycles(factories=None, **_)
Pass that remarks all the marked cycles. The new markers start at
1
and increment up for every marked cycle found.
RemoveEmptyCycle
- class trueq.compilation.RemoveEmptyCycle(preserve_marker=True, **_)
Pass which removes empty cycles from groups of cycles with matching markers.
By default if the group of cycles contain no
Operation
s at all, this will return a single empty cycle with the original marker.- Parameters:
preserve_marker (
bool
) – Whether to disable this pass from removing a group of cycles altogether, if they are all empty, for the sake of preserving the marker value. IfTrue
(default), in such a case, one empty cycle will be kept with the marker value of the group.
RemoveId
- class trueq.compilation.RemoveId(marker=0, **_)
Pass that removes single qubit identity gates from one
Cycle
.Returns a list containing 1
Cycle
.import trueq as tq # Make a circuit containing 4 id gates in a row circuit = tq.Circuit() for _ in range(4): circuit.append({0: tq.Gate.id}) # remove all identity gates compiler = tq.Compiler([tq.compilation.RemoveId()]) compiler.compile(circuit)
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.empty - Marker 0
Compilation tools may only recompile cycles with equal markers.empty - Marker 0
Compilation tools may only recompile cycles with equal markers.empty - Marker 0
Compilation tools may only recompile cycles with equal markers.empty - Parameters:
marker (
int
|NoneType
) – The cycle marker where this pass will be applied. ifNone
then this pass is applied to all cycles regardless of cycle marker.
TryInOrder
- class trueq.compilation.TryInOrder(replacements=None, **_)
An
OperationReplacement
where a list ofOperationReplacement
s is stored, and each is attempted in order until noCompilationError
is raised.All replacements in
TryInOrder
must beOperationReplacement
s.- Parameters:
replacements (
list
) – Optional, a list ofOperationReplacement
s to be applied in order until one succeeds.
- append(replacement)
Appends a replacement to the list of existing replacements.
- Parameters:
replacement (
OperationReplacement
) – The replacement to be appended.
- apply(label, operation)
Accepts labels and an
Operation
and returns a list of dictionaries, where the dictionary keys are labels and the values areOperation
s.The returned list may contain any number of dictionaries.
- Parameters:
labels (
tuple
) – A tuple containing the qubit labels which the operation acts on.operation (
trueq.Operation
) – The operation to be altered by the replacement.
- Returns:
A list of dictionaries, where the keys are labels, and the values are
trueq.Operation
s.- Return type:
list
UnmarkCycles
- class trueq.compilation.UnmarkCycles(factories=None, **_)
Pass which sets all cycle markers to
0
.
Helper Functions
- class trueq.compilation.count_streaks(circuit)
Iterates through a
Circuit
, finding all multi-qubit gates and counting the number of times that there are repeated operations on the same pair of qubits.Repeated operations on a pair of qubits can often be merged and do not require extra swaps to map a circuit onto a specific chip topology. Therefore we want to count “streaks”, where a “streak” on a pair of qubits is a series of cycles in a circuit where the qubit pair of interest does not interact with any other qubits.
For example, given a circuit of 6 cnot gates, where there are 2 cnots in a row on
(0, 1)
followed by a cnot on(1, 2)
, then 3 more cnots in a row on(0, 1)
.On labels (0, 1) there is 1 streak of 2 in a row and 1 of 3 in a row. On labels (1, 2) there is 1 streak of length 1.
import trueq as tq circ = tq.Circuit({(0, 1): tq.Gate.cx}) circ.append({(0, 1): tq.Gate.cx}) circ.append({(1, 2): tq.Gate.cx}) circ.append({(0, 1): tq.Gate.cx}) circ.append({(1, 0): tq.Gate.cx}) circ.append({(0, 1): tq.Gate.cx}) circ.draw() tq.compilation.count_streaks(circ)
{frozenset({0, 1}): {2: 1, 3: 1}, frozenset({1, 2}): {1: 1}}
This function returns a nested dictionary whose keys are pairs of qubits that have a multi-qubit gate acting on them, and the values are the numbers of streaks of each length. In the above example,
(0, 1)
has a value of`{2: 1, 3: 1}`
, meaning it found 1 streak of length 2 and 1 streak of length 3.Note that single qubit operations will not break a streak, and operations may happen in parallel and those will be counted as independent streaks.
The keys of the dictionary can be used to define the connectivity graph of the circuit itself, and are useful for validation of matching circuit topology to chip topology.
- Parameters:
circuit (
trueq.Circuit
) – The circuit of which to calculate the topology and streaks.- Return type:
dict
- class trueq.compilation.decompose_clifford(clifford, labels=None, graph=None, root=None)
Decomposes a
Clifford
into a circuit of one- and two-qudit gates.import trueq as tq import trueq.math as tqm tq.compilation.decompose_clifford(tqm.Clifford.random(3))
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.y- Name:
-
- Gate.y
- Aliases:
-
- Gate.y
- Gate.cliff2
- Generators:
-
- 'Y': -180.0
- Matrix:
-
-
1.00 -1.00
-
(1): Gate.z- Name:
-
- Gate.z
- Aliases:
-
- Gate.z
- Gate.cliff3
- Generators:
-
- 'Z': 180.0
- Matrix:
-
-
1.00 -1.00
-
(2): Gate.cliff15- Name:
-
- Gate.cliff15
- Aliases:
-
- Gate.cliff15
- Generators:
-
- 'Y': -127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71j -0.71j -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(1, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(2): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(1, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(2): Gate.cliff16- Name:
-
- Gate.cliff16
- Aliases:
-
- Gate.cliff16
- Generators:
-
- 'Y': -69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71 0.71j -0.71j
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
(2): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.cliff15- Name:
-
- Gate.cliff15
- Aliases:
-
- Gate.cliff15
- Generators:
-
- 'Y': -127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71j -0.71j -0.71
-
  By default, the returned circuit acts on labels
0, 1, ..., n - 1
, wheren
is the number of systems the Clifford acts on. However custom labels can be specified with thelabels
parameter.import trueq as tq import trueq.math as tqm tq.compilation.decompose_clifford(tqm.Clifford.random(3), labels=[2, 3, 4])
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.sy- Name:
-
- Gate.sy
- Aliases:
-
- Gate.sy
- Gate.cliff7
- Generators:
-
- 'Y': 90.0
- Matrix:
-
-
0.71 -0.71 0.71 0.71
-
(3): Gate.y- Name:
-
- Gate.y
- Aliases:
-
- Gate.y
- Gate.cliff2
- Generators:
-
- 'Y': -180.0
- Matrix:
-
-
1.00 -1.00
-
(4): Gate.cliff19- Name:
-
- Gate.cliff19
- Aliases:
-
- Gate.cliff19
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': 69.282
- Matrix:
-
-
0.71 -0.71 0.71j 0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(3, 4): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(3): Gate.cliff16- Name:
-
- Gate.cliff16
- Aliases:
-
- Gate.cliff16
- Generators:
-
- 'Y': -69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71 0.71j -0.71j
-
(4): Gate.cliff16- Name:
-
- Gate.cliff16
- Aliases:
-
- Gate.cliff16
- Generators:
-
- 'Y': -69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71 0.71j -0.71j
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(3): Gate.cliff16- Name:
-
- Gate.cliff16
- Aliases:
-
- Gate.cliff16
- Generators:
-
- 'Y': -69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71 0.71j -0.71j
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2, 4): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
(4): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  When
graph
is specified the two-qudit gates are restricted to only act on qudits that are adjacent in the provided topology.In the example below, we decompose a four qubit clifford acting on the specified labels with linear connectivity. Here the only allowed two-qubit gate pairings are
2-3
,3-4
, and4-5
.import trueq as tq import trueq.math as tqm tq.compilation.decompose_clifford( tqm.Clifford.random(4), labels=[2, 3, 4, 5], graph=tq.visualization.Graph.linear(6), )
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.sy- Name:
-
- Gate.sy
- Aliases:
-
- Gate.sy
- Gate.cliff7
- Generators:
-
- 'Y': 90.0
- Matrix:
-
-
0.71 -0.71 0.71 0.71
-
(3): Gate.cliff6- Name:
-
- Gate.cliff6
- Aliases:
-
- Gate.cliff6
- Generators:
-
- 'Y': -90.0
- Matrix:
-
-
0.71 0.71 -0.71 0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(2, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
(3): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(2, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(3): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(5): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(4): Gate.cliff13- Name:
-
- Gate.cliff13
- Aliases:
-
- Gate.cliff13
- Generators:
-
- 'X': -127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 -0.71 -0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(4, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(3): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(4): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(4, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(3): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
1.00 1.00j
-
(4): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(3, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(3): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(3, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.cliff21- Name:
-
- Gate.cliff21
- Aliases:
-
- Gate.cliff21
- Generators:
-
- 'Y': -69.282
- 'X': 69.282
- 'Z': 69.282
- Matrix:
-
-
0.71 0.71 -0.71j 0.71j
-
(3): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
1.00 1.00j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(5, 4): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(4): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(5): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(5, 4): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(4): Gate.cliff18- Name:
-
- Gate.cliff18
- Aliases:
-
- Gate.cliff18
- Generators:
-
- 'Y': 69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71j 0.71 -0.71j
-
(5): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(4, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(3): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(4): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(4, 3): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(3): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
(4): Gate.s- Name:
-
- Gate.s
- Aliases:
-
- Gate.s
- Gate.sz
- Gate.cliff9
- Generators:
-
- 'Z': 90.0
- Matrix:
-
-
1.00 1.00j
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(3, 2): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(3): Gate.cliff16- Name:
-
- Gate.cliff16
- Aliases:
-
- Gate.cliff16
- Generators:
-
- 'Y': -69.282
- 'X': -69.282
- 'Z': -69.282
- Matrix:
-
-
0.71 0.71 0.71j -0.71j
-
Additionally, we are able to decompose cliffords acting on non-connected labels of a given graph. For example:
import trueq as tq import trueq.math as tqm tq.compilation.decompose_clifford( tqm.Clifford.cz(), labels=[0, 2], graph=tq.visualization.Graph.linear(3), )
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".Circuit- Key:
- No key present in circuit.
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(0, 1): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(2, 1): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(2): Gate.id- Name:
-
- Gate.id
- Aliases:
-
- Gate.id
- Gate.i
- Gate.cliff0
- Likeness:
-
- Identity
- Generators:
-
- 'I': 0
- Matrix:
-
-
1.00 1.00
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(1, 0): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
(1): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
- Marker 0
Compilation tools may only recompile cycles with equal markers.(1, 0): Gate.cz- Name:
-
- Gate.cz
- Aliases:
-
- Gate.cz
- Likeness:
-
- CNOT
- Generators:
-
- 'ZZ': -90.0
- 'ZI': 90.0
- 'IZ': 90.0
- Matrix:
-
-
1.00 1.00 1.00 -1.00
-
  - Marker 0
Compilation tools may only recompile cycles with equal markers.(0): Gate.h- Name:
-
- Gate.h
- Aliases:
-
- Gate.h
- Gate.f
- Gate.cliff12
- Generators:
-
- 'X': 127.279
- 'Z': 127.279
- Matrix:
-
-
0.71 0.71 0.71 -0.71
-
  - Parameters:
clifford (
trueq.math.weyl.Clifford
) – The Clifford to be decomposed.labels (
Iterable
) – The labels that the Clifford is acting on. The default value is0, 1, ..., n - 1
, wheren
is the number of systems the Clifford acts on.graph (
trueq.visualization.Graph
) – The graph that specifies the qudit layout. The default value is a system with fully connected qudits.root (
int
) – The root vertex to use when creating a spanning tree ofgraph
. The default value is an element of the center ofgraph
.
rtype:
trueq.Circuit
- Raises:
ValueError – If sizes
clifford
andlabels
are different.ValueError – If labels of
graph
do not containlabels
.ValueError – If
graph
is not connected.
- class trueq.compilation.decompose_control(gate, dim=None)
Decomposes the provided
Gate
as a smaller unitary acting on a subset of qubits conditioned on a particular bitstring on the remaining qubits.The output format is a triple
(control, u_sys, u)
whereu
is a unitary matrix,u_sys
is a tuple of subsystem indices thatu
acts on to create the gate, andcontrol
is a dictionary mapping the remaining subsystem indices to the computation basis state thatu
is controlled on.This function interprets every gate to be a controlled unitary by allowing
u_sys
to be a list of all subsystem indexes andcontrol
to be an empty dictionary.In the first example, we see that a CNOT is an X gate on subsystem
(1,)
(i.e. the second of two subsystems) with control string"1"
.import trueq.compilation as tqc control, u_sys, u = tqc.decompose_control(tq.Gate.cnot) print("control:", control, "u_sys:", u_sys) print(u)
control: {0: 1} u_sys: (1,) [[0.+0.j 1.+0.j] [1.+0.j 0.+0.j]]
In the second example, we see that a CZ is a 1 dimensional gate conditioned on both qubits being in the
"11"
state:import trueq.compilation as tqc control, u_sys, u = tqc.decompose_control(tq.Gate.cz) print("control:", control, "u_sys:", u_sys) print(u)
control: {0: 1, 1: 1} u_sys: () [[-1.+0.j]]
In the final example, we see that this method is essentially an inverse function to
controlled()
. Note thatu
is swapped relative togate
becauseu_sys
is always ordered, whereaspos
can be any order, as in this example.import trueq.compilation as tqc gate = tq.Gate.random(4) control, u_sys, u = tqc.decompose_control(gate.controlled("10", pos=[3, 1])) print("control:", control, "u_sys:", u_sys) # note that we must add swaps because pos=[3, 1] above reversed the subsystems assert tq.Gate.swap @ tq.Gate(u) @ tq.Gate.swap == gate
control: {0: 1, 2: 0} u_sys: (1, 3)
- Parameters:
gate (
Gate
) – The gate to decompose.dim (
int
|None
) – The dimension of each subsystem. If not provided, the smallest compatible prime will be chosen, and failing that, the size of the gate itself.
- Raises:
ValueError – If the provided
dim
is incompatible with the gate size.