quimb.operator

Tools for ‘symbolically’ and consistently defining operators and hamiltonians, which can then be built out into various matrix or tensor network forms such as sparse matrices and MPOs.

Submodules

Classes

SparseOperatorBuilder

Object for building operators with sparse structure. Specifically,

HilbertSpace

Take a set of 'sites' (any sequence of sortable, hashable objects), and

Functions

get_mat(op[, dtype])

fermi_hubbard_from_edges(edges[, t, U, mu, order, ...])

Create a Fermi-Hubbard Hamiltonian on the graph defined by edges.

fermi_hubbard_spinless_from_edges(edges[, t, V, mu, ...])

Create a spinless Fermi-Hubbard Hamiltonian on the graph defined by

heisenberg_from_edges(edges[, j, b, order, sector, ...])

Create a Heisenberg Hamiltonian on the graph defined by edges.

rand_operator(n, m, k[, kmin, seed, ops])

Generate a random operator with n qubits and m terms.

Package Contents

class quimb.operator.SparseOperatorBuilder(terms=(), hilbert_space: quimb.operator.hilbertspace.HilbertSpace = None, dtype=None, jordan_wigner=False, pauli_decompose=False, atol=1e-12)[source]

Object for building operators with sparse structure. Specifically, a sum of terms, where each term is a product of operators, where each of these local operators acts on a single site and has at most one entry per row.

Parameters:
  • terms (sequence, optional) – The terms to initialize the builder with. add_term is simply called on each of these.

  • hilbert_space (HilbertSpace) – The Hilbert space to build the operator in. If this is not supplied then a minimal Hilbert space will be constructed from the sites used, when required. The default symmetry and sector to build operators in is inherited from this Hilbert space, but can be overridden.

  • dtype (numpy.dtype or str, optional) – A default data type for the coefficients of the operator. If not provided, will be automatically determined at building time based on the terms in the operator. If the operator is complex, will be set to np.complex128. If the operator is real, will be set to np.float64. Individual building methods can override this.

  • jordan_wigner (bool, optional) – Whether to apply the Jordan-Wigner transformation to the terms automatically when processing them. This prepends pauli Z strings to all creation and annihilation operators.

  • pauli_decompose (bool or "zx", optional) – Whether to apply the Pauli decomposition to the terms automatically when processing them. This decomposes all local operators into sums of Pauli operators. If “zx” is supplied, the decomposition is done in terms of the real ZX = iY operator instead of Y.

  • atol (float, optional) – The absolute tolerance for considering coefficients to be null when simplifying and decomposing terms.

_sites_used
_hilbert_space = None
_terms_raw
_terms_final = None
_transform_jordan_wigner = False
_transform_pauli_decompose = False
_atol = 1e-12
_dtype = None
_coupling_maps
_cache
property sites_used

A tuple of the sorted coordinates/sites seen so far.

property hilbert_space: quimb.operator.hilbertspace.HilbertSpace

The Hilbert space of the operator. Created from the sites seen so far if not supplied at construction.

property nsites

The total number of coordinates/sites seen so far.

site_to_reg(site)[source]

Get the register / linear index of coordinate site.

reg_to_site(reg)[source]

Get the site of register / linear index reg.

property terms_raw

A tuple of the raw terms seen so far, as a mapping from operator strings to coefficients.

_reset_caches()[source]

Reset any cached representations of the operator, used whenever the terms are modified in any way, and thus require reprocessing.

_get_terms_final()[source]

Get the processed terms, applying any requested transformations, if not already done.

property terms

A tuple of the, possibly transformed, terms seen so far.

property nterms

The total number of terms seen so far.

property locality

The locality of the operator, the maximum support of any term.

property iscomplex

Whether the operator has complex terms.

add_term(*coeff_ops)[source]

Add a term to the operator.

Parameters:
  • coeff (float, optional) – The overall coefficient of the term.

  • ops (sequence of tuple[str, hashable]) –

    The operators of the term, together with the sites they act on. Each term should be a pair of (operator, site), where operator can be:

    • 'x', 'y', 'z': Pauli matrices

    • 'sx', 'sy', 'sz': spin operators (i.e. scaled Pauli matrices)

    • '+', '-': creation/annihilation operators

    • 'n', 'sn', or 'h': number, symmetric number (n - 1/2) and hole (1 - n) operators.

    And site is a hashable object that represents the site that the operator acts on. If this builder has an associated Hilbert space already, the site must be present in that Hilbert space, else a minimal Hilbert space will be constructed from the sites used, when required.

