qilisdk.analog.hamiltonian

Attributes

Coefficient

Classes

PauliOperator

A generic abstract Pauli operator that acts on one qubit.

PauliZ

A generic abstract Pauli operator that acts on one qubit.

PauliX

A generic abstract Pauli operator that acts on one qubit.

PauliY

A generic abstract Pauli operator that acts on one qubit.

PauliI

A generic abstract Pauli operator that acts on one qubit.

Hamiltonian

Represent a Hamiltonian expressed as a linear combination of Pauli operators.

Functions

Z(→ Hamiltonian)

X(→ Hamiltonian)

Y(→ Hamiltonian)

I(→ Hamiltonian)

Module Contents

Z(qubit: int) Hamiltonian[font]
X(qubit: int) Hamiltonian[font]
Y(qubit: int) Hamiltonian[font]
I(qubit: int = 0) Hamiltonian[font]
class PauliOperator(qubit: int)[font]

Bases: abc.ABC

A generic abstract Pauli operator that acts on one qubit.

Exemple

from qilisdk.analog import PauliX

op = PauliX(0)

Note: You can also use the factory functions X(q), Y(q), Z(q), I(q) to get a Hamiltonian object.

property qubit: int[font]
property name: str[font]
classmethod matrix_for_dtype(dtype: numpy.dtype) numpy.ndarray[font]
property matrix: numpy.ndarray[font]
to_hamiltonian() Hamiltonian[font]

Convert this single operator to a Hamiltonian with one term.

Retorna:

The converted Hamiltonian.

Tipus de retorn:

Hamiltonian

class PauliZ(qubit: int)[font]

Bases: PauliOperator

A generic abstract Pauli operator that acts on one qubit.

Exemple

from qilisdk.analog import PauliX

op = PauliX(0)

Note: You can also use the factory functions X(q), Y(q), Z(q), I(q) to get a Hamiltonian object.

class PauliX(qubit: int)[font]

Bases: PauliOperator

A generic abstract Pauli operator that acts on one qubit.

Exemple

from qilisdk.analog import PauliX

op = PauliX(0)

Note: You can also use the factory functions X(q), Y(q), Z(q), I(q) to get a Hamiltonian object.

class PauliY(qubit: int)[font]

Bases: PauliOperator

A generic abstract Pauli operator that acts on one qubit.

Exemple

from qilisdk.analog import PauliX

op = PauliX(0)

Note: You can also use the factory functions X(q), Y(q), Z(q), I(q) to get a Hamiltonian object.

class PauliI(qubit: int)[font]

Bases: PauliOperator

A generic abstract Pauli operator that acts on one qubit.

Exemple

from qilisdk.analog import PauliX

op = PauliX(0)

Note: You can also use the factory functions X(q), Y(q), Z(q), I(q) to get a Hamiltonian object.

type Coefficient = float | list[float][font]
class Hamiltonian(elements: dict[tuple[PauliOperator, ...], complex | qilisdk.core.expression.Expression | qilisdk.core.variables.Parameter] | None = None)[font]

Bases: qilisdk.core.parameterizable.Parameterizable

Represent a Hamiltonian expressed as a linear combination of Pauli operators.

Exemple

from qilisdk.analog.hamiltonian import Hamiltonian, X, Z

H = X(0) * X(1) + Z(1)

Build a Hamiltonian from a mapping of Pauli operator products to coefficients.

Paràmetres:

elements (dict[tuple[PauliOperator, ], complex | Expression | Parameter], optional) –

Mapping from operator tuples to numerical coefficients or symbolic parameters. For example:

{
    (Z(0), Y(1)): 1.0,
    (X(1),): 1j,
}

Defaults to None, which creates an empty Hamiltonian.

Llença:

ValueError – If the provided coefficients include generic variables instead of parameters.

ZERO: int = 0[font]
property nqubits: int[font]

Number of qubits on which the Hamiltonian acts.

property elements: dict[tuple[PauliOperator, ...], complex][font]

Return the stored operator-coefficient mapping with symbolic terms evaluated.

simplify() Hamiltonian[font]

Simplify the Hamiltonian expression by removing near-zero terms and accumulating constant terms.

Retorna:

Simplified Hamiltonian

Tipus de retorn:

Hamiltonian

to_matrix() scipy.sparse.spmatrix[font]

Return the full matrix representation of the Hamiltonian by summing over all terms.

Retorna:

The sparse matrix representation of the Hamiltonian.

Tipus de retorn:

spmatrix

to_qtensor(total_nqubits: int | None = None) qilisdk.core.qtensor.QTensor[font]

Return the Hamiltonian as a QTensor built from the sparse matrix representation.

Paràmetres:

total_nqubits (int, optional) – Specify the total number of qubits that this hamiltonian acts on. Defaults to None.

Retorna:

