Skip to main content
IBM Quantum Platform

qiskit_noise_learning.sequences.PartialPauliPermutation

class qiskit_noise_learning.sequences.PartialPauliPermutation(partial_permutation_indices: NDArray[int8])

GitHub

Bases: Instruction

Partially-specified permutations of the single-qubit phaseless Paulis on n qubits.

A PartialPauliPermutation represents a partial-specification of a layer of single qubit Cliffords for situations where the specific phases of the Pauli group need not be constrained. The partial nature of the specification is to enable progressively building such layers. Once a partial permutation is “complete” in the sense that is a full specification of a permutation, as indicated by the bool property PartialPauliPermutation.is_complete, a default Clifford implementing the permutation is assigned to each qubit according to the ordering in COMPLETE_TO_C1_TABLEAU.

Two partial permutations on a qubit are mergeable (see is_mergeable_with() and merge()) if there exists a single-qubit Clifford that implements both of their permutations, which without loss of generality is the statement that one doesn’t map a Pauli to a different Pauli than the other.

The main data representation of the class is a list of integers, where each integer indexes a particular single-qubit partial Pauli permutation given in partial_permutation_sets(), which provides a fixed ordering.

However, a human-readable set-based representation can also be used for construction via the PartialPauliPermutation.from_sets() class method, or can be retrieved from an instance via the PartialPauliPermutation.to_sets() method. For a single qubit, the partial permutation is specified as a set whose entries are tuples of the form (p0, p1), where p0 and p1 are strings drawn from ["Z", "X", "Y"]. This tuple indicates that p0 is mapped by the permutation to p1.

Parameters

partial_permutation_indices – A numpy array of index-specified partial permutations. The number of qubits is determined from the length.

__init__

__init__(partial_permutation_indices: NDArray[int8])


Methods

Column 1
Column 2
__init__(partial_permutation_indices)
complete()Return a new partial Permutation that is complete and consistent with self.
compose(other)Compose with another partial permutation.
empty(num_qubits)Generate the completely unspecified instance on num_qubits.
from_qubit_sparse_pauli_lists(in_paulis, ...)Construct a PartialPauliPermutation that maps in_paulis to out_paulis.
from_qubit_sparse_paulis(in_pauli, out_pauli)Construct a PartialPauliPermutation that maps in_pauli to out_pauli.
from_sets(sets)Construct from a list of sets.
is_mergeable_with(other)Whether or not this instruction is mergeable with another one.
merge(other)Merge self and other into a single instruction.
propagate(...)Given a Pauli, propagate it through the Clifford implied by this permutation.
to_sets()Return the set representation.

Attributes

Column 1
Column 2
inverseReturn the inversion of this partial permutation.
is_completeWhether self represents a complete specification of single-qubit Pauli permutations.
num_qubits
partial_permutation_indicesRaw numerical format of the partial permutation.
structure_tokenA hashable summary of this instruction that constrains mergeability.

inverse

Type: Self

Return the inversion of this partial permutation.

This returns a partially-specified inversion: only the existing mappings in this instance will be inverted. Note that the completion convention has been chosen to be consistent with inversion, in the sense that self.inverse.complete() == self.complete().inverse. Furthermore, the Clifford implied by COMPLETE_TO_C1_TABLEAU is the inverse of the implied Clifford.

is_complete

Type: bool

Whether self represents a complete specification of single-qubit Pauli permutations.

partial_permutation_indices

Type: NDArray[int8]

Raw numerical format of the partial permutation.

structure_token

Type: Hashable

A hashable summary of this instruction that constrains mergeability.

This token serves as a cheap check of non-mergeability: instructions with unequal structure tokens are never mergeable. The token must therefore distinguish instruction types from one another.

complete

complete() → Self

Return a new partial Permutation that is complete and consistent with self.

Note that the conventions have been chosen to ensure that:

  • Any partially-specified permutation consistent with the identity is mapped to the identity, and
  • self.inverse.complete() == self.complete().inverse.

Returns

A new PartialPauliPermutation containing the completion of self.

compose

compose(other: Self) → Self

Compose with another partial permutation.

