qml.Hamiltonian¶

class Hamiltonian(coeffs, observables, simplify=False, grouping_type=None, method='rlf', id=None, do_queue=True)[source]

Operator representing a Hamiltonian.

The Hamiltonian is represented as a linear combination of other operators, e.g., $$\sum_{k=0}^{N-1} c_k O_k$$, where the $$c_k$$ are trainable parameters.

Parameters
• coeffs (tensor_like) – coefficients of the Hamiltonian expression

• observables (Iterable[Observable]) – observables in the Hamiltonian expression, of same length as coeffs

• simplify (bool) – Specifies whether the Hamiltonian is simplified upon initialization (like-terms are combined). The default value is False.

• grouping_type (str) – If not None, compute and store information on how to group commuting observables upon initialization. This information may be accessed when QNodes containing this Hamiltonian are executed on devices. The string refers to the type of binary relation between Pauli words. Can be 'qwc' (qubit-wise commuting), 'commuting', or 'anticommuting'.

• method (str) – The graph coloring heuristic to use in solving minimum clique cover for grouping, which can be 'lf' (Largest First) or 'rlf' (Recursive Largest First). Ignored if grouping_type=None.

• id (str) – name to be assigned to this Hamiltonian instance

Example:

A Hamiltonian can be created by simply passing the list of coefficients as well as the list of observables:

>>> coeffs = [0.2, -0.543]
>>> obs = [qml.PauliX(0) @ qml.PauliZ(1), qml.PauliZ(0) @ qml.Hadamard(2)]
>>> H = qml.Hamiltonian(coeffs, obs)
>>> print(H)
(-0.543) [Z0 H2]
+ (0.2) [X0 Z1]


The coefficients can be a trainable tensor, for example:

>>> coeffs = tf.Variable([0.2, -0.543], dtype=tf.double)
>>> obs = [qml.PauliX(0) @ qml.PauliZ(1), qml.PauliZ(0) @ qml.Hadamard(2)]
>>> H = qml.Hamiltonian(coeffs, obs)
>>> print(H)
(-0.543) [Z0 H2]
+ (0.2) [X0 Z1]


The user can also provide custom observables:

>>> obs_matrix = np.array([[0.5, 1.0j, 0.0, -3j],
[-1.0j, -1.1, 0.0, -0.1],
[0.0, 0.0, -0.9, 12.0],
[3j, -0.1, 12.0, 0.0]])
>>> obs = qml.Hermitian(obs_matrix, wires=[0, 1])
>>> H = qml.Hamiltonian((0.8, ), (obs, ))
>>> print(H)
(0.8) [Hermitian0,1]


Alternatively, the molecular_hamiltonian() function from the Quantum Chemistry module can be used to generate a molecular Hamiltonian.

In many cases, Hamiltonians can be constructed using Pythonic arithmetic operations. For example:

>>> qml.Hamiltonian([1.], [qml.PauliX(0)]) + 2 * qml.PauliZ(0) @ qml.PauliZ(1)


is equivalent to the following Hamiltonian:

>>> qml.Hamiltonian([1, 2], [qml.PauliX(0), qml.PauliZ(0) @ qml.PauliZ(1)])


While scalar multiplication requires native python floats or integer types, addition, subtraction, and tensor multiplication of Hamiltonians with Hamiltonians or other observables is possible with tensor-valued coefficients, i.e.,

>>> H1 = qml.Hamiltonian(torch.tensor([1.]), [qml.PauliX(0)])
>>> H2 = qml.Hamiltonian(torch.tensor([2., 3.]), [qml.PauliY(0), qml.PauliX(1)])
>>> obs3 = [qml.PauliX(0), qml.PauliY(0), qml.PauliX(1)]
>>> H3 = qml.Hamiltonian(torch.tensor([1., 2., 3.]), obs3)
>>> H3.compare(H1 + H2)
True


A Hamiltonian can store information on which commuting observables should be measured together in a circuit:

>>> obs = [qml.PauliX(0), qml.PauliX(1), qml.PauliZ(0)]
>>> coeffs = np.array([1., 2., 3.])
>>> H = qml.Hamiltonian(coeffs, obs, grouping_type='qwc')
>>> H.grouping_indices
[[0, 1], [2]]


This attribute can be used to compute groups of coefficients and observables:

>>> grouped_coeffs = [coeffs[indices] for indices in H.grouping_indices]
>>> grouped_obs = [[H.ops[i] for i in indices] for indices in H.grouping_indices]
>>> grouped_coeffs
>>> grouped_obs
[[qml.PauliX(0), qml.PauliX(1)], [qml.PauliZ(0)]]


Devices that evaluate a Hamiltonian expectation by splitting it into its local observables can use this information to reduce the number of circuits evaluated.

Note that one can compute the grouping_indices for an already initialized Hamiltonian by using the compute_grouping method.

 coeffs Return the coefficients defining the Hamiltonian. eigvals Eigenvalues of an instantiated observable. grad_method grouping_indices Return the grouping indices attribute. hash returns an integer hash uniquely representing the operator id String for the ID of the operator. matrix Matrix representation of an instantiated operator in the computational basis. name String for the name of the operator. num_params num_wires ops Return the operators defining the Hamiltonian. par_domain parameters Current parameter values. return_type terms The terms of the Hamiltonian expression $$\sum_{k=0}^{N-1} c_k O_k$$ wires The sorted union of wires from all operators.
