quimb

Quantum Information for Many-Body calculations.

Subpackages

Submodules

Package Contents

Classes

qarray

Thin subclass of numpy.ndarray with some convenient quantum

Lazy

A simple class representing an unconstructed matrix. This can be passed

Evolution

A class for evolving quantum systems according to Schrodinger equation.

oset

An ordered set which stores elements as the keys of dict (ordered as of

LRU

Least recently used dict, which evicts old items. Taken from python

Functions

prod(iterable)

isket(qob)

Checks if qob is in ket form -- an array column.

isbra(qob)

Checks if qob is in bra form -- an array row.

isop(qob)

Checks if qob is an operator.

isvec(qob)

Checks if qob is row-vector, column-vector or one-dimensional.

issparse(qob)

Checks if qob is explicitly sparse.

isdense(qob)

Checks if qob is explicitly dense.

isreal(qob, **allclose_opts)

Checks if qob is approximately real.

isherm(qob, **allclose_opts)

Checks if qob is hermitian.

ispos(qob[, tol])

Checks if the dense hermitian qob is approximately positive

mul(x, y)

Element-wise multiplication, dispatched to correct dense or sparse

dag(qob)

Conjugate transpose.

dot(a, b)

Matrix multiplication, dispatched to dense or sparse functions.

vdot(a, b)

Accelerated 'Hermitian' inner product of two arrays. In other words,

rdot(a, b)

Real dot product of two dense vectors.

ldmul(diag, mat)

Accelerated left diagonal multiplication. Equivalent to

rdmul(mat, diag)

Accelerated left diagonal multiplication.

outer(a, b)

Outer product between two vectors (no conjugation).

explt(l, t)

Complex exponenital as used in solution to schrodinger equation.

get_thread_pool([num_workers])

normalize(qob[, inplace])

Normalize a quantum object.

chop(qob[, tol, inplace])

Set small values of a dense or sparse array to zero.

quimbify(data[, qtype, normalized, chopped, sparse, ...])

Converts data to 'quantum' i.e. complex matrices, kets being columns.

infer_size(p[, base])

Infer the size, i.e. number of 'sites' in a state.

trace(mat)

Trace of a dense or sparse operator.

identity(d[, sparse, stype, dtype])

Return identity of size d in complex format, optionally sparse.

dim_map(dims, coos[, cyclic, trim])

Flatten 2d+ dimensions and coordinates.

dim_compress(dims, inds)

Compress neighbouring subsytem dimensions.

kron(*ops[, stype, coo_build, parallel, ownership])

Tensor (kronecker) product of variable number of arguments.

kronpow(a, p, **kron_opts)

Returns a tensored with itself p times

ikron(ops, dims, inds[, sparse, stype, coo_build, ...])

Tensor an operator into a larger space by padding with identities.

pkron(op, dims, inds, **ikron_opts)

Advanced, padded tensor product.

permute(p, dims, perm)

Permute the subsytems of state or opeator.

itrace(a[, axes])

General tensor trace, i.e. multiple contractions, for a dense array.

partial_trace(p, dims, keep)

Partial trace of a dense or sparse state.

expectation(a, b)

'Expectation' between a vector/operator and another vector/operator.

eigensystem(A, isherm, *[, k, sort, return_vecs])

Find all or some eigenpairs of an operator.

eigensystem_partial(A, k, isherm, *[, B, which, ...])

Return a few eigenpairs from an operator.

groundstate(ham, **kwargs)

Alias for finding lowest eigenvector only.

groundenergy(ham, **kwargs)

Alias for finding lowest eigenvalue only.

bound_spectrum(A[, backend])

Return the smallest and largest eigenvalue of hermitian operator A.

eigh_window(A, w_0, k[, w_sz, backend, return_vecs, ...])

Return mid-spectrum eigenpairs from a hermitian operator.

eigvalsh_window(*args, **kwargs)

Alias for only finding the eigenvalues in a relative window.

eigvecsh_window(*args, **kwargs)

Alias for only finding the eigenvectors in a relative window.

svd(A[, return_vecs])

Compute full singular value decomposition of an operator, using numpy.

svds(A, k[, ncv, return_vecs, backend])

Compute the partial singular value decomposition of an operator.

norm(A[, ntype])

Operator norms.

expm(A[, herm])

Matrix exponential, can be accelerated if explicitly hermitian.

sqrtm(A[, herm])

Matrix square root, can be accelerated if explicitly hermitian.

expm_multiply(mat, vec[, backend])

Compute the action of expm(mat) on vec.

rsvd(A, eps_or_k[, compute_uv, mode, use_qb, q, p, ...])

Fast, randomized, iterative SVD. Adaptive variant of method due

estimate_rank(A, eps[, k_max, use_sli, k_start, ...])

Estimate the rank of an linear operator. Uses a low quality random

get_mpi_pool([num_workers, num_threads])

Get the MPI executor pool, with specified number of processes and

can_use_mpi_pool()

Function to determine whether we are allowed to call get_mpi_pool.

spin_operator(label[, S])

Generate a general spin-operator.

pauli(xyz[, dim])

Generates the pauli operators for dimension 2 or 3.

hadamard([dtype, sparse])

The Hadamard gate.

phase_gate(phi[, dtype, sparse])

The generalized qubit phase-gate, which adds phase phi to the

S_gate([dtype, sparse])

The S-gate (phase gate).

T_gate([dtype, sparse])

The T-gate (pi/8 gate).

U_gate(theta, phi, lamda[, dtype, sparse])

Arbitrary unitary single qubit gate.

rotation(phi[, xyz, dtype, sparse])

The single qubit rotation gate.

Xsqrt(**qu_opts)

Rx(pi / 2).

Ysqrt(**qu_opts)

Ry(pi / 2).

Zsqrt(**qu_opts)

Rz(pi / 2).

Wsqrt(**qu_opts)

R[X + Y](pi / 2).

swap([dim, dtype])

The SWAP operator acting on subsystems of dimension dim.

iswap([dtype])

fsim(theta, phi[, dtype])

The 'fermionic simulation' gate:

fsimg(theta, zeta, chi, gamma, phi[, dtype])

The 'fermionic simulation' gate, with:

ncontrolled_gate(ncontrol, gate[, dtype, sparse])

Build an n-qubit controlled gate. The control qubits are the

controlled(s[, dtype, sparse])

Construct a controlled pauli gate for two qubits.

CNOT([dtype, sparse])

The controlled-not gate.

cX([dtype, sparse])

The controlled-X gate.

cY([dtype, sparse])

The controlled-Y gate.

cZ([dtype, sparse])

The controlled-Z gate.

ccX([dtype, sparse])

The double controlled X gate, or Toffoli gate.

ccY([dtype, sparse])

The double controlled Y gate.

ccZ([dtype, sparse])

The double controlled Z gate.

controlled_swap([dtype, sparse])

The controlled swap or Fredkin gate. The control qubit is the first

ham_heis(n[, j, b, cyclic, parallel, nthreads, ownership])

Constructs the nearest neighbour 1d heisenberg spin-1/2 hamiltonian.

ham_ising(n[, jz, bx])

Generate the quantum transverse field ising model hamiltonian. This is a

ham_XY(n, jxy, bz, **ham_opts)

Generate the quantum transverse field XY model hamiltonian. This is a

ham_XXZ(n, delta[, jxy])

Generate the XXZ-model hamiltonian. This is a

ham_j1j2(n[, j1, j2, bz, cyclic, ownership])

Generate the j1-j2 hamiltonian, i.e. next nearest neighbour

ham_mbl(n, dh[, j, bz, cyclic, seed, dh_dist, dh_dim, ...])

Constructs a heisenberg hamiltonian with isotropic coupling and

ham_heis_2D(n, m[, j, bz, cyclic, parallel, ownership])

Construct the 2D spin-1/2 heisenberg model hamiltonian:

zspin_projector(n[, sz, stype, dtype])

Construct the projector onto spin-z subpspaces.

create([n])

The creation operator acting on an n-level system.

destroy([n])

The annihilation operator acting on an n-level system.

num(n, **qu_opts)

The number operator acting on an n-level system.

ham_hubbard_hardcore(n[, t, V, mu, cyclic, parallel, ...])

Generate the spinless fermion hopping hamiltonian.

basis_vec(i, dim[, ownership])

Constructs a unit vector ket:

up(**kwargs)

Returns up-state, aka. |0>, +Z eigenstate:

down(**kwargs)

Returns down-state, aka. |1>, -Z eigenstate:

plus(**kwargs)

Returns plus-state, aka. |+>, +X eigenstate:

minus(**kwargs)

Returns minus-state, aka. |->, -X eigenstate:

yplus(**kwargs)

Returns yplus-state, aka. |y+>, +Y eigenstate:

yminus(**kwargs)

Returns yplus-state, aka. |y->, -Y eigenstate:

bloch_state(ax, ay, az[, purified])

Construct qubit density operator from bloch vector:

bell_state(s, **kwargs)

One of the four bell-states.

singlet(**kwargs)

Alias for the 'psi-' bell-state.

thermal_state(ham, beta[, precomp_func])

Generate a thermal state of a Hamiltonian.

neel_state(n[, down_first])

Construct Neel state for n spins, i.e. alternating up/down.

singlet_pairs(n, **kwargs)

Construct fully dimerised spin chain.

werner_state(p, **kwargs)

Construct Werner State, i.e. fractional mix of identity with singlet.

ghz_state(n, **kwargs)

Construct GHZ state of n spins, i.e. equal superposition of all up

w_state(n, **kwargs)

Construct W-state: equal superposition of all single spin up states.

levi_civita(perm)

Compute the generalised levi-civita coefficient for a permutation.

perm_state(ps)

Construct the anti-symmetric state which is the +- sum of all

graph_state_1d(n[, cyclic, sparse])

Graph State on a line.

computational_state(binary, **kwargs)

Generate the qubit computational state with binary.

randn([shape, dtype, scale, loc, num_threads, seed, dist])

Fast multithreaded generation of random normally distributed data.

rand(*args, **kwargs)

rand_matrix(d[, scaled, sparse, stype, density, ...])

Generate a random matrix of order d with normally distributed

rand_herm(d[, sparse, density, dtype])

Generate a random hermitian operator of order d with normally

rand_pos(d[, sparse, density, dtype])

Generate a random positive operator of size d, with normally

rand_rho(d[, sparse, density, dtype])

Generate a random positive operator of size d with normally

rand_ket(d[, sparse, stype, density, dtype])

Generates a ket of length d with normally distributed entries.

rand_uni(d[, dtype])

Generate a random unitary operator of size d, distributed according to

rand_haar_state(d[, dtype])

Generate a random state of dimension d according to the Haar

gen_rand_haar_states(d, reps[, dtype])

Generate many random Haar states, recycling a random unitary operator

rand_mix(d[, tr_d_min, tr_d_max, mode, dtype])

Constructs a random mixed state by tracing out a random ket

rand_product_state(n[, qtype, dtype])

Generates a ket of n many random pure qubits.

rand_matrix_product_state(n, bond_dim[, phys_dim, ...])

Generate a random matrix product state (in dense form, see

rand_seperable(dims[, num_mix, dtype])

Generate a random, mixed, seperable state. E.g rand_seperable([2, 2])

rand_iso(n, m[, dtype])

Generate a random isometry of shape (n, m).

rand_mera(n[, invariant, dtype])

Generate a random mera state of n qubits, which must be a power

seed_rand(seed)

See the random number generators, by instantiating a new set of bit

set_rand_bitgen(bitgen)

Set the core bit generator type to use, from either numpy or

fidelity(p1, p2[, squared])

Fidelity between two quantum states. By default, the unsquared fidelity

purify(rho)

Take state rho and purify it into a wavefunction of squared

entropy(a[, rank])

Compute the (von Neumann) entropy.

mutinf(p[, dims, sysa, rank])

Find the mutual information for a bipartition of a state.

mutinf_subsys(psi_abc, dims, sysa, sysb[, approx_thresh])

Calculate the mutual information of two subsystems of a pure state,

schmidt_gap(psi_ab, dims, sysa)

Find the schmidt gap of the bipartition of psi_ab. That is, the

tr_sqrt(A[, rank])

Return the trace of the sqrt of a positive semidefinite operator.

partial_transpose(p[, dims, sysa])

Partial transpose of a density operator.

negativity(p[, dims, sysa])

Compute negativity between two subsytems.

logneg(p[, dims, sysa])

Compute logarithmic negativity between two subsytems.

logneg_subsys(psi_abc, dims, sysa, sysb[, approx_thresh])

Compute the logarithmic negativity between two subsystems of a pure

concurrence(p[, dims, sysa, sysb])

Concurrence of two-qubit state.

one_way_classical_information(p_ab, prjs[, precomp_func])

One way classical information for two qubit density operator.

quantum_discord(p[, dims, sysa, sysb, method, tol, ...])

Quantum Discord for two qubit density operator.

trace_distance(p1, p2)

Trace distance between two states:

cprint(psi[, prec])

Print a state in the computational basis.

decomp(a, fn, fn_args, fn_d, nmlz_func[, mode, tol])

Decomposes an operator via the Hilbert-schmidt inner product.

correlation(p, A, B, sysa, sysb[, dims, sparse, ...])

Calculate the correlation between two sites given two operators.

pauli_correlations(p[, ss, sysa, sysb, sum_abs, ...])

Calculate the correlation between sites for a list of operator pairs

ent_cross_matrix(p[, sz_blc, ent_fn, calc_self_ent, ...])

Calculate the pair-wise function ent_fn between all sites or blocks

qid(p, dims, inds[, precomp_func, sparse_comp, ...])

is_degenerate(op[, tol])

Check if operator has any degenerate eigenvalues, determined relative

is_eigenvector(x, A[, tol])

Determines whether a vector is an eigenvector of an operator.

page_entropy(sz_subsys, sz_total)

Calculate the page entropy, i.e. expected entropy for a subsytem

heisenberg_energy(L)

Get the analytic isotropic heisenberg chain ground energy for length L.

dephase(rho, p[, rand_rank])

Dephase rho by amount p, that is, mix it

kraus_op(rho, Ek[, dims, where, check])

Operate on a mixed state with a set of kraus operators:

projector(A[, eigenvalue, tol, autoblock])

Compute the projector for the target eigenvalue of operator

measure(p, A[, eigenvalue, tol])

Measure state p with observable A, collapsing the state in the

simulate_counts(p, C[, phys_dim, seed])

Simulate measuring each qubit of p in the computational basis,

approx_spectral_function(A, f[, tol, bsz, R, ...])

Approximate a spectral function, that is, the quantity Tr(f(A)).

tr_abs_approx(*args, **kwargs)

tr_exp_approx(*args, **kwargs)

tr_sqrt_approx(*args, **kwargs)

tr_xlogx_approx(*args, **kwargs)

entropy_subsys_approx(psi_ab, dims, sysa[, backend])

Approximate the (Von Neumann) entropy of a pure state's subsystem.

logneg_subsys_approx(psi_abc, dims, sysa, sysb, **kwargs)

Estimate the logarithmic negativity of a pure state's subsystem.

negativity_subsys_approx(psi_abc, dims, sysa, sysb, ...)

Estimate the negativity of a pure state's subsystem.

xlogx(x)

save_to_disk(obj, fname, **dump_opts)

Save an object to disk using joblib.dump.

load_from_disk(fname, **load_opts)

Load an object form disk using joblib.load.

tree_map(f, tree[, is_leaf])

Map f over all leaves in tree, returning a new pytree.

tree_apply(f, tree[, is_leaf])

Apply f to all leaves in tree, no new pytree is built.

tree_flatten(tree[, get_ref, is_leaf])

Flatten tree into a list of leaves.

tree_unflatten(objs, tree[, is_leaf])

Unflatten objs into a pytree of the same structure as tree.

format_number_with_error(x, err)

Given x with error err, format a string showing the relevant

default_to_neutral_style(fn)

Wrap a function or method to use the neutral style by default.

Attributes

qu

Alias of quimbify().

ket

Convert an object into a ket.

bra

Convert an object into a bra.

dop

Convert an object into a density operator.

sparse

Convert an object into sparse form.

eye

Alias for identity().

speye

Sparse identity.

expec

Alias for expectation().

nmlz

Alias for normalize().

tr

Alias for trace().

ptr

Alias for partial_trace().

eig

eigh

eigvals

eigvalsh

eigvecs

eigvecsh

Rx

Ry

Rz

cswap

fredkin

toffoli

zplus

zminus

xplus

xminus

rand_mps

entropy_subsys

Calculate the entropy of a pure states' subsystem, optionally switching

mutual_information

tr_sqrt_subsys

Compute the trace sqrt of a subsystem, possibly using an approximate

logarithmic_negativity

pauli_decomp

Decompose an operator into Paulis.

bell_decomp

Decompose an operator into bell-states.

NEUTRAL_STYLE

class quimb.qarray(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)[source]

Bases: numpy.ndarray

Thin subclass of numpy.ndarray with some convenient quantum linear algebra related methods and attributes (.H, &, etc.), and matrix-like preservation of at least 2-dimensions so as to distiguish kets and bras.

property H
property A
__array__()[source]
__and__(other)[source]
normalize(inplace=True)[source]
nmlz(inplace=True)[source]
chop(inplace=True)[source]
tr()[source]
partial_trace(dims, keep)[source]
ptr(dims, keep)[source]
__str__()[source]

Return str(self).

__repr__()[source]

Return repr(self).

quimb.prod(iterable)
quimb.isket(qob)[source]

Checks if qob is in ket form – an array column.

quimb.isbra(qob)[source]

Checks if qob is in bra form – an array row.

quimb.isop(qob)[source]

Checks if qob is an operator.

quimb.isvec(qob)[source]

Checks if qob is row-vector, column-vector or one-dimensional.

quimb.issparse(qob)[source]

Checks if qob is explicitly sparse.

quimb.isdense(qob)[source]

Checks if qob is explicitly dense.

quimb.isreal(qob, **allclose_opts)[source]

Checks if qob is approximately real.

quimb.isherm(qob, **allclose_opts)[source]

Checks if qob is hermitian.

Parameters:

qob (dense or sparse operator) – Matrix to check.

Return type:

bool

quimb.ispos(qob, tol=1e-15)[source]

Checks if the dense hermitian qob is approximately positive semi-definite, using the cholesky decomposition.

Parameters:

qob (dense operator) – Matrix to check.

Return type:

bool

quimb.mul(x, y)[source]

Element-wise multiplication, dispatched to correct dense or sparse function.

Parameters:
  • x (dense or sparse operator) – First array.

  • y (dense or sparse operator) – Second array.

Returns:

Element wise product of x and y.

Return type:

dense or sparse operator

quimb.dag(qob)[source]

Conjugate transpose.

quimb.dot(a, b)[source]

Matrix multiplication, dispatched to dense or sparse functions.

Parameters:
  • a (dense or sparse operator) – First array.

  • b (dense or sparse operator) – Second array.

Returns:

Dot product of a and b.

Return type:

dense or sparse operator

quimb.vdot(a, b)[source]

Accelerated ‘Hermitian’ inner product of two arrays. In other words, b here will be conjugated by the function.

quimb.rdot(a, b)[source]

Real dot product of two dense vectors.

Here, b will not be conjugated before the inner product.

quimb.ldmul(diag, mat)[source]

Accelerated left diagonal multiplication. Equivalent to numpy.diag(diag) @ mat, but faster than numpy.

Parameters:
  • diag (vector or 1d-array) – Vector representing the diagonal of a matrix.

  • mat (dense or sparse matrix) – A normal (non-diagonal) matrix.

Returns:

Dot product of the matrix whose diagonal is diag and mat.

Return type:

dense or sparse matrix

quimb.rdmul(mat, diag)[source]

Accelerated left diagonal multiplication.

Equivalent to mat @ numpy.diag(diag), but faster.

Parameters:
  • mat (dense or sparse matrix) – A normal (non-diagonal) matrix.

  • diag (vector or 1d-array) – Vector representing the diagonal of a matrix.

Returns:

Dot product of mat and the matrix whose diagonal is diag.

Return type:

dense or sparse matrix

quimb.outer(a, b)[source]

Outer product between two vectors (no conjugation).

quimb.explt(l, t)[source]

Complex exponenital as used in solution to schrodinger equation.

quimb.get_thread_pool(num_workers=None)
quimb.normalize(qob, inplace=True)[source]

Normalize a quantum object.

Parameters:
  • qob (dense or sparse vector or operator) – Quantum object to normalize.

  • inplace (bool, optional) – Whether to act inplace on the given operator.

Returns:

Normalized quantum object.

Return type:

dense or sparse vector or operator

quimb.chop(qob, tol=1e-15, inplace=True)[source]

Set small values of a dense or sparse array to zero.

Parameters:
  • qob (dense or sparse vector or operator) – Quantum object to chop.

  • tol (float, optional) – Fraction of max(abs(qob)) to chop below.

  • inplace (bool, optional) – Whether to act on input array or return copy.

Returns:

Chopped quantum object.

Return type:

dense or sparse vector or operator

quimb.quimbify(data, qtype=None, normalized=False, chopped=False, sparse=None, stype=None, dtype=complex)[source]

Converts data to ‘quantum’ i.e. complex matrices, kets being columns.

Parameters:
  • data (dense or sparse array_like) – Array describing vector or operator.

  • qtype ({'ket', 'bra' or 'dop'}, optional) – Quantum object type output type. Note that if an operator is given as data and 'ket' or 'bra' as qtype, the operator will be unravelled into a column or row vector.

  • sparse (bool, optional) – Whether to convert output to sparse a format.

  • normalized (bool, optional) – Whether to normalise the output.

  • chopped (bool, optional) – Whether to trim almost zero entries of the output.

  • stype ({'csr', 'csc', 'bsr', 'coo'}, optional) – Format of output matrix if sparse, defaults to 'csr'.

Return type:

dense or sparse vector or operator

Notes

  1. Will unravel an array if 'ket' or 'bra' given.

  2. Will conjugate if 'bra' given.

  3. Will leave operators as is if 'dop' given, but construct one if vector given with the assumption that it was a ket.

Examples

Create a ket (column vector):

>>> qu([1, 2j, 3])
qarray([[1.+0.j],
        [0.+2.j],
        [3.+0.j]])

Create a single precision bra (row vector):

>>> qu([1, 2j, 3], qtype='bra', dtype='complex64')
qarray([[1.-0.j, 0.-2.j, 3.-0.j]], dtype=complex64)

Create a density operator from a vector:

>>> qu([1, 2j, 3], qtype='dop')
qarray([[1.+0.j, 0.-2.j, 3.+0.j],
        [0.+2.j, 4.+0.j, 0.+6.j],
        [3.+0.j, 0.-6.j, 9.+0.j]])

Create a sparse density operator:

>>> qu([1, 0, 0], sparse=True, qtype='dop')
<3x3 sparse matrix of type '<class 'numpy.complex128'>'
    with 1 stored elements in Compressed Sparse Row format>
quimb.qu[source]

Alias of quimbify().

quimb.ket

Convert an object into a ket.

quimb.bra

Convert an object into a bra.

quimb.dop

Convert an object into a density operator.

quimb.sparse

Convert an object into sparse form.

quimb.infer_size(p, base=2)[source]

Infer the size, i.e. number of ‘sites’ in a state.

Parameters:
  • p (vector or operator) – An array representing a state with a shape attribute.

  • base (int, optional) – Size of the individual states that p is composed of, e.g. this defauts 2 for qubits.

Returns:

Number of composite systems.

Return type:

int

Examples

>>> infer_size(singlet() & singlet())
4
>>> infersize(rand_rho(5**3), base=5)
3
quimb.trace(mat)[source]

Trace of a dense or sparse operator.

Parameters:

mat (operator) – Operator, dense or sparse.

Returns:

x – Trace of mat

Return type:

float

quimb.identity(d, sparse=False, stype='csr', dtype=complex)[source]

Return identity of size d in complex format, optionally sparse.

Parameters:
  • d (int) – Dimension of identity.

  • sparse (bool, optional) – Whether to output in sparse form.

  • stype (str, optional) – If sparse, what format to use.

Returns:

id – Identity operator.

Return type:

qarray or sparse matrix

quimb.eye[source]

Alias for identity().

quimb.speye

Sparse identity.

quimb.dim_map(dims, coos, cyclic=False, trim=False)[source]

Flatten 2d+ dimensions and coordinates.

Maps multi-dimensional coordinates and indices to flat arrays in a regular way. Wraps or deletes coordinates beyond the system size depending on parameters cyclic and trim.

Parameters:
  • dims (nested tuple of int) – Multi-dim array of systems’ internal dimensions.

  • coos (list of tuples of int) – Array of coordinate tuples to convert

  • cyclic (bool, optional) – Whether to automatically wrap coordinates beyond system size or delete them.

  • trim (bool, optional) – If True, any coordinates beyond dimensions will be deleted, overidden by cyclic.

Returns:

  • flat_dims (tuple) – Flattened version of dims.

  • inds (tuple) – Indices corresponding to the original coordinates.

Examples

>>> dims = [[2, 3], [4, 5]]
>>> coords = [(0, 0), (1, 1)]
>>> flat_dims, inds = dim_map(dims, coords)
>>> flat_dims
(2, 3, 4, 5)
>>> inds
(0, 3)
>>> dim_map(dims, [(2, 0), (-1, 1)], cyclic=True)
((2, 3, 4, 5), (0, 3))
quimb.dim_compress(dims, inds)[source]

Compress neighbouring subsytem dimensions.

Take some dimensions and target indices and compress both, i.e. merge adjacent dimensions that are both either in dims or not. For example, if tensoring an operator onto a single site, with many sites the identity, treat these as single large identities.

Parameters:
  • dims (tuple of int) – List of system’s dimensions - 1d or flattened (e.g. with dim_map).

  • inds (tuple of int) – List of target indices, i.e. dimensions not to merge.

Returns:

  • dims (tuple of int) – New compressed dimensions.

  • inds (tuple of int) – New indexes corresponding to the compressed dimensions. These are guaranteed to now be alternating i.e. either (0, 2, …) or (1, 3, …).

Examples

>>> dims = [2] * 10
>>> inds = [3, 4]
>>> compressed_dims, compressed_inds = dim_compress(dims, inds)
>>> compressed_dims
(8, 4, 32)
>>> compressed_inds
(1,)
quimb.kron(*ops, stype=None, coo_build=False, parallel=False, ownership=None)[source]

Tensor (kronecker) product of variable number of arguments.

Parameters:
  • ops (sequence of vectors or matrices) – Objects to be tensored together.

  • stype (str, optional) – Desired output format if resultant object is sparse. Should be one of {'csr', 'bsr', 'coo', 'csc'}. If None, infer from input matrices.

  • coo_build (bool, optional) – Whether to force sparse construction to use the 'coo' format (only for sparse matrices in the first place.).

  • parallel (bool, optional) – Perform a parallel reduce on the operators, can be quicker.

  • ownership ((int, int), optional) – If given, only construct the rows in range(*ownership). Such that the final operator is actually X[slice(*ownership), :]. Useful for constructing operators in parallel, e.g. for MPI.

Returns:

X – Tensor product of ops.

Return type:

dense or sparse vector or operator

Notes

  1. The product is performed as (a & (b & (c & ...)))

Examples

Simple example:

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[1., 1.1], [1.11, 1.111]])
>>> kron(a, b)
qarray([[1.   , 1.1  , 2.   , 2.2  ],
        [1.11 , 1.111, 2.22 , 2.222],
        [3.   , 3.3  , 4.   , 4.4  ],
        [3.33 , 3.333, 4.44 , 4.444]])

