paulicirc.gadgets

Pauli gadgets.

CommutationCode

CommutationCode

A number 0-7 describing how two Pauli gadgets are to be commuted past each other. See Gadget.commute_past for a description of the commutation procedure and associated commutation code conventions.

Gadget

final class Gadget(data, num_qubits=None, *, _ephemeral=False)[source]

Bases: object

A Pauli gadget.

static assemble_data(legs, phase)[source]

Assembles gadget data from the given legs and phase.

Parameters:
Return type:

GadgetData

clone()[source]

Creates a persistent copy of the gadget.

Return type:

Self

commute_past(other, code)[source]

Commutes this gadget past the given gadget, using the given CommutationCode to determine how the gadgets are to be commuted.

If code=0, the gadgets are not commuted:

p.commute_past(q, 0) # -> (p, q, None)

If the gadgets have even overlap, commutation always swaps them, regardless of the commutation code:

# p.overlap(q) % 2 == 0
p.commute_past(q, code) # -> (q, p, None)

If the gadgets have odd overlap, commutation codes 1-7 correspond to the six possible ways to commute them, each resulting in a gadget triple:

# p.overlap(q) % 2 != 0
# code in range(1, 8)
p.commute_past(q, code) # -> (r, s, t)

The following mathematical procedure is used to compute the triple (r, s, t) of gadgets obtained by commuting (p, q). Note that gadget ordering is read left-to-right, so that (p, q) means “p first, q second” and (r, s, t) means “r first, s second, r third”; this is the opposite convention to matrix multiplication, which is read right-to-left instead.

  1. The gadgets (p, q) are simultaneously mapped, by means of a suitable Clifford circuit, to X and Z rotations on qubit 0. The rotations are either (x(0, p.phase), z(0, q.phase)) or (z(0, p.phase), x(0, q.phase)), depending on whether there is an even or odd number of occurrences, respectively, of ZX, XY or YZ pairs in corresponding legs of p and q.

  2. The X and Z rotations on qubit 0 are commuted past each other in one of six possible ways, described below and corresponding to commutation codes 1-7. This results in a sequence of three Pauli rotations on qubit 0, chosen between X, Y and Z rotations.

  3. The three Pauli rotations on qubit 0 are simultaneously mapped back to gadgets (r, s, t) by the inverse of the Clifford circuit from Step 1.

The 6 possible commutations for Step 2 correspond to commutation codes 1-7 as follows, each commutation appearing in one of two flavours depending on whether Step 1 resulted in (rx, rz) or (rz, rx).

  • Code 1: (x, z) -> (z, y, z) and (z, x) -> (x, y, x)

  • Code 2: (x, z) -> (y, z, y) and (z, x) -> (y, x, y)

  • Code 3: (x, z) -> (x, y, x) and (z, x) -> (z, y, z)

  • Code 4: (x, z) -> (y, x, y) and (z, x) -> (y, z, y)

  • Code 5: (x, z) -> (z, x, y) and (z, x) -> (x, z, y)

  • Code 6: (x, z) -> (z, y, x) and (z, x) -> (x, y, z)

  • Code 7: (x, z) -> (y, z, x) and (z, x) -> (y, x, z)

Parameters:
Return type:

tuple[Gadget, Gadget, Gadget | None]

commutes_with(other)[source]

Returns whether this gadget commutes with the given gadget, i.e. whether the overlap is even.

Parameters:

other (Gadget)

Return type:

bool

static frac2phase(frac)[source]

Converts a fraction of \(\pi\) to a phase (as a float).

Parameters:

frac (Fraction)

Return type:

Phase

classmethod from_legs(legs, phase)[source]

Returns the gadget with given legs and phase.

Parameters:
Return type:

Self

classmethod from_paulistr(paulistr, phase)[source]

Returns the gadget with given legs (as paulistr) and phase.

Parameters:
Return type:

Self

classmethod from_sparse_paulistr(paulistr, qubits, num_qubits, phase)[source]

Returns the gadget with given legs (as a sparse paulistr) and phase.

Parameters:
Return type:

Self

inverse()[source]

Returns the inverse of this gadget, with phase negated.

Return type:

Self

property is_legless

Whether the gadget has no legs.

Return type:

bool

property is_zero

Whether the gadget has zero phase.

Return type:

bool

property leg_paulistr

Paulistring representation of the gadget legs.

Return type:

str

property legs

Legs of the gadget.

Return type:

PauliArray

static legs_from_paulistr(paulistr)[source]