The QTensor object representation of the Hamiltonian.

Tipus de retorn:

QTensor

Llença:

ValueError – If the total_nqubits provided is lower than the number of qubits effected by the hamiltonian.

get_static_hamiltonian() Hamiltonian[font]

Return a Hamiltonian containing only constant coefficients.

draw(style: qilisdk.utils.visualization.style.HamiltonianStyle | None = None, filepath: str | None = None) None[font]

Render this Hamiltonian as an interaction graph and optionally save it to a file.

Every qubit is drawn as a node whose disc is split into one slice per local field acting on it (labelled with the Pauli type), and every two-qubit term is drawn as an edge between the qubits it couples, with a line style per coupling type. Slice and edge colours encode the coefficient of the corresponding term, as described by the accompanying colour bar. Expressions acting on three or more qubits are drawn as star-shaped hyperedges joined at their centroid, and a constant (identity) term is annotated as an energy offset.

If filepath is given, the resulting figure is saved to disk (the output format is inferred from the file extension, e.g. .png, .pdf, .svg); otherwise the figure is shown.

Paràmetres:
  • style (HamiltonianStyle | None, optional) – Customization options for the plot appearance. Defaults to HamiltonianStyle.

  • filepath (str | None, optional) – If provided, saves the plot to the specified file path.

Exemple

from qilisdk.analog import X, Z

H = X(0) + 2 * Z(1) + 0.5 * Z(0) * Z(1)
H.draw()
get_commuting_partitions() list[dict[tuple[PauliOperator, ...], complex | qilisdk.core.expression.Expression | qilisdk.core.variables.Parameter]][font]

Split the Hamiltonian into a list of partitions, each containing commuting terms.

For now this is a greedy algorithm, but a smarter graph-coloring approach could be used later.

Retorna:

A list of dictionaries, each representing a partition of the Hamiltonian containing commuting terms.

Tipus de retorn:

list[dict[tuple[PauliOperator, …], complex | Expression | Parameter]]

classmethod transverse_field(nqubits: int, x_coefficient: Coefficient = 1.0) Hamiltonian[font]

Build a transverse field, \(\sum_i h_i\, X_i\).

Exemple

from qilisdk.analog import Hamiltonian

H = Hamiltonian.transverse_field(nqubits=2, x_coefficient=1.3)
# 1.3 X(0) + 1.3 X(1)

H = Hamiltonian.transverse_field(nqubits=2, x_coefficient=[1.3, 0.7])
# 1.3 X(0) + 0.7 X(1)
Paràmetres:
  • nqubits (int) – the number of qubits the Hamiltonian acts on.

  • x_coefficient (Coefficient, optional) – the field strength on every qubit, or a list holding the strength of each qubit in turn. Defaults to 1.0.

Retorna:

the transverse-field Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if nqubits is not greater than zero.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod longitudinal_field(nqubits: int, z_coefficient: Coefficient = 1.0) Hamiltonian[font]

Build a longitudinal field, \(\sum_i h_i\, Z_i\).

Exemple

from qilisdk.analog import Hamiltonian

H = Hamiltonian.longitudinal_field(nqubits=2, z_coefficient=1.3)
# 1.3 Z(0) + 1.3 Z(1)

H = Hamiltonian.longitudinal_field(nqubits=2, z_coefficient=[1.3, 0.7])
# 1.3 Z(0) + 0.7 Z(1)
Paràmetres:
  • nqubits (int) – the number of qubits the Hamiltonian acts on.

  • z_coefficient (Coefficient, optional) – the field strength on every qubit, or a list holding the strength of each qubit in turn. Defaults to 1.0.

Retorna:

the longitudinal-field Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if nqubits is not greater than zero.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod ising(nqubits: int, zz_coefficient: Coefficient = 1.0, z_coefficient: Coefficient = 0.0) Hamiltonian[font]

Build an all-to-all Ising Hamiltonian, \(\sum_{i<j} J_{ij}\, Z_i Z_j + \sum_i h_i\, Z_i\).

Exemple

from qilisdk.analog import Hamiltonian

H = Hamiltonian.ising(nqubits=2, zz_coefficient=2.0)
# 2 Z(0) Z(1)
Paràmetres:
  • nqubits (int) – the number of qubits the Hamiltonian acts on. Must be at least 2.

  • zz_coefficient (Coefficient, optional) – the coupling on every pair of qubits, or a list holding the coupling of each pair in turn, ordered as (0, 1), (0, 2), ..., (1, 2), .... Defaults to 1.0.

  • z_coefficient (Coefficient, optional) – the longitudinal field on every qubit, or a list holding the field of each qubit in turn. Defaults to 0.0, which leaves the field out entirely.

Retorna:

the Ising Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if nqubits is less than 2.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod ising_chain(nqubits: int, zz_coefficient: Coefficient = 1.0, z_coefficient: Coefficient = 0.0, periodic: bool = False) Hamiltonian[font]