__iadd__(term)[source]
__isub__(term)[source]
jordan_wigner_transform(value=None)[source]

Toggle transforming the terms in this operator by pre-prending pauli Z strings to all creation and annihilation operators. This is always applied directly as the first processing step to the raw terms, so that the fermionic ordering is respected.

Note this doesn’t decompose +, - into (X + iY) / 2 and (X - iY) / 2, it just prepends Z strings. Use pauli_decompose to get the full decomposition.

The placement of the Z strings is defined by the ordering of the hilbert space, by default, the sorted order of the site labels.

Parameters:

value (bool, optional) – Whether to apply the Jordan-Wigner transformation. If None (the default) then this method acts as toggle. Whereas supplying True or False explicitly sets or unsets the transformation.

pauli_decompose(value=None, atol=None, use_zx=False)[source]

Transform the terms in this operator by decomposing them into Pauli strings.

Parameters:

value (bool, optional) – Whether to apply the Pauli decomposition. If None (the default) then this method acts as toggle. Whereas supplying True or False explicitly sets or unsets the transformation.

show(filler='.')[source]

Print an ascii representation of the terms in this operator.

get_dtype(dtype=None)[source]

Calculate the numpy data type of the operator to use.

Parameters:

dtype (numpy.dtype or str, optional) – The data type of the coefficients. If not provided, will be automatically determined based on the terms in the operator.

Returns:

dtype – The data type of the coefficients.

Return type:

numpy.dtype

get_coupling_map(dtype=None)[source]

Build and cache the coupling map for the specified dtype.

Parameters:

dtype (numpy.dtype, optional) – The data type of the coefficients. If not provided, will be automatically determined based on the terms in the operator.

Returns:

coupling_map – The operator defined as tuple of flat arrays.

Return type:

tuple[ndarray]

flatconfig_coupling(flatconfig, dtype=None)[source]

Get an array of other configurations coupled to the given individual flatconfig by this operator, and the corresponding coupling coefficients. This is for use with VMC for example.

Parameters:
  • flatconfig (array[np.uint8]) – The linear array of the configuration to get the coupling for.

  • dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically determined based on the terms in the operator.

Returns:

  • coupled_flatconfigs (ndarray[np.uint8]) – Each distinct flatconfig coupled to flatconfig.

  • coeffs (ndarray[dtype]) – The corresponding coupling coefficients.

config_coupling(config, dtype=None)[source]

Get a list of other configurations coupled to config by this operator, and the corresponding coupling coefficients. This is for use with VMC for example.

Parameters:

config (dict[site, int]) – The configuration to get the coupling for.

Returns:

  • coupled_configs (list[dict[site, np.uint8]]) – Each distinct configuration coupled to config.

  • coeffs (list[dtype]) – The corresponding coupling coefficients.

evaluate_exact_flatconfigs(fn_amplitude, progbar=False)[source]

Calculate the expectation value of this operator with respect to a wavefunction provided as a function with signature:

fn_amplitude(flatconfig: ndarray[np.uint8]) -> z: float | complex
evaluate_exact_configs(fn_amplitude, progbar=False)[source]

Calculate the expectation value of this operator with respect to a wavefunction provided as a function with signature:

fn_amplitude(config: dict[site, int]) -> z: float | complex
build_coo_data(sector=None, symmetry=None, dtype=None, parallel=False)[source]

Build the raw data for a sparse matrix in COO format, optionally in parallel.

Parameters:
  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

  • dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically determined based on the terms in the operator.

  • parallel (bool or int, optional) – Whether to build the matrix in parallel (multi-threaded). If True, will use number of threads equal to the number of available CPU cores. If False, will use a single thread. If an integer is provided, it will be used as the number of threads to use.

