Trait pauli_tracker::tracker::Tracker
source · pub trait Tracker {
type Stack;
type Pauli: Pauli;
Show 40 methods
// Required methods
fn new_qubit(&mut self, bit: usize) -> Option<Self::Stack>;
fn track_pauli(&mut self, bit: usize, pauli: Self::Pauli);
fn track_pauli_string(&mut self, string: PauliString<Self::Pauli>);
fn s(&mut self, bit: usize);
fn h(&mut self, bit: usize);
fn cz(&mut self, bit_a: usize, bit_b: usize);
fn move_x_to_x(&mut self, source: usize, destination: usize);
fn move_x_to_z(&mut self, source: usize, destination: usize);
fn move_z_to_x(&mut self, source: usize, destination: usize);
fn move_z_to_z(&mut self, source: usize, destination: usize);
fn measure(&mut self, bit: usize) -> Result<Self::Stack, MissingBit>;
// Provided methods
fn track_x(&mut self, bit: usize) { ... }
fn track_y(&mut self, bit: usize) { ... }
fn track_z(&mut self, bit: usize) { ... }
fn id(&mut self, _: usize) { ... }
fn x(&mut self, bit: usize) { ... }
fn y(&mut self, bit: usize) { ... }
fn z(&mut self, bit: usize) { ... }
fn sdg(&mut self, bit: usize) { ... }
fn sz(&mut self, bit: usize) { ... }
fn szdg(&mut self, bit: usize) { ... }
fn hxy(&mut self, bit: usize) { ... }
fn sy(&mut self, bit: usize) { ... }
fn sydg(&mut self, bit: usize) { ... }
fn sh(&mut self, bit: usize) { ... }
fn hs(&mut self, bit: usize) { ... }
fn shs(&mut self, bit: usize) { ... }
fn sx(&mut self, bit: usize) { ... }
fn sxdg(&mut self, bit: usize) { ... }
fn hyz(&mut self, bit: usize) { ... }
fn cx(&mut self, control: usize, target: usize) { ... }
fn cy(&mut self, control: usize, target: usize) { ... }
fn swap(&mut self, bit_a: usize, bit_b: usize) { ... }
fn zcz(&mut self, control: usize, target: usize) { ... }
fn zcx(&mut self, bit_a: usize, bit_b: usize) { ... }
fn zcy(&mut self, control: usize, target: usize) { ... }
fn iswap(&mut self, bit_a: usize, bit_b: usize) { ... }
fn iswapdg(&mut self, bit_a: usize, bit_b: usize) { ... }
fn remove_x(&mut self, bit: usize) { ... }
fn remove_z(&mut self, bit: usize) { ... }
}
Expand description
The core API to track Paulis through a Clifford circuit.
The implementors must ensure that they implement the methods correctly according to the conjugation rules of Clifford gates with Pauli gates 1. While many gates have default implementations, one might want to implement them directly for performance reasons2.
For extensive examples, please refer to the library documentation.
The supported gates are also described in conjugation-rules. Note that all Clifford gates can be generated from S, H and CZ (cf conjugation-rules).
Using rust-analyzer’s “implement members” feature inserts some weird looking docs, which may not compile. This is because we generate a bunch of the methods with macros. You should delete these docs. ↩
The default implementations are implemented using the generators Tracker::h, Tracker::s and Tracker::cz. For example, Tracker::cx is implement as
self.h(target); self.cz(control, target); self.h(target);
. This can probably be done more efficiently by directly implementing this method (it’s for example trivial for Tracker::swap: three cnots vs one mem::swap). On the other hand, the default implementations are making use of the fact that the update rules are the same per coset with respect to the Pauli group, e.g., Tracker::sdg is justself.s(target);
, which is hopefully inlined (at least after lto). There’s probably no need to implement them directly, but only to implement the canonical coset repepresentatives directly. For the single qubit gates, these are: I, S, H, SH, HS, SHS (these are all single qubit Cliffords up to Paulis and phases). For the double-qubit gates, the standard representatives are: CZ, CX, CY, SWAP, iSWAP (these are NOT all two-qubits cosets (there are 720); we don’t write our standard representatives in S, H and CZ, because that would really get out of hand, instead we try to choose the most common gates). The conjugation-rules document contains some useful operator identities. ↩
Required Associated Types§
sourcetype Stack
type Stack
The storage type used to store the tracked Paulis for each qubit, e.g., PauliStack for the Frames tracker or just a simple Pauli for the Live tracker (in this case it’s a stack with one element …).
sourcetype Pauli: Pauli
type Pauli: Pauli
The type of Pauli representation used for operations like track_pauli. It is usally the type that is the most compatible with Self::Stack.
Required Methods§
sourcefn new_qubit(&mut self, bit: usize) -> Option<Self::Stack>
fn new_qubit(&mut self, bit: usize) -> Option<Self::Stack>
Insert a new qubit
into the tracker. If the qubit
is already present, the old
value is overwritten and returned.
sourcefn track_pauli(&mut self, bit: usize, pauli: Self::Pauli)
fn track_pauli(&mut self, bit: usize, pauli: Self::Pauli)
Track a new frame consisting of the Pauli gate pauli
at qubit
.
If qubit
is not tracked, the method does not error, but simply tracks an empty
frame.
sourcefn track_pauli_string(&mut self, string: PauliString<Self::Pauli>)
fn track_pauli_string(&mut self, string: PauliString<Self::Pauli>)
Track a new frame including multiple Pauli gates, i.e., i.e., do Tracker::track_pauli for multiple Paulis but all within the same frame.
sourcefn h(&mut self, bit: usize)
fn h(&mut self, bit: usize)
Update the tracked frames according the Hadamard gate on the qubit
.
sourcefn cz(&mut self, bit_a: usize, bit_b: usize)
fn cz(&mut self, bit_a: usize, bit_b: usize)
Update the tracked frames according to the Control Z on the bit_a
and bit_b
qubits.
sourcefn move_x_to_x(&mut self, source: usize, destination: usize)
fn move_x_to_x(&mut self, source: usize, destination: usize)
“Move” the
X
Pauli stack from the origin
qubit to the destination
qubit, transforming
it to an
X
stack.
sourcefn move_x_to_z(&mut self, source: usize, destination: usize)
fn move_x_to_z(&mut self, source: usize, destination: usize)
“Move” the
X
Pauli stack from the origin
qubit to the destination
qubit, transforming
it to an
Z
stack.
sourcefn move_z_to_x(&mut self, source: usize, destination: usize)
fn move_z_to_x(&mut self, source: usize, destination: usize)
“Move” the
Z
Pauli stack from the origin
qubit to the destination
qubit, transforming
it to an
X
stack.
sourcefn move_z_to_z(&mut self, source: usize, destination: usize)
fn move_z_to_z(&mut self, source: usize, destination: usize)
“Move” the
Z
Pauli stack from the origin
qubit to the destination
qubit, transforming
it to an
Z
stack.
Provided Methods§
sourcefn id(&mut self, _: usize)
fn id(&mut self, _: usize)
Update the tracked frames according the I gate on the qubit
.
(The identity)
sourcefn x(&mut self, bit: usize)
fn x(&mut self, bit: usize)
Update the tracked frames according the X gate on the qubit
. Equivalent to the I gate.
sourcefn y(&mut self, bit: usize)
fn y(&mut self, bit: usize)
Update the tracked frames according the Y gate on the qubit
. Equivalent to the I gate.
sourcefn z(&mut self, bit: usize)
fn z(&mut self, bit: usize)
Update the tracked frames according the Z gate on the qubit
. Equivalent to the I gate.
sourcefn sdg(&mut self, bit: usize)
fn sdg(&mut self, bit: usize)
Update the tracked frames according the S^dagger gate on the qubit
. Equivalent to the S gate.
sourcefn sz(&mut self, bit: usize)
fn sz(&mut self, bit: usize)
Update the tracked frames according the sqrt(Z) gate on the qubit
. Equivalent to the S gate.
sourcefn szdg(&mut self, bit: usize)
fn szdg(&mut self, bit: usize)
Update the tracked frames according the sqrt(Z)^dagger gate on the qubit
. Equivalent to the S gate.
sourcefn hxy(&mut self, bit: usize)
fn hxy(&mut self, bit: usize)
Update the tracked frames according the H^{xy} gate on the qubit
. Equivalent to the S gate.
sourcefn sy(&mut self, bit: usize)
fn sy(&mut self, bit: usize)
Update the tracked frames according the sqrt(Y) gate on the qubit
. Equivalent to the H gate.
sourcefn sydg(&mut self, bit: usize)
fn sydg(&mut self, bit: usize)
Update the tracked frames according the sqrt(Y)^dagger gate on the qubit
. Equivalent to the H gate.
sourcefn sx(&mut self, bit: usize)
fn sx(&mut self, bit: usize)
Update the tracked frames according the sqrt(X) gate on the qubit
. Equivalent to the SHS gate.
sourcefn sxdg(&mut self, bit: usize)
fn sxdg(&mut self, bit: usize)
Update the tracked frames according the sqrt(X)^dagger gate on the qubit
. Equivalent to the SHS gate.
sourcefn hyz(&mut self, bit: usize)
fn hyz(&mut self, bit: usize)
Update the tracked frames according the H_yz gate on the qubit
. Equivalent to the SHS gate.
sourcefn cx(&mut self, control: usize, target: usize)
fn cx(&mut self, control: usize, target: usize)
Update the tracked frames according to the Control X (Control Not) on the control
and target
qubits.
sourcefn cy(&mut self, control: usize, target: usize)
fn cy(&mut self, control: usize, target: usize)
Update the tracked frames according to the Control Y on the control
and target
qubits.
sourcefn swap(&mut self, bit_a: usize, bit_b: usize)
fn swap(&mut self, bit_a: usize, bit_b: usize)
Update the tracked frames according to the Swap on the bit_a
and bit_b
qubits.
sourcefn zcz(&mut self, control: usize, target: usize)
fn zcz(&mut self, control: usize, target: usize)
Update the tracked frames according to the Z-Control Z on the control
and target
qubits.
sourcefn zcx(&mut self, bit_a: usize, bit_b: usize)
fn zcx(&mut self, bit_a: usize, bit_b: usize)
Update the tracked frames according to the Z-Control X on the bit_a
and bit_b
qubits.
sourcefn zcy(&mut self, control: usize, target: usize)
fn zcy(&mut self, control: usize, target: usize)
Update the tracked frames according to the Z-Control X on the control
and target
qubits.
sourcefn iswap(&mut self, bit_a: usize, bit_b: usize)
fn iswap(&mut self, bit_a: usize, bit_b: usize)
Update the tracked frames according to the iSwap on the bit_a
and bit_b
qubits.