quimb¶
Quantum Information for Many-Body calculations.
Subpackages¶
Submodules¶
Attributes¶
Alias of |
|
Convert an object into a ket. |
|
Convert an object into a bra. |
|
Convert an object into a density operator. |
|
Convert an object into sparse form. |
|
Alias for |
|
Sparse identity. |
|
Alias for |
|
Alias for |
|
Alias for |
|
Alias for |
|
Calculate the entropy of a pure states' subsystem, optionally switching |
|
Compute the trace sqrt of a subsystem, possibly using an approximate |
|
Decompose an operator into Paulis. |
|
Decompose an operator into bell-states. |
|
Classes¶
Thin subclass of |
|
A simple class representing an unconstructed matrix. This can be passed |
|
A class for evolving quantum systems according to Schrodinger equation. |
|
An ordered set which stores elements as the keys of dict (ordered as of |
|
Least recently used dict, which evicts old items. Taken from python |
Functions¶
|
|
|
Checks if |
|
Checks if |
|
Checks if |
|
Checks if |
|
Checks if |
|
Checks if |
|
Checks if |
|
Checks if |
|
Checks if the dense hermitian |
|
Element-wise multiplication, dispatched to correct dense or sparse |
|
Conjugate transpose. |
|
Matrix multiplication, dispatched to dense or sparse functions. |
|
Accelerated 'Hermitian' inner product of two arrays. In other words, |
|
Real dot product of two dense vectors. |
|
Accelerated left diagonal multiplication. Equivalent to |
|
Accelerated left diagonal multiplication. |
|
Outer product between two vectors (no conjugation). |
|
Complex exponenital as used in solution to schrodinger equation. |
|
|
|
Normalize a quantum object. |
|
Set small values of a dense or sparse array to zero. |
|
Converts data to 'quantum' i.e. complex matrices, kets being columns. |
|
Infer the size, i.e. number of 'sites' in a state. |
|
Trace of a dense or sparse operator. |
|
Return identity of size d in complex format, optionally sparse. |
|
Flatten 2d+ dimensions and coordinates. |
|
Compress neighbouring subsytem dimensions. |
|
Tensor (kronecker) product of variable number of arguments. |
|
Returns a tensored with itself p times |
|
Tensor an operator into a larger space by padding with identities. |
|
Advanced, padded tensor product. |
|
Permute the subsytems of state or opeator. |
|
General tensor trace, i.e. multiple contractions, for a dense array. |
|
Partial trace of a dense or sparse state. |
|
'Expectation' between a vector/operator and another vector/operator. |
|
Find all or some eigenpairs of an operator. |
|
Return a few eigenpairs from an operator. |
|
Alias for finding lowest eigenvector only. |
|
Alias for finding lowest eigenvalue only. |
|
Return the smallest and largest eigenvalue of hermitian operator |
|
Return mid-spectrum eigenpairs from a hermitian operator. |
|
Alias for only finding the eigenvalues in a relative window. |
|
Alias for only finding the eigenvectors in a relative window. |
|
Compute full singular value decomposition of an operator, using numpy. |
|
Compute the partial singular value decomposition of an operator. |
|
Operator norms. |
|
Matrix exponential, can be accelerated if explicitly hermitian. |
|
Matrix square root, can be accelerated if explicitly hermitian. |
|
Compute the action of |
|
Fast, randomized, iterative SVD. Adaptive variant of method due |
|
Estimate the rank of an linear operator. Uses a low quality random |
|
Get the MPI executor pool, with specified number of processes and |
Function to determine whether we are allowed to call get_mpi_pool. |
|
|
Generate a general spin-operator. |
|
Generates the pauli operators for dimension 2 or 3. |
|
The Hadamard gate. |
|
The generalized qubit phase-gate, which adds phase |
|
The S-gate (phase gate). |
|
The T-gate (pi/8 gate). |
|
Arbitrary unitary single qubit gate. |
|
The single qubit rotation gate. |
|
Rx(pi / 2). |
|
Ry(pi / 2). |
|
Rz(pi / 2). |
|
R[X + Y](pi / 2). |
|
The SWAP operator acting on subsystems of dimension dim. |
|
|
|
The 'fermionic simulation' gate: |
|
The 'fermionic simulation' gate, with: |
|
Build an n-qubit controlled gate. The control qubits are the |
|
Construct a controlled pauli gate for two qubits. |
|
The controlled-not gate. |
|
The controlled-X gate. |
|
The controlled-Y gate. |
|
The controlled-Z gate. |
|
The double controlled X gate, or Toffoli gate. |
|
The double controlled Y gate. |
|
The double controlled Z gate. |
|
The controlled swap or Fredkin gate. The control qubit is the first |
|
Constructs the nearest neighbour 1d heisenberg spin-1/2 hamiltonian. |
|
Generate the quantum transverse field ising model hamiltonian. This is a |
|
Generate the quantum transverse field XY model hamiltonian. This is a |
|
Generate the XXZ-model hamiltonian. This is a |
|
Generate the j1-j2 hamiltonian, i.e. next nearest neighbour |
|
Constructs a heisenberg hamiltonian with isotropic coupling and |
|
Construct the 2D spin-1/2 heisenberg model hamiltonian: |
|
Construct the projector onto spin-z subpspaces. |
|
The creation operator acting on an n-level system. |
|
The annihilation operator acting on an n-level system. |
|
The number operator acting on an n-level system. |
|
Generate the spinless fermion hopping hamiltonian. |
|
Constructs a unit vector ket: |
|
Returns up-state, aka. |
|
Returns down-state, aka. |
|
Returns plus-state, aka. |
|
Returns minus-state, aka. |
|
Returns yplus-state, aka. |
|
Returns yplus-state, aka. |
|
Construct qubit density operator from bloch vector: |
|
One of the four bell-states. |
|
Alias for the 'psi-' bell-state. |
|
Generate a thermal state of a Hamiltonian. |
|
Construct Neel state for n spins, i.e. alternating up/down. |
|
Construct fully dimerised spin chain. |
|
Construct Werner State, i.e. fractional mix of identity with singlet. |
|
Construct GHZ state of n spins, i.e. equal superposition of all up |
|
Construct W-state: equal superposition of all single spin up states. |
|
Compute the generalised levi-civita coefficient for a permutation. |
|
Construct the anti-symmetric state which is the +- sum of all |
|
Graph State on a line. |
|
Generate the qubit computational state with |
|
Fast multithreaded generation of random normally distributed data. |
|
|
|
Generate a random matrix of order d with normally distributed |
|
Generate a random hermitian operator of order d with normally |
|
Generate a random positive operator of size d, with normally |
|
Generate a random positive operator of size d with normally |
|
Generates a ket of length d with normally distributed entries. |
|
Generate a random unitary operator of size d, distributed according to |
|
Generate a random state of dimension d according to the Haar |
|
Generate many random Haar states, recycling a random unitary operator |
|
Constructs a random mixed state by tracing out a random ket |
|
Generates a ket of n many random pure qubits. |
|
Generate a random matrix product state (in dense form, see |
|
Generate a random, mixed, seperable state. E.g rand_seperable([2, 2]) |
|
Generate a random isometry of shape |
|
Generate a random mera state of |
|
See the random number generators, by instantiating a new set of bit |
|
Set the core bit generator type to use, from either |
|
Fidelity between two quantum states. By default, the unsquared fidelity |
|
Take state rho and purify it into a wavefunction of squared |
|
Compute the (von Neumann) entropy. |
|
Find the mutual information for a bipartition of a state. |
|
Calculate the mutual information of two subsystems of a pure state, |
|
Find the schmidt gap of the bipartition of |
|
Return the trace of the sqrt of a positive semidefinite operator. |
|
Partial transpose of a density operator. |
|
Compute negativity between two subsytems. |
|
Compute logarithmic negativity between two subsytems. |
|
Compute the logarithmic negativity between two subsystems of a pure |
|
Concurrence of two-qubit state. |
|
One way classical information for two qubit density operator. |
|
Quantum Discord for two qubit density operator. |
|
Trace distance between two states: |
|
Print a state in the computational basis. |
|
Decomposes an operator via the Hilbert-schmidt inner product. |
|
Calculate the correlation between two sites given two operators. |
|
Calculate the correlation between sites for a list of operator pairs |
|
Calculate the pair-wise function ent_fn between all sites or blocks |
|
|
|
Check if operator has any degenerate eigenvalues, determined relative |
|
Determines whether a vector is an eigenvector of an operator. |
|
Calculate the page entropy, i.e. expected entropy for a subsytem |
Get the analytic isotropic heisenberg chain ground energy for length L. |
|
|
Dephase |
|
Operate on a mixed state with a set of kraus operators: |
|
Compute the projector for the target |
|
Measure state |
|
Simulate measuring each qubit of |
|
Approximate a spectral function, that is, the quantity |
|
|
|
|
|
|
|
|
|
Approximate the (Von Neumann) entropy of a pure state's subsystem. |
|
Estimate the logarithmic negativity of a pure state's subsystem. |
|
Estimate the negativity of a pure state's subsystem. |
|
|
|
Save an object to disk using joblib.dump. |
|
Load an object form disk using joblib.load. |
|
Map |
|
Apply |
|
Flatten |
|
Unflatten |
|
Given |
Wrap a function or method to use the neutral style by default. |
Package Contents¶
- 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¶
- quimb.prod(iterable)¶
- quimb.isherm(qob, **allclose_opts)[source]¶
Checks if
qob
is hermitian.- Parameters:
qob (dense or sparse operator) – Matrix to check.
- Return type:
- 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:
- 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
andy
.- Return type:
dense or sparse operator
- 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
andb
.- 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
andmat
.- 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 isdiag
.- Return type:
dense or sparse matrix
- 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.
- 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 asdata
and'ket'
or'bra'
asqtype
, 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
Will unravel an array if
'ket'
or'bra'
given.Will conjugate if
'bra'
given.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:
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:
- quimb.identity(d, sparse=False, stype='csr', dtype=complex)[source]¶
Return identity of size d in complex format, optionally sparse.
- 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
andtrim
.- 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:
- 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'
}. IfNone
, 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 actuallyX[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
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)
.
- 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 byinds
.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 actuallyX[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
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 ondims[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.
inds (tuple of int) – Indices of the dimensions to place operators on. If multiple operators are specified,
inds[1]
corresponds toops[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
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:
- Returns:
pp – Permuted state or operator.
- Return type:
vector or operator
See also
Examples
>>> IX = speye(2) & pauli('X', sparse=True) >>> XI = permute(IX, dims=[2, 2], perm=[1, 0]) >>> np.allclose(XI.toarray(), 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:
See also
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:
See also
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
andb
, 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
withb
.- Return type:
- quimb.expec[source]¶
Alias for
expectation()
.
- quimb.nmlz[source]¶
Alias for
normalize()
.
- 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. Seeeigensystem_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 ifreturn_vecs
.
- 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.
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
approximatesA
.- Return type:
(Uk,) sk (, VHk)
- 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)
onvec
.- 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 anownership
keyword to avoid forming every row.This is essentially like using
functools.partial
and assigning theshape
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>
- fn¶
- args¶
- kwargs¶
- shape¶
- factor¶
- dtype = None¶
- 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 thank
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 nok_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
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:
- Returns:
P – The pauli operator.
- Return type:
immutable operator
See also
- quimb.phase_gate(phi, dtype=complex, sparse=False)[source]¶
The generalized qubit phase-gate, which adds phase
phi
to the|1>
state.
- 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}\]
- 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.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
andphi
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.
- quimb.controlled(s, dtype=complex, sparse=False)[source]¶
Construct a controlled pauli gate for two qubits.
- 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.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 anddelta
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 sitei
isdh * cos(2 * pi * beta * i + delta)
withdelta
a random offset between(0, 2 * pi)
, possibly seeded byseed
.
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:
- Returns:
prj – The (non-square) projector onto the specified subspace(s). The subspace size
D
is given byn choose (n / 2 + s)
for eachs
specified insz
.- Return type:
immutable sparse operator, shape (2**n, D)
Examples
>>> zspin_projector(n=2, sz=0).toarray() 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.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}\]
- quimb.up(**kwargs)[source]¶
Returns up-state, aka.
|0>
, +Z eigenstate:\[\begin{split}|0\rangle = \begin{pmatrix} 1 \\ 0 \end{pmatrix}\end{split}\]
- quimb.down(**kwargs)[source]¶
Returns down-state, aka.
|1>
, -Z eigenstate:\[\begin{split}|1\rangle = \begin{pmatrix} 0 \\ 1 \end{pmatrix}\end{split}\]
- 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.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.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)\]
- quimb.bell_state(s, **kwargs)[source]¶
One of the four bell-states.
If n = 2**-0.5, they are:
'psi-'
:n * ( |01> - |10> )
'psi+'
:n * ( |01> + |10> )
'phi-'
:n * ( |00> - |11> )
'phi+'
:n * ( |00> + |11> )
They can be enumerated in this order.
- quimb.thermal_state(ham, beta, precomp_func=False)[source]¶
Generate a thermal state of a Hamiltonian.
- Parameters:
- 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:
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.
- 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.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.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:
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_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].
See also
- 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].
See also
- 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.
See also
- 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.
See also
- 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:
- 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.
- 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 usesquimb.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
orrandomgen
.- 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>|
.
- 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:
See also
- 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:
See also
- 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 entropyH
, and two subsystems A and B.- Parameters:
p (vector or operator) – State, can be vector or operator.
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, ifp
comes from tracing out three qubits from a system, then its rank is 2^3 = 8 etc.
- Return type:
See also
- 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:
See also
mutinf
,entropy_subsys
,entropy_subsys_approx
,logneg_subsys
- 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.
- 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:
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:
- Return type:
operator
See also
- 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:
- Return type:
See also
- 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:
- Return type:
See also
- 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:
See also
- 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:
- Return type:
- 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:
- Return type:
- 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:
- 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
See also
- 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
andprecomp_func
.- Return type:
- 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.
- quimb.is_eigenvector(x, A, tol=1e-14)[source]¶
Determines whether a vector is an eigenvector of an operator.
- 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.
- 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
- quimb.dephase(rho, p, rand_rank=None)[source]¶
Dephase
rho
by amountp
, that is, mix it with the maximally mixed state:rho -> (1 - p) * rho + p * I / d
- Parameters:
- 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 operatorA
.- 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 observableA
, 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 ofqiskit
.- Parameters:
- Returns:
results – The counts for each bit string measured.
- Return type:
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 SciPyLinearOperator
), assume a time-dependent hamiltonian such thatham(t)
is the Hamiltonian at timet
. In this case, the latest call toham
will be cached (and made immutable) in case it is needed by callbacks passed tocompute
.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 ifmethod
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 incompute
.
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 thecompute
argument. It should return-1
to stop the integration, otherwise it should returnNone
or0
.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 ifmethod='expm'
.progbar (bool, optional) – Whether to show a progress bar when calling
at_times
or integrating with theupdate_to
method.
- _p0¶
- _isdop¶
- _d¶
- _progbar¶
- _timedep¶
- _method¶
- _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.
- _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(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
.
- property pt¶
- State of the system at the current time (t).
- Type:
quantum state
- quimb.approx_spectral_function(A, f, tol=0.01, *, bsz=1, R=1024, R_min=3, 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, progbar=False, plot=False, **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
andtau
. Default: 1%.bsz (int, optional) – Number of simultenous vector columns to use at once, 1 equating to the standard lanczos method. If
bsz > 1
thenA
must implement matrix-matrix multiplication. This is a more performant way of essentially increasingR
, 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 withR
. Iftol
is non-zero, this is the maximum number of repeats.R_min (int, optional) – The minimum number of repeats to perform. Default: 3.
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
. Iftau
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()
orconstruct_lanczos_tridiag()
.
- Returns:
The approximate value
Tr(f(a))
.- Return type:
scalar
See also
construct_lanczos_tridiag
- 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()
.
- 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',)¶
- _d¶
- class quimb.LRU(maxsize, *args, **kwds)[source]¶
Bases:
collections.OrderedDict
Least recently used dict, which evicts old items. Taken from python collections OrderedDict docs.
- maxsize¶
- quimb.tree_map(f, tree, is_leaf=is_not_container)[source]¶
Map
f
over all leaves intree
, 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 whichis_leaf(x)
returnsTrue
.
- Return type:
pytree
- quimb.tree_apply(f, tree, is_leaf=is_not_container)[source]¶
Apply
f
to all leaves intree
, 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 whichis_leaf(x)
returnsTrue
.
- 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)
returnsTrue
are returned in the flattened list.
- Returns:
objs (list) – The flattened list of leaf objects.
(ref_tree) (pytree) – If
get_ref
isTrue
, a reference tree, with leaves of typeLeaf
, 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 astree
.- 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)
returnsTrue
will have the next item fromobjs
inserted. By default checks for theLeaf
object inserted bytree_flatten(..., get_ref=True)
.
- Return type:
pytree
- quimb.format_number_with_error(x, err)[source]¶
Given
x
with errorerr
, format a string showing the relevant digits ofx
with two significant digits of the error bracketed, and overall exponent if necessary.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¶