# pyquil.paulis module¶

Module for working with Pauli algebras.

pyquil.paulis.HASH_PRECISION = 1000000.0

The precision used when hashing terms to check equality. The simplify() method uses np.isclose() for coefficient comparisons to 0 which has its own default precision. We can’t use np.isclose() for hashing terms though.

pyquil.paulis.ID() [source]

Identity operator.

class pyquil.paulis.PauliSum(terms: Sequence[PauliTerm])[source]

Bases: `object`

A sum of one or more PauliTerms.

Initialize a PauliSum with a list of PauliTerms.

Parameters:

terms (Sequence) – A Sequence of PauliTerms.

compact_str() str[source]

Return a string representation of the PauliSum that is more compact than `str(pauli_sum)`.

```>>> pauli_sum = 2.0 * sX(1) * sZ(2) + 1.5 * sY(2)
>>> str(pauli_sum)
'(2+0j)*X1*Z2 + (1.5+0j)*Y2'
>>> pauli_sum.compact_str()
'(2+0j)*X1Z2+(1.5+0j)*Y2'
```
classmethod from_compact_str(str_pauli_sum: str) [source]

Construct a PauliSum from the result of str(pauli_sum).

get_programs() tuple[list[Program], ndarray][source]

Get a Pyquil Program corresponding to each term in the PauliSum and a coefficient for each program.

Returns:

(programs, coefficients)

get_qubits() list[Qubit | QubitPlaceholder | FormalArgument | int][source]

Get the qubits that this PauliSum operates on.

Returns:

A list of all the qubits in the sum of terms.

simplify() [source]

Simplify the sum of Pauli operators according to Pauli algebra rules.

class pyquil.paulis.PauliTerm(op: str, index: Qubit | QubitPlaceholder | FormalArgument | int | None, coefficient: Expression | int | float | complex = 1.0)[source]

Bases: `object`

A term is a product of Pauli operators operating on different qubits.

Create a new Pauli Term with a Pauli operator at a particular index and a leading coefficient.

Parameters:
• op – The Pauli operator as a string “X”, “Y”, “Z”, or “I”

• index – The qubit index that that operator is applied to.

• coefficient – The coefficient multiplying the operator, e.g. 1.5 * Z_1

compact_str() str[source]

Return string representation of the Pauli term that is more compact than `str(term)`.

```>>> term = 2.0 * sX(1) * sZ(2)
>>> str(term)
'(2+0j)*X1*Z2'
>>> term.compact_str()
'(2+0j)*X1Z2'
```
copy() [source]

Create a new PauliTerm, with a completely new dictionary of operators.

classmethod from_compact_str(str_pauli_term: str) [source]

Construct a PauliTerm from the result of str(pauli_term).

classmethod from_list(terms_list: Sequence[tuple[str, Qubit | QubitPlaceholder | FormalArgument | int]], coefficient: Expression | int | float | complex = 1.0) [source]

Allocate a PauliTerm from a list of operators and indices.

This is more efficient than multiplying together individual terms.

Parameters:

terms_list (list) – A list of tuples, e.g. [(“X”, 0), (“Y”, 1)]

Returns:

PauliTerm

get_qubits() list[Qubit | QubitPlaceholder | FormalArgument | int][source]

Get all the qubits that this PauliTerm operates on.

id(sort_ops: bool = True) str[source]

Return an identifier string for the PauliTerm (ignoring the coefficient).

Don’t use this to compare terms. This function will not work with qubits that aren’t sortable.

Parameters:

sort_ops – Whether to sort operations by qubit. This is True by default for backwards compatibility but will change in a future version. Callers should never rely on comparing id’s for testing equality. See `operations_as_set` instead.

Returns:

A string representation of this term’s operations.

operations_as_set() frozenset[tuple[Qubit | QubitPlaceholder | FormalArgument | int, str]][source]

Return a frozenset of operations in this term.

Use this in place of `id()` if the order of operations in the term does not matter.

Returns:

frozenset of (qubit, op_str) representing Pauli operations

