qml.pauli.pauli_to_binary¶
-
pauli_to_binary
(pauli_word, n_qubits=None, wire_map=None, check_is_pauli_word=True)[source]¶ Converts a Pauli word to the binary vector (symplectic) representation.
This functions follows convention that the first half of binary vector components specify PauliX placements while the last half specify PauliZ placements.
- Parameters
pauli_word (Union[Identity, PauliX, PauliY, PauliZ, Tensor, Prod, SProd]) – the Pauli word to be converted to binary vector representation
n_qubits (int) – number of qubits to specify dimension of binary vector representation
wire_map (dict) – dictionary containing all wire labels used in the Pauli word as keys, and unique integer labels as their values
check_is_pauli_word (bool) – If True (default) then a check is run to verify that pauli_word is in fact a Pauli word.
- Returns
the
2*n_qubits
dimensional binary vector representation of the input Pauli word- Return type
array
- Raises
TypeError – if the input
pauli_word
is not an instance of Identity, PauliX, PauliY, PauliZ or tensor products thereofValueError – if
n_qubits
is less than the number of wires acted on by the Pauli word
Example
If
n_qubits
andwire_map
are both unspecified, the dimensionality of the binary vector will be2 * len(pauli_word.wires)
. Regardless of wire labels, the vector components encoding Pauli operations will be read from left-to-right in the tensor product whenwire_map
is unspecified, e.g.,>>> pauli_to_binary(qml.X('a') @ qml.Y('b') @ qml.Z('c')) array([1., 1., 0., 0., 1., 1.]) >>> pauli_to_binary(qml.X('c') @ qml.Y('a') @ qml.Z('b')) array([1., 1., 0., 0., 1., 1.])
The above cases have the same binary representation since they are equivalent up to a relabelling of the wires. To keep binary vector component enumeration consistent with wire labelling across multiple Pauli words, or define any arbitrary enumeration, one can use keyword argument
wire_map
to set this enumeration.>>> wire_map = {'a': 0, 'b': 1, 'c': 2} >>> pauli_to_binary(qml.X('a') @ qml.Y('b') @ qml.Z('c'), wire_map=wire_map) array([1., 1., 0., 0., 1., 1.]) >>> pauli_to_binary(qml.X('c') @ qml.Y('a') @ qml.Z('b'), wire_map=wire_map) array([1., 0., 1., 1., 1., 0.])
Now the two Pauli words are distinct in the binary vector representation, as the vector components are consistently mapped from the wire labels, rather than enumerated left-to-right.
If
n_qubits
is unspecified, the dimensionality of the vector representation will be inferred from the size of support of the Pauli word,>>> pauli_to_binary(qml.X(0) @ qml.X(1)) array([1., 1., 0., 0.]) >>> pauli_to_binary(qml.X(0) @ qml.X(5)) array([1., 1., 0., 0.])
Dimensionality higher than twice the support can be specified by
n_qubits
,>>> pauli_to_binary(qml.X(0) @ qml.X(1), n_qubits=6) array([1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> pauli_to_binary(qml.X(0) @ qml.X(5), n_qubits=6) array([1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
For these Pauli words to have a consistent mapping to vector representation, we once again need to specify a
wire_map
.>>> wire_map = {0:0, 1:1, 5:5} >>> pauli_to_binary(qml.X(0) @ qml.X(1), n_qubits=6, wire_map=wire_map) array([1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> pauli_to_binary(qml.X(0) @ qml.X(5), n_qubits=6, wire_map=wire_map) array([1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.])
Note that if
n_qubits
is unspecified andwire_map
is specified, the dimensionality of the vector representation will be inferred from the highest integer inwire_map.values()
.>>> wire_map = {0:0, 1:1, 5:5} >>> pauli_to_binary(qml.X(0) @ qml.X(5), wire_map=wire_map) array([1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.])