Build a 1D nearest-neighbour Ising chain, \(\sum_i J_i\, Z_i Z_{i+1} + \sum_i h_i\, Z_i\).

Exemple

from qilisdk.analog import Hamiltonian

H = Hamiltonian.ising_chain(nqubits=3, zz_coefficient=2.0)
# 2 Z(0) Z(1) + 2 Z(1) Z(2)

# Closing the chain into a ring adds the bond between the two ends.
H = Hamiltonian.ising_chain(nqubits=3, zz_coefficient=2.0, periodic=True)
# 2 Z(0) Z(1) + 2 Z(1) Z(2) + 2 Z(0) Z(2)
Paràmetres:
  • nqubits (int) – the number of qubits in the chain. Must be at least 2.

  • zz_coefficient (Coefficient, optional) – the coupling on every bond, or a list holding the coupling of each bond in turn, ordered along the chain and ending with the wrap-around bond when periodic is set. Defaults to 1.0.

  • z_coefficient (Coefficient, optional) – the longitudinal field on every qubit, or a list holding the field of each qubit in turn. Defaults to 0.0, which leaves the field out entirely.

  • periodic (bool, optional) – whether to close the chain into a ring by coupling the last qubit back to the first. Ignored for fewer than 3 qubits, where the ring bond would duplicate the one bond the chain already has. Defaults to False.

Retorna:

the Ising chain Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if nqubits is less than 2.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod ising_grid(rows: int, columns: int, zz_coefficient: Coefficient = 1.0, z_coefficient: Coefficient = 0.0, periodic: bool = False) Hamiltonian[font]

Build a 2D nearest-neighbour Ising model on a rows x columns square lattice.

Qubits are numbered in row-major order, so the qubit at (row, column) has index row * columns + column, and the Hamiltonian acts on rows * columns qubits. Each qubit is coupled to its neighbour to the right and its neighbour below, giving the usual square lattice.

Exemple

from qilisdk.analog import Hamiltonian

# A 2x2 lattice: qubits 0 1 on the top row, 2 3 on the bottom.
H = Hamiltonian.ising_grid(rows=2, columns=2)
# Z(0) Z(1) + Z(0) Z(2) + Z(1) Z(3) + Z(2) Z(3)
Paràmetres:
  • rows (int) – the number of lattice rows.

  • columns (int) – the number of lattice columns.

  • zz_coefficient (Coefficient, optional) – the coupling on every bond, or a list holding the coupling of each bond in turn, ordered by the site each bond starts from in row-major order and, within a site, giving its horizontal bond before its vertical one. Defaults to 1.0.

  • z_coefficient (Coefficient, optional) – the longitudinal field on every qubit, or a list holding the field of each qubit in turn. Defaults to 0.0, which leaves the field out entirely.

  • periodic (bool, optional) – whether to wrap the lattice into a torus by coupling each edge back to the opposite one. Wrapping is skipped along any direction shorter than 3 sites, where it would duplicate an existing bond. Defaults to False.

Retorna:

the Ising grid Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if rows or columns is not greater than zero.

  • ValueError – if the lattice holds fewer than 2 qubits.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod transverse_field_ising(nqubits: int, x_coefficient: Coefficient = 1.0, zz_coefficient: Coefficient = 1.0, z_coefficient: Coefficient = 0.0) Hamiltonian[font]

Build an all-to-all transverse-field Ising Hamiltonian.

\[H = \sum_{i<j} J_{ij}\, Z_i Z_j + \sum_i h^x_i\, X_i + \sum_i h^z_i\, Z_i\]

Exemple

from qilisdk.analog import Hamiltonian

H = Hamiltonian.transverse_field_ising(nqubits=2, x_coefficient=1.3, zz_coefficient=-2)
# 1.3 X(0) + 1.3 X(1) - 2 Z(0) Z(1)
Paràmetres:
  • nqubits (int) – the number of qubits the Hamiltonian acts on. Must be at least 2.

  • x_coefficient (Coefficient, optional) – the transverse field on every qubit, or a list holding the field of each qubit in turn. Defaults to 1.0.

  • zz_coefficient (Coefficient, optional) – the coupling on every pair of qubits, or a list holding the coupling of each pair in turn, ordered as (0, 1), (0, 2), ..., (1, 2), .... Defaults to 1.0.

  • z_coefficient (Coefficient, optional) – the longitudinal field on every qubit, or a list holding the field of each qubit in turn. Defaults to 0.0, which leaves the field out entirely.

Retorna:

the transverse-field Ising Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if nqubits is less than 2.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod heisenberg(nqubits: int, xx_coefficient: Coefficient = 1.0, yy_coefficient: Coefficient | None = None, zz_coefficient: Coefficient | None = None, z_coefficient: Coefficient = 0.0) Hamiltonian[font]