For complete permutations, self.compose(other) returns the permutation assciated with C1 @ C2, where C1 and C2 are the Cliffords associated, respectively, with self and other. Partially specified permutations only contain a single mapping, and the composition is defined in the natural way only when the output of other is the input of self. Note finally that composition is not defined if one of self and other is incomplete, and the other is complete. This is due to the inability to ensure the commutation of completion and composition, described below.

Note that the completion convention has been chosen to be consistent with composition, in the sense that self.compose(other).complete() == self.complete().compose(other.complete()). Furthermore, for complete permutations, the mapping to the Clifford implied by COMPLETE_TO_C1_TABLEAU is a group homomorphism (preserves multiplication).

Parameters

other – The other to compose with.

Returns

The composed permutation.

Raises

ValueError – If the composition of self with other is undefined.

empty

classmethod empty(num_qubits: int) → Self

Generate the completely unspecified instance on num_qubits.

Parameters

num_qubits – Number of qubits.

Returns

A new, trivial PartialPauliPermutation.

from_qubit_sparse_paulis

classmethod from_qubit_sparse_paulis(in_pauli: QubitSparsePauli, out_pauli: QubitSparsePauli) → Self

Construct a PartialPauliPermutation that maps in_pauli to out_pauli.

Parameters

  • in_pauli – The Pauli to be mapped.
  • out_pauli – The Pauli to be mapped to.

Returns

A new PartialPauliPermutation that maps in_pauli to out_pauli.

Raises

ValueError – If in_pauli and out_pauli are not on the same number of qubits, or if they do not act on the same qubits.

from_qubit_sparse_pauli_lists

classmethod from_qubit_sparse_pauli_lists(in_paulis: QubitSparsePauliList, out_paulis: QubitSparsePauliList) → Self

Construct a PartialPauliPermutation that maps in_paulis to out_paulis.

Parameters

  • in_paulis – The Paulis to be mapped.
  • out_paulis – The Paulis to be mapped to.

Returns

A new PartialPauliPermutation.

Raises

ValueError – If the number of qubits are inconsistent, or the implied permutations are inconsistent.

from_sets

classmethod from_sets(sets: list[frozenset[tuple[str, str]]]) → Self

Construct from a list of sets.

See the class documentation for a description of the expected format.

Parameters

sets – The sets specifying the partial permutation.

Returns

A new instance.

Raises

ValueError – If any of the sets are not valid.

is_mergeable_with

is_mergeable_with(other)

Whether or not this instruction is mergeable with another one.

Two instructions are mergeable if a third instruction exists that simultaneously implements both of their actions. The trivial case is when the instructions are equal: the third instruction can be a third instance of the same instruction. However, non-trivial cases are possible because some instruction types, notably PartialPauliPermutation, do not necessarily fully specify their own action, so that unequal instances can nevertheless still have their constraints simultaneously satisfied by a single third instance.

If this method returns True, then the method merge() should succeed.

Parameters

other – The other instruction to check mergeablitity with.

Returns

Whether this instruction is mergeable with the other.

merge

merge(other)

Merge self and other into a single instruction.

Parameters

other – The other instruction to merge with.

Returns

Some instruction (possibly the same instance) that simultaneously implements the action of this instruction and the other instruction.

propagate

propagate(pauli: QubitSparsePauli, inverse: bool = False) → QubitSparsePauli

propagate(pauli: PhasedQubitSparsePauli, inverse: bool = False) → PhasedQubitSparsePauli

Given a Pauli, propagate it through the Clifford implied by this permutation.

This method works for both phased and unphased propagation depending on the type of the Pauli supplied. Unphased propagation can be performed on incomplete permutations, so long as the permutation is defined on the Pauli. Phased propagation requires self to be complete, so that an explicit Clifford can be associated with this instance.

Parameters

pauli – The Pauli to apply the layer to.

Returns

The evolved Pauli.

Raises

  • ValueError – If pauli.num_qubits != self.num_qubits, or if isinstance(pauli, PhasedQubitSparsePauli and not self.is_complete, or if pauli is unphased and this instance is undefined on it.
  • TypeError – If pauli is an invalid type.

to_sets

to_sets() → list[frozenset[tuple[str, str]]]

Return the set representation.

Was this page helpful?
Report a bug, typo, or request content on GitHub.