Returns:

  • data (array) – The data entries for the sparse matrix in COO format.

  • rows (array) – The row indices for the sparse matrix in COO format.

  • cols (array) – The column indices for the sparse matrix in COO format.

  • d (int) – The total number of basis states.

build_sparse_matrix(sector=None, symmetry=None, dtype=None, stype='csr', parallel=False)[source]

Build a sparse matrix in the given format. Optionally in parallel.

Parameters:
  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

  • dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically determined based on the terms in the operator.

  • stype (str, optional) – The sparse matrix format to use. Can be one of ‘coo’, ‘csr’, ‘csc’, ‘bsr’, ‘lil’, ‘dok’, or ‘dia’. Default is ‘csr’.

  • parallel (bool, optional) – Whether to build the matrix in parallel (multi-threaded).

Return type:

scipy.sparse matrix

build_dense(sector=None, symmetry=None, dtype=None, parallel=False)[source]

Get the dense (numpy.ndarray) matrix representation of this operator.

Parameters:
  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

  • dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically determined based on the terms in the operator.

  • parallel (bool or int, optional) – Whether to build the matrix in parallel (multi-threaded). If True, will use number of threads equal to the number of available CPU cores. If False, will use a single thread. If an integer is provided, it will be used as the number of threads to use.

Returns:

A – The dense matrix representation of this operator.

Return type:

numpy.ndarray

matvec(x, out=None, sector=None, symmetry=None, dtype=None, parallel=False)[source]

Apply this operator lazily (i.e. without constructing a sparse matrix) to a vector. This uses less memory but is much slower.

Parameters:
  • x (array) – The vector to apply the operator to.

  • out (array, optional) – An array to store the result in. If not provided, a new array will be created.

  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used. The implicit size should match that of x.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

  • dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically set as the same as the input vector.

  • parallel (bool or int, optional) – Whether to apply the operator in parallel (multi-threaded). If True, will use number of threads equal to the number of available CPU cores. If False, will use a single thread. If an integer is provided, it will be used as the number of threads to use. Uses num_threads more memory but is faster.

Returns:

out – The result of applying the operator to the vector.

Return type:

array

aslinearoperator(sector=None, symmetry=None, dtype=None, parallel=False)[source]

Get a scipy.sparse.linalg.LinearOperator for this operator. This is a lazy representation of the operator, which uses matvec to apply the operator to a vector. Less memory is required than constructing the full sparse matrix, but it is significantly slower.

Note currently the operator is assumed to be hermitian.

Parameters:
  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

  • dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically determined based on the terms in the operator.

  • parallel (bool or int, optional) – Whether to apply the operator in parallel (multi-threaded). If True, will use number of threads equal to the number of available CPU cores. If False, will use a single thread. If an integer is provided, it will be used as the number of threads to use. Uses num_threads more memory but is faster.

Returns:

Alo – The linear operator representation of this operator.

Return type:

scipy.sparse.linalg.LinearOperator

build_local_terms(dtype=None)[source]

Get a dictionary of local terms, where each key is a sorted tuple of sites, and each value is the local matrix representation of the operator on those sites. For use with e.g. tensor network algorithms.

Note terms acting on the same sites are summed together and the size of each local matrix is exponential in the locality of that term.

Returns:

Hk – The local terms.

Return type:

dict[tuple[hashable], numpy.ndarray]

build_local_ham(dtype=None)[source]

Get a LocalHamGen object for this operator.

Parameters:

dtype (numpy.dtype, optional) – The data type of the matrix. If not provided, will be automatically determined based on the terms in the operator.

Returns:

H – The local Hamiltonian representation of this operator.

Return type:

LocalHamGen

build_state_machine_greedy(atol=1e-12)[source]
draw_state_machine(method='greedy', figsize='auto', G=None)[source]

Draw the fintie state machine for this operator, as if buildling the MPO.

build_mpo(method='greedy', dtype=None, **mpo_opts)[source]

Build a matrix product operator (MPO) representation of this operator.

Parameters:
  • method (str, optional) – The method to use for building the MPO. Currently only “greedy” is supported.

  • dtype (type, optional) – The data type of the MPO. If not supplied, will be chosen automatically based on the terms in the operator.

  • mpo_opts (keyword arguments) – Additional options to pass to the MPO constructor. See MatrixProductOperator for details.