Partial construction of rows:

>>> ops = [rand_matrix(2, sparse=True) for _ in range(10)]
>>> kron(*ops, ownership=(256, 512))
<256x1024 sparse matrix of type '<class 'numpy.complex128'>'
        with 13122 stored elements in Compressed Sparse Row format>
quimb.kronpow(a, p, **kron_opts)[source]

Returns a tensored with itself p times

Equivalent to reduce(lambda x, y: x & y, [a] * p).

Parameters:
  • a (dense or sparse vector or operator) – Object to tensor power.

  • p (int) – Tensor power.

  • kron_opts – Supplied to kron().

Return type:

dense or sparse vector or operator

quimb.ikron(ops, dims, inds, sparse=None, stype=None, coo_build=False, parallel=False, ownership=None)[source]

Tensor an operator into a larger space by padding with identities.

Automatically placing a large operator over several dimensions is allowed and a list of operators can be given which are then placed cyclically.

Parameters:
  • op (operator or sequence of operators) – Operator(s) to place into the tensor space. If more than one, these are cyclically placed at each of the dims specified by inds.

  • dims (sequence of int or nested sequences of int) – The subsystem dimensions. If treated as an array, should have the same number of dimensions as the system.

  • inds (tuple of int, or sequence of tuple of int) – Indices, or coordinates, of the dimensions to place operator(s) on. Each dimension specified can be smaller than the size of op (as long as it factorizes it).

  • sparse (bool, optional) – Whether to construct the new operator in sparse form.

  • stype (str, optional) – If sparse, which format to use for the output.

  • coo_build (bool, optional) – Whether to build the intermediary matrices using the 'coo' format - can be faster to build sparse in this way, then convert to chosen format, including dense.

  • parallel (bool, optional) – Whether to build the operator in parallel using threads (only good for big (d > 2**16) operators).

  • ownership ((int, int), optional) – If given, only construct the rows in range(*ownership). Such that the final operator is actually X[slice(*ownership), :]. Useful for constructing operators in parallel, e.g. for MPI.