pauli_string(qubits: Iterable[int] | None = None) str[source]

Return a string representation of this PauliTerm without its coefficient and with implicit qubit indices.

If an iterable of qubits is provided, each character in the resulting string represents a Pauli operator on the corresponding qubit.

```>>> p = PauliTerm("X", 0) * PauliTerm("Y", 1, 1.0j)
>>> p.pauli_string()
'XY'
>>> p.pauli_string(qubits=[0])
'X'
>>> p.pauli_string(qubits=[0, 2])
'XI'
```
Parameters:

qubits (iterable of) – The iterable of qubits to represent, given as ints.

Returns:

The string representation of this PauliTerm, sans coefficient

property program: Program

Create Program from the PauliTerm.

exception pyquil.paulis.UnequalLengthWarning(*args: object, **kwargs: object)[source]

Bases: `Warning`

Warning issued when multiplying PauliTerms of different lengths.

Initialize the warning.

pyquil.paulis.ZERO() [source]

Zero operator.

pyquil.paulis.check_commutation(pauli_list: Sequence[PauliTerm], pauli_two: PauliTerm) bool[source]

Check if commuting a PauliTerm commutes with a list of other terms by natural calculation.

Uses the result in Section 3 of arXiv:1405.5749v2, modified slightly here to check for the number of anti-coincidences (which must always be even for commuting PauliTerms) instead of the no. of coincidences, as in the paper.

Parameters:
• pauli_list – A list of PauliTerm objects

• pauli_two_term – A PauliTerm object

Returns:

True if pauli_two object commutes with pauli_list, False otherwise

pyquil.paulis.commuting_sets(pauli_terms: PauliSum) list[list[PauliTerm]][source]

Gather the Pauli terms of pauli_terms variable into commuting sets.

Uses algorithm defined in (Raeisi, Wiebe, Sanders, arXiv:1108.4318, 2011) to find commuting sets. Except uses commutation check from arXiv:1405.5749v2

Parameters:

pauli_terms – A PauliSum object

Returns:

List of lists where each list contains a commuting set

pyquil.paulis.exponential_map(term: PauliTerm) Callable[[float], Program][source]

Return a function f(alpha) that constructs the Program corresponding to exp(-1j*alpha*term).

Parameters:

term – A pauli term to exponentiate

Returns:

A function that takes an angle parameter and returns a program.

pyquil.paulis.exponentiate(term: PauliTerm) [source]

Create a pyQuil program that simulates the unitary evolution exp(-1j * term).

Parameters:

term – A pauli term to exponentiate

Returns:

A Program object

pyquil.paulis.exponentiate_commuting_pauli_sum(pauli_sum: PauliSum) Callable[[float], Program][source]

Return a function that maps all substituent PauliTerms and sums them into a program.

NOTE: Use this function with care. Substituent PauliTerms should commute.

Parameters:

pauli_sum – PauliSum to exponentiate.

Returns:

A function that parametrizes the exponential.

pyquil.paulis.exponentiate_pauli_sum(pauli_sum: ) ndarray[Any, dtype[complex128]][source]

Exponentiate a sequence of PauliTerms, which may or may not commute.

The Pauliterms must have fixed (non-parametric) coefficients. The coefficients are interpreted in cycles rather than radians or degrees.

e^{-ipisum_i theta_i P_i}

Thus, 1.0 corresponds to one full rotation.

To produce a CZ gate:

```>>> from numpy import pi
>>> phi = pi
>>> coeff = phi / (-4 * pi)  # -0.25
>>> hamiltonian = PauliTerm("Z", 0) * PauliTerm("Z", 1) - 1 * PauliTerm("Z", 0) - 1 * PauliTerm("Z", 1)
>>> exponentiate_pauli_sum(coeff * hamiltonian)
array([[...]])
```

To produce the Quil XY(theta) gate, you can use:

```>>> theta = pi / 2
>>> coeff = theta / (-4 * pi)
>>> hamiltonian = PauliTerm("X", 0) * PauliTerm("X", 1) + PauliTerm("Y", 0) * PauliTerm("Y", 1)
>>> exponentiate_pauli_sum(coeff * hamiltonian)
array([[...]])
```