Returns:

mpo – The MPO representation of this operator.

Return type:

MatrixProductOperator

__repr__()[source]
build_matrix_ikron(**ikron_opts)[source]

Build either the dense or sparse matrix of this operator via explicit calls to ikron. This is a slower but useful alternative testing method.

quimb.operator.get_mat(op, dtype=None)[source]
class quimb.operator.HilbertSpace(sites, dims=2, order=None, sector=None, symmetry=None)[source]

Take a set of ‘sites’ (any sequence of sortable, hashable objects), and map this into a ‘register’ or linearly indexed range, optionally using a particular ordering. A symmetry and sector can also be specified, which will change the size of the Hilbert space and how the valid configurations are enumerated.

Some nomenclature:

  • site: a hashable label for a site in the Hilbert space. This can be any python object (e.g. tuple[str | int]).

  • register: a linear index for a site in the Hilbert space. This is an integer in the range [0, nsites), and requires an ordering of the sites.

  • configuration: a mapping from sites to their occupation number or spin state. This is a dictionary mapping from site to int.

  • flat configuration: a flat array of the occupation number or spin state of each site in the order given by this Hilbert space (i.e. a mapping of register to int). This is a 1D array of length nsites with dtype np.uint8, for efficient manipulation with numba and numpy.

  • rank: a linear index for a configuration in the Hilbert space, taking into account any symmetries and sectors. This is an integer in the range [0, size), where size is the size of the Hilbert space given the symmetry and sector.

Parameters:
  • sites (int, sequence of hashable objects, or dict) – The sites to map into a linear register. If an integer, simply use range(sites). If a dict, the keys are the sites and the values are the dimensions, in which case the dims argument is ignored.

  • dims (int or sequence of int, optional) – The local dimensions of each site. If an integer, all sites have the same dimension. If a sequence, it should be the same length as sites. You can also provide the dimensions as part of the sites argument by passing a dict, in which case this argument is ignored.

  • order (bool, sequence[hashable] or callable, optional) – How to order the sites. If None or False (default), the sites are kept in the order supplied. If True, the sites are sorted. If a sequence, it should be a permutation of the sites, and this will be used to order them. If a callable, it should be a sorting key function which will be used to order the sites.

  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, no sector is assumed.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space if any. If None and a sector is provided, the symmetry will be inferred from the sector if possible.

_size = None
_sizes = None
_strides = None
_pt = None
set_ordering(order)[source]

Set the ordering of the sites in this Hilbert space.

Parameters:

order (bool, sequence[hashable] or callable, optional) – How to order the sites. If None or False (default), the sites are kept in the order supplied. If True, the sites are sorted. If a sequence, it should be a permutation of the sites, and this will be used to order them. If a callable, it should be a sorting key function which will be used to order the sites.

classmethod from_edges(edges, order=None)[source]

Construct a HilbertSpace from a set of edges, which are pairs of sites.

Parameters:
  • edges (Iterable[tuple[hashable, hashable]]]) – The edges to parse.

  • order (bool, sequence[hashable] or callable, optional) – How to order the sites. If None or False (default), the sites are kept in the order supplied. If True, the sites are sorted. If a sequence, it should be a permutation of the sites, and this will be used to order them. If a callable, it should be a sorting key function which will be used to order the sites.

property sites

The ordered tuple of all sites in the Hilbert space.

property sector

The sector of the Hilbert space.

get_sector_numba(sector=None, symmetry=None)[source]

The sector of the Hilbert space, in ‘numba form’. A non-default symmetry and sector can be provided.

Parameters:
  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

Returns:

  • sector (ndarray[int64]) – The sector of the Hilbert space, in ‘numba form’. This is a 1D array of length 1, 2 or 4, depending on the symmetry.

  • symmetry (str) – The symmetry of the Hilbert space. This is one of “None”, “Z2”, “U1”, or “U1U1”.

property symmetry

The symmetry of the Hilbert space.

property nsites

The total number of sites in the Hilbert space.

get_sizes()[source]

Get a numpy array of the ordered sizes of each site in the Hilbert space.

property sizes

Get a numpy array of the ordered sizes of each site in the Hilbert space.