Build an all-to-all Heisenberg Hamiltonian.

\[H = \sum_{i<j} \left( J^x_{ij} X_i X_j + J^y_{ij} Y_i Y_j + J^z_{ij} Z_i Z_j \right) + \sum_i h_i\, Z_i\]

Leaving yy_coefficient and zz_coefficient at their defaults gives the isotropic XXX model; setting zz_coefficient alone gives the XXZ model; setting all three independently gives the fully anisotropic XYZ model.

Exemple

from qilisdk.analog import Hamiltonian

# Isotropic XXX model.
H = Hamiltonian.heisenberg(nqubits=2, xx_coefficient=0.5)
# 0.5 X(0) X(1) + 0.5 Y(0) Y(1) + 0.5 Z(0) Z(1)

# XXZ model with an anisotropic ZZ coupling.
H = Hamiltonian.heisenberg(nqubits=2, xx_coefficient=1.0, zz_coefficient=0.3)

# A disordered field, set qubit by qubit.
H = Hamiltonian.heisenberg(nqubits=3, xx_coefficient=1.0, z_coefficient=[-1.2, 0.4, 2.7])
Paràmetres:
  • nqubits (int) – the number of qubits the Hamiltonian acts on. Must be at least 2.

  • xx_coefficient (Coefficient, optional) – the XX coupling on every pair of qubits, or a list holding the coupling of each pair in turn, ordered as (0, 1), (0, 2), ..., (1, 2), .... Defaults to 1.0.

  • yy_coefficient (Coefficient, optional) – the YY coupling, given the same way as xx_coefficient. Defaults to None, which reuses xx_coefficient.

  • zz_coefficient (Coefficient, optional) – the ZZ coupling, given the same way as xx_coefficient. Defaults to None, which reuses xx_coefficient.

  • z_coefficient (Coefficient, optional) – the longitudinal field on every qubit, or a list holding the field of each qubit in turn. Defaults to 0.0, which leaves the field out entirely.

Retorna:

the Heisenberg Hamiltonian.

Tipus de retorn:

Hamiltonian

Llença:
  • ValueError – if nqubits is less than 2.

  • ValueError – if a list of coefficients does not hold one value per term.

classmethod from_qtensor(tensor: qilisdk.core.qtensor.QTensor, tol: float | None = None, prune: float | None = None) Hamiltonian[font]

Expand a qtensor (dense operator) on n qubits into a sum of Pauli strings, returning a qilisdk.analog.Hamiltonian.

Paràmetres:
  • tol (float) – Hermiticity check tolerance. Defaults to global zero tolerance setting.

  • prune (float) – Drop coefficients whose absolute value satisfies abs(c) < prune to reduce numerical noise. Defaults to global zero tolerance setting.

Retorna:

Sum_{P in {I,X,Y,Z}^{⊗ n}} c_P * P with c_P = Tr(qt * P) / 2^n

Tipus de retorn:

Hamiltonian

Llença:

ValueError – If the input is not square, not a power-of-two dimension, or not Hermitian w.r.t. tol.

classmethod parse(hamiltonian_str: str) Hamiltonian[font]
commutator(h: Hamiltonian) Hamiltonian[font]

compute the commutator of the current hamiltonian with another hamiltonian (h)

Paràmetres:

h (Hamiltonian) – the second hamiltonian.

Retorna:

the commutator.

Tipus de retorn:

Hamiltonian

anticommutator(h: Hamiltonian) Hamiltonian[font]

compute the anticommutator of the current hamiltonian with another hamiltonian (h)

Paràmetres:

h (Hamiltonian) – the second hamiltonian.

Retorna:

the anticommutator.

Tipus de retorn:

Hamiltonian

commutes_with(h: Hamiltonian) bool[font]

Check whether this Hamiltonian commutes with another one ([self, h] == 0).

This is faster than materialising the full commutator self * h - h * self: every pair of Pauli strings either commutes or anticommutes, and which one holds can be decided with a cheap qubit-overlap parity check instead of a matrix/operator product. Commuting pairs contribute nothing to the commutator and are skipped entirely, so only the anticommuting pairs (for which [P, Q] = 2 P Q) are ever multiplied out and accumulated.

Paràmetres:

h (Hamiltonian) – the Hamiltonian to test commutation against.

Retorna:

True if the two Hamiltonians commute, False otherwise.

Tipus de retorn:

bool

vector_norm() float[font]
Retorna:

the vector norm of the hamiltonian.

Tipus de retorn:

float

frobenius_norm() float[font]
Retorna:

the forbenius norm of the hamiltonian.

Tipus de retorn:

float

trace() qilisdk.core.types.Number[font]
Retorna:

the trace of the hamiltonian.

Tipus de retorn:

float