quimb.calc

Functions for more advanced calculations of quantities and properties of quantum objects.

Attributes

dop

Convert an object into a density operator.

expec

Alias for expectation().

eye

Alias for identity().

njit

Numba no-python jit, but obeying cache setting.

ptr

Alias for partial_trace().

qu

Alias of quimbify().

tr

Alias for trace().

eigh

eigvalsh

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.

Functions

dag(qob)

Conjugate transpose.

dot(a, b)

Matrix multiplication, dispatched to dense or sparse functions.

ensure_qarray(fn)

Decorator that wraps output as a qarray.

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

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

infer_size(p[, base])

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

isop(qob)

Checks if qob is an operator.

issparse(qob)

Checks if qob is explicitly sparse.

isvec(qob)

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

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

Tensor (kronecker) product of variable number of arguments.

prod(iterable)

realify(fn[, imag_tol])

Decorator that drops fn's output imaginary part if very small.

zeroify(fn[, tol])

Decorator that rounds fn's output to zero if very small.

norm(A[, ntype])

Operator norms.

sqrtm(A[, herm])

Matrix square root, can be accelerated if explicitly hermitian.

norm_trace_dense(A[, isherm])

Returns the trace norm of operator A, that is,

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

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

gen_bipartite_spectral_fn(exact_fn, approx_fn, ...)

Generate a function that computes a spectral quantity of the subsystem

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

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

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

Approximate the trace sqrt of a pure state's subsystem.

pauli(xyz[, dim])

Generates the pauli operators for dimension 2 or 3.

basis_vec(i, dim[, ownership])

Constructs a unit vector ket:

bell_state(s, **kwargs)

One of the four bell-states.

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

Construct qubit density operator from bloch vector:

int2tup(x)

array_contract(arrays, inputs[, output, optimize, backend])

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

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,

dephase(rho, p[, rand_rank])

Dephase rho by amount p, that is, mix it

entropy(a[, rank])

Compute the (von Neumann) entropy.

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

Find the mutual information for a bipartition of a state.

check_dims_and_indices(dims, *syss)

Make sure all indices found in the tuples syss are in

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.

partial_transpose_norm(p, dims, sysa)

Compute the norm of the partial transpose for (log)-negativity,

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

negativity(p[, dims, sysa])

Compute negativity between two subsytems.

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.

Module Contents

quimb.calc.dag(qob)[source]

Conjugate transpose.

quimb.calc.dop

Convert an object into a density operator.

quimb.calc.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.calc.ensure_qarray(fn)[source]

Decorator that wraps output as a qarray.

quimb.calc.expec[source]

Alias for expectation().

quimb.calc.eye[source]

Alias for identity().

quimb.calc.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.calc.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.calc.isop(qob)[source]

Checks if qob is an operator.

quimb.calc.issparse(qob)[source]

Checks if qob is explicitly sparse.

quimb.calc.isvec(qob)[source]

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

quimb.calc.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.calc.njit

Numba no-python jit, but obeying cache setting.

quimb.calc.prod(iterable)
quimb.calc.ptr[source]

Alias for partial_trace().

quimb.calc.qu[source]

Alias of quimbify().

quimb.calc.realify(fn, imag_tol=1e-12)[source]

Decorator that drops fn’s output imaginary part if very small.

quimb.calc.tr[source]

Alias for trace().

quimb.calc.zeroify(fn, tol=1e-14)[source]

Decorator that rounds fn’s output to zero if very small.

quimb.calc.eigh
quimb.calc.eigvalsh
quimb.calc.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.calc.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.calc.norm_trace_dense(A, isherm=False)[source]

Returns the trace norm of operator A, that is, the sum of the absolute eigenvalues.

quimb.calc.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.calc.gen_bipartite_spectral_fn(exact_fn, approx_fn, pure_default)[source]

Generate a function that computes a spectral quantity of the subsystem of a pure state. Automatically computes for the smaller subsystem, or switches to the approximate method for large subsystems.

Parameters:
  • exact_fn (callable) – The function that computes the quantity on a density matrix, with signature: exact_fn(rho_a, rank=...).

  • approx_fn (callable) – The function that approximately computes the quantity using a lazy representation of the whole system. With signature approx_fn(psi_ab, dims, sysa, **approx_opts).

  • pure_default (float) – The default value when the whole state is the subsystem.

Returns:

bipartite_spectral_fn – The function, with signature: (psi_ab, dims, sysa, approx_thresh=2**13, **approx_opts)

Return type:

callable

quimb.calc.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.calc.tr_sqrt_subsys_approx(psi_ab, dims, sysa, backend=None, **kwargs)[source]

Approximate the trace sqrt of a pure state’s subsystem.

Parameters:
  • psi_ab (ket) – Bipartite state to partially trace and find trace sqrt 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.calc.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.calc.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.calc.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.calc.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.calc.int2tup(x)[source]
quimb.calc.array_contract(arrays, inputs, output=None, optimize=None, backend=None, **kwargs)[source]
quimb.calc.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.calc.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.calc.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.calc.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.calc.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.calc.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}
quimb.calc.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.calc.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.calc.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.calc.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.calc.mutual_information[source]
quimb.calc.check_dims_and_indices(dims, *syss)[source]

Make sure all indices found in the tuples syss are in range(len(dims)).

quimb.calc.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.calc.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.calc.tr_sqrt(A, rank=None)[source]

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

quimb.calc.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

quimb.calc.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.calc.partial_transpose_norm(p, dims, sysa)[source]

Compute the norm of the partial transpose for (log)-negativity, taking a shortcut (trace sqrt of reduced subsytem), when system is a vector.

quimb.calc.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.calc.logarithmic_negativity[source]
quimb.calc.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.calc.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

See also

logneg, partial_transpose, negativity_subsys_approx

quimb.calc.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.calc.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.calc.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.calc.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.calc.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.calc.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.calc.pauli_decomp

Decompose an operator into Paulis.

quimb.calc.bell_decomp

Decompose an operator into bell-states.

quimb.calc.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.calc.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.calc.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.calc.qid(p, dims, inds, precomp_func=False, sparse_comp=True, norm_func=norm, power=2, coeff=1)[source]
quimb.calc.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.calc.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.calc.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.calc.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