A global phase is applied to the unitary such that the [0,0] element is always real.

Parameters:

pauli_sum – PauliSum to exponentiate.

Returns:

The matrix exponent of the PauliSum

pyquil.paulis.integer_types = (<class 'int'>, <class 'numpy.int64'>, <class 'numpy.int32'>, <class 'numpy.int16'>, <class 'numpy.int8'>)

Explicitly include numpy integer dtypes (for python 3).

pyquil.paulis.is_identity(term: ) bool[source]

Return True if PauliTerm or PauliSum is a scalar multiple of identity, False otherwise.

Parameters:

term – Either a PauliTerm or PauliSum

Returns:

True if the PauliTerm or PauliSum is a scalar multiple of identity, False otherwise

pyquil.paulis.is_zero(pauli_object: ) bool[source]

Return True if a PauliTerm or PauliSum is zero, False otherwise.

Parameters:

pauli_object – Either a PauliTerm or PauliSum

Returns:

True if PauliTerm is zero, False otherwise

pyquil.paulis.sI(q: int | None = None) [source]

Return the identity operator, optionally on a particular qubit.

This can be specified without a qubit.

Parameters:

qubit_index – The optional index of a qubit.

Returns:

A PauliTerm object

pyquil.paulis.sX(q: int) [source]

Return the sigma_X operator on a particular qubit.

Parameters:

qubit_index – The index of the qubit

Returns:

A PauliTerm object

pyquil.paulis.sY(q: int) [source]

Return the sigma_Y operator on a particular qubit.

Parameters:

qubit_index – The index of the qubit

Returns:

A PauliTerm object

pyquil.paulis.sZ(q: int) [source]

Return the sigma_Z operator on a particular qubit.

Parameters:

qubit_index – The index of the qubit

Returns:

A PauliTerm object

pyquil.paulis.simplify_pauli_sum(pauli_sum: PauliSum) [source]

Simplify the sum of Pauli operators according to Pauli algebra rules.

Warning: The simplified expression may re-order pauli operations, and may impact the observed performance when running on the QPU.

pyquil.paulis.suzuki_trotter(trotter_order: int, trotter_steps: int) list[tuple[float, int]][source]

Generate trotterization coefficients for a given number of Trotter steps.

U = exp(A + B) is approximated as exp(w1*o1)exp(w2*o2)… This method returns a list [(w1, o1), (w2, o2), … , (wm, om)] of tuples where o=0 corresponds to the A operator, o=1 corresponds to the B operator, and w is the coefficient in the exponential. For example, a second order Suzuki-Trotter approximation to exp(A + B) results in the following [(0.5/trotter_steps, 0), (1/trotter_steps, 1), (0.5/trotter_steps, 0)] * trotter_steps.

Parameters:
• trotter_order – order of Suzuki-Trotter approximation

• trotter_steps – number of steps in the approximation

Returns:

List of tuples corresponding to the coefficient and operator type: o=0 is A and o=1 is B.

pyquil.paulis.term_with_coeff(term: PauliTerm, coeff: Expression | int | float | complex) [source]

Change the coefficient of a PauliTerm.

Parameters:
• term – A PauliTerm object

• coeff – The coefficient to set on the PauliTerm

Returns:

A new PauliTerm that duplicates term but sets coeff

pyquil.paulis.trotterize(first_pauli_term: PauliTerm, second_pauli_term: PauliTerm, trotter_order: int = 1, trotter_steps: int = 1) [source]

Create a Quil program that approximates exp( (A + B)t) where A and B are PauliTerm operators.

Parameters:
• first_pauli_term – PauliTerm denoted A

• second_pauli_term – PauliTerm denoted B

• trotter_order – Optional argument indicating the Suzuki-Trotter approximation order–only accepts orders 1, 2, 3, 4.

• trotter_steps – Optional argument indicating the number of products to decompose the exponential into.

Returns:

Quil program