Returns the legs corresponding to the given paulistr.

Parameters:

paulistr (str)

Return type:

PauliArray

static legs_from_sparse_paulistr(paulistr, qubits, num_qubits)[source]

Returns the legs corresponding to the given sparse paulistr.

Parameters:
Return type:

PauliArray

property num_qubits

Number of qubits in the gadget.

Return type:

int

overlap(other)[source]

Returns the overlap between the legs of this gadgets and those of the given gadget, computed as the number of qubits where the legs of the two gadgets differ and are both not the identity Pauli (the value 0, as a Pauli).

Parameters:

other (Gadget)

Return type:

int

property phase

Phase of the gadget, as an integer; see Phase.

Return type:

Phase

static phase2frac(phase)[source]

Converts a phase to a fraction of \(\pi\). The number of bits of precision is controlled by the value of options.display_prec: this is set to 8 by default, corresponding to multiples of \(\pi/256\).

Parameters:

phase (Phase)

Return type:

Fraction

property phase_frac

Exact representation of the gadget phase as a fraction of \(\pi\).

Return type:

Fraction

property phase_str

String representation of the gadget phase, as a fraction of \(\pi\).

Return type:

str

classmethod random(num_qubits, *, allow_zero=True, allow_legless=True, rng=None)[source]

Returns a gadget with uniformly sampled legs and phase.

Parameters:
  • num_qubits (int)

  • allow_zero (bool; default = True)

  • allow_legless (bool; default = True)

  • rng (int | RNG | None)

Return type:

Self

statevec(input, canonical_phase=False)[source]

Computes the statevector resulting from the application of this gadget to the given input statevector.

Parameters:
Return type:

Complex128Array1D

unitary(*, canonical_phase=True)[source]

Returns the unitary matrix associated to this Pauli gadget.

Parameters:

canonical_phase (bool; default = True)

Return type:

Complex128Array2D

classmethod zero(num_qubits)[source]

Returns the gadget with no legs and zero phase.

Parameters:

num_qubits (int)

Return type:

Self

GadgetData

GadgetData

Type alias for data encoding a single Pauli gadget. This is a 1D array of bytes, where the last 2 bytes encode the phase.

The leg bit-pairs are packed, with 4 legs stored in each byte; see Pauli.

The phase is stored as a 16-bit integer, with the most significant byte first; see Phase.

alias of ndarray[tuple[int, …], dtype[uint8]]

PAULI_CHARS

PAULI_CHARS = ('_', 'X', 'Z', 'Y')

Single-character representations of Paulis, in order compatible with the chosen encoding (cf. Pauli).

PAULI_MATS

PAULI_MATS = (array([[1.+0.j, 0.+0.j],        [0.+0.j, 1.+0.j]]), array([[0.+0.j, 1.+0.j],        [1.+0.j, 0.+0.j]]), array([[ 1.+0.j,  0.+0.j],        [ 0.+0.j, -1.+0.j]]), array([[ 0.+0.j, -0.-1.j],        [ 0.+1.j,  0.+0.j]]))

The four Pauli matrices.

PHASE_NBYTES

PHASE_NBYTES = 8

Number of bytes used for phase representation.

Pauli

Pauli

Type alias for a Pauli, encoded as a 2-bit integer: 0b00 is I, 0b01 is X, 0b10 is Z, 0b11 is Y.

alias of Literal[0, 1, 2, 3]

PauliArray

PauliArray

Type alias for a 1D array of Paulis, as 1D UInt8 array with entries in range(4).

alias of ndarray[tuple[int, …], dtype[uint8]]

PauliArray2D

PauliArray2D

Type alias for a 2D array of Paulis, as 1D UInt8 array with entries in range(4).

alias of ndarray[tuple[int, …], dtype[uint8]]

PauliChar

PauliChar

Type alias for single-character representations of Paulis. Note that I is represented as _, following the same convention as stim.

alias of Literal[‘_’, ‘X’, ‘Z’, ‘Y’]

Phase

Phase

Type alias for a phase, as a 64-bit float.

PhaseArray

PhaseArray

Type alias for a 1D array of phases.

alias of ndarray[tuple[int, …], dtype[floating[Any]]]

PhaseDataArray

PhaseDataArray

Type alias for a 1D array of encoded phase data, as a 2D UInt8 NumPy array of shape (n, PHASE_NBYTES).

alias of ndarray[tuple[int, …], dtype[uint8]]

PhaseLike

PhaseLike = float | fractions.Fraction