Returns:

Operator such that ops act on dims[inds].

Return type:

qarray or sparse matrix

See also

kron, pkron

Examples

Place an operator between two identities:

>>> IZI = ikron(pauli('z'), [2, 2, 2], 1)
>>> np.allclose(IZI, eye(2) & pauli('z') & eye(2))
True

Overlay a large operator on several sites:

>>> rho_ab = rand_rho(4)
>>> rho_abc = ikron(rho_ab, [5, 2, 2, 7], [1, 2])  # overlay both 2s
>>> rho_abc.shape
(140, 140)

Place an operator at specified sites, regardless of size:

>>> A = rand_herm(5)
>>> ikron(A, [2, -1, 2, -1, 2, -1], [1, 3, 5]).shape
(1000, 1000)

Create a two site interaction (note the coefficient jx we only need to multiply into a single input operator):

>>> Sx = spin_operator('X')
>>> jx = 0.123
>>> jSxSx = ikron([jx * Sx, Sx], [2, 2, 2, 2], [0, 3])
>>> np.allclose(jSxSx, jx * (Sx & eye(2) & eye(2) & Sx))
True
quimb.pkron(op, dims, inds, **ikron_opts)[source]

Advanced, padded tensor product.

Construct an operator such that op acts on dims[inds], and allow it to be arbitrarily split and reversed etc., in other words, permute and then tensor it into a larger space.

Parameters:
  • ops (matrix-like or tuple of matrix-like) – Operator to place into the tensor space.

  • dims (tuple of int) – Dimensions of tensor space.

  • inds (tuple of int) – Indices of the dimensions to place operators on. If multiple operators are specified, inds[1] corresponds to ops[1] and so on.

  • sparse (bool, optional) – Whether to construct the new operator in sparse form.

  • stype (str, optional) – If sparse, which format to use for the output.

  • coo_build (bool, optional) – Whether to build the intermediary matrices using the 'coo' format - can be faster to build sparse in this way, then convert to chosen format, including dense.

Returns:

Operator such that ops act on dims[inds].

Return type:

operator

See also

ikron, permute

Examples

Here we take an operator that acts on spins 0 and 1 with X and Z, and transform it to act on spins 2 and 0 – i.e. reverse it and sandwich an identity between the two sites it acts on.

>>> XZ = pauli('X') & pauli('Z')
>>> ZIX = pkron(XZ, dims=[2, 3, 2], inds=[2, 0])
>>> np.allclose(ZIX, pauli('Z') & eye(3) & pauli('X'))
True
quimb.permute(p, dims, perm)[source]

Permute the subsytems of state or opeator.

Parameters:
  • p (vector or operator) – State or operator to permute.

  • dims (tuple of int) – Internal dimensions of the system.

  • perm (tuple of int) – New order of indexes range(len(dims)).

Returns:

pp – Permuted state or operator.

Return type:

vector or operator

See also

pkron

Examples

>>> IX = speye(2) & pauli('X', sparse=True)
>>> XI = permute(IX, dims=[2, 2], perm=[1, 0])
>>> np.allclose(XI.A, pauli('X') & eye(2))
True
quimb.itrace(a, axes=(0, 1))[source]

General tensor trace, i.e. multiple contractions, for a dense array.

Parameters:
  • a (numpy.ndarray) – Tensor to trace.

  • axes ((2,) int or (2,) array of int) –

    • (2,) int: Perform trace on the two indices listed.

    • (2,) array of int: Trace out first sequence of indices with second sequence indices.

Returns:

The tensor remaining after tracing out the specified axes.

Return type:

numpy.ndarray

See also

trace, partial_trace

Examples

Trace out a single pair of dimensions:

>>> a = randn(2, 3, 4, 2, 3, 4)
>>> itrace(a, axes=(0, 3)).shape
(3, 4, 3, 4)

Trace out multiple dimensions:

>>> itrace(a, axes=([1, 2], [4, 5])).shape
(2, 2)
quimb.partial_trace(p, dims, keep)[source]

Partial trace of a dense or sparse state.

Parameters:
  • p (ket or density operator) – State to perform partial trace on - can be sparse.

  • dims (sequence of int or nested sequences of int) – The subsystem dimensions. If treated as an array, should have the same number of dimensions as the system.

  • keep (int, sequence of int or sequence of tuple[int]) – Index or indices of subsytem(s) to keep. If a sequence of integer tuples, each should be a coordinate such that the length matches the number of dimensions of the system.

Returns:

rho – Density operator of subsytem dimensions dims[keep].

Return type:

qarray

See also

itrace

Examples

Trace out single subsystem of a ket:

>>> psi = bell_state('psi-')
>>> ptr(psi, [2, 2], keep=0)  # expect identity
qarray([[ 0.5+0.j,  0.0+0.j],
        [ 0.0+0.j,  0.5+0.j]])

Trace out multiple subsystems of a density operator:

>>> rho_abc = rand_rho(3 * 4 * 5)
>>> rho_ab = partial_trace(rho_abc, [3, 4, 5], keep=[0, 1])
>>> rho_ab.shape
(12, 12)

Trace out qutrits from a 2D system:

>>> psi_abcd = rand_ket(3 ** 4)
>>> dims = [[3, 3],
...         [3, 3]]
>>> keep = [(0, 0), (1, 1)]
>>> rho_ac = partial_trace(psi_abcd, dims, keep)
>>> rho_ac.shape
(9, 9)
quimb.expectation(a, b)[source]

‘Expectation’ between a vector/operator and another vector/operator.

The ‘operator’ inner product between a and b, but also for vectors. This means that for consistency:

  • for two vectors it will be the absolute expec squared |<a|b><b|a>|, not <a|b>.

  • for a vector and an operator its will be <a|b|a>

  • for two operators it will be the Hilbert-schmidt inner product tr(A @ B)

In this way expectation(a, b) == expectation(dop(a), b) == expectation(dop(a), dop(b)).

Parameters:
  • a (vector or operator) – First state or operator - assumed to be ket if vector.

  • b (vector or operator) – Second state or operator - assumed to be ket if vector.

Returns:

x – ‘Expectation’ of a with b.

Return type:

float

quimb.expec[source]

Alias for expectation().

quimb.nmlz[source]

Alias for normalize().

quimb.tr[source]

Alias for trace().

quimb.ptr[source]

Alias for partial_trace().

quimb.eigensystem(A, isherm, *, k=-1, sort=True, return_vecs=True, **kwargs)[source]

Find all or some eigenpairs of an operator.

Parameters:
  • A (operator) – The operator to decompose.

  • isherm (bool) – Whether the operator is assumed to be hermitian or not.

  • k (int, optional) – If negative, find all eigenpairs, else perform partial eigendecomposition and find k pairs. See eigensystem_partial().

  • sort (bool, optional) – Whether to sort the eigenpairs in ascending eigenvalue order.

  • kwargs – Supplied to the backend function.

Returns:

  • el ((k,) array) – Eigenvalues.

  • ev ((d, k) array) – Corresponding eigenvectors as columns of array, such that ev @ diag(el) @ ev.H == A.

quimb.eig
quimb.eigh
quimb.eigvals
quimb.eigvalsh
quimb.eigvecs
quimb.eigvecsh
quimb.eigensystem_partial(A, k, isherm, *, B=None, which=None, return_vecs=True, sigma=None, ncv=None, tol=None, v0=None, sort=True, backend=None, fallback_to_scipy=False, **backend_opts)[source]

Return a few eigenpairs from an operator.

Parameters:
  • A (sparse, dense or linear operator) – The operator to solve for.

  • k (int) – Number of eigenpairs to return.

  • isherm (bool) – Whether to use hermitian solve or not.

  • B (sparse, dense or linear operator, optional) – If given, the RHS operator defining a generalized eigen problem.

  • which ({'SA', 'LA', 'LM', 'SM', 'TR'}) – Where in spectrum to take eigenvalues from (see :func:scipy.sparse.linalg.eigsh)

  • return_vecs (bool, optional) – Whether to return the eigenvectors.

  • sigma (float, optional) – Which part of spectrum to target, implies which=’TR’ if which is None.

  • ncv (int, optional) – number of lanczos vectors, can use to optimise speed

  • tol (None or float) – Tolerance with which to find eigenvalues.

  • v0 (None or 1D-array like) – An initial vector guess to iterate with.

  • sort (bool, optional) – Whether to explicitly sort by ascending eigenvalue order.

  • backend ({'AUTO', 'NUMPY', 'SCIPY',) – ‘LOBPCG’, ‘SLEPC’, ‘SLEPC-NOMPI’}, optional Which solver to use.

  • fallback_to_scipy (bool, optional) – If an error occurs and scipy is not being used, try using scipy.

  • backend_opts – Supplied to the backend solver.

Returns:

  • elk ((k,) array) – The k eigenvalues.

  • evk ((d, k) array) – Array with k eigenvectors as columns if return_vecs.

quimb.groundstate(ham, **kwargs)[source]

Alias for finding lowest eigenvector only.

quimb.groundenergy(ham, **kwargs)[source]

Alias for finding lowest eigenvalue only.

quimb.bound_spectrum(A, backend='auto', **kwargs)[source]

Return the smallest and largest eigenvalue of hermitian operator A.

quimb.eigh_window(A, w_0, k, w_sz=None, backend='AUTO', return_vecs=True, offset_const=1 / 104729, **kwargs)[source]

Return mid-spectrum eigenpairs from a hermitian operator.

Parameters:
  • A ((d, d) operator) – Operator to retrieve eigenpairs from.

  • w_0 (float [0.0, 1.0]) – Relative window centre to retrieve eigenpairs from.

  • k (int) – Target number of eigenpairs to retrieve.

  • w_sz (float, optional) – Relative maximum window width within which to keep eigenpairs.

  • backend (str, optional) – Which eigh() backend to use.

  • return_vecs (bool, optional) – Whether to return eigenvectors as well.

  • offset_const (float, optional) – Small fudge factor (relative to window range) to avoid 1 / 0 issues.

Returns:

  • el ((k,) array) – Eigenvalues around w_0.

  • ev ((d, k) array) – The eigenvectors, if return_vecs=True.