get_strides()[source]

Get the strides for each site in the Hilbert space.

property strides

Get the strides for each site in the Hilbert space.

get_pascal_table()[source]

Get a sufficiently large pascal table for this Hilbert space.

get_size(sector=None, symmetry=None)[source]

Get the size of the Hilbert space, optionally given a non-default symmetry and sector.

Parameters:
  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, the default sector is used.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space. If None, the default symmetry is used, or inferred from the supplied sector if possible.

property size

Get the size of this Hilbert space, taking into account the default symmetry and sector.

site_size(site)[source]

Get the local dimension of a given site.

site_to_reg(site)[source]

Convert a site to a linear register index.

reg_to_site(reg)[source]

Convert a linear register index back to a site.

has_site(site)[source]

Check if this HilbertSpace contains a given site.

rank_to_flatconfig(rank)[source]

Convert a rank (linear index) into a flat configuration.

Parameters:

rank (int) – The rank (linear index) to convert.

Returns:

flatconfig – A flat configuration, with the occupation number or spin state of each site in the order given by this HilbertSpace.

Return type:

ndarray[uint8]

flatconfig_to_rank(flatconfig)[source]

Convert a flat configuration into a rank (linear index).

Parameters:

flatconfig (ndarray[uint8]) – A flat configuration, with the occupation number or spin state of each site in the order given by this HilbertSpace.

Returns:

rank – The rank (linear index) of the flat configuration in the Hilbert space.

Return type:

int

config_to_flatconfig(config)[source]

Turn a configuration into a flat configuration, assuming the order given by this HilbertSpace.

Parameters:

config (dict[hashable, int]) – A dictionary mapping sites to their occupation number / spin.

Returns:

flatconfig – A flat configuration, with the occupation number or spin state of each site in the order given by this HilbertSpace.

Return type:

ndarray[uint8]

flatconfig_to_config(flatconfig)[source]

Turn a flat configuration into a configuration, assuming the order given by this HilbertSpace.

Parameters:

flatconfig (ndarray[uint8]) – A flat configuration, with the occupation number or spin state of each site in the order given by this HilbertSpace.

Returns:

config – A dictionary mapping sites to their occupation number / spin state.

Return type:

dict[hashable, int]

rank_to_config(rank)[source]

Convert a rank (linear index) into a configuration.

Parameters:

rank (int) – The rank (linear index) to convert.

Returns:

config – A dictionary mapping sites to their occupation number / spin state.

Return type:

dict[hashable, int]

config_to_rank(config)[source]

Convert a configuration into a rank (linear index).

Parameters:

config (dict[hashable, int]) – A dictionary mapping sites to their occupation number / spin state.

Returns:

rank – The rank (linear index) of the configuration in the Hilbert space.

Return type:

int

rand_rank(seed=None)[source]

Get a random rank (linear index) in the Hilbert space.

Parameters:

seed (None, int or numpy.random.Generator, optional) – The random seed or generator to use. If None, a new generator will be created with default settings.

Returns:

rank – A random rank in the Hilbert space.

Return type:

int64

rand_flatconfig(seed=None)[source]

Get a random flat configuration.

Parameters:

seed (None, int or numpy.random.Generator, optional) – The random seed or generator to use. If None, a new generator will be created with default settings.

Returns:

flatconfig – A flat configuration, with the occupation number or spin state of each site in the order given by this HilbertSpace.

Return type:

ndarray[uint8]

rand_config(seed=None)[source]

Get a random configuration.

Parameters:

seed (None, int or numpy.random.Generator, optional) – The random seed or generator to use. If None, a new generator will be created with default settings.

Returns:

config – A dictionary mapping sites to their occupation number / spin state.

Return type:

dict[hashable, np.uint8]

__repr__()[source]
quimb.operator.fermi_hubbard_from_edges(edges, t=1.0, U=1.0, mu=0.0, order=None, sector=None, symmetry=None, hilbert_space=None, dtype=None, pauli_decompose=False)[source]

Create a Fermi-Hubbard Hamiltonian on the graph defined by edges. The Hamiltonian is given by:

