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.
- 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) PauliSum [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.
- 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'
- classmethod from_compact_str(str_pauli_term: str) PauliTerm [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) PauliTerm [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
- exception pyquil.paulis.UnequalLengthWarning(*args: object, **kwargs: object)[source]¶
Bases:
Warning
Warning issued when multiplying PauliTerms of different lengths.
Initialize the warning.
- 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) Program [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: PauliSum | PauliTerm) 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: PauliTerm | PauliSum) 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: PauliTerm | PauliSum) 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) PauliTerm [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) PauliTerm [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) PauliTerm [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) PauliTerm [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) 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) PauliTerm [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) Program [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