quimb.eigvalsh_window(*args, **kwargs)[source]

Alias for only finding the eigenvalues in a relative window.

quimb.eigvecsh_window(*args, **kwargs)[source]

Alias for only finding the eigenvectors in a relative window.

quimb.svd(A, return_vecs=True)[source]

Compute full singular value decomposition of an operator, using numpy.

Parameters:
  • A ((m, n) array) – The operator.

  • return_vecs (bool, optional) – Whether to return the singular vectors.

Returns:

  • U ((m, k) array) – Left singular vectors (if return_vecs=True) as columns.

  • s ((k,) array) – Singular values.

  • VH ((k, n) array) – Right singular vectors (if return_vecs=True) as rows.

quimb.svds(A, k, ncv=None, return_vecs=True, backend='AUTO', **kwargs)[source]

Compute the partial singular value decomposition of an operator.

Parameters:
  • A (dense, sparse or linear operator) – The operator to decompose.

  • k (int, optional) – number of singular value (triplets) to retrieve

  • ncv (int, optional) – Number of lanczos vectors to use performing decomposition.

  • return_vecs (bool, optional) – Whether to return the left and right vectors

  • backend ({'AUTO', 'SCIPY', 'SLEPC', 'SLEPC-NOMPI', 'NUMPY'}, optional) – Which solver to use to perform decomposition.

Returns:

Singular value(s) (and vectors) such that Uk @ np.diag(sk) @ VHk approximates A.

Return type:

(Uk,) sk (, VHk)

quimb.norm(A, ntype=2, **kwargs)[source]

Operator norms.

Parameters:
  • A (operator) – The operator to find norm of.

  • ntype (str) –

    Norm to calculate, if any of:

    • {2, ‘2’, ‘spectral’}: largest singular value

    • {‘f’, ‘fro’}: frobenius norm

    • {‘t’, ‘nuc’, ‘tr’, ‘trace’}: sum of singular values

Returns:

x – The operator norm.

Return type:

float

quimb.expm(A, herm=False)[source]

Matrix exponential, can be accelerated if explicitly hermitian.

Parameters:
  • A (dense or sparse operator) – Operator to exponentiate.

  • herm (bool, optional) – If True (not default), and A is dense, digonalize the matrix in order to perform the exponential.

quimb.sqrtm(A, herm=True)[source]

Matrix square root, can be accelerated if explicitly hermitian.

Parameters:
  • A (dense array) – Operator to take square root of.

  • herm (bool, optional) – If True (the default), and A is dense, digonalize the matrix in order to take the square root.

Return type:

array

quimb.expm_multiply(mat, vec, backend='AUTO', **kwargs)[source]

Compute the action of expm(mat) on vec.

Parameters:
  • mat (operator) – Operator with which to act with exponential on vec.

  • vec (vector-like) – Vector to act with exponential of operator on.

  • backend ({'AUTO', 'SCIPY', 'SLEPC', 'SLEPC-KRYLOV', 'SLEPC-EXPOKIT'}) – Which backend to use.

  • kwargs – Supplied to backend function.

Returns:

Result of expm(mat) @ vec.

Return type:

vector

class quimb.Lazy(fn, *args, shape=None, factor=None, **kwargs)[source]

A simple class representing an unconstructed matrix. This can be passed to, for example, MPI workers, who can then construct the matrix themselves. The main function fn should ideally take an ownership keyword to avoid forming every row.

This is essentially like using functools.partial and assigning the shape attribute.

Parameters:
  • fn (callable) – A function that constructs an operator.

  • shape – Shape of the constructed operator.

  • args – Supplied to fn.

  • kwargs – Supplied to fn.

Returns:

Lazy

Return type:

callable

Examples

Setup the lazy operator:

>>> H_lazy = Lazy(ham_heis, n=10, shape=(2**10, 2**10), sparse=True)
>>> H_lazy
<Lazy(ham_heis, shape=(1024, 1024), dtype=None)>

Build a matrix slice (usually done automatically by e.g. eigs):

>>> H_lazy(ownership=(256, 512))
<256x1024 sparse matrix of type '<class 'numpy.float64'>'
        with 1664 stored elements in Compressed Sparse Row format>
__imul__(x)[source]
__mul__(x)[source]
__rmul__(x)[source]
__call__(**kwargs)[source]
__repr__()[source]

Return repr(self).

quimb.rsvd(A, eps_or_k, compute_uv=True, mode='adapt+block', use_qb=20, q=2, p=0, k_max=None, k_start=2, k_incr=1.4, G0=None, AH=None)[source]

Fast, randomized, iterative SVD. Adaptive variant of method due originally to Halko. This scales as log(k) rather than k so can be more efficient.

Parameters:
  • A (operator, shape (m, n)) – The operator to decompose.

  • eps_or_k (float or int) – Either the relative precision or the number of singular values to target. If precision, this is relative to the largest singular value.

  • compute_uv (bool, optional) – Whether to return the left and right singular vectors.

  • mode ({'adapt+block', 'adapt', 'block'}, optional) –

    How to perform the randomized SVD. If eps_or_k is an integer then this is implicitly ‘block’ and ignored. Else:

    • ’adapt+block’, perform an initial low quality pass to estimate the rank of A, then use the subspace and rank from that to perform an accurate fully blocked RSVD.

    • ’adapt’, just perform the adaptive randomized SVD.

  • q (int, optional) – The number of power iterations, increase for accuracy at the expense of runtime.

  • p (int, optional) – Oversampling factor. Perform projections with this many extra columns and then throw then away.

  • k_max (int, optional) – Maximum adaptive rank. Default: min(A.shape).

  • k_start (int, optional) – Initial k when increasing rank adaptively.

  • k_incr (float, optional) – Adaptive rank increment factor. Increase the k-step (from k_start) by this factor each time. Set to 1 to use a constant step.

  • G0 (array_like, shape (n, k), optional) – Initial subspace to start iterating on. If not given a random one will be generated.

Returns:

  • U, array, shape (m, k) – Left singular vectors, if compute_uv=True.

  • s, array, shape (k,) – Singular values.

  • V, array, shape (k, n) – Right singular vectors, if compute_uv=True.

quimb.estimate_rank(A, eps, k_max=None, use_sli=True, k_start=2, k_incr=1.4, q=0, p=0, get_vectors=False, G0=None, AH=None, use_qb=20)[source]

Estimate the rank of an linear operator. Uses a low quality random SVD with a resolution of ~ 10.

Parameters:
  • A (linear operator) – The operator to find rank of.

  • eps (float) – Find rank to this relative (compared to largest singular value) precision.

  • k_max (int, optional) – The maximum rank to find.

  • use_sli (bool, optional) – Whether to use scipy.linalg.interpolative.estimate_rank() if possible (double precision and no k_max set).

  • k_start (int, optional) – Begin the adaptive SVD with a block of this size.

  • k_incr (float, optional) – Adaptive rank increment factor. Increase the k-step (from k_start) by this factor each time. Set to 1 to use a constant step.

  • q (int, optional) – Number of power iterations.

  • get_vectors (bool, optional) – Return the right singular vectors found in the pass.

  • G0 (, optional)

Returns:

  • rank (int) – The rank.

  • VH (array) – The (adjoint) right singular vectors if get_vectors=True.

quimb.get_mpi_pool(num_workers=None, num_threads=1)

Get the MPI executor pool, with specified number of processes and threads per process.

quimb.can_use_mpi_pool()[source]

Function to determine whether we are allowed to call get_mpi_pool.

quimb.spin_operator(label, S=1 / 2, **kwargs)[source]

Generate a general spin-operator.

Parameters:
  • label (str) –

    The type of operator, can be one of six options:

    • {'x', 'X'}, x-spin operator.

    • {'y', 'Y'}, y-spin operator.

    • {'z', 'Z'}, z-spin operator.

    • {'+', 'p'}, Raising operator.

    • {'-', 'm'}, Lowering operator.

    • {'i', 'I'}, identity operator.

  • S (float, optional) – The spin of particle to act on, default to spin-1/2.

  • kwargs – Passed to quimbify().

Returns:

S – The spin operator.

Return type:

immutable operator

See also

pauli

Examples

>>> spin_operator('x')
qarray([[0. +0.j, 0.5+0.j],
        [0.5+0.j, 0. +0.j]])
>>> qu.spin_operator('+', S=1)
qarray([[0.        +0.j, 1.41421356+0.j, 0.        +0.j],
        [0.        +0.j, 0.        +0.j, 1.41421356+0.j],
        [0.        +0.j, 0.        +0.j, 0.        +0.j]])
>>> qu.spin_operator('Y', sparse=True)
<2x2 sparse matrix of type '<class 'numpy.complex128'>'
    with 2 stored elements in Compressed Sparse Row format>
quimb.pauli(xyz, dim=2, **kwargs)[source]

Generates the pauli operators for dimension 2 or 3.

Parameters:
  • xyz (str) – Which spatial direction, upper or lower case from {'I', 'X', 'Y', 'Z'}.

  • dim (int, optional) – Dimension of spin operator (e.g. 3 for spin-1), defaults to 2 for spin half.

  • kwargs – Passed to quimbify.

Returns:

P – The pauli operator.

Return type:

immutable operator

See also

spin_operator

quimb.hadamard(dtype=complex, sparse=False)[source]

The Hadamard gate.

quimb.phase_gate(phi, dtype=complex, sparse=False)[source]

The generalized qubit phase-gate, which adds phase phi to the |1> state.

quimb.S_gate(dtype=complex, sparse=False)[source]

The S-gate (phase gate).

quimb.T_gate(dtype=complex, sparse=False)[source]

The T-gate (pi/8 gate).

quimb.U_gate(theta, phi, lamda, dtype=complex, sparse=False)[source]

Arbitrary unitary single qubit gate.

\[\begin{split}U_3(\theta, \phi, \lambda) = \begin{bmatrix} \cos(\theta / 2) & - e^{i \lambda} \sin(\theta / 2) \\ e^{i \phi} \sin(\theta / 2) & e^{i(\lambda + \phi)}\cos(\theta / 2) \end{bmatrix}\end{split}\]
Parameters:
  • theta (float) – Angle between 0 and pi.

  • phi (float) – Angle between 0 and 2 pi.

  • lamba (float) – Angle between 0 and 2 pi.

Returns:

U – The unitary matrix, cached.

Return type:

(2, 2) array

quimb.rotation(phi, xyz='Z', dtype=complex, sparse=False)[source]

The single qubit rotation gate.

quimb.Rx
quimb.Ry
quimb.Rz
quimb.Xsqrt(**qu_opts)[source]

Rx(pi / 2).

\[\begin{split}X^{\frac{1}{2}} = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & - i \\ - i & 1 \end{bmatrix}\end{split}\]
quimb.Ysqrt(**qu_opts)[source]

Ry(pi / 2).

\[\begin{split}Y^{\frac{1}{2}} = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & - 1 \\ 1 & 1 \end{bmatrix}\end{split}\]
quimb.Zsqrt(**qu_opts)[source]

Rz(pi / 2).

\[\begin{split}Z^{\frac{1}{2}} = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 - i & 0 \\ 0 & 1 + i \end{bmatrix}\end{split}\]
quimb.Wsqrt(**qu_opts)[source]

R[X + Y](pi / 2).

\[\begin{split}W^{\frac{1}{2}} = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & -\sqrt{i} \\ \sqrt{-i} & 1 \end{bmatrix}\end{split}\]
quimb.swap(dim=2, dtype=complex, **kwargs)[source]

The SWAP operator acting on subsystems of dimension dim.

quimb.iswap(dtype=complex, **kwargs)[source]
quimb.fsim(theta, phi, dtype=complex, **kwargs)[source]

The ‘fermionic simulation’ gate:

\[\begin{split}\mathrm{fsim}(\theta, \phi) = \begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & \cos(\theta) & -i sin(\theta) & 0\\ 0 & -i sin(\theta) & \cos(\theta) & 0\\ 0 & 0 & 0 & \exp(-i \phi) \end{bmatrix}\end{split}\]

Note that theta and phi should be specified in radians and the sign convention with this gate varies. Here for example, fsim(- pi / 2, 0) == iswap().

quimb.fsimg(theta, zeta, chi, gamma, phi, dtype=complex, **kwargs)[source]

The ‘fermionic simulation’ gate, with:

  • \(\theta\) is the iSWAP angle

  • \(\phi\) is the controlled-phase angle

  • \(\zeta, \chi, \gamma\) are single-qubit phase angles.

\[\begin{split}\mathrm{fsimg}(\theta, \zeta, \chi, \gamma, \phi) = \begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & \exp(-i(\gamma +\zeta )) \cos(\theta) & -i \exp(-i(\gamma - \chi )) sin(\theta) & 0\\ 0 & -i \exp(-i(\gamma + \chi )) sin(\theta) & \exp(-i(\gamma - \zeta )) \cos(\theta) & 0\\ 0 & 0 & 0 & \exp(-i (\phi +2 \gamma)) \end{bmatrix}\end{split}\]

See Equation 18 of https://arxiv.org/abs/2010.07965. Note that theta, phi, zeta, chi, gamma should be specified in radians and the sign convention with this gate varies. Here for example, fsimg(- pi / 2, 0, 0, 0,0) == iswap().

quimb.ncontrolled_gate(ncontrol, gate, dtype=complex, sparse=False)[source]