\[H = -t \sum_{\{i,j\}}^{|E|} \sum_{\sigma \in \uparrow, \downarrow} \left( c_{\sigma,i}^\dagger c_{\sigma,j} + c_{\sigma,j}^\dagger c_{\sigma,i} \right) + U \sum_{i}^{|V|} n_{\uparrow,i} n_{\downarrow,i} - \mu \sum_{i}^{|V|} \left( n_{\uparrow,i} + n_{\downarrow,i} \right)\]

where \(\{i,j\}\) are the edges of the graph, and \(c_{\sigma,i}\) is the fermionic annihilation operator acting on site \(i\) with spin \(\sigma\). The Jordan-Wigner transformation is used to implement fermionic statistics.

Parameters:
  • edges (Iterable[tuple[hashable, hashable]]) – The edges, as pairs of hashable ‘sites’, that define the graph. Multiple edges are allowed, but will be treated as a single edge.

  • t (float or tuple[float, float] or dict or callable, optional) – The hopping amplitude. Default is 1.0. If a tuple it specifies the up and down spin hoppings respectively. A dict or callable can be supplied to have edge-dependent hoppings.

  • U (float or dict or callable, optional) – The on-site interaction strength. Default is 1.0. A dict or callable can be supplied to have site-dependent interactions.

  • mu (float or tuple[float, float] or dict or callable, optional) – The chemical potential. Default is 0.0. If a tuple it specifies the up and down spin chemical potentials respectively. A dict or callable can be supplied to have site-dependent chemical potentials.

  • order (callable or sequence of hashable objects, optional) – If provided, use this to order the sites. If a callable, it should be a sorting key. If a sequence, it should be a permutation of the sites, and key=order.index will be used.

  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, no sector is assumed.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space if any. If None and a sector is provided, the symmetry will be inferred from the sector if possible.

  • hilbert_space (HilbertSpace, optional) – The Hilbert space to use. If not given, one will be constructed automatically from the edges. This overrides the order, symmetry, and sector parameters.

  • dtype ({None, str, type}, optional) – The data type of the Hamiltonian. If None, a default dtype will be used, np.float64 for real and np.complex128 for complex.

  • pauli_decompose (bool, optional) – Whether to decompose the Hamiltonian into Pauli strings after Jordan-Wigner transforming. Default is False.

Returns:

H – The Hamiltonian as a SparseOperatorBuilder object.

Return type:

SparseOperatorBuilder

quimb.operator.fermi_hubbard_spinless_from_edges(edges, t=1.0, V=0.0, mu=0.0, delta=0.0, order=None, sector=None, symmetry=None, hilbert_space=None, dtype=None, pauli_decompose=False)[source]

Create a spinless Fermi-Hubbard Hamiltonian on the graph defined by edges. The Hamiltonian is given by:

\[H = -t \sum_{\{i,j\}}^{|E|} \left( c_i^\dagger c_j + c_j^\dagger c_i \right) + V \sum_{\{i,j\}}^{|E|} n_i n_j - \mu \sum_{i}^{|V|} n_i + \Delta \sum_{\{i,j\}}^{|E|} \left( c_i^\dagger c_j^\dagger + c_j c_i \right)\]

where \(\{i,j\}\) are the edges of the graph, and \(c_i\) is the fermionic annihilation operator acting on site \(i\). The Jordan-Wigner transformation is used to implement fermionic statistics.

Parameters:
  • edges (Iterable[tuple[hashable, hashable]]) – The edges, as pairs of hashable ‘sites’, that define the graph. Multiple edges are allowed, but will be treated as a single edge.

  • t (float or dict or callable, optional) – The hopping amplitude. Default is 1.0. A dict or callable can be supplied to have edge-dependent hoppings.

  • V (float or dict or callable, optional) – The nearest neighbor interaction strength. Default is 0.0. A dict or callable can be supplied to have edge-dependent interactions.

  • mu (float or dict or callable, optional) – The chemical potential. Default is 0.0. A dict or callable can be supplied to have site-dependent chemical potentials.

  • delta (float or dict or callable, optional) – The superconducting pairing strength. Default is 0.0. A dict or callable can be supplied to have edge-dependent pairings.

  • order (callable or sequence of hashable objects, optional) – If provided, use this to order the sites. If a callable, it should be a sorting key. If a sequence, it should be a permutation of the sites, and key=order.index will be used.

  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, no sector is assumed.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space if any. If None and a sector is provided, the symmetry will be inferred from the sector if possible.

  • hilbert_space (HilbertSpace, optional) – The Hilbert space to use. If not given, one will be constructed automatically from the edges. This overrides the order, symmetry, and sector parameters.

  • dtype ({None, str, type}, optional) – The data type of the Hamiltonian. If None, a default dtype will be used, np.float64 for real and np.complex128 for complex.

  • pauli_decompose (bool, optional) – Whether to decompose the Hamiltonian into Pauli strings after Jordan-Wigner transforming. Default is False.