coeffs

Return the coefficients defining the Hamiltonian.

Returns

coefficients in the Hamiltonian expression

Return type

Iterable[float])

eigvals

Eigenvalues of an instantiated observable.

The order of the eigenvalues needs to match the order of the computational basis vectors when the observable is diagonalized using diagonalizing_gates. This is a requirement for using qubit observables in quantum functions.

Example:

>>> U = qml.PauliZ(wires=1)
>>> U.eigvals
>>> array([1, -1])

Returns

eigvals representation

Return type

array

grad_method = 'A'
grouping_indices

Return the grouping indices attribute.

Returns

indices needed to form groups of commuting observables

Return type

list[list[int]]

hash

returns an integer hash uniquely representing the operator

Type

int

id

String for the ID of the operator.

matrix

Matrix representation of an instantiated operator in the computational basis.

Example:

>>> U = qml.RY(0.5, wires=1)
>>> U.matrix
>>> array([[ 0.96891242+0.j, -0.24740396+0.j],
[ 0.24740396+0.j,  0.96891242+0.j]])

Returns

matrix representation

Return type

array

name
num_params = 1
num_wires = -1
ops

Return the operators defining the Hamiltonian.

Returns

observables in the Hamiltonian expression

Return type

Iterable[Observable])

par_domain = 'A'
parameters

Current parameter values.

return_type = None
terms

The terms of the Hamiltonian expression $$\sum_{k=0}^{N-1} c_k O_k$$

Returns

tuples of coefficients and operations, each of length N

Return type

(tuple, tuple)

wires

The sorted union of wires from all operators.

Returns

Combined wires present in all terms, sorted.

Return type

(Wires)

 compare(other) Compares with another Hamiltonian, Observable, or Tensor, to determine if they are equivalent. compute_grouping([grouping_type, method]) Compute groups of indices corresponding to commuting observables of this Hamiltonian, and store it in the grouping_indices attribute. Returns the list of operations such that they diagonalize the observable in the computational basis. queue([context]) Queues a qml.Hamiltonian instance Simplifies the Hamiltonian by combining like-terms.
compare(other)[source]

Compares with another Hamiltonian, Observable, or Tensor, to determine if they are equivalent.

Hamiltonians/observables are equivalent if they represent the same operator (their matrix representations are equal), and they are defined on the same wires.

Warning

The compare method does not check if the matrix representation of a Hermitian observable is equal to an equivalent observable expressed in terms of Pauli matrices, or as a linear combination of Hermitians. To do so would require the matrix form of Hamiltonians and Tensors be calculated, which would drastically increase runtime.

Returns

True if equivalent.

Return type

(bool)

Examples

>>> A = np.array([[1, 0], [0, -1]])
>>> H = qml.Hamiltonian(
...     [0.5, 0.5],
...     [qml.Hermitian(A, 0) @ qml.PauliY(1), qml.PauliY(1) @ qml.Hermitian(A, 0) @ qml.Identity("a")]
... )
>>> obs = qml.Hermitian(A, 0) @ qml.PauliY(1)
>>> print(H.compare(obs))
True

>>> H1 = qml.Hamiltonian([1, 1], [qml.PauliX(0), qml.PauliZ(1)])
>>> H2 = qml.Hamiltonian([1, 1], [qml.PauliZ(0), qml.PauliX(1)])
>>> H1.compare(H2)
False

>>> ob1 = qml.Hamiltonian([1], [qml.PauliX(0)])
>>> ob2 = qml.Hermitian(np.array([[0, 1], [1, 0]]), 0)
>>> ob1.compare(ob2)
False

compute_grouping(grouping_type='qwc', method='rlf')[source]

Compute groups of indices corresponding to commuting observables of this Hamiltonian, and store it in the grouping_indices attribute.

Parameters
• grouping_type (str) – The type of binary relation between Pauli words used to compute the grouping. Can be 'qwc', 'commuting', or 'anticommuting'.

• method (str) – The graph coloring heuristic to use in solving minimum clique cover for grouping, which can be 'lf' (Largest First) or 'rlf' (Recursive Largest First).

diagonalizing_gates()

Returns the list of operations such that they diagonalize the observable in the computational basis.

Returns

A list of gates that diagonalize the observable in the computational basis.

Return type

list(qml.Operation)

queue(context=<class 'pennylane.queuing.QueuingContext'>)[source]

Queues a qml.Hamiltonian instance

simplify()[source]

Simplifies the Hamiltonian by combining like-terms.

Example

>>> ops = [qml.PauliY(2), qml.PauliX(0) @ qml.Identity(1), qml.PauliX(0)]
>>> H = qml.Hamiltonian([1, 1, -2], ops)
>>> H.simplify()
>>> print(H)
(-1) [X0]
+ (1) [Y2]


Warning

Calling this method will reset grouping_indices to None, since the observables it refers to are updated.