Build an n-qubit controlled gate. The control qubits are the first ncontrol qubits.

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

  • gate (array_like) – The gate to apply to the controlled qubit(s).

  • dtype (str) – The data type of the returned matrix.

  • sparse (bool) – Whether to return a sparse matrix.

Returns:

C – The n-qubit controlled gate.

Return type:

qarray

quimb.controlled(s, dtype=complex, sparse=False)[source]

Construct a controlled pauli gate for two qubits.

Parameters:
  • s (str) – Which pauli to use, including ‘not’ aliased to ‘x’.

  • sparse (bool, optional) – Whether to construct a sparse operator.

Returns:

C – The controlled two-qubit gate operator.

Return type:

qarray

quimb.CNOT(dtype=complex, sparse=False)[source]

The controlled-not gate.

quimb.cX(dtype=complex, sparse=False)[source]

The controlled-X gate.

quimb.cY(dtype=complex, sparse=False)[source]

The controlled-Y gate.

quimb.cZ(dtype=complex, sparse=False)[source]

The controlled-Z gate.

quimb.ccX(dtype=complex, sparse=False)[source]

The double controlled X gate, or Toffoli gate.

quimb.ccY(dtype=complex, sparse=False)[source]

The double controlled Y gate.

quimb.ccZ(dtype=complex, sparse=False)[source]

The double controlled Z gate.

quimb.controlled_swap(dtype=complex, sparse=False)[source]

The controlled swap or Fredkin gate. The control qubit is the first qubit, if in state |1> a swap is performed on the last two qubits.

quimb.cswap[source]
quimb.fredkin[source]
quimb.toffoli[source]
quimb.ham_heis(n, j=1.0, b=0.0, cyclic=False, parallel=False, nthreads=None, ownership=None)[source]

Constructs the nearest neighbour 1d heisenberg spin-1/2 hamiltonian.

Parameters:
  • n (int) – Number of spins.

  • j (float or tuple(float, float, float), optional) – Coupling constant(s), with convention that positive = antiferromagnetic. Can supply scalar for isotropic coupling or vector (jx, jy, jz).

  • b (float or tuple(float, float, float), optional) – Magnetic field, defaults to z-direction only if tuple not given.

  • cyclic (bool, optional) – Whether to couple the first and last spins.

  • sparse (bool, optional) – Whether to return the hamiltonian in sparse form.

  • stype (str, optional) – What format of sparse operator to return if sparse.

  • parallel (bool, optional) – Whether to build the operator in parallel. By default will do this for n > 16.

  • nthreads (int optional) – How mny threads to use in parallel to build the operator.

  • ownership ((int, int), optional) – If given, which range of rows to generate.

  • kwargs – Supplied to quimbify().

Returns:

H – The Hamiltonian.

Return type:

immutable operator

quimb.ham_ising(n, jz=1.0, bx=1.0, **ham_opts)[source]

Generate the quantum transverse field ising model hamiltonian. This is a simple alias for ham_heis() with Z-interactions and an X-field.

quimb.ham_XY(n, jxy, bz, **ham_opts)[source]

Generate the quantum transverse field XY model hamiltonian. This is a simple alias for ham_heis() with X- and Y-interactions and a Z-field.

quimb.ham_XXZ(n, delta, jxy=1.0, **ham_opts)[source]

Generate the XXZ-model hamiltonian. This is a simple alias for ham_heis() with matched X- and Y-interactions and delta Z coupling.

quimb.ham_j1j2(n, j1=1.0, j2=0.5, bz=0.0, cyclic=False, ownership=None)[source]

Generate the j1-j2 hamiltonian, i.e. next nearest neighbour interactions.

Parameters:
  • n (int) – Number of spins.

  • j1 (float, optional) – Nearest neighbour coupling strength.

  • j2 (float, optional) – Next nearest neighbour coupling strength.

  • bz (float, optional) – B-field strength in z-direction.

  • cyclic (bool, optional) – Cyclic boundary conditions.

  • sparse (bool, optional) – Return hamiltonian as sparse-csr operator.

  • ownership ((int, int), optional) – If given, which range of rows to generate.

  • kwargs – Supplied to quimbify().

Returns:

H – The Hamiltonian.

Return type:

immutable operator

quimb.ham_mbl(n, dh, j=1.0, bz=0.0, cyclic=False, seed=None, dh_dist='s', dh_dim=1, beta=None, ownership=None)[source]

Constructs a heisenberg hamiltonian with isotropic coupling and random fields acting on each spin - the many-body localized (MBL) spin hamiltonian.

Parameters:
  • n (int) – Number of spins.

  • dh (float or (float, float, float)) – Strength of random fields (stdev of gaussian distribution), can be scalar (isotropic noise) or 3-vector for (x, y, z) directions.

  • j (float or (float, float, float), optional) – Coupling strength, can be scalar (isotropic) or 3-vector.

  • bz (float, optional) – Global magnetic field (in z-direction).

  • cyclic (bool, optional) – Whether to use periodic boundary conditions.

  • seed (int, optional) – Number to seed random number generator with.

  • dh_dist ({'g', 's', 'qr'}, optional) –

    Type of random distribution for the noise:

    • ”s”: square, with bounds (-dh, dh)

    • ”g”: gaussian, with standard deviation dh

    • ”qp”: quasi periodic, with amplitude dh and ‘wavenumber’ beta so that the field at site i is dh * cos(2 * pi * beta * i + delta) with delta a random offset between (0, 2 * pi), possibly seeded by seed.

  • dh_dim ({1, 2, 3} or str, optional) – The number of dimensions the noise acts in, or string specifier like 'yz'.

  • beta (float, optional) – The wave number if dh_dist='qr', defaults to the golden ratio``(5**0.5 - 1) / 2``.

  • sparse (bool, optional) – Whether to construct the hamiltonian in sparse form.

  • stype ({'csr', 'csc', 'coo'}, optional) – The sparse format.

  • ownership ((int, int), optional) – If given, which range of rows to generate.

  • kwargs – Supplied to quimbify().

Returns:

H – The MBL hamiltonian for spin-1/2.

Return type:

operator

See also

MPO_ham_mbl

quimb.ham_heis_2D(n, m, j=1.0, bz=0.0, cyclic=False, parallel=False, ownership=None)[source]

Construct the 2D spin-1/2 heisenberg model hamiltonian:

\[\hat{H} = \sum_{<i, j>} J_X S^X_i S^X_j + J_Y S^Y_i S^Y_j + J_Z S^Z_i S^Z_j\]

where the sum runs over pairs \(<i,j>\) on a 2D square lattice.

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

  • m (int) – The number of columns.

  • j (float or (float, float, float), optional) – The coupling strength(s). Isotropic if scalar else if vector (Jx, Jy, Jz) = j.

  • bz (float, optional) – The z direction magnetic field.

  • cyclic (bool, optional) – Whether to use periodic boundary conditions.

  • sparse (bool, optional) – Whether to construct the hamiltonian in sparse form.

  • stype ({'csr', 'csc', 'coo'}, optional) – The sparse format.

  • parallel (bool, optional) – Construct the hamiltonian in parallel. Faster but might use more memory.

  • ownership ((int, int), optional) – If given, which range of rows to generate.

  • kwargs – Supplied to quimbify().

Returns:

H – The hamiltonian.

Return type:

operator

quimb.zspin_projector(n, sz=0, stype='csr', dtype=float)[source]

Construct the projector onto spin-z subpspaces.

Parameters:
  • n (int) – Total size of spin system.

  • sz (float or sequence of floats) – Spin-z value(s) subspace(s) to find projector for.

  • stype (str) – Sparse format of the output operator.

  • dtype ({float, complex}, optional) – The data type of the operator to generate.

Returns:

prj – The (non-square) projector onto the specified subspace(s). The subspace size D is given by n choose (n / 2 + s) for each s specified in sz.

Return type:

immutable sparse operator, shape (2**n, D)

Examples

