Hamiltonians#
The main abstract Hamiltonian object of Qibo is:
- class qibo.hamiltonians.abstract.AbstractHamiltonian[source]#
Qibo abstraction for Hamiltonian objects.
- abstract property matrix#
Return the full matrix representation.
For \(n\) qubits, can be a dense \(2^{n} \times 2^{n}\) array or a sparse matrix, depending on how the Hamiltonian was created.
- abstract eigenvalues(k=6)[source]#
Computes the eigenvalues for the Hamiltonian.
- Parameters:
k (int) – Number of eigenvalues to calculate if the Hamiltonian was created using a sparse matrix. This argument is ignored if the Hamiltonian was created using a dense matrix. See
qibo.backends.abstract.AbstractBackend.eigvalsh()for more details.
- abstract eigenvectors(k=6)[source]#
Computes a tensor with the eigenvectors for the Hamiltonian.
- Parameters:
k (int) – Number of eigenvalues to calculate if the Hamiltonian was created using a sparse matrix. This argument is ignored if the Hamiltonian was created using a dense matrix. See
qibo.backends.abstract.AbstractBackend.eigh()for more details.
- ground_state()[source]#
Computes the ground state of the Hamiltonian.
Uses
qibo.hamiltonians.AbstractHamiltonian.eigenvectors()and returns eigenvector corresponding to the lowest energy.
- abstract exp(a)[source]#
Computes a tensor corresponding to \(\exp(-i \, a \, H)\).
- Parameters:
a (complex) – Complex number to multiply Hamiltonian before exponentiation.
- abstract expectation(circuit, nshots=None)[source]#
Computes the expectation value for a given circuit.
- Parameters:
circuit (Circuit) – circuit to calculate the expectation value from. If the circuit has already been executed, this will just make use of the cached result, otherwise it will execute the circuit.
nshots (int, optional) – number of shots to calculate the expectation value, if
Noneit will try to compute the exact expectation value (if possible). Defaults toNone.
- Returns:
The expectation value.
- Return type:
Matrix Hamiltonian#
The first implementation of Hamiltonians uses the full matrix representation of the Hamiltonian operator in the computational basis. For \(n\) qubits, this matrix has size \(2^{n} \times 2^{n}\). Therefore, its construction is feasible only when \(n\) is small.
Alternatively, the user can construct this Hamiltonian using a sparse matrices.
Sparse matrices from the
scipy.sparse
module are supported by the numpy and qibojit backends while the
tensorflow.sparse can be
used for tensorflow. Scipy sparse matrices support algebraic
operations (addition, subtraction, scalar multiplication), linear algebra
operations (eigenvalues, eigenvectors, matrix exponentiation) and
multiplication to dense or other sparse matrices. All these properties are
inherited by qibo.hamiltonians.Hamiltonian objects created
using sparse matrices. Tensorflow sparse matrices support only multiplication
to dense matrices. Both backends support calculating Hamiltonian expectation
values using a sparse Hamiltonian matrix.
- class qibo.hamiltonians.Hamiltonian(nqubits, matrix, backend=None)[source]#
Hamiltonian based on a dense or sparse matrix representation.
- Parameters:
nqubits (int) – number of quantum bits.
matrix (ArrayLike) – Matrix representation of the Hamiltonian in the computational basis as an array of shape \(2^{n} \times 2^{n}\). Sparse matrices based on
scipy.sparsefornumpy/qibojitbackends (or ontf.sparsefor thetensorflowbackend) are also supported.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- property matrix: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]#
Returns the full matrix representation.
For \(n\) qubits, can be a dense \(2^{n} \times 2^{n}\) array or a sparse matrix, depending on how the Hamiltonian was created.
- eigenvalues(k=6)[source]#
Computes the eigenvalues for the Hamiltonian.
- Parameters:
k (int) – Number of eigenvalues to calculate if the Hamiltonian was created using a sparse matrix. This argument is ignored if the Hamiltonian was created using a dense matrix. See
qibo.backends.abstract.AbstractBackend.eigvalsh()for more details.- Return type:
_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]
- eigenvectors(k=6)[source]#
Computes a tensor with the eigenvectors for the Hamiltonian.
- Parameters:
k (int) – Number of eigenvalues to calculate if the Hamiltonian was created using a sparse matrix. This argument is ignored if the Hamiltonian was created using a dense matrix. See
qibo.backends.abstract.AbstractBackend.eigh()for more details.- Return type:
_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]
- expectation(circuit, nshots=None, qubit_map=None)[source]#
Computes the expectation value for a given circuit. This works only for diagonal observables if
nshots != None.- Parameters:
circuit (
qibo.models.circuit.Circuit) – circuit to calculate the expectation value from. If the circuit has already been executed, this will just make use of the cached result, otherwise it will execute the circuit.nshots (int, optional) – number of shots to calculate the expectation value, if
Noneit will try to compute the exact expectation value (if possible). Defaults toNone.qubit_map (dict | None) –
- Returns:
The expectation value.
- Return type:
- expectation_from_samples(frequencies, qubit_map=None)[source]#
Compute the expectation value starting from some samples, works only for diagonal observables.
- energy_fluctuation(circuit)[source]#
Evaluate energy fluctuation:
\[\Xi_{k}(\mu) = \sqrt{\bra{\mu} \, H^{2} \, \ket{\mu} - \bra{\mu} \, H \, \ket{\mu}^2} \, .\]for a given state \(\ket{\mu}\).
- Parameters:
circuit (
qibo.models.circuit.Circuit) – circuit to compute the energy fluctuation from.- Returns:
Energy fluctuation value.
- Return type:
Symbolic Hamiltonian#
Qibo allows the user to define Hamiltonians using sympy symbols. In this
case the full Hamiltonian matrix is not constructed unless this is required.
This makes the implementation more efficient for larger qubit numbers.
For more information on constructing Hamiltonians using symbols we refer to the
How to define custom Hamiltonians using symbols? example.
- class qibo.hamiltonians.SymbolicHamiltonian(form, nqubits=None, backend=None)[source]#
Hamiltonian based on a symbolic representation.
Calculations using symbolic Hamiltonians are either done directly using the given
sympyexpression as it is (form) or by parsing the correspondingterms(which areqibo.core.terms.SymbolicTermobjects). The latter approach is more computationally costly as it uses asympy.expandcall on the given form before parsing the terms. For this reason thetermsare calculated only when needed, for example during Trotterization. The dense matrix of the symbolic Hamiltonian can be calculated directly fromformwithout requiringtermscalculation (seeqibo.core.hamiltonians.SymbolicHamiltonian.calculate_dense()for details).- Parameters:
form (sympy.Expr) – Hamiltonian form as a
sympy.Expr. Ideally the Hamiltonian should be written using Qibo symbols. See How to define custom Hamiltonians using symbols? example for more details.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.nqubits (int | None) –
- property dense: Hamiltonian#
Creates the equivalent Hamiltonian matrix.
- property terms: list#
List of terms of which the Hamiltonian is a sum of.
Terms will be objects of type
qibo.core.terms.HamiltonianTerm.
- property simple_terms: tuple[list[float], list[str], list[tuple[int, ...]]]#
A simpler (more framework agnostic) representation of the of terms composing the Hamiltonian, defined as: their scalar coefficients, the strings of the names of their observables and the qubits they act on
- Returns:
(Tuple[List[float], List[str], List[Tuple[int, …]]])
- property diagonal_terms: list[list[qibo.hamiltonians.terms.SymbolicTerm]]#
List of terms that can be diagonalized simultaneously, i.e. that commute with each other. In detail each element of the list is a sublist of commuting
qibo.hamiltonians.terms.SymbolicTermterms.
- property diagonal_simple_terms: tuple[list[list[float]], list[list[str]], list[list[tuple[int, ...]]]]#
A simpler (more framework agnostic) representation of the simultaneously diagonalizable terms of the hamiltonian, defined as: their scalar coefficients, the strings of the names of their observables and the qubits they act on.
- Returns:
Tuple[List[List[float]], List[List[str]], List[List[Tuple[int, …]]]]
- property matrix: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]#
Returns the full matrix representation.
Consisting of \(2^{n} \times 2^{n}`\) elements.
- eigenvalues(k=6)[source]#
Computes the eigenvalues for the Hamiltonian.
- Parameters:
k (int) – Number of eigenvalues to calculate if the Hamiltonian was created using a sparse matrix. This argument is ignored if the Hamiltonian was created using a dense matrix. See
qibo.backends.abstract.AbstractBackend.eigvalsh()for more details.- Return type:
_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]
- eigenvectors(k=6)[source]#
Computes a tensor with the eigenvectors for the Hamiltonian.
- Parameters:
k (int) – Number of eigenvalues to calculate if the Hamiltonian was created using a sparse matrix. This argument is ignored if the Hamiltonian was created using a dense matrix. See
qibo.backends.abstract.AbstractBackend.eigh()for more details.- Return type:
_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]
- ground_state()[source]#
Computes the ground state of the Hamiltonian.
Uses
qibo.hamiltonians.AbstractHamiltonian.eigenvectors()and returns eigenvector corresponding to the lowest energy.
- expectation(circuit, nshots=None)[source]#
Computes the expectation value for a given circuit.
- Parameters:
circuit (
qibo.models.circuit.Circuit) – circuit to calculate the expectation value from. If the circuit has already been executed, this will just make use of the cached result, otherwise it will execute the circuit.nshots (int, optional) – number of shots to calculate the expectation value, if
Noneit will try to compute the exact expectation value (if possible). Defaults toNone.
- Returns:
The expectation value.
- Return type:
- expectation_from_samples(frequencies, qubit_map=None)[source]#
Compute the expectation value starting from some samples, works only for diagonal observables.
When a qibo.hamiltonians.SymbolicHamiltonian is used for time
evolution then Qibo will automatically perform this evolution using the Trotter
of the evolution operator. This is done by automatically splitting the Hamiltonian
to sums of commuting terms, following the description of Sec. 4.1 of
arXiv:1901.05824.
For more information on time evolution we refer to the
How to simulate time evolution? example.
In addition to the abstract Hamiltonian models, Qibo provides the following pre-coded Hamiltonians:
Non-interacting Pauli-X#
- class qibo.hamiltonians.X(nqubits, dense=True, backend=None)[source]#
Non-interacting Pauli-\(X\) Hamiltonian.
\[H = - \sum _{k=0}^N \, X_{k} \, .\]- Parameters:
nqubits (int) – number of qubits.
dense (bool, optional) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Return type:
Non-interacting Pauli-Y#
- class qibo.hamiltonians.Y(nqubits, dense=True, backend=None)[source]#
Non-interacting Pauli-\(Y\) Hamiltonian.
\[H = - \sum _{k=0}^{N} \, Y_{k} \, .\]- Parameters:
nqubits (int) – number of qubits.
dense (bool, optional) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Return type:
Non-interacting Pauli-Z#
- class qibo.hamiltonians.Z(nqubits, dense=True, backend=None)[source]#
Non-interacting Pauli-\(Z\) Hamiltonian.
\[H = - \sum _{k=0}^{N} \, Z_{k} \, .\]- Parameters:
nqubits (int) – number of qubits.
dense (bool, optional) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Return type:
Ising model#
- class qibo.hamiltonians.Ising(nqubits, coupling_constants, local_field_strengths, dense=True, closed_boundary=True, backend=None)[source]#
One-dimensional \(n\)-qubit Ising model.
\[H = \sum_{k} \, J_{k} \, Z_{k} \, Z_{k + 1} + \sum_{k} h_{k}^{(z)} \, Z_{k} + \sum_{k} h_{k}^{(x)} \, X_{k} \, ,\]where \(\{J_{k}\}_{k}\) are called the
coupling constants, \(\{h_{k}^{(z)}, h_{k}^{(x)}\}_{k}\) are called thelocal field strengths, and \(\{X, \, Y, \, Z\}\) are the usual Pauli operators.- Parameters:
nqubits (int) – number of qubits.
coupling_constants (float or int or ArrayLike) –
listorndarraycontaining all coupling constants \(\{J_{k}\}_{k}\). Ifintorfloat, then \(J_{k}\) is equal tocoupling_constantsfor all $k$.local_field_strengths (list or tuple or float or int) – array containing all local field strengths \(\left\{\left(h_{k}^{(z)}, \, h_{k}^{(x)}\right)\right\}_{k}\), e.g., \(\left\{h_{k}^{(z)}\right\}_{k}\) in the first column and \(\left\{h_{k}^{(x)}\right\}_{k}\) in the second column. If
intorfloat, the coefficients \(h_{k}^{(z)}\) and \(h_{k}^{(x)}\) are equal tolocal_field_strengths, \(\forall \, k\). IfTuple[int, int], \(h_{k}^{(z)}\) \(\left(h_{k}^{(x)}\right)\) is set to the first (second) element of the tuple, \(\forall \, k\).dense (bool, optional) – If
True, creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.closed_boundary (bool, optional) – If
True, returns Ising Hamiltonian with periodic boundary condition. IfFalse, returns Hamiltonian with open boundaries. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Returns:
Ising Hamiltonian.
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
Transverse-field Ising model#
- class qibo.hamiltonians.TFIM(nqubits, h=0.0, dense=True, closed_boundary=True, backend=None)[source]#
One-dimensional, \(n\)-qubit Transverse field Ising model.
\[H = - \sum _{k=0}^{n-1} \, \left(Z_{k} \, Z_{k + 1} + h \, X_{k}\right) \, ,\]with \(Z_{n-1} Z_{n} \equiv Z_{n-1} Z_{0}\) if
closed_boundary=True.- Parameters:
nqubits (int) – number of qubits.
h (float, optional) – value of the transverse field. Defaults to \(0.0\).
dense (bool, optional) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.closed_boundary (bool, optional) – If
True, returns TFIM with periodic boundary condition. IfFalse, returns Hamiltonian with open boundaries. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Return type:
Max Cut#
- class qibo.hamiltonians.MaxCut(nqubits, dense=True, adj_matrix=None, backend=None)[source]#
Max Cut Hamiltonian.
\[H = -\frac{1}{2} \, \sum _{j, k = 0}^{N} \, \left(1 - Z_{j} \, Z_{k}\right) \, .\]- Parameters:
nqubits (int) – number of qubits.
dense (bool) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian.adj_matrix (list[list[float]] | np.ndarray) – Adjecency matrix of the graph. Defaults to a homogeneous fully connected graph with all edges having an equal 1.0 weight.
backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Return type:
LABS#
- class qibo.hamiltonians.LABS(nqubits, dense=True, backend=None)[source]#
Create Hamiltonian of the Low Autocorrelation Binary Sequences (LABS) problem.
Given an integer \(n > 2\), the LABS problem consists of finding a binary sequence \(b \in \{0, \, 1\}^{n}\) the minimizes the sidelobe energy \(E(b)\) defined as
\[E(b) = \sum_{j=1}^{n-1} \, C_{j}^{2}(b) \, ; \quad C_{j}(b) = \sum_{k=0}^{n-j} \, b_{k} \, b_{k + j} \, ,\]where \(C_{j}(b)\) is the \(j\)-th autocorrelation of \(b\).
- Parameters:
nqubits (int) – Total number of qubits.
dense (bool, optional) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Return type:
References
1. T. Packebusch and S. Mertens, Low autocorrelation binary sequences, J. Phys. A: Math. Theor. 49 (2016) 165001.
Fermi-Hubbard model#
- class qibo.hamiltonians.FermiHubbard(nsites, hopping_strength=-1.0, interaction_strength=0.5, dense=True, closed_boundary=True, labelling='snake', backend=None)[source]#
Jordan-Wigner-transformed Fermi-Hubbard model on a one-dimensional chain or on a two-dimensional rectangular lattice.
In second quantization, the Hamiltonian is defined as
\[H_{\textrm{FH}} = t \, \sum_{\langle j, \, k \rangle, \, \sigma} \, \left( a_{j,\sigma}^{\dagger} \, a_{k,\sigma} + a_{k,\sigma}^{\dagger} \, a_{j,\sigma} \right) + U \, \sum_{j} \, n_{j,\uparrow} \, n_{j,\downarrow} \, ,\]where \(\langle j, \, k \rangle\) runs over all pairs of nearest-neighbor lattice sites, \(a_{j,\sigma}\) (\(a_{j,\sigma}^{\dagger}\)) is the annihilation (creation) operator for spin \(\sigma \in \{\uparrow, \, \downarrow \}\) at site \(j\), \(n_{j,\sigma} = a_{j,\sigma}^{\dagger}\,a_{j,\sigma}\) is the number operator for spin \(\sigma\) at site \(j\), \(t\) is the tunneling amplitude, and \(U\) is the Coulomb potential.
Lattice sites are labeled according to
labelling. For a lattice with \(n_{c}\) columns, site \((r, \, c)\) has label \(j = r \, n_{c} + c\) in the"row_major"scheme, in which every row is traversed from left to right. In the"snake"scheme, the first row is traversed from left to right, the second row from right to left, and so on. Thus, the label is the same as in the"row_major"scheme if \(r\) is even, and \(j = r \, n_{c} + n_{c} - 1 - c\) if \(r\) is odd. Qubits \(2j\) and \(2j + 1\) encode the spin-up and spin-down modes of site \(j\), respectively. Both schemes are equivalent for chains and single-row lattices.Every hopping term between qubits \(p < q\) is multiplied by the Jordan-Wigner string \(\prod_{p < m < q} Z_{m}\), so that fermionic anticommutation is correctly accounted for. A chain with \(n\) sites,
nsites=n, is the same model as a lattice with a single row,nsites=(1, n).Note
For periodic boundaries, bonds that wrap around a dimension are implemented as the same Jordan-Wigner-string hopping terms as the remaining bonds, without the correction that depends on the parity of the total number of particles.
- Parameters:
nsites (int or tuple[int, int]) – if an
int, total number of sites in a one-dimensional chain. If atuple\((n_{r}, \, n_{c})\), number of rows and columns of a two-dimensional lattice.hopping_strength (float or int, optional) – tunneling amplitude. Defaults to \(-1.0\).
interaction_strength (float or int, optional) – Coulomb potential. Defaults to \(0.5\).
dense (bool, optional) – If
Trueit creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.closed_boundary (bool, optional) – If
True, returns Fermi-Hubbard model with periodic boundary condition along every dimension with more than two sites. IfFalse, returns Hamiltonian with open boundaries. Defaults toTrue.labelling (str, optional) – scheme used to label the lattice sites, either
"snake"or"row_major". Defaults to"snake".backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Returns:
Fermi-Hubbard Hamiltonian \(H_{\textrm{FH}}\).
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
Heisenberg model#
- class qibo.hamiltonians.Heisenberg(nqubits, coupling_constants, external_field_strengths, dense=True, backend=None)[source]#
Heisenberg model on a \(1\)-dimensional periodic lattice.
The general \(n\)-qubit Hamiltonian is given by
\[\begin{split}\begin{align} H &= -\sum_{k = 1}^{n} \, \left( J_{x} \, X_{k} \, X_{k + 1} + J_{y} \, Y_{k} \, Y_{k + 1} + J_{z} \, Z_{k} \, Z_{k + 1} \right) \\ &\quad\,\, - \sum_{k = 1}^{n} \left( h_{x} \, X_{k} + h_{y} \, Y_{k} + h_{z} \, Z_{k} \right) \, , \end{align}\end{split}\]where \(\{J_{x}, \, J_{y}, \, J_{z}\}\) are called the
coupling constants, \(\{h_{x}, \, h_{y}, \, h_{z}\}\) are called theexternal field strengths, and \(\{X, \, Y, \, Z\}\) are the usual Pauli operators.- Parameters:
nqubits (int) – number of qubits.
coupling_constants (list or tuple or float or int) – list or tuple with the three coupling constants \(\{J_{x}, J_{y}, J{z}\}\). If
intorfloat, then \(J_{x} = J_{y} = J_{z}\).external_field_strength (list or tuple or float or int) – list or tuple with the external magnetic field strengths \(\{h_{x}, \, h_{y}, \, h_{z}\}\). If
intorfloat, then \(h_{x} = h_{y} = h_{z}\).dense (bool, optional) – If
True, creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.external_field_strengths (float) –
- Returns:
Heisenberg Hamiltonian.
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
Heisenberg XXX#
- class qibo.hamiltonians.XXX(nqubits, coupling_constant=1, external_field_strengths=None, dense=True, backend=None)[source]#
Heisenberg \(\mathrm{XXX}\) model with periodic boundary conditions.
The \(n\)-qubit \(\mathrm{XXX}\) Hamiltonian is given by
\[H = -J \, \sum_{k = 1}^{n} \, \left( X_{k} \, X_{k + 1} + Y_{k} \, Y_{k + 1} + Z_{k} \, Z_{k + 1} \right) - \sum_{k = 1}^{n} \left(h_{x} \, X_{k} + h_{y} \, Y_{k} + h_{z} \, Z_{k} \right) \, ,\]where \(J\) is the
coupling_constant, \(\{h_{x}, \, h_{y}, \, h_{z}\}\) are called theexternal field strengths, and \(\{X, \, Y, \, Z\}\) are the usual Pauli operators.- Parameters:
nqubits (int) – number of qubits.
coupling_constant (float or int, optional) – coupling constant \(J\). Defaults to \(1\).
external_field_strengths (float or int or list or tuple, optional) – list or tuple with the external magnetic field strengths \(\{h_{x}, \, h_{y}, \, h_{z}\}\). If
intorfloat, then \(h_{x} = h_{y} = h_{z}\). Defaults to \([1/2, \, 0, \, 0]\).dense (bool, optional) – If
True, creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Returns:
Heisenberg \(\mathrm{XXX}\) Hamiltonian.
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
Heisenberg XXZ#
- class qibo.hamiltonians.XXZ(nqubits, delta=0.5, dense=True, backend=None)[source]#
Heisenberg \(\mathrm{XXZ}\) model with periodic boundary conditions.
\[H = \sum _{k=0}^N \, \left( X_{k} \, X_{k + 1} + Y_{k} \, Y_{k + 1} + \delta Z_{k} \, Z_{k + 1} \right) \, .\]Example
from qibo.hamiltonians import XXZ h = XXZ(3) # initialized XXZ model with 3 qubits
- Parameters:
nqubits (int) – number of qubits.
delta (float or int, optional) – coefficient for the \(Z\) component. Defaults to \(0.5\).
dense (bool, optional) – If
True, creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Returns:
Heisenberg \(\mathrm{XXZ}\) Hamiltonian.
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
Folded XXZ model#
- class qibo.hamiltonians.FoldedXXZ(nqubits, dense=True, backend=None)[source]#
Folded XXZ model on an one-dimensional chain with open boundary conditions.
This model is the \(\Delta \rightarrow \infty\) limit of the XXZ model.
\[H_{\Delta \rightarrow \infty} = -\frac{1}{8} \, \sum_{j=0}^{n-4} \, (1 + Z_{j} \, Z_{j+3}) \, (X_{j+1} \, X_{j+2} + Y_{j+1} \, Y_{j+2})\]- Parameters:
nqubits (int) – number of qubits. It is equivalent to the number of chain sites \(N\) plus \(2\) boundary qubits, i.e., \(N + 2\).
dense (bool, optional) – If
True, creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Returns:
The folded XXZ Hamiltonian.
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
References
1. R. Ruiz, A. Sopena, B. Pozsgay, and E. López, Efficient eigenstate preparation in an integrable model with Hilbert space fragmentation, PRX Quantum 6, 030316 (2025).
Graph Partitioning Problem#
- class qibo.hamiltonians.GPP(adjacency_matrix, penalty_coeff=0.0, node_weights=None, dense=True, backend=None)[source]#
The Graph Partitioning Problem (GPP) as a quadratic function.
For a (possibly weighted) graph \(G = (V, E)\) defined by its set \(V\) of vertices and set \(E\) of edges, the GPP is the task of dividing a graph’s vertices into \(m\) subsets of approximately equal size, such that \(\bigcup_{k=1}^{m} \, V_{k} = V\), while minimizing the number of edges that connect vertices in different subsets.
The formulation of the GPP as a quadratic unconstrained binary optimization (QUBO) reduces to minimizing the following objective function \(C(x)\):
\[C(x) = \sum_{(j,k) \in E} \, A_{jk} \, (x_{j} + x_{k} - 2 \, x_{j} \, x_{k}) \, + \lambda \, P(x),\]where \(x_{j} \in \{0, \, 1\}\) is a binary variable,
\[P(x) = \left(\sum_{k} \, v_{k} \, x_{k} - \sum_{k} \, \frac{v_{k}}{2}\right)^{2}\]is a term designed to penalize deviations in the total node weight on each partition, and \(\lambda > 0\) is a hyperparameter.
- Parameters:
adjacency_matrix (ndarray) – Square symmetric matrix with weigths \(A_{jk}\) representing the edges of the graph. For an unweighted graph, \(A_{jk} = 1, \,\, \forall \, j,k\).
penalty_coeff (float or int, optional) – hyperparameter \(\lambda\) defining the strength of the penalty term. Defaults to \(0.0\).
node_weights (ArrayLike, optional) – Weight of the nodes of the graph. Used when \(\lambda \neq 0\). If
None, all node weights default to \(1\). Defaults toNone.dense (bool, optional) – If
True, creates the Hamiltonian as aqibo.core.hamiltonians.Hamiltonian, otherwise it creates aqibo.core.hamiltonians.SymbolicHamiltonian. Defaults toTrue.backend (
qibo.backends.abstract.Backend, optional) – backend to be used in the execution. IfNone, it uses the current backend. Defaults toNone.
- Returns:
GPP Hamiltonian \(H_{C}\).
- Return type:
qibo.hamiltonians.Hamiltonianorqibo.hamiltonians.SymbolicHamiltonian
References
1. W. Aboumrad, D. Zhu, C. Girotto, F.-H. Rouet, J. Jojo, R. Lucas, J. Pathak, A. Kaushik, and M. Roetteler, Accelerating large-scale linear algebra using variational quantum imaginary time evolution, arXiv:2503.13128 (2025).
Note
All pre-coded Hamiltonians can be created as
qibo.hamiltonians.Hamiltonian using dense=True
or qibo.hamiltonians.SymbolicHamiltonian
using the dense=False. In the first case the Hamiltonian is created
using its full matrix representation of size (2 ** n, 2 ** n)
where n is the number of qubits that the Hamiltonian acts on. This
matrix is used to calculate expectation values by direct matrix multiplication
to the state and for time evolution by exact exponentiation.
In contrast, when dense=False the Hamiltonian contains a more compact
representation as a sum of local terms. This compact representation can be
used to calculate expectation values via a sum of the local term expectations
and time evolution via the Trotter decomposition of the evolution operator.
This is useful for systems that contain many qubits for which constructing
the full matrix is intractable.