qiskit_noise_learning.sequences.PartialPauliPermutation
class qiskit_noise_learning.sequences.PartialPauliPermutation(partial_permutation_indices: NDArray[int8])
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 |
|---|---|
inverse | Return the inversion of this partial permutation. |
is_complete | Whether self represents a complete specification of single-qubit Pauli permutations. |
num_qubits | |
partial_permutation_indices | Raw numerical format of the partial permutation. |
structure_token | A 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 ifisinstance(pauli, PhasedQubitSparsePauli and not self.is_complete, or ifpauliis unphased and this instance is undefined on it. - TypeError – If
pauliis an invalid type.
to_sets
to_sets() → list[frozenset[tuple[str, str]]]
Return the set representation.