>>> zspin_projector(n=2, sz=0).A
array([[0., 0.],
       [1., 0.],
       [0., 1.],
       [0., 0.]]

Project a 9-spin Heisenberg-Hamiltonian into its spin-1/2 subspace:

>>> H = ham_heis(9, sparse=True)
>>> H.shape
(512, 512)
>>> P = zspin_projector(n=9, sz=1 / 2)
>>> H0 = P.T @ H @ P
>>> H0.shape
(126, 126)
quimb.create(n=2, **qu_opts)[source]

The creation operator acting on an n-level system.

quimb.destroy(n=2, **qu_opts)[source]

The annihilation operator acting on an n-level system.

quimb.num(n, **qu_opts)[source]

The number operator acting on an n-level system.

quimb.ham_hubbard_hardcore(n, t=0.5, V=1.0, mu=1.0, cyclic=False, parallel=False, ownership=None)[source]

Generate the spinless fermion hopping hamiltonian.

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

  • t (float, optional) – The hopping energy.

  • V (float, optional) – The interaction energy.

  • mu (float, optional) – The chemical potential - defaults to half-filling.

  • cyclic (bool, optional) – Whether to use periodic boundary conditions.

  • parallel (bool, optional) – Construct the hamiltonian in parallel. Faster but might use more memory.

  • ownership ((int, int), optional) – If given, which range of rows to generate.

  • kwargs – Supplied to quimbify().

Returns:

H – The hamiltonian.

Return type:

operator

quimb.basis_vec(i, dim, ownership=None, **kwargs)[source]

Constructs a unit vector ket:

\[\begin{split}|i\rangle = \begin{pmatrix} 0 \\ \vdots \\ 1 \\ \vdots \\ 0 \end{pmatrix}\end{split}\]
Parameters:
  • i (int) – Which index should the single non-zero, unit entry.

  • dim (int) – Total size of hilbert space.

  • sparse (bool, optional) – Return vector as sparse matrix.

  • kwargs – Supplied to qu.

Returns:

The basis vector.

Return type:

vector

quimb.up(**kwargs)[source]

Returns up-state, aka. |0>, +Z eigenstate:

\[\begin{split}|0\rangle = \begin{pmatrix} 1 \\ 0 \end{pmatrix}\end{split}\]
quimb.zplus[source]
quimb.down(**kwargs)[source]

Returns down-state, aka. |1>, -Z eigenstate:

\[\begin{split}|1\rangle = \begin{pmatrix} 0 \\ 1 \end{pmatrix}\end{split}\]
quimb.zminus[source]
quimb.plus(**kwargs)[source]

Returns plus-state, aka. |+>, +X eigenstate:

\[\begin{split}|+\rangle = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 \\ 1 \end{pmatrix}\end{split}\]
quimb.xplus[source]
quimb.minus(**kwargs)[source]

Returns minus-state, aka. |->, -X eigenstate:

\[\begin{split}|-\rangle = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 \\ -1 \end{pmatrix}\end{split}\]
quimb.xminus[source]
quimb.yplus(**kwargs)[source]

Returns yplus-state, aka. |y+>, +Y eigenstate:

\[\begin{split}|y+\rangle = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 \\ i \end{pmatrix}\end{split}\]
quimb.yminus(**kwargs)[source]

Returns yplus-state, aka. |y->, -Y eigenstate:

\[\begin{split}|y-\rangle = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 \\ -i \end{pmatrix}\end{split}\]
quimb.bloch_state(ax, ay, az, purified=False, **kwargs)[source]

Construct qubit density operator from bloch vector:

\[\rho = \frac{1}{2} \left( I + a_x X + a_y Y + a_z Z \right)\]
Parameters:
  • ax (float) – X component of bloch vector.

  • ay (float) – Y component of bloch vector.

  • az (float) – Z component of bloch vector.

  • purified – Whether to map vector to surface of bloch sphere.

Returns:

Density operator of qubit ‘pointing’ in (ax, ay, az) direction.

Return type:

Matrix

quimb.bell_state(s, **kwargs)[source]

One of the four bell-states.

If n = 2**-0.5, they are:

  1. 'psi-' : n * ( |01> - |10> )

  2. 'psi+' : n * ( |01> + |10> )

  3. 'phi-' : n * ( |00> - |11> )

  4. 'phi+' : n * ( |00> + |11> )

They can be enumerated in this order.

Parameters:
  • s (str or int) – String of number of state corresponding to above.

  • kwargs – Supplied to qu called on state.

Returns:

p – The bell-state s.

Return type:

immutable vector

quimb.singlet(**kwargs)[source]

Alias for the ‘psi-’ bell-state.

quimb.thermal_state(ham, beta, precomp_func=False)[source]

Generate a thermal state of a Hamiltonian.

Parameters:
  • ham (operator or (1d-array, 2d-array)) – Hamiltonian, either full or tuple of (evals, evecs).

  • beta (float) – Inverse temperature of state.

  • precomp_func (bool, optional) – If True, return a function that takes beta only and is closed over the solved hamiltonian.

Returns:

Density operator of thermal state, or function to generate such given a temperature.

Return type:

operator or callable

quimb.neel_state(n, down_first=False, **kwargs)[source]

Construct Neel state for n spins, i.e. alternating up/down.

Parameters:
  • n (int) – Number of spins.

  • down_first (bool, optional) – Whether to start with ‘1’ or ‘0’ first.

  • kwargs – Supplied to qu called on state.

See also

computational_state, MPS_neel_state

quimb.singlet_pairs(n, **kwargs)[source]

Construct fully dimerised spin chain.

I.e. bell_state('psi-') & bell_state('psi-') & ...

Parameters:
  • n (int) – Number of spins.

  • kwargs – Supplied to qu called on state.

Return type:

vector

quimb.werner_state(p, **kwargs)[source]

Construct Werner State, i.e. fractional mix of identity with singlet.

Parameters:
  • p (float) – Singlet Fraction.

  • kwargs – Supplied to qu() called on state.

Return type:

qarray

quimb.ghz_state(n, **kwargs)[source]

Construct GHZ state of n spins, i.e. equal superposition of all up and down.

Parameters:
  • n (int) – Number of spins.

  • kwargs – Supplied to qu called on state.

Return type:

vector

quimb.w_state(n, **kwargs)[source]

Construct W-state: equal superposition of all single spin up states.

Parameters:
  • n (int) – Number of spins.

  • kwargs – Supplied to qu called on state.

Return type:

vector

quimb.levi_civita(perm)[source]

Compute the generalised levi-civita coefficient for a permutation.

Parameters:

perm (sequence of int) – The permutation, a re-arrangement of range(n).

Returns:

Either -1, 0 or 1.

Return type:

int

quimb.perm_state(ps)[source]

Construct the anti-symmetric state which is the +- sum of all tensored permutations of states ps.

Parameters:

ps (sequence of states) – The states to combine.

Returns:

The permutation state, dimension same as kron(*ps).

Return type:

vector or operator

Examples

A singlet is the perm_state of up and down.

>>> states = [up(), down()]
>>> pstate = perm_state(states)
>>> expec(pstate, singlet())
1.0
quimb.graph_state_1d(n, cyclic=False, sparse=False)[source]

Graph State on a line.

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

  • cyclic (bool, optional) – Whether to use cyclic boundary conditions for the graph.

  • sparse (bool, optional) – Whether to return a sparse state.

Returns:

The 1d-graph state.

Return type:

vector

quimb.computational_state(binary, **kwargs)[source]

Generate the qubit computational state with binary.

Parameters:

binary (sequence of 0s and 1s) – The binary of the computation state.

Examples

>>> computational_state('101'):
qarray([[0.+0.j],
        [0.+0.j],
        [0.+0.j],
        [0.+0.j],
        [0.+0.j],
        [1.+0.j],
        [0.+0.j],
        [0.+0.j]])
>>> qu.computational_state([0, 1], qtype='dop')
qarray([[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])

See also

MPS_computational_state, basic_vec

quimb.randn(shape=(), dtype=float, scale=1.0, loc=0.0, num_threads=None, seed=None, dist='normal')[source]

Fast multithreaded generation of random normally distributed data.

Parameters:
  • shape (tuple[int]) – The shape of the output random array.

  • dtype ({'complex128', 'float64', 'complex64' 'float32'}, optional) – The data-type of the output array.

  • scale (float, optional) – A multiplicative scale for the random numbers.

  • loc (float, optional) – An additive location for the random numbers.

  • num_threads (int, optional) – How many threads to use. If None, decide automatically.

  • dist ({'normal', 'uniform', 'rademacher', 'exp'}, optional) – Type of random number to generate.

quimb.rand(*args, **kwargs)[source]
quimb.rand_matrix(d, scaled=True, sparse=False, stype='csr', density=None, dtype=complex, seed=None)[source]

Generate a random matrix of order d with normally distributed entries. If scaled is True, then in the limit of large d the eigenvalues will be distributed on the unit complex disk.

Parameters:
  • d (int) – Matrix dimension.

  • scaled (bool, optional) – Whether to scale the matrices values such that its spectrum approximately lies on the unit disk (for dense matrices).

  • sparse (bool, optional) – Whether to produce a sparse matrix.

  • stype ({'csr', 'csc', 'coo', ...}, optional) – The type of sparse matrix if sparse=True.

  • density (float, optional) – Target density of non-zero elements for the sparse matrix. By default aims for about 10 entries per row.

  • dtype ({complex, float}, optional) – The data type of the matrix elements.

Returns:

mat – Random matrix.

Return type:

qarray or sparse matrix

quimb.rand_herm(d, sparse=False, density=None, dtype=complex)[source]

Generate a random hermitian operator of order d with normally distributed entries. In the limit of large d the spectrum will be a semi-circular distribution between [-1, 1].

quimb.rand_pos(d, sparse=False, density=None, dtype=complex)[source]

Generate a random positive operator of size d, with normally distributed entries. In the limit of large d the spectrum will lie between [0, 1].

quimb.rand_rho(d, sparse=False, density=None, dtype=complex)[source]

Generate a random positive operator of size d with normally distributed entries and unit trace.

quimb.rand_ket(d, sparse=False, stype='csr', density=0.01, dtype=complex)[source]

Generates a ket of length d with normally distributed entries.

quimb.rand_uni(d, dtype=complex)[source]

Generate a random unitary operator of size d, distributed according to the Haar measure.

quimb.rand_haar_state(d, dtype=complex)[source]

Generate a random state of dimension d according to the Haar distribution.

quimb.gen_rand_haar_states(d, reps, dtype=complex)[source]

Generate many random Haar states, recycling a random unitary operator by using all of its columns (not a good idea?).

quimb.rand_mix(d, tr_d_min=None, tr_d_max=None, mode='rand', dtype=complex)[source]

Constructs a random mixed state by tracing out a random ket where the composite system varies in size between 2 and d. This produces a spread of states including more purity but has no real meaning.

quimb.rand_product_state(n, qtype=None, dtype=complex)[source]

Generates a ket of n many random pure qubits.

quimb.rand_matrix_product_state(n, bond_dim, phys_dim=2, dtype=complex, cyclic=False, trans_invar=False)[source]

Generate a random matrix product state (in dense form, see MPS_rand_state() for tensor network form).

Parameters:
  • n (int) – Number of sites.

  • bond_dim (int) – Dimension of the bond (virtual) indices.

  • phys_dim (int, optional) – Physical dimension of each local site, defaults to 2 (qubits).

  • cyclic (bool (optional)) – Whether to impose cyclic boundary conditions on the entanglement structure.

  • trans_invar (bool (optional)) – Whether to generate a translationally invariant state, requires cyclic=True.

Returns:

ket – The random state, with shape (phys_dim**n, 1)

Return type:

qarray

quimb.rand_mps[source]
quimb.rand_seperable(dims, num_mix=10, dtype=complex)[source]

Generate a random, mixed, seperable state. E.g rand_seperable([2, 2]) for a mixed two qubit state with no entanglement.

Parameters:
  • dims (tuple of int) – The local dimensions across which to be seperable.

  • num_mix (int, optional) – How many individual product states to sum together, each with random weight.

Returns:

Mixed seperable state.

Return type:

qarray

quimb.rand_iso(n, m, dtype=complex)[source]

Generate a random isometry of shape (n, m).

quimb.rand_mera(n, invariant=False, dtype=complex)[source]

Generate a random mera state of n qubits, which must be a power of 2. This uses quimb.tensor.

quimb.seed_rand(seed)[source]

See the random number generators, by instantiating a new set of bit generators with a ‘seed sequence’.

quimb.set_rand_bitgen(bitgen)[source]

Set the core bit generator type to use, from either numpy or randomgen.

Parameters:

bitgen ({'PCG64', 'SFC64', 'MT19937', 'Philox', str}) – Which bit generator to use.

quimb.fidelity(p1, p2, squared=False)[source]

Fidelity between two quantum states. By default, the unsquared fidelity is used, equivalent in the pure state case to |<psi|phi>|.

Parameters:
  • p1 (vector or operator) – First state.

  • p2 (vector or operator) – Second state.

  • squared (bool, optional) – Whether to use the squared convention or not, by default False.

Return type:

float

quimb.purify(rho)[source]

Take state rho and purify it into a wavefunction of squared dimension.

Parameters:

rho (operator) – Density operator to purify.

Returns:

The purified ket.

Return type:

vector

quimb.entropy(a, rank=None)[source]

Compute the (von Neumann) entropy.

Parameters:
  • a (operator or 1d array) – Positive operator or list of positive eigenvalues.

  • rank (int (optional)) – If operator has known rank, then a partial decomposition can be used to accelerate the calculation.

Returns:

The von Neumann entropy.

Return type:

float

quimb.entropy_subsys[source]

Calculate the entropy of a pure states’ subsystem, optionally switching to an approximate lanczos method when the subsystem is very large.

Parameters:
  • psi_ab (vector) – Bipartite state.

  • dims (sequence of int) – The sub-dimensions of the state.

  • sysa (sequence of int) – The indices of which dimensions to calculate the entropy for.

  • approx_thresh (int, optional) – The size of sysa at which to switch to the approx method. Set to None to never use the approximation.

  • **approx_opts – Supplied to entropy_subsys_approx(), if used.

Returns:

The subsytem entropy.

Return type:

float

quimb.mutual_information[source]
quimb.mutinf(p, dims=(2, 2), sysa=0, rank=None)[source]

Find the mutual information for a bipartition of a state.

That is, H(A) + H(B) - H(AB), for von Neumann entropy H, and two subsystems A and B.

Parameters:
  • p (vector or operator) – State, can be vector or operator.

  • dims (tuple(int), optional) – Internal dimensions of state.

  • sysa (int, optional) – Index of first subsystem, A.

  • sysb (int, optional) – Index of second subsystem, B.

  • rank (int, optional) – If known, the rank of rho_ab, to speed calculation of H(AB) up. For example, if p comes from tracing out three qubits from a system, then its rank is 2^3 = 8 etc.

Return type:

float

quimb.mutinf_subsys(psi_abc, dims, sysa, sysb, approx_thresh=2**13, **approx_opts)[source]

Calculate the mutual information of two subsystems of a pure state, possibly using an approximate lanczos method for large subsytems.

Parameters:
  • psi_abc (vector) – Tri-partite pure state.

  • dims (sequence of int) – The sub dimensions of the state.

  • sysa (sequence of int) – The index(es) of the subsystem(s) to consider part of ‘A’.

  • sysb (sequence of int) – The index(es) of the subsystem(s) to consider part of ‘B’.

  • approx_thresh (int, optional) – The size of subsystem at which to switch to the approximate lanczos method. Set to None to never use the approximation.

  • approx_opts – Supplied to entropy_subsys_approx(), if used.

Returns:

The mutual information.

Return type:

float

quimb.schmidt_gap(psi_ab, dims, sysa)[source]

Find the schmidt gap of the bipartition of psi_ab. That is, the difference between the two largest eigenvalues of the reduced density operator.

Parameters:
  • psi_ab (vector) – Bipartite state.

  • dims (sequence of int) – The sub-dimensions of the state.

  • sysa (sequence of int) – The indices of which dimensions to calculate the entropy for.

Return type:

float

quimb.tr_sqrt(A, rank=None)[source]

Return the trace of the sqrt of a positive semidefinite operator.

quimb.tr_sqrt_subsys[source]

Compute the trace sqrt of a subsystem, possibly using an approximate lanczos method when the subsytem is big.

Parameters:
  • psi_ab (vector) – Bipartite state.

  • dims (sequence of int) – The sub-dimensions of the state.

  • sysa (sequence of int) – The indices of which dimensions to calculate the trace sqrt for.

  • approx_thresh (int, optional) – The size of sysa at which to switch to the approx method. Set to None to never use the approximation.

  • **approx_opts – Supplied to tr_sqrt_subsys_approx(), if used.

Returns:

The subsytem entropy.

Return type:

float

See also

tr_sqrt, tr_sqrt_subsys_approx, partial_transpose_norm

quimb.partial_transpose(p, dims=(2, 2), sysa=0)[source]

Partial transpose of a density operator.

Parameters:
  • p (operator or vector) – The state to partially transpose.

  • dims (tuple(int), optional) – The internal dimensions of the state.

  • sysa (sequence of int) – The indices of ‘system A’, everything else assumed to be ‘system B’.

Return type:

operator

See also

logneg, negativity

quimb.negativity(p, dims=(2, 2), sysa=0)[source]

Compute negativity between two subsytems.

This is defined as (| rho_{AB}^{T_B} | - 1) / 2. If len(dims) > 2, then the non-target dimensions will be traced out first.

Parameters:
  • p (ket vector or density operator) – State to compute logarithmic negativity for.

  • dims (tuple(int), optional) – The internal dimensions of p.

  • sysa (int, optional) – Index of the first subsystem, A, relative to dims.

Return type:

float

quimb.logarithmic_negativity[source]
quimb.logneg(p, dims=(2, 2), sysa=0)[source]

Compute logarithmic negativity between two subsytems. This is defined as log_2( | rho_{AB}^{T_B} | ). This only handles bipartitions (including pure states efficiently), and will not trace anything out.

Parameters:
  • p (ket vector or density operator) – State to compute logarithmic negativity for.

  • dims (tuple(int), optional) – The internal dimensions of p.

  • sysa (int, optional) – Index of the first subsystem, A, relative to dims.

Return type:

float

quimb.logneg_subsys(psi_abc, dims, sysa, sysb, approx_thresh=2**13, **approx_opts)[source]

Compute the logarithmic negativity between two subsystems of a pure state, possibly using an approximate lanczos for large subsystems. Uses a special method if the two subsystems form a bipartition of the state.

Parameters:
  • psi_abc (vector) – Tri-partite pure state.

  • dims (sequence of int) – The sub dimensions of the state.

  • sysa (sequence of int) – The index(es) of the subsystem(s) to consider part of ‘A’.

  • sysb (sequence of int) – The index(es) of the subsystem(s) to consider part of ‘B’.

  • approx_thresh (int, optional) – The size of subsystem at which to switch to the approximate lanczos method. Set to None to never use the approximation.

  • approx_opts – Supplied to logneg_subsys_approx(), if used.

Returns:

The logarithmic negativity.

Return type:

float

quimb.concurrence(p, dims=(2, 2), sysa=0, sysb=1)[source]

Concurrence of two-qubit state.

If len(dims) > 2, then the non-target dimensions will be traced out first.

Parameters:
  • p (ket vector or density operator) – State to compute concurrence for.

  • dims (tuple(int), optional) – The internal dimensions of p.

  • sysa (int, optional) – Index of the first subsystem, A, relative to dims.

  • sysb (int, optional) – Index of the first subsystem, B, relative to dims.

Return type:

float

quimb.one_way_classical_information(p_ab, prjs, precomp_func=False)[source]

One way classical information for two qubit density operator.

Parameters:
  • p_ab (operator) – State of two qubits

  • prjs (sequence of matrices) – The POVMs.

  • precomp_func (bool, optional) – Whether to return a pre-computed function, closed over the actual state.

Returns:

The one-way classical information or the function to compute it for the given state which takes a set of POVMs as its single argument.

Return type:

float or callable

quimb.quantum_discord(p, dims=(2, 2), sysa=0, sysb=1, method='COBYLA', tol=1e-12, maxiter=2**14)[source]

Quantum Discord for two qubit density operator.

If len(dims) > 2, then the non-target dimensions will be traced out first.

Parameters:
  • p (ket vector or density operator) – State to compute quantum discord for.

  • dims (tuple(int), optional) – The internal dimensions of p.

  • sysa (int, optional) – Index of the first subsystem, A, relative to dims.

  • sysb (int, optional) – Index of the first subsystem, B, relative to dims.

Return type:

float

quimb.trace_distance(p1, p2)[source]

Trace distance between two states:

\[\delta(\rho, \sigma) = \frac{1}{2} \left| \rho - \sigma \right|_\mathrm{tr}\]

If two wavefunctions are supplied the trace distance will be computed via the more efficient expression:

\[\delta(|\psi\rangle\langle\psi|, |\phi\rangle\langle\phi|) = \sqrt{1 - \langle \psi | \phi \rangle^2}\]
Parameters:
  • p1 (ket or density operator) – The first state.

  • p2 (ket or density operator) – The second state.

Return type:

float

quimb.cprint(psi, prec=6)[source]

Print a state in the computational basis.

Parameters:
  • psi (vector) – The pure state.

  • prec (int, optional) – How many significant figures to print.

Examples

>>> cprint(rand_ket(2**2))
(-0.0751069-0.192635j) |00>
  (0.156837-0.562213j) |01>
(-0.307381+0.0291168j) |10>
  (-0.14302+0.707661j) |11>
>>> cprint(w_state(4))
(0.5+0j) |0001>
(0.5+0j) |0010>
(0.5+0j) |0100>
(0.5+0j) |1000>
quimb.decomp(a, fn, fn_args, fn_d, nmlz_func, mode='p', tol=0.001)[source]

Decomposes an operator via the Hilbert-schmidt inner product.

Can both print the decomposition or return it.

Parameters:
  • a (ket or density operator) – Operator to decompose.

  • fn (callable) – Function to generate operator/state to decompose with.

  • fn_args – Sequence of args whose permutations will be supplied to fn.

  • fn_d (int) – The dimension of the operators that fn produces.

  • nmlz_func (callable) – Function to produce a normlization coefficient given the n permutations of operators that will be produced.

  • mode – String, include 'p' to print the decomp and/or 'c' to return OrderedDict, sorted by size of contribution.

  • tol – Print operators with contirbution above tol only.

Returns:

Pauli operator name and expec with a.

Return type:

None or OrderedDict

quimb.pauli_decomp

Decompose an operator into Paulis.

quimb.bell_decomp

Decompose an operator into bell-states.

quimb.correlation(p, A, B, sysa, sysb, dims=None, sparse=None, precomp_func=False)[source]

Calculate the correlation between two sites given two operators.

Parameters:
  • p (ket or density operator) – State to compute correlations for, ignored if precomp_func=True.

  • A (operator) – Operator to act on first subsystem.

  • B (operator) – Operator to act on second subsystem.

  • sysa (int) – Index of first subsystem.

  • sysb (int) – Index of second subsystem.

  • dims (tuple of int, optional) – Internal dimensions of p, will be assumed to be qubits if not given.

  • sparse (bool, optional) – Whether to compute with sparse operators.

  • precomp_func (bool, optional) – Whether to return result or single arg function closed over precomputed operator.

Returns:

The correlation, <ab> - <a><b>, or a function to compute for an arbitrary state.

Return type:

float or callable

quimb.pauli_correlations(p, ss=('xx', 'yy', 'zz'), sysa=0, sysb=1, sum_abs=False, precomp_func=False)[source]

Calculate the correlation between sites for a list of operator pairs choisen from the pauli matrices.

Parameters:
  • p (ket or density operator) – State to compute correlations for. Ignored if precomp_func=True.

  • ss (tuple or str) – List of pairs specifiying pauli matrices.

  • sysa (int, optional) – Index of first site.

  • sysb (int, optional) – Index of second site.

  • sum_abs (bool, optional) – Whether to sum over the absolute values of each correlation

  • precomp_func (bool, optional) – whether to return the values or a single argument function closed over precomputed operators etc.

Returns:

Either the value(s) of each correlation or the function(s) to compute the correlations for an arbitrary state, depending on sum_abs and precomp_func.

Return type:

list of float, list of callable, float or callable

quimb.ent_cross_matrix(p, sz_blc=1, ent_fn=logneg, calc_self_ent=True, upscale=False)[source]

Calculate the pair-wise function ent_fn between all sites or blocks of a state.

Parameters:
  • p (ket or density operator) – State.

  • sz_blc (int) – Size of the blocks to partition the state into. If the number of individual sites is not a multiple of this then the final (smaller) block will be ignored.

  • ent_fn (callable) – Bipartite function, notionally entanglement

  • calc_self_ent (bool) – Whether to calculate the function for each site alone, purified. If the whole state is pure then this is the entanglement with the whole remaining system.

  • upscale (bool, optional) – Whether, if sz_blc != 1, to upscale the results so that the output array is the same size as if it was.

Returns:

array of pairwise ent_fn results.

Return type:

2D-array

quimb.qid(p, dims, inds, precomp_func=False, sparse_comp=True, norm_func=norm, power=2, coeff=1)[source]
quimb.is_degenerate(op, tol=1e-12)[source]

Check if operator has any degenerate eigenvalues, determined relative to mean spacing of all eigenvalues.

Parameters:
  • op (operator or 1d-array) – Operator or assumed eigenvalues to check degeneracy for.

  • tol (float) – How much closer than evenly spaced the eigenvalue gap has to be to count as degenerate.

Returns:

n_dgen – Number of degenerate eigenvalues.

Return type:

int

quimb.is_eigenvector(x, A, tol=1e-14)[source]

Determines whether a vector is an eigenvector of an operator.

Parameters:
  • x (vector) – Vector to check.

  • A (operator) – Matrix to check.

  • tol (float, optional) – The variance must be smaller than this value.

Returns:

Whether A @ x = l * x for some scalar l.

Return type:

bool

quimb.page_entropy(sz_subsys, sz_total)[source]

Calculate the page entropy, i.e. expected entropy for a subsytem of a random state in Hilbert space.

Parameters:
  • sz_subsys (int) – Dimension of subsystem.

  • sz_total (int) – Dimension of total system.

Returns:

s – Entropy in bits.

Return type:

float

quimb.heisenberg_energy(L)[source]

Get the analytic isotropic heisenberg chain ground energy for length L. Useful for testing. Assumes the heisenberg model is defined with spin operators not pauli matrices (overall factor of 2 smaller). Taken from [1].

[1] Nickel, Bernie. “Scaling corrections to the ground state energy of the spin-½ isotropic anti-ferromagnetic Heisenberg chain.” Journal of Physics Communications 1.5 (2017): 055021

Parameters:

L (int) – The length of the chain.

Returns:

energy – The ground state energy.

Return type:

float

quimb.dephase(rho, p, rand_rank=None)[source]

Dephase rho by amount p, that is, mix it with the maximally mixed state:

rho -> (1 - p) * rho + p * I / d

Parameters:
  • rho (operator) – The state.

  • p (float) – The final proportion of identity.

  • rand_rank (int or float, optional) – If given, dephase with a random diagonal operator with this many non-zero entries. If float, proportion of full size.

Returns:

rho_dephase – The dephased density operator.

Return type:

operator

quimb.kraus_op(rho, Ek, dims=None, where=None, check=False)[source]

Operate on a mixed state with a set of kraus operators:

\[\sigma = \sum_k E_k \rho E_k^{\dagger}\]
Parameters:
  • rho ((d, d) density matrix) – The density operator to perform operation on.

  • Ek ((K, d, d) array or sequence of K (d, d) arrays) – The Kraus operator(s).

  • dims (sequence of int, optional) – The subdimensions of rho.

  • where (int or sequence of int, optional) – Which of the subsystems to apply the operation on.

  • check (bool, optional) – Where to check sum_k(Ek.H @ Ek) == 1.

Returns:

sigma – The state after the kraus operation.

Return type:

density matrix

Examples

The depolarising channel:

In [1]: import quimb as qu

In [2]: rho = qu.rand_rho(2)

In [3]: I, X, Y, Z = (qu.pauli(s) for s in 'IXYZ')

In [4]: [qu.expec(rho, A) for A in (X, Y, Z)]
Out[4]: [-0.652176185230622, -0.1301762132792484, 0.22362918368272583]

In [5]: p = 0.1

In [6]: Ek = [
   ...:     (1 - p)**0.5 * I,
   ...:     (p / 3)**0.5 * X,
   ...:     (p / 3)**0.5 * Y,
   ...:     (p / 3)**0.5 * Z
   ...: ]

In [7]: sigma = qu.kraus_op(rho, Ek)

In [8]: [qu.expec(sigma, A) for A in (X, Y, Z)]
Out[8]: [-0.5652193605332058, -0.11281938484201527, 0.1938119591916957]
quimb.projector(A, eigenvalue=1.0, tol=1e-12, autoblock=False)[source]

Compute the projector for the target eigenvalue of operator A.

Parameters:
  • A (operator or tuple[array, operator].) – The hermitian observable. If a tuple is supplied, assume this is the eigendecomposition of the observable.

  • eigenvalue (float, optional) – The target eigenvalue to construct the projector for, default: 1.

  • tol (float, optional) – The tolerance with which to select all eigenvalues.

  • autoblock (bool, optional) – Whether to use automatic symmetry exploitation.

Returns:

P – The projector onto the target eigenspace.

Return type:

dense matrix

quimb.measure(p, A, eigenvalue=None, tol=1e-12)[source]

Measure state p with observable A, collapsing the state in the process and returning the relevant eigenvalue.

\[\left| \psi \right\rangle \rightarrow \frac{ P_i \left| \psi \right\rangle }{ \sqrt{\left\langle \psi \right| P_i \left| \psi \right\rangle} }\]

and

\[\rho \rightarrow \frac{ P_i \rho P_i^{\dagger} }{ \text{Tr} \left[ P_i \rho \right] }\]

along with the corresponding eigenvalue \(\lambda_i\).

Parameters:
  • p (vector or matrix) – The quantum state to measure.

  • A (matrix or tuple[array, matrix]) – The hermitian operator corresponding to an observable. You can supply also a pre-diagonalized operator here as a tuple of eigenvalues and eigenvectors.

  • tol (float, optional) – The tolerance within which to group eigenspaces.

  • eigenvalue (float, optional) – If specified, deterministically collapse to this result. Otherwise randomly choose a result as in ‘real-life’.

Returns:

  • result (float) – The result of the measurement.

  • p_after (vector or matrix) – The quantum state post measurement.

quimb.simulate_counts(p, C, phys_dim=2, seed=None)[source]

Simulate measuring each qubit of p in the computational basis, producing output like that of qiskit.

Parameters:
  • p (vector or operator) – The quantum state, assumed to be normalized, as either a ket or density operator.

  • C (int) – The number of counts to perform.

  • phys_dim (int, optional) – The assumed size of the subsystems of p, defaults to 2 for qubits.

Returns:

results – The counts for each bit string measured.

Return type:

dict[str, int]

Examples

Simulate measuring the state of each qubit in a GHZ-state:

>>> import quimb as qu
>>> psi = qu.ghz_state(3)
>>> qu.simulate_counts(psi, 1024)
{'000': 514, '111': 510}
class quimb.Evolution(p0, ham, t0=0, compute=None, int_stop=None, method='integrate', int_small_step=False, expm_backend='AUTO', expm_opts=None, progbar=False)[source]

Bases: object

A class for evolving quantum systems according to Schrodinger equation.

The evolution can be performed in a number of ways:

  • diagonalise the Hamiltonian (or use already diagonalised system).

  • integrate the complex ODE, that is, the Schrodinger equation, using scipy. Here either a mid- or high-order Dormand-Prince adaptive time stepping scheme is used (see scipy.integrate.complex_ode).

Parameters:
  • p0 (quantum state) – Inital state, either vector or operator. If vector, converted to ket.

  • ham (operator, tuple (1d array, operator), or callable) – Governing Hamiltonian, if tuple then assumed to contain (eigvals, eigvecs) of presolved system. If callable (but not a SciPy LinearOperator), assume a time-dependent hamiltonian such that ham(t) is the Hamiltonian at time t. In this case, the latest call to ham will be cached (and made immutable) in case it is needed by callbacks passed to compute.

  • t0 (float, optional) – Initial time (i.e. time of state p0), defaults to zero.

  • compute (callable, or dict of callable, optional) –

    Function(s) to compute on the state at each time step. Function(s) should take args (t, pt) or (t, pt, ham) if the Hamiltonian is required. If ham is required, it will be passed in to the function exactly as given to this Evolution instance, except if method is 'solve', in which case it will be passed in as the solved system (eigvals, eigvecs). If supplied with:

    • single callable : Evolution.results will contain the results as a list,

    • dict of callables : Evolution.results will contain the results as a dict of lists with corresponding keys to those given in compute.

  • int_stop (callable, optional) – A condition to terminate the integration early if method is 'integrate'. This callable is called at every successful integration step and should take args (t, pt) or (t, pt, ham) similar to the function(s) in the compute argument. It should return -1 to stop the integration, otherwise it should return None or 0.

  • method ({'integrate', 'solve', 'expm'}) –

    How to evolve the system:

    • 'integrate': use definite integration. Get system at each time step, only need action of Hamiltonian on state. Generally efficient.

    • 'solve': diagonalise dense hamiltonian. Best for small systems and allows arbitrary time steps without loss of precision.

    • 'expm': compute the evolved state using the action of the operator exponential in a ‘single shot’ style. Only needs action of Hamiltonian, for very large systems can use distributed MPI.

  • int_small_step (bool, optional) – If method='integrate', whether to use a low or high order integrator to give naturally small or large steps.

  • expm_backend ({'auto', 'scipy', 'slepc'}) – How to perform the expm_multiply function if method='expm'. Can further specifiy 'slepc-krylov', or 'slepc-expokit'.

  • expm_opts (dict) – Supplied to expm_multiply() function if method='expm'.

  • progbar (bool, optional) – Whether to show a progress bar when calling at_times or integrating with the update_to method.

property t

Current time of simulation.

Type:

float

property pt

State of the system at the current time (t).

Type:

quantum state

property results

Results of the compute callback(s) for each time step.

Type:

list, or dict of lists, optional

_setup_callback(fn, int_stop)[source]

Setup callbacks in the correct place to compute into _results

_setup_solved_ham()[source]

Solve the hamiltonian if needed and find the initial state in the energy eigenbasis for quick evolution later.

_start_integrator(ham, small_step)[source]

Initialize a stepping integrator.

_update_to_expm_ket(t)[source]

Update the simulation to time t, without explicitly computing the operator exponential itself.

_update_to_solved_ket(t)[source]

Update simulation consisting of a solved hamiltonian and a wavefunction to time t.

_update_to_solved_dop(t)[source]

Update simulation consisting of a solved hamiltonian and a density operator to time t.

_update_to_integrate(t)[source]

Update simulation consisting of unsolved hamiltonian.

update_to(t)[source]

Update the simulation to time t using relevant method.

Parameters:

t (float) – Time to update the evolution to.

at_times(ts)[source]

Generator expression to yield state af list of times.

Parameters:

ts (sequence of floats) – Times at which to evolve to, then yield the state.

Yields:

pt (quantum state) – Quantum state of evolution at next time in ts.

Notes

If integrating, currently any compute callbacks will be called at every integration step, not just the times ts – i.e. in general len(Evolution.results) != len(ts) and if the adaptive step times are needed they should be added as a callback, e.g. compute['t'] = lambda t, _: return t.

quimb.approx_spectral_function(A, f, tol=0.01, *, bsz=1, R=1024, tol_scale=1, tau=0.0001, k_min=10, k_max=512, beta_tol=1e-06, mpi=False, mean_p=0.7, mean_s=1.0, pos=False, v0=None, verbosity=0, single_precision='AUTO', info=None, **lanczos_opts)[source]

Approximate a spectral function, that is, the quantity Tr(f(A)).

Parameters:
  • A (dense array, sparse matrix or LinearOperator) – Operator to approximate spectral function for. Should implement A.dot(vec).

  • f (callable) – Scalar function with which to act on approximate eigenvalues.

  • tol (float, optional) – Relative convergence tolerance threshold for error on mean of repeats. This can pretty much be relied on as the overall accuracy. See also tol_scale and tau. Default: 1%.

  • bsz (int, optional) – Number of simultenous vector columns to use at once, 1 equating to the standard lanczos method. If bsz > 1 then A must implement matrix-matrix multiplication. This is a more performant way of essentially increasing R, at the cost of more memory. Default: 1.

  • R (int, optional) – The number of repeats with different initial random vectors to perform. Increasing this should increase accuracy as sqrt(R). Cost of algorithm thus scales linearly with R. If tol is non-zero, this is the maximum number of repeats.

  • tau (float, optional) – The relative tolerance required for a single lanczos run to converge. This needs to be small enough that each estimate with a single random vector produces an unbiased sample of the operators spectrum..

  • k_min (int, optional) – The minimum size of the krylov subspace to form for each sample.

  • k_max (int, optional) – The maximum size of the kyrlov space to form. Cost of algorithm scales linearly with K. If tau is non-zero, this is the maximum size matrix to form.

  • tol_scale (float, optional) – This sets the overall expected scale of each estimate, so that an absolute tolerance can be used for values near zero. Default: 1.

  • beta_tol (float, optional) – The ‘breakdown’ tolerance. If the next beta ceofficient in the lanczos matrix is less that this, implying that the full non-null space has been found, terminate early. Default: 1e-6.

  • mpi (bool, optional) – Whether to parallelize repeat runs over MPI processes.

  • mean_p (float, optional) – Factor for robustly finding mean and err of repeat estimates, see ext_per_trim().

  • mean_s (float, optional) – Factor for robustly finding mean and err of repeat estimates, see ext_per_trim().

  • v0 (vector, or callable) – Initial vector to iterate with, sets R=1 if given. If callable, the function to produce a random intial vector (sequence).

  • pos (bool, optional) – If True, make sure any approximate eigenvalues are positive by clipping below 0.

  • verbosity ({0, 1, 2}, optional) – How much information to print while computing.

  • single_precision ({'AUTO', False, True}, optional) – Try and convert the operator to single precision. This can lead to much faster operation, especially if a GPU is available. Additionally, double precision is not really needed given the stochastic nature of the algorithm.

  • lanczos_opts – Supplied to single_random_estimate() or construct_lanczos_tridiag().

Returns:

The approximate value Tr(f(a)).

Return type:

scalar

See also

construct_lanczos_tridiag

quimb.tr_abs_approx(*args, **kwargs)[source]
quimb.tr_exp_approx(*args, **kwargs)[source]
quimb.tr_sqrt_approx(*args, **kwargs)[source]
quimb.tr_xlogx_approx(*args, **kwargs)[source]
quimb.entropy_subsys_approx(psi_ab, dims, sysa, backend=None, **kwargs)[source]

Approximate the (Von Neumann) entropy of a pure state’s subsystem.

Parameters:
  • psi_ab (ket) – Bipartite state to partially trace and find entopy of.

  • dims (sequence of int, optional) – The sub dimensions of psi_ab.

  • sysa (int or sequence of int, optional) – Index(es) of the ‘a’ subsystem(s) to keep.

  • kwargs – Supplied to approx_spectral_function().

quimb.logneg_subsys_approx(psi_abc, dims, sysa, sysb, **kwargs)[source]

Estimate the logarithmic negativity of a pure state’s subsystem.

Parameters:
  • psi_abc (ket) – Pure tripartite state, for which estimate the entanglement between ‘a’ and ‘b’.

  • dims (sequence of int) – The sub dimensions of psi_abc.

  • sysa (int or sequence of int, optional) – Index(es) of the ‘a’ subsystem(s) to keep, with respect to all the dimensions, dims, (i.e. pre-partial trace).

  • sysa – Index(es) of the ‘b’ subsystem(s) to keep, with respect to all the dimensions, dims, (i.e. pre-partial trace).

  • kwargs – Supplied to approx_spectral_function().

quimb.negativity_subsys_approx(psi_abc, dims, sysa, sysb, **kwargs)[source]

Estimate the negativity of a pure state’s subsystem.

Parameters:
  • psi_abc (ket) – Pure tripartite state, for which estimate the entanglement between ‘a’ and ‘b’.

  • dims (sequence of int) – The sub dimensions of psi_abc.

  • sysa (int or sequence of int, optional) – Index(es) of the ‘a’ subsystem(s) to keep, with respect to all the dimensions, dims, (i.e. pre-partial trace).

  • sysa – Index(es) of the ‘b’ subsystem(s) to keep, with respect to all the dimensions, dims, (i.e. pre-partial trace).

  • kwargs – Supplied to approx_spectral_function().

quimb.xlogx(x)[source]
quimb.save_to_disk(obj, fname, **dump_opts)[source]

Save an object to disk using joblib.dump.

quimb.load_from_disk(fname, **load_opts)[source]

Load an object form disk using joblib.load.

class quimb.oset(it=())[source]

An ordered set which stores elements as the keys of dict (ordered as of python 3.6). ‘A few times’ slower than using a set directly for small sizes, but makes everything deterministic.

__slots__ = ('_d',)
pop[source]
classmethod _from_dict(d)[source]
classmethod from_dict(d)[source]

Public method makes sure to copy incoming dictionary.

copy()[source]
__deepcopy__(memo)[source]
add(k)[source]
discard(k)[source]
remove(k)[source]
clear()[source]
update(*others)[source]
union(*others)[source]
intersection_update(*others)[source]
intersection(*others)[source]
difference_update(*others)[source]
difference(*others)[source]
popleft()[source]
popright()[source]
__eq__(other)[source]

Return self==value.

__or__(other)[source]
__ior__(other)[source]
__and__(other)[source]
__iand__(other)[source]
__sub__(other)[source]
__isub__(other)[source]
__len__()[source]
__iter__()[source]
__contains__(x)[source]
__repr__()[source]

Return repr(self).

class quimb.LRU(maxsize, *args, **kwds)[source]

Bases: collections.OrderedDict

Least recently used dict, which evicts old items. Taken from python collections OrderedDict docs.

__getitem__(key)[source]

x.__getitem__(y) <==> x[y]

__setitem__(key, value)[source]

Set self[key] to value.

quimb.tree_map(f, tree, is_leaf=is_not_container)[source]

Map f over all leaves in tree, returning a new pytree.

Parameters:
  • f (callable) – A function to apply to all leaves in tree.

  • tree (pytree) – A nested sequence of tuples, lists, dicts and other objects.

  • is_leaf (callable) – A function to determine if an object is a leaf, f is only applied to objects for which is_leaf(x) returns True.

Return type:

pytree

quimb.tree_apply(f, tree, is_leaf=is_not_container)[source]

Apply f to all leaves in tree, no new pytree is built.

Parameters:
  • f (callable) – A function to apply to all leaves in tree.

  • tree (pytree) – A nested sequence of tuples, lists, dicts and other objects.

  • is_leaf (callable) – A function to determine if an object is a leaf, f is only applied to objects for which is_leaf(x) returns True.

quimb.tree_flatten(tree, get_ref=False, is_leaf=is_not_container)[source]

Flatten tree into a list of leaves.

Parameters:
  • tree (pytree) – A nested sequence of tuples, lists, dicts and other objects.

  • is_leaf (callable) – A function to determine if an object is a leaf, only objects for which is_leaf(x) returns True are returned in the flattened list.

Returns:

  • objs (list) – The flattened list of leaf objects.

  • (ref_tree) (pytree) – If get_ref is True, a reference tree, with leaves of None, is returned which can be used to reconstruct the original tree.

quimb.tree_unflatten(objs, tree, is_leaf=is_leaf_object)[source]

Unflatten objs into a pytree of the same structure as tree.

Parameters:
  • objs (sequence) – A sequence of objects to be unflattened into a pytree.

  • tree (pytree) – A nested sequence of tuples, lists, dicts and other objects, the objs will be inserted into a new pytree of the same structure.

  • is_leaf (callable) – A function to determine if an object is a leaf, only objects for which is_leaf(x) returns True will have the next item from objs inserted. By default checks for the Leaf object inserted by tree_flatten(..., get_ref=True).

Return type:

pytree

quimb.format_number_with_error(x, err)[source]

Given x with error err, format a string showing the relevant digits of x with two significant digits of the error bracketed, and overall exponent if necessary.

Parameters:
  • x (float) – The value to print.

  • err (float) – The error on x.

Return type:

str

Examples

>>> print_number_with_uncertainty(0.1542412, 0.0626653)
'0.154(63)'
>>> print_number_with_uncertainty(-128124123097, 6424)
'-1.281241231(64)e+11'
quimb.NEUTRAL_STYLE
quimb.default_to_neutral_style(fn)[source]

Wrap a function or method to use the neutral style by default.