Returns:

H – The Hamiltonian as a SparseOperatorBuilder object.

Return type:

SparseOperatorBuilder

quimb.operator.heisenberg_from_edges(edges, j=1.0, b=0.0, order=None, sector=None, symmetry=None, hilbert_space=None, dtype=None)[source]

Create a Heisenberg Hamiltonian on the graph defined by edges.

\[H = \sum_{\{i,j\}}^{|E|} \left( J_x S^x_i S^x_j + J_y S^y_i S^y_j + J_z S^z_i S^z_j \right) - \sum_{i}^{|V|} \left( B_x S^x_i + B_y S^y_i + B_z S^z_i \right)\]

where \(\{i,j\}\) are the edges of the graph, and \(S^x_i\) is the spin-1/2 operator acting on site \(i\) in the x-direction, etc. Note positive values of \(J\) correspond to antiferromagnetic coupling here, and the magnetic field is in the z-direction by default.

Parameters:
  • edges (Iterable[tuple[hashable, hashable]]) – The edges, as pairs of hashable ‘sites’, that define the graph. Multiple edges are allowed, and will be treated as a single edge.

  • j (float or tuple[float, float, float] or dict or callable, optional) – The Heisenberg exchange coupling constant(s). If a single float is given, it is used for all three terms. If a tuple of three floats is given, they are used for the xx, yy, and zz terms respectively. Note that positive values of j correspond to antiferromagnetic coupling. A dict or callable can be supplied to have edge-dependent couplings.

  • b (float or tuple[float, float, float] or dict or callable, optional) – The magnetic field strength(s). If a single float is given, it is used taken as a z-field. If a tuple of three floats is given, they are used for the x, y, and z fields respectively. A dict or callable can be supplied to have site-dependent fields.

  • order (callable or sequence of hashable objects, optional) – If provided, use this to order the sites. If a callable, it should be a sorting key. If a sequence, it should be a permutation of the sites, and key=order.index will be used.

  • sector ({None, str, int, ((int, int), (int, int))}, optional) – The sector of the Hilbert space. If None, no sector is assumed.

  • symmetry ({None, "Z2", "U1", "U1U1"}, optional) – The symmetry of the Hilbert space if any. If None and a sector is provided, the symmetry will be inferred from the sector if possible.

  • hilbert_space (HilbertSpace, optional) – The Hilbert space to use. If not given, one will be constructed automatically from the edges. This overrides the order, symmetry, and sector parameters.

  • dtype ({None, str, type}, optional) – The data type of the Hamiltonian. If None, a default dtype will be used, np.float64 for real and np.complex128 for complex.

Returns:

H – The Hamiltonian as a SparseOperatorBuilder object.

Return type:

SparseOperatorBuilder

quimb.operator.rand_operator(n, m, k, kmin=None, seed=None, ops='XYZ')[source]

Generate a random operator with n qubits and m terms. Each term is a sum of k operators acting on different qubits. The operators are chosen randomly from the set {X, Y, Z, +, -, n}. The coefficients are drawn from a normal distribution.

Parameters:
  • n (int) – The number of qubits.

  • m (int) – The number of terms in the operator.

  • k (int) – The number of operators in each term.

  • kmin (int, optional) – The minimum number of operators in each term. If not given, kmin = k.

  • seed (int, optional) – The random seed for reproducibility.

  • ops (str, optional) – The set of operators to choose from.

Returns:

The random operator as a SparseOperatorBuilder object.

Return type:

SparseOperatorBuilder