QubitSparsePauli
class qiskit.quantum_info.QubitSparsePauli
Bases: object
A phase-less Pauli operator stored in a qubit-sparse format.
Representation
A Pauli operator is a tensor product of single-qubit Pauli operators of the form , for . The internal representation of a QubitSparsePauli
stores only the non-identity single-qubit Pauli operators.
Internally, each single-qubit Pauli operator is stored with a numeric value, explicitly:
Label | Operator | Numeric value | Pauli attribute |
---|---|---|---|
"I" | (identity) | Not stored. | Not stored. |
"X" | (Pauli X) | 0b10 (2) | X |
"Y" | (Pauli Y) | 0b11 (3) | Y |
"Z" | (Pauli Z) | 0b01 (1) | Z |
Attribute | Length | Description |
---|---|---|
paulis | Each of the non-identity single-qubit Pauli operators. These correspond to the non-identity in the list, where the entries are stored in order of increasing first, and in order of increasing within each term. | |
indices | The corresponding qubit () for each of the operators in paulis . QubitSparsePauli requires that this list is term-wise sorted, and algorithms can rely on this invariant being upheld. |
The parameter is the total number of non-identity single-qubit terms.
The scalar item of the paulis
array is stored as a numeric byte. The numeric values are related to the symplectic Pauli representation that SparsePauliOp
uses, and are accessible with named access by an enumeration:
Pauli
class Pauli
An IntEnum
that provides named access to the numerical values used to represent each of the single-qubit alphabet terms enumerated in Alphabet of single-qubit Pauli operators used in QubitSparsePauliList.
This class is attached to QubitSparsePauli
. Access it as QubitSparsePauli.Pauli
. If this is too much typing, and you are solely dealing with QubitSparsePauliList
objects and the Pauli
name is not ambiguous, you might want to shorten it as:
>>> ops = QubitSparsePauli.Pauli
>>> assert ops.X is QubitSparsePauli.Pauli.X
You can access all the values of the enumeration either with attribute access, or with dictionary-like indexing by string:
>>> assert QubitSparsePauli.Pauli.X is QubitSparsePauli.Pauli["X"]
The bits representing each single-qubit Pauli are the (phase-less) symplectic representation of the Pauli operator.
Values
X
Default value: 2
The Pauli operator. Uses the single-letter label "X"
.
Y
Default value: 3
The Pauli operator. Uses the single-letter label "Y"
.
Z
Default value: 1
The Pauli operator. Uses the single-letter label "Z"
.
Each of the array-like attributes behaves like a Python sequence. You can index and slice these with standard list
-like semantics. Slicing an attribute returns a Numpy ndarray
containing a copy of the relevant data with the natural dtype
of the field; this lets you easily do mathematics on the results, like bitwise operations on paulis
.
Construction
QubitSparsePauli
defines several constructors. The default constructor will attempt to delegate to one of the more specific constructors, based on the type of the input. You can always use the specific constructors to have more control over the construction.
Method | Summary |
---|---|
from_label() | Convert a dense string label into a QubitSparsePauli . |
from_sparse_label() | Build a QubitSparsePauli from a tuple of a sparse string label and the qubits they apply to. |
from_pauli() | Raise a single Pauli into a single-element QubitSparsePauli . |
from_raw_parts() | Build the list from the raw data arrays. |
__new__
__new__(data, /, num_qubits=None)
The default constructor of QubitSparsePauli
.
This delegates to one of the explicit conversion-constructor methods, based on the type of the data
argument. If num_qubits
is supplied and constructor implied by the type of data
does not accept a number, the given integer must match the input.
Parameters
- data – The data type of the input. This can be another
QubitSparsePauli
, in which case the input is copied, or it can be a valid format for eitherfrom_label()
orfrom_sparse_label()
. - num_qubits (int|None) – Optional number of qubits for the operator. For most data inputs, this can be inferred and need not be passed. It is only necessary for the sparse-label format. If given unnecessarily, it must match the data input.
Attributes
indices
Read-only view onto the indices of each non-identity single-qubit term.
The indices will always be in sorted order.
num_qubits
The number of qubits the term is defined on.
paulis
Read-only view onto the individual single-qubit terms.
The only valid values in the array are those with a corresponding Pauli
.
Methods
commutes
commutes(other)
Check if self` commutes with another qubit sparse pauli.
Parameters
other (QubitSparsePauli) – the qubit sparse Pauli to check for commutation with.
compose
compose(other)
Phaseless composition with another QubitSparsePauli
.
Parameters
other (QubitSparsePauli) – the qubit sparse Pauli to compose with.
copy
copy()
Get a copy of this term.
from_label
static from_label(label, /)
Construct from a dense string label.
The label must be a sequence of the alphabet 'IXYZ'
. The label is interpreted analogously to a bitstring. In other words, the right-most letter is associated with qubit 0, and so on. This is the same as the labels for Pauli
and SparsePauliOp
.
Parameters
label (str) – the dense label.
Examples
>>> QubitSparsePauli.from_label("IIIIXZI")
<QubitSparsePauli on 7 qubits: X_2 Z_1>
>>> label = "IYXZI"
>>> pauli = Pauli(label)
>>> assert QubitSparsePauli.from_label(label) == QubitSparsePauli.from_pauli(pauli)
from_pauli
static from_pauli(pauli, /)
Construct a QubitSparsePauli
from a single Pauli
instance.
Note that the phase of the Pauli is dropped.
Parameters
pauli (Pauli
) – the single Pauli to convert.
Examples
>>> label = "IYXZI"
>>> pauli = Pauli(label)
>>> QubitSparsePauli.from_pauli(pauli)
<QubitSparsePauli on 5 qubits: Y_3 X_2 Z_1>
>>> assert QubitSparsePauli.from_label(label) == QubitSparsePauli.from_pauli(pauli)
from_raw_parts
static from_raw_parts(num_qubits, paulis, indices)
Construct a QubitSparsePauli
from raw Numpy arrays that match the required data representation described in the class-level documentation.
The data from each array is copied into fresh, growable Rust-space allocations.
Parameters
- num_qubits – number of qubits the operator acts on.
- paulis – list of the single-qubit terms. This should be a Numpy array with dtype
uint8
(which is compatible withPauli
). - indices – sorted list of the qubits each single-qubit term corresponds to. This should be a Numpy array with dtype
uint32
.
Examples
Construct a operator acting on qubit 50 of 100 qubits.
>>> num_qubits = 100
>>> terms = np.array([QubitSparsePauli.Pauli.Z], dtype=np.uint8)
>>> indices = np.array([50], dtype=np.uint32)
>>> QubitSparsePauli.from_raw_parts(num_qubits, terms, indices)
<QubitSparsePauli on 100 qubits: Z_50>
from_sparse_label
static from_sparse_label(sparse_label, num_qubits)
Construct a qubit sparse Pauli from a sparse label, given as a tuple of a string of Paulis, and the indices of the corresponding qubits.
This is analogous to SparsePauliOp.from_sparse_list()
.
Parameters
- sparse_label (tuple[str, Sequence[int]]) – labels and the qubits each single-qubit term applies to.
- num_qubits (int) – the number of qubits the operator acts on.
Examples
Construct a simple Pauli:
>>> QubitSparsePauli.from_sparse_label(
... ("ZX", (1, 4)),
... num_qubits=5,
... )
<QubitSparsePauli on 5 qubits: X_4 Z_1>
This method can replicate the behavior of from_label()
, if the qubit-arguments field of the tuple is set to decreasing integers:
>>> label = "XYXZ"
>>> from_label = QubitSparsePauli.from_label(label)
>>> from_sparse_label = QubitSparsePauli.from_sparse_label(
... (label, (3, 2, 1, 0)),
... num_qubits=4
... )
>>> assert from_label == from_sparse_label
identity
static identity(num_qubits)
Get the identity operator for a given number of qubits.
Examples
Get the identity on 100 qubits:
>>> QubitSparsePauli.identity(100)
<QubitSparsePauli on 100 qubits: >
to_qubit_sparse_pauli_list
to_qubit_sparse_pauli_list()
Convert this Pauli into a single element QubitSparsePauliList
.