Type alias for values which can be used to specify a phase:

  • as a floating point value in \([0, 2\pi)\), see Phase

  • as a fraction of \(\pi\)

QubitIdx

QubitIdx

Type alias for the index of a qubit.

QubitIdxs

QubitIdxs

Type alias for a sequence of indexes of qubits.

alias of Sequence[int] | ndarray[tuple[int, …], dtype[unsignedinteger[Any]]]

are_same_phase

are_same_phase(lhs, rhs)[source]

Low-level function. Whether the given phases are deemed to be the same.

Parameters:
Return type:

bool

are_same_phases

are_same_phases(lhs, rhs)[source]

Low-level function. Whether the given phase arrays are deemed to be the same.

Parameters:
Return type:

bool

broadcast_idxs

broadcast_idxs(*idxs_seq)[source]

Low-level function. Broadcasts any number of sequences of qubit indexes to a common length, defined as the least common multiple of lengths for index sequences. Individual qubit indexes passed to this function are considered the same as singleton index sequences. If any sequence is empty, the returned sequences are all empty.

Parameters:

idxs_seq (QubitIdx | QubitIdxs; variadic positional)

Return type:

tuple[QubitIdxs, …]

commute_gadget_pair

commute_gadget_pair = CPUDispatcher(<function commute_gadget_pair>)[source]

Low-level function. Used by Gadget.commute_past to commute a pair of gadgets. It operates on a single array, containing the linearised data for the two gadgets to be commuted, as well as auxiliary space for a third gadget. It expects data for the third gadget to be set to zero, except for the desired commutation code (cf. CommutationCode) which should be written on the last byte.

decode_phases

decode_phases = CPUDispatcher(<function decode_phases>)[source]

Low-level function. Decodes phase data from a gadget circuit into an array of phases.

encode_phases

encode_phases = CPUDispatcher(<function encode_phases>)[source]

Low-level function. Encodes an array of phases into phase data for a gadget circuit.

gadget_data_len

gadget_data_len(num_qubits)[source]

Low-level function. Low-level function. Returns the length of gadget data.

Parameters:

num_qubits (int)

Return type:

int

gadget_overlap

gadget_overlap = CPUDispatcher(<function gadget_overlap>)[source]

Low-level function. Gadget overlap.

get_gadget_leg_at

get_gadget_leg_at = CPUDispatcher(<function get_gadget_leg_at>)[source]

Low-level function. Extracts single leg data from the given gadget data.

get_gadget_legs

get_gadget_legs = CPUDispatcher(<function get_gadget_legs>)[source]

Low-level function. Extract an array of leg information from given gadget data. The returned array has values in range(4), where the encoding is explained in GadgetData.

get_gadget_legs_at

get_gadget_legs_at = CPUDispatcher(<function get_gadget_legs_at>)[source]

Low-level function. Extracts multiple leg data from the given gadget data.

get_phase

get_phase = CPUDispatcher(<function get_phase>)[source]

Low-level function. Extracts phase data from the given gadget data.

invert_phases

invert_phases = CPUDispatcher(<function invert_phases>)[source]

Low-level function. Inplace phase inversion for the given phase data.

is_zero_phase

is_zero_phase = CPUDispatcher(<function is_zero_phase>)[source]

Low-level function. Whether the given phase is deemed to be zero.

pauli_product_phase

pauli_product_phase = CPUDispatcher(<function pauli_product_phase>)[source]

Low-level function. Computes the phase acquired by a product of two paulistrings. Returns an integer \(e\) modulo 4, such that the phase is \(i^{e}\).

set_gadget_leg_at

set_gadget_leg_at = CPUDispatcher(<function set_gadget_leg_at>)[source]

Low-level function. Sets single leg data from the given gadget data.

set_gadget_legs

set_gadget_legs(g, legs)[source]

Low-level function. Sets leg information in the given gadget data. The input array should have values in range(4), where the encoding is explained in GadgetData.

Parameters:
Return type:

None

set_gadget_legs_at

set_gadget_legs_at = CPUDispatcher(<function set_gadget_legs_at>)[source]

Low-level function. Sets multiple leg data from the given gadget data.

set_phase

set_phase = CPUDispatcher(<function set_phase>)[source]

Low-level function. Sets phase data in the given gadget data.

zero_gadget_data

zero_gadget_data(num_qubits)[source]

Low-level function. Returns blank data for a gadget with the given number of qubits.

Parameters:

num_qubits (int)

Return type:

GadgetData