quimb.tensor.decomp

Functions for decomposing and projecting matrices, purely at the level of arrays (rather than wrapped as Tensors). The includes the main entry point array_split, which dispatches to a registered split driver based on the method.

Attributes

Functions

array_split(x[, method, absorb, max_bond, cutoff, ...])

Split a 2D array (or batch of 2D arrays) into left and right factors

array_svals(x[, method])

Compute the singular values of a 2D array without forming the full

parse_method(method)

parse_method_absorb([method, absorb, truncation])

Parse the method and absorb options. Possibly resolve "auto" settings

parse_split_opts([method, absorb, max_bond, cutoff, ...])

Automatically select method and absorb, convert defaults and settings to

parse_split_left_right_isom([method, absorb])

Based on split method and absorb mode, determine whether the left and

register_split_driver(name[, sparse, default_absorb])

Decorator to register functions which can decompose a matrix, and sets

register_svals_driver(name)

Decorator to register functions which can compute the singular values of

dag_numba(x)

safe_inverse(s, cutoff)

safe_inverse_numba(s, cutoff)

rdmul(x, d)

Right-multiplication a matrix by a vector representing a diagonal.

rdmul_numba(x, d)

rddiv(x, d)

Right-multiplication of a matrix by a vector representing an inverse

rddiv_numba(x, d)

ldmul(d, x)

Left-multiplication a matrix by a vector representing a diagonal.

ldmul_numba(d, x)

lddiv(d, x)

Left-multiplication of a matrix by a vector representing an inverse

lddiv_numba(d, x)

sgn(x)

Get the 'sign' of x, such that x / sgn(x) is real and

sgn_numba(x)

sgn_tf(x)

_do_absorb(U, s, VH[, absorb, xp])

_do_absorb_numba(U, s, VH, absorb)

_trim_and_renorm_svd_result(U, s, VH[, cutoff, ...])

Give full SVD decomposion result U, s, VH, optionally trim,

svd_truncated(x[, cutoff, cutoff_mode, max_bond, ...])

Singular value decomposition of raw 2d array x, with optional

_compute_number_svals_to_keep_numba(s, cutoff, cutoff_mode)

Find the number of singular values to keep of s given cutoff and

_compute_svals_renorm_factor_numba(s, n_chi, renorm)

Find the normalization constant for s such that the new sum squared

_trim_and_renorm_svd_result_numba(U, s, VH, cutoff, ...)

Accelerated version of _trim_and_renorm_svd_result.

svd_truncated_numba(x[, cutoff, cutoff_mode, ...])

Accelerated version of svd_truncated for numpy arrays.

svd_truncated_numpy(x[, cutoff, cutoff_mode, ...])

Numpy version of svd_truncated, trying the accelerated version

svd_truncated_lazy(x[, cutoff, cutoff_mode, max_bond, ...])

svdvals(x)

SVD-decomposition, but return singular values only.

svd_via_eig(x[, absorb, max_bond, descending, right])

Singular value decomposition of raw 2d array x, via hermitian

svd_via_eig_truncated(x[, cutoff, cutoff_mode, ...])

Singular value decomposition of raw 2d array x, via hermitian

_svd_via_eig_numba(x[, absorb, max_bond, descending, ...])

Numba-accelerated SVD via eigendecomposition of the Gram matrix,

_svd_via_eig_truncated_numba(x[, cutoff, cutoff_mode, ...])

SVD-split via eigen-decomposition, with optional dynamic truncation.

svd_via_eig_truncated_numpy(x[, cutoff, cutoff_mode, ...])

svdvals_eig(x)

SVD-decomposition via eigen, but return singular values only.

svd_rand_truncated(x, max_bond[, absorb, oversample, ...])

Singular value decomposition of raw 2d array x, via randomized

_with_diag_shift(x, xp[, shift])

_with_diag_shift_numba(x[, shift])

eigh_truncated(x[, cutoff, cutoff_mode, max_bond, ...])

SVD-like decomposition using hermitian eigen-decomposition, only works

eigh_truncated_numba(x[, cutoff, cutoff_mode, ...])

SVD-decomposition, using hermitian eigen-decomposition, only works if

eigh_truncated_numpy(x[, cutoff, cutoff_mode, ...])

qr_stabilized(x[, absorb, stabilized])

QR-decomposition, with stabilized R factor.

_qr_stabilized_numba(x[, absorb, stabilized])

_lq_stabilized_numba(x[, absorb, stabilized])

qr_stabilized_numpy(x[, absorb, stabilized])

qr_stabilized_lazy(x[, absorb])

_cholesky_maybe_with_diag_shift(x[, absorb, shift])

cholesky_regularized(x[, absorb, shift])

Cholesky decomposition, only works if x is positive definite. The

_cholesky_regularized_numba(x[, absorb, shift])

cholesky_regularized_numpy(x[, absorb, shift])

qr_via_cholesky(x[, absorb, shift, solve_triangular])

Perform a QR-like or LQ-like decomposition via Cholesky decomposition

_choose_k(x, cutoff, max_bond)

Choose the number of singular values to target.

svds(x[, cutoff, cutoff_mode, max_bond, absorb, renorm])

SVD-decomposition using iterative methods. Allows the

isvd(x[, cutoff, cutoff_mode, max_bond, absorb, renorm])

SVD-decomposition using interpolative matrix random methods. Allows the

_rsvd_numpy(x[, cutoff, cutoff_mode, max_bond, ...])

rsvd(x[, cutoff, cutoff_mode, max_bond, absorb, renorm])

SVD-decomposition using randomized methods (due to Halko). Allows the

eigsh(x[, cutoff, cutoff_mode, max_bond, absorb, renorm])

SVD-decomposition using iterative hermitian eigen decomp, thus assuming

lu_truncated(x[, cutoff, cutoff_mode, max_bond, ...])

LU-decomposition with optional truncation.

polar_right(x)

Polar decomposition of x as x = U @ P, where U is unitary and P is

polar_right_numba(x)

polar_left(x)

Polar decomposition of x as x = P @ U, where U is unitary and P is

polar_left_numba(x)

_similarity_compress_eig(X, max_bond, renorm)

_similarity_compress_eig_numba(X, max_bond, renorm)

_similarity_compress_eigh(X, max_bond, renorm)

_similarity_compress_eigh_numba(X, max_bond, renorm)

_similarity_compress_svd(X, max_bond, renorm, asymm)

_similarity_compress_svd_numba(X, max_bond, renorm, asymm)

_similarity_compress_biorthog(X, max_bond, renorm)

_similarity_compress_biorthog_numba(X, max_bond, renorm)

similarity_compress(X, max_bond[, renorm, method])

isometrize_qr(x)

Perform isometrization using the QR decomposition.

isometrize_svd(x)

Perform isometrization using the SVD decomposition.

isometrize_exp(x)

Perform isometrization using anti-symmetric matrix exponentiation.

isometrize_cayley(x)

Perform isometrization using an anti-symmetric Cayley transform.

isometrize_modified_gram_schmidt(A)

Perform isometrization explicitly using the modified Gram Schmidt

isometrize_householder(X)

isometrize_torch_householder(x)

Isometrize x using the Householder reflection method, as implemented

isometrize(x[, method])

Generate an isometric (or unitary if square) / orthogonal matrix from

squared_op_to_reduced_factor(x2, dl, dr[, right, method])

Given the square, x2, of an operator x, compute either the left

compute_oblique_projectors(Rl, Rr[, max_bond, cutoff, ...])

Compute the oblique projectors for two reduced factor matrices that

compute_bondenv_projectors(E, max_bond[, cutoff, ...])

Given 4D environment tensor of a bond, iteratively compute projectors

Module Contents

quimb.tensor.decomp.array_split(x, method='auto', absorb='auto', max_bond=None, cutoff=1e-10, cutoff_mode='rsum2', renorm=None, info=None, **kwargs)[source]

Split a 2D array (or batch of 2D arrays) into left and right factors (and possibly singular values) using a matrix decomposition. This is the main array-level entry point, dispatching to a registered split driver based on method, with absorb controlling the output form of the decomposition, and max_bond, cutoff and others controlling static and dynamic truncation respectively.

Parameters:
  • x (array_like) – The array or batch of arrays to split, of shape (..., m, n).

  • method (str, optional) –

    The decomposition method to use:

    • 'auto': use the default method based on absorb and whether truncation is requested via max_bond and/or cutoff.

    The five main methods are:

    • 'svd': full SVD, allowing all truncation options.

    • 'svd:eig': full SVD via eigendecomposition, allowing all truncation options. This can be faster than the standard SVD, but entails some loss of precision.

    • 'svd:rand': low-rank SVD via randomized projection, allows (and is only beneficial for) static truncation

    • 'qr': QR decomposition, by default left factor is isometric.

    • 'qr:cholesky': QR decomposition via Cholesky factorization, by default left factor is isometric. This can be faster than the standard QR, but entails some loss of precision.

    All of these can return different forms (and take various shortucts) based on absorb. Other methods are:

    • 'lq': LQ decomposition, right factor is isometric. This is simply an alias for method='qr' with absorb='left'.

    • 'eigh': full eigen-decomposition, array must be hermitian.

    • 'eigsh': iterative eigen-decomposition, array must be hermitian.

    • 'svds': iterative SVD, allows truncation.

    • 'isvd': iterative SVD using interpolative methods, allows truncation (see scipy.linalg.interpolative).

    • 'rsvd': randomized iterative SVD with truncation (alternative implementation).

    • 'lu': full LU decomposition, allows truncation. Favors sparsity but is not rank optimal.

    • 'polar_right': polar decomposition as A = U @ P.

    • 'polar_left': polar decomposition as A = P @ U.

    • 'cholesky': cholesky decomposition, array must be positive definite.

  • absorb (str or None, optional) –

    Desired form the decomposition / where to absorb the singular- or eigen- values. Common options are:

    • 'auto': use the method’s default absorb mode.

    • 'both' / 'Usq,sqVH': absorb sqrt(s) into both factors.

    • 'left' / 'Us,VH': absorb s into the left factor, leaving the right factor isometric (LQ-like).

    • 'right' / 'U,sVH': absorb s into the right factor, leaving the left factor isometric (QR-like).

    • None / 'U,s,VH': return s unabsorbed.

    Additional options for returning partial results (e.g. only one factor, unrequested factors returned as None):

    • 'lorthog' / 'U': return only the left isometric factor.

    • 'rorthog' / 'VH': return only the right isometric factor.

    • 'lfactor' / 'Us': return only the left factor with s absorbed (the L in an LQ decomposition).

    • 'rfactor' / 'sVH': return only the right factor with s absorbed (the R in a QR decomposition).

    • 's': return only the singular values.

    Note in all cases unrequested factors are returned as None.

  • max_bond (int or None, optional) – The maximum bond dimension (number of singular values) to keep. None means no limit.

  • cutoff (float, optional) – Threshold for discarding singular values, only used by methods that support dynamic truncation.

  • cutoff_mode ({'rsum2', 'rel', 'abs', 'sum2', 'rsum1', 'sum1'}, optional) –

    How to interpret cutoff when discarding singular values:

    • 'rel': values less than cutoff * s[0] discarded.

    • 'abs': values less than cutoff discarded.

    • 'sum2': sum squared of values discarded must be < cutoff.

    • 'rsum2': sum squared of values discarded must be less than cutoff times the total sum of squared values.

    • 'sum1': sum values discarded must be < cutoff.

    • 'rsum1': sum of values discarded must be less than cutoff times the total sum of values.

  • renorm (int or bool, optional) – Whether to renormalize the kept singular values to maintain the Frobenius or nuclear norm. 0 or False means no renormalization. True automatically picks the power based on cutoff_mode.

  • info (dict or None, optional) – If a dict is passed, store truncation info in the dict. Currently only supports the key ‘error’ for the truncation error, which is only computed if method in {"svd", "svd:eig"}.

  • **kwargs – Additional keyword arguments passed to the underlying split driver.

Returns:

  • left (array or None) – The left factor, or None if not requested by absorb.

  • s (array or None) – The singular/eigen values, or None if absorbed into the factors.

  • right (array or None) – The right factor, or None if not requested by absorb.

quimb.tensor.decomp.array_svals(x, method='svd', **kwargs)[source]

Compute the singular values of a 2D array without forming the full decomposition, using a registered singular value driver.

Parameters:
  • x (array_like) – The 2D array whose singular values to compute.

  • method (str, optional) – The method to use. Must have a registered singular value driver (e.g. 'svd' or 'svd:eig').

  • **kwargs – Additional keyword arguments passed to the underlying driver.

Returns:

s – The singular values in descending order.

Return type:

array

quimb.tensor.decomp.get_U_s_VH = None
quimb.tensor.decomp.get_s = 2
quimb.tensor.decomp.get_Usq = -12
quimb.tensor.decomp.get_VH = -11
quimb.tensor.decomp.get_Us = -10
quimb.tensor.decomp.get_Us_VH = -1
quimb.tensor.decomp.get_Usq_sqVH = 0
quimb.tensor.decomp.get_U_sVH = 1
quimb.tensor.decomp.get_U = 10
quimb.tensor.decomp.get_sVH = 11
quimb.tensor.decomp.get_sqVH = 12
quimb.tensor.decomp._ABSORB_MAP
quimb.tensor.decomp._ABSORB_TRANSPOSE_MAP
quimb.tensor.decomp._RETURNS_LEFT_ABSORBS
quimb.tensor.decomp._RETURNS_RIGHT_ABSORBS
quimb.tensor.decomp.cutoff_mode_abs = 1
quimb.tensor.decomp.cutoff_mode_rel = 2
quimb.tensor.decomp.cutoff_mode_sum2 = 3
quimb.tensor.decomp.cutoff_mode_rsum2 = 4
quimb.tensor.decomp.cutoff_mode_sum1 = 5
quimb.tensor.decomp.cutoff_mode_rsum1 = 6
quimb.tensor.decomp._CUTOFF_MODE_MAP
quimb.tensor.decomp._MAX_BOND_LOOKUP
quimb.tensor.decomp._CUTOFF_LOOKUP
quimb.tensor.decomp._RENORM_LOOKUP
quimb.tensor.decomp.parse_method(method)[source]
quimb.tensor.decomp.parse_method_absorb(method='auto', absorb='auto', truncation=True)[source]

Parse the method and absorb options. Possibly resolve “auto” settings to defaults, and convert from string aliases to numeric codes.

quimb.tensor.decomp.parse_split_opts(method='auto', absorb='auto', max_bond=None, cutoff=1e-10, cutoff_mode='rsum2', renorm=None)[source]

Automatically select method and absorb, convert defaults and settings to numeric type for numba, and only supply valid options for given method.

quimb.tensor.decomp.parse_split_left_right_isom(method='auto', absorb='auto')[source]

Based on split method and absorb mode, determine whether the left and right factors are isometric, and can be marked as such.

quimb.tensor.decomp._SPLIT_FNS
quimb.tensor.decomp._SPLIT_VALUES_FNS
quimb.tensor.decomp._DENSE_ONLY_METHODS
quimb.tensor.decomp._DEFAULT_ABSORB
quimb.tensor.decomp.register_split_driver(name, sparse=False, default_absorb=get_Usq_sqVH)[source]

Decorator to register functions which can decompose a matrix, and sets various flags specifying its capabilities and thus which options are valid to supply in array_split.

Parameters:
  • name (str) – The name of the method, corresponding to the method argument of array_split.

  • truncation ({"none", "static", "dynamic"}, optional) – Whether the method can handle truncation, and if so, whether it can only handle static truncation (i.e. max_bond) or dynamic truncation as well (i.e. cutoff and cutoff_mode).

  • sparse (bool, optional) – Whether the method can handle sparse arrays directly.

quimb.tensor.decomp.register_svals_driver(name)[source]

Decorator to register functions which can compute the singular values of a matrix without computing the full decomposition, which is used in array_svals.

Parameters:

name (str) – The name of the method, corresponding to the method argument of array_svals.

quimb.tensor.decomp.dag_numba(x)[source]
quimb.tensor.decomp.safe_inverse(s, cutoff)[source]
quimb.tensor.decomp.safe_inverse_numba(s, cutoff)[source]
quimb.tensor.decomp.rdmul(x, d)[source]

Right-multiplication a matrix by a vector representing a diagonal.

quimb.tensor.decomp.rdmul_numba(x, d)[source]
quimb.tensor.decomp.rddiv(x, d)[source]

Right-multiplication of a matrix by a vector representing an inverse diagonal.

quimb.tensor.decomp.rddiv_numba(x, d)[source]
quimb.tensor.decomp.ldmul(d, x)[source]

Left-multiplication a matrix by a vector representing a diagonal.

quimb.tensor.decomp.ldmul_numba(d, x)[source]
quimb.tensor.decomp.lddiv(d, x)[source]

Left-multiplication of a matrix by a vector representing an inverse diagonal.

quimb.tensor.decomp.lddiv_numba(d, x)[source]
quimb.tensor.decomp.sgn(x)[source]

Get the ‘sign’ of x, such that x / sgn(x) is real and non-negative.

quimb.tensor.decomp.sgn_numba(x)[source]
quimb.tensor.decomp.sgn_tf(x)[source]
quimb.tensor.decomp._do_absorb(U, s, VH, absorb=None, xp=None)[source]
quimb.tensor.decomp._do_absorb_numba(U, s, VH, absorb)[source]
quimb.tensor.decomp._trim_and_renorm_svd_result(U, s, VH, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, use_abs=False, info=None, xp=None)[source]

Give full SVD decomposion result U, s, VH, optionally trim, renormalize, and absorb the singular values. See svd_truncated for details.

quimb.tensor.decomp.svd_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None)[source]

Singular value decomposition of raw 2d array x, with optional truncation based on max_bond and/or dynamically on cutoff.

Parameters:
  • cutoff (float, optional) – Singular value cutoff threshold, if cutoff <= 0.0, then only max_bond is used.

  • cutoff_mode ({1, 2, 3, 4, 5, 6}, optional) –

    How to perform the truncation based on cutoff:

    • 1 / ‘abs’: trim values below cutoff

    • 2 / ‘rel’: trim values below s[0] * cutoff

    • 3 / ‘sum2’: trim s.t. sum(s_trim**2) < cutoff.

    • 4 / ‘rsum2’: trim s.t. sum(s_trim**2) < sum(s**2) * cutoff.

    • 5 / ‘sum1’: trim s.t. sum(s_trim**1) < cutoff.

    • 6 / ‘rsum1’: trim s.t. sum(s_trim**1) < sum(s**1) * cutoff.

  • max_bond (int, optional) – An explicit maximum bond dimension, use -1 for none.

  • absorb (int or None, optional) – How to absorb the singular values, as a pre-converted numeric code (get_Us_VH=-1: left, get_Usq_sqVH=0: both, get_U_sVH=1: right, None: return separately). Use array_split with string aliases (e.g. 'left', 'both', 'right', None) for a friendlier interface.

  • renorm (int, optional) – Whether to renormalize the kept singular values. 0 means no renormalization, 1 maintains the trace norm, 2 maintains the Frobenius norm.

  • info (dict or None, optional) – If a dict is passed, store truncation info in the dict. Currently only supports the key ‘error’ for the truncation error.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp._compute_number_svals_to_keep_numba(s, cutoff, cutoff_mode)[source]

Find the number of singular values to keep of s given cutoff and cutoff_mode.

quimb.tensor.decomp._compute_svals_renorm_factor_numba(s, n_chi, renorm)[source]

Find the normalization constant for s such that the new sum squared of the n_chi largest values equals the sum squared of all the old ones.

quimb.tensor.decomp._trim_and_renorm_svd_result_numba(U, s, VH, cutoff, cutoff_mode, max_bond, absorb, renorm, use_abs=False, calc_error=False)[source]

Accelerated version of _trim_and_renorm_svd_result.

quimb.tensor.decomp.svd_truncated_numba(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, calc_error=False)[source]

Accelerated version of svd_truncated for numpy arrays.

quimb.tensor.decomp.svd_truncated_numpy(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None)[source]

Numpy version of svd_truncated, trying the accelerated version first, then falling back to the more stable scipy version.

quimb.tensor.decomp.svd_truncated_lazy(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]
quimb.tensor.decomp.svdvals(x)[source]

SVD-decomposition, but return singular values only.

quimb.tensor.decomp.svd_via_eig(x, absorb=None, max_bond=-1, descending=True, right=None)[source]

Singular value decomposition of raw 2d array x, via hermitian eigen-decomposition of the Gram matrix (xdag @ x or x @ xdag), with static truncation (max_bond only) and various absorb return options, each with their own shortcuts.

Parameters:
  • x (array-like) – The 2d array to decompose.

  • absorb (str or None, optional) –

    What to compute / where to absorb the singular values:

    • None / 'U,s,VH': return s as the middle element of the 3-tuple, unabsorbed.

    • 'both' / 'Usq,sqVH': absorb sqrt(s) into both factors.

    • 'left' / 'Us,VH': absorb s into the left factor, leaving the right factor isometric (LQ-like).

    • 'right' / 'U,sVH': absorb s into the right factor, leaving the left factor isometric (QR-like).

    • 'lorthog' / 'U': return only the left isometric factor.

    • 'rorthog' / 'VH': return only the right isometric factor.

    • 'lfactor' / 'Us': return only the left factor with s absorbed (the L in an LQ decomposition).

    • 'rfactor' / 'sVH': return only the right factor with s absorbed (the R in a QR decomposition).

    • 's': return only the singular values.

  • max_bond (int, optional) – An explicit maximum bond dimension, use -1 for no truncation.

  • descending (bool, optional) – Whether to return singular values in descending order, default False.

  • right (bool, optional) – Whether to use decompose (xdag @ x: True) or (x @ xdag: False). If None (default), then will choose based on shape of x, and if square, then based on what is requested in absorb.

Returns:

  • U (array or None) – Left singular vectors, possibly with s absorbed, or None if not requested.

  • s (array or None) – Singular values, or None if not requested.

  • VH (array or None) – Right singular vectors, possibly with s absorbed, or None if not requested.

quimb.tensor.decomp.svd_via_eig_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None)[source]

Singular value decomposition of raw 2d array x, via hermitian eigen-decomposition of the Gram matrix, with optional truncation based on max_bond and/or dynamically on cutoff.

Parameters:
  • cutoff (float, optional) – Singular value cutoff threshold, if cutoff <= 0.0, then only max_bond is used.

  • cutoff_mode ({1, 2, 3, 4, 5, 6}, optional) –

    How to perform the truncation based on cutoff:

    • 1 / ‘abs’: trim values below cutoff

    • 2 / ‘rel’: trim values below s[0] * cutoff

    • 3 / ‘sum2’: trim s.t. sum(s_trim**2) < cutoff.

    • 4 / ‘rsum2’: trim s.t. sum(s_trim**2) < sum(s**2) * cutoff.

    • 5 / ‘sum1’: trim s.t. sum(s_trim**1) < cutoff.

    • 6 / ‘rsum1’: trim s.t. sum(s_trim**1) < sum(s**1) * cutoff.

  • max_bond (int, optional) – An explicit maximum bond dimension, use -1 for none.

  • absorb (int or None, optional) – How to absorb the singular values, as a pre-converted numeric code (get_Us_VH=-1: left, get_Usq_sqVH=0: both, get_U_sVH=1: right, None: return separately). Use array_split with string aliases (e.g. 'left', 'both', 'right', None) for a friendlier interface.

  • renorm (int, optional) – Whether to renormalize the kept singular values. 0 means no renormalization, 1 maintains the trace norm, 2 maintains the Frobenius norm.

  • info (dict or None, optional) – If a dict is passed, store truncation info in the dict. Currently only supports the key ‘error’ for the truncation error.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp._svd_via_eig_numba(x, absorb=get_U_s_VH, max_bond=-1, descending=True, right=None)[source]

Numba-accelerated SVD via eigendecomposition of the Gram matrix, with static truncation (max_bond only) and all absorb return options, each with their own shortcuts. Mirrors the structure of svd_via_eig.

Parameters:
  • x (array-like) – The 2d array to decompose.

  • absorb (int or None, optional) – Numeric absorb code controlling what to compute / return.

  • max_bond (int, optional) – An explicit maximum bond dimension, use -1 for no truncation.

  • descending (bool, optional) – Whether to return singular values in descending order.

Returns:

  • U (array or None)

  • s (array or None)

  • VH (array or None)

quimb.tensor.decomp._svd_via_eig_truncated_numba(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, calc_error=False)[source]

SVD-split via eigen-decomposition, with optional dynamic truncation. Uses _svd_via_eig_numba shortcuts when the full spectrum is not needed.

quimb.tensor.decomp.svd_via_eig_truncated_numpy(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None)[source]
quimb.tensor.decomp.svdvals_eig(x)[source]

SVD-decomposition via eigen, but return singular values only.

quimb.tensor.decomp.svd_rand_truncated(x, max_bond, absorb=get_Usq_sqVH, oversample=10, num_iterations=2, method_lorthog='qr', method_reduced='svd', right=None, lorthog_opts=None, reduced_opts=None, seed=None)[source]

Singular value decomposition of raw 2d array x, via randomized sketching, with static truncation (max_bond only) and various absorb return options, each with their own shortcuts. The speedup over full SVD is proportional to the truncation.

Parameters:
  • x (array_like) – The 2d array to decompose.

  • max_bond (int) – An explicit maximum bond dimension / target rank for the randomized sketch. You can use None or a negative value to indicate no truncation, though this is not recommended as there is no speedup.

  • absorb (str or None, optional) –

    What to compute / where to absorb the singular values:

    • None / 'U,s,VH': return s as the middle element of the 3-tuple, unabsorbed.

    • 'both' / 'Usq,sqVH': absorb sqrt(s) into both factors.

    • 'left' / 'Us,VH': absorb s into the left factor, leaving the right factor isometric (LQ-like).

    • 'right' / 'U,sVH': absorb s into the right factor, leaving the left factor isometric (QR-like).

    • 'lorthog' / 'U': return only the left isometric factor.

    • 'rorthog' / 'VH': return only the right isometric factor.

    • 'lfactor' / 'Us': return only the left factor with s absorbed (the L in an LQ decomposition).

    • 'rfactor' / 'sVH': return only the right factor with s absorbed (the R in a QR decomposition).

    • 's': return only the singular values.

  • oversample (int, optional) – Extra dimensions for the random sketch to improve accuracy, default 10.

  • num_iterations (int, optional) – Number of power iterations to improve accuracy, default 2.

  • method_reduced (str, optional) – The decomposition method to use for the reduced matrix, e.g. 'svd', 'svd:eig', etc. Default is 'svd'.

  • method_lorthog (str, optional) – The decomposition method to use for forming the orthonormal basis of the random sketch, e.g. 'qr', 'svd:eig', 'svd', etc. Default is 'qr'.

  • right (bool, optional) – Whether to sketch from the right or left. If None (default), then will choose based on value of absorb.

  • lorthog_opts (dict or None, optional) – Extra options to pass to the decomposition method for forming the orthonormal basis of the random sketch.

  • reduced_opts (dict or None, optional) – Extra options to pass to the decomposition method for the reduced matrix.

  • seed (int, Generator or None, optional) – Random seed or existing generator for reproducibility.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp._with_diag_shift(x, xp, shift=0.0)[source]
quimb.tensor.decomp._with_diag_shift_numba(x, shift=0.0)[source]
quimb.tensor.decomp.eigh_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, positive=0, shift=False)[source]

SVD-like decomposition using hermitian eigen-decomposition, only works if x is hermitian.

Parameters:

shift (bool or float, optional) –

Whether to add a small shift to the diagonal of x for regularization. The valid options are:

  • True: add trace(x) * eps to the diagonal of x, where eps is the machine epsilon for the dtype of x.

  • False: never add a shift.

  • float: use the provided value as a relative shift, i.e. add shift * trace(x) to the diagonal of x.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp.eigh_truncated_numba(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, positive=0, shift=0.0)[source]

SVD-decomposition, using hermitian eigen-decomposition, only works if x is hermitian.

quimb.tensor.decomp.eigh_truncated_numpy(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, positive=0, shift=False)[source]
quimb.tensor.decomp.qr_stabilized(x, absorb=get_U_sVH, stabilized=True, **kwargs)[source]

QR-decomposition, with stabilized R factor.

Parameters:
  • x (array_like) – The 2d array to decompose.

  • absorb (str or int, optional) –

    What form to compute / where to ‘absorb’ the singular values:

    • "right" / 'U,sVH': usual QR decomposition.

    • "lorthog" / "U": just the left isometric factor (Q).

    • "rfactor" / "sVH": just the right factor (R).

    • "left" / 'Us,VH': LQ-like decomposition.

    • "lfactor" / "Us": just the left factor (L) of LQ.

    • "rorthog" / "VH": just the right isometric factor (Q) of LQ.

  • stabilized (bool, optional) – Whether to stabilize the diagonal of R by setting its phase to 1 and absorbing the phase into Q. This can improve the numerical stability of gradients for example.

  • kwargs – Extra kwargs to pass to the underlying QR function.

Returns:

  • left (array_like) – The left isometric factor (Q).

  • s (None)

  • right (array_like) – The right upper triangular factor (R).

quimb.tensor.decomp._qr_stabilized_numba(x, absorb=get_U_sVH, stabilized=True)[source]
quimb.tensor.decomp._lq_stabilized_numba(x, absorb=get_Us_VH, stabilized=True)[source]
quimb.tensor.decomp.qr_stabilized_numpy(x, absorb=get_U_sVH, stabilized=True, **kwargs)[source]
quimb.tensor.decomp.qr_stabilized_lazy(x, absorb=get_U_sVH, **kwargs)[source]
quimb.tensor.decomp._cholesky_maybe_with_diag_shift(x, absorb=get_Usq_sqVH, shift=0.0)[source]
quimb.tensor.decomp.cholesky_regularized(x, absorb=get_Usq_sqVH, shift=True)[source]

Cholesky decomposition, only works if x is positive definite. The shift parameter controls optional regularization for close to singular matrices.

Parameters:
  • x (array_like) – The 2D array to decompose.

  • absorb (int, optional) –

    How to absorb the factors. The valid options are:

    • "both" or get_Usq_sqVH: return (L, None, L^H)

    • "lsqrt" or get_Usq: return (L, None, None)

    • "rsqrt" or get_sqVH: return (None, None, L^H)

  • shift ("auto", bool or float, optional) –

    Whether to add a small shift to the diagonal of x for regularization. The valid options are:

    • True: always add a small shift computed as above.

    • "auto": try without shift, if it fails, then add a small shift computed as trace(x) * eps, eps is the machine epsilon for the dtype of x.

    • False: never add a shift, just try the Cholesky decomposition directly.

    • float: use the provided value as a relative shift, i.e. add shift * trace(x) to the diagonal of x.

Returns:

  • left (array_like or None) – The lower triangular Cholesky factor (L).

  • s (None)

  • right (array_like or None) – The conjugate transpose of L (L^H).

quimb.tensor.decomp._cholesky_regularized_numba(x, absorb=get_Usq_sqVH, shift=-1.0)[source]
quimb.tensor.decomp.cholesky_regularized_numpy(x, absorb=get_Usq_sqVH, shift=True)[source]
quimb.tensor.decomp.qr_via_cholesky(x, absorb=get_Us_VH, shift=True, solve_triangular=True)[source]

Perform a QR-like or LQ-like decomposition via Cholesky decomposition of the Gram matrix.

quimb.tensor.decomp._choose_k(x, cutoff, max_bond)[source]

Choose the number of singular values to target.

quimb.tensor.decomp.svds(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]

SVD-decomposition using iterative methods. Allows the computation of only a certain number of singular values, e.g. max_bond, from the get-go, and is thus more efficient. Can also supply scipy.sparse.linalg.LinearOperator.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp.isvd(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]

SVD-decomposition using interpolative matrix random methods. Allows the computation of only a certain number of singular values, e.g. max_bond, from the get-go, and is thus more efficient. Can also supply scipy.sparse.linalg.LinearOperator.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp._rsvd_numpy(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]
quimb.tensor.decomp.rsvd(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]

SVD-decomposition using randomized methods (due to Halko). Allows the computation of only a certain number of singular values, e.g. max_bond, from the get-go, and is thus more efficient. Can also supply scipy.sparse.linalg.LinearOperator.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp.eigsh(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]

SVD-decomposition using iterative hermitian eigen decomp, thus assuming that x is hermitian. Allows the computation of only a certain number of singular values, e.g. max_bond, from the get-go, and is thus more efficient. Can also supply scipy.sparse.linalg.LinearOperator.

Returns:

  • left (array_like or None)

  • s (array_like or None)

  • right (array_like or None)

quimb.tensor.decomp.lu_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0)[source]

LU-decomposition with optional truncation.

Returns:

  • left (array_like) – The permuted lower triangular factor (PL).

  • s (None)

  • right (array_like) – The upper triangular factor (U).

quimb.tensor.decomp.polar_right(x)[source]

Polar decomposition of x as x = U @ P, where U is unitary and P is positive semidefinite.

Returns:

  • left (array_like) – The unitary factor (U).

  • s (None)

  • right (array_like) – The positive semidefinite factor (P).

quimb.tensor.decomp.polar_right_numba(x)[source]
quimb.tensor.decomp.polar_left(x)[source]

Polar decomposition of x as x = P @ U, where U is unitary and P is positive semidefinite.

Returns:

  • left (array_like) – The positive semidefinite factor (P).

  • s (None)

  • right (array_like) – The unitary factor (U).

quimb.tensor.decomp.polar_left_numba(x)[source]
quimb.tensor.decomp._similarity_compress_eig(X, max_bond, renorm)[source]
quimb.tensor.decomp._similarity_compress_eig_numba(X, max_bond, renorm)[source]
quimb.tensor.decomp._similarity_compress_eigh(X, max_bond, renorm)[source]
quimb.tensor.decomp._similarity_compress_eigh_numba(X, max_bond, renorm)[source]
quimb.tensor.decomp._similarity_compress_svd(X, max_bond, renorm, asymm)[source]
quimb.tensor.decomp._similarity_compress_svd_numba(X, max_bond, renorm, asymm)[source]
quimb.tensor.decomp._similarity_compress_biorthog(X, max_bond, renorm)[source]
quimb.tensor.decomp._similarity_compress_biorthog_numba(X, max_bond, renorm)[source]
quimb.tensor.decomp._similarity_compress_fns
quimb.tensor.decomp.similarity_compress(X, max_bond, renorm=False, method='eigh')[source]
quimb.tensor.decomp.isometrize_qr(x)[source]

Perform isometrization using the QR decomposition.

quimb.tensor.decomp.isometrize_svd(x)[source]

Perform isometrization using the SVD decomposition.

quimb.tensor.decomp.isometrize_exp(x)[source]

Perform isometrization using anti-symmetric matrix exponentiation.

\[U_A = \exp \left( X - X^\dagger \right)\]

If x is rectangular it is completed with zeros first.

quimb.tensor.decomp.isometrize_cayley(x)[source]

Perform isometrization using an anti-symmetric Cayley transform.

\[U_A = (I + \dfrac{A}{2})(I - \dfrac{A}{2})^{-1}\]

where \(A = X - X^\dagger\). If x is rectangular it is completed with zeros first.

quimb.tensor.decomp.isometrize_modified_gram_schmidt(A)[source]

Perform isometrization explicitly using the modified Gram Schmidt procedure (this is slow but a useful reference).

quimb.tensor.decomp.isometrize_householder(X)[source]
quimb.tensor.decomp.isometrize_torch_householder(x)[source]

Isometrize x using the Householder reflection method, as implemented by the torch_householder package.

quimb.tensor.decomp._ISOMETRIZE_METHODS
quimb.tensor.decomp.isometrize(x, method='qr')[source]

Generate an isometric (or unitary if square) / orthogonal matrix from array x.

Parameters:
  • x (array) – The matrix to project into isometrix form.

  • method (str, optional) –

    The method used to generate the isometry. The options are:

    • ”qr”: use the Q factor of the QR decomposition of x with the constraint that the diagonal of R is positive.

    • ”svd”: uses U @ VH of the SVD decomposition of x. This is useful for finding the ‘closest’ isometric matrix to x, such as when it has been expanded with noise etc. But is less stable for differentiation / optimization.

    • ”exp”: use the matrix exponential of x - dag(x), first completing x with zeros if it is rectangular. This is a good parametrization for optimization, but more expensive for non-square x.

    • ”cayley”: use the Cayley transform of x - dag(x), first completing x with zeros if it is rectangular. This is a good parametrization for optimization (one the few compatible with HIPS/autograd e.g.), but more expensive for non-square x.

    • ”householder”: use the Householder reflection method directly. This requires that the backend implements “linalg.householder_product”.

    • ”torch_householder”: use the Householder reflection method directly, using the torch_householder package. This requires that the package is installed and that the backend is "torch". This is generally the best parametrizing method for “torch” if available.

    • ”mgs”: use a python implementation of the modified Gram Schmidt method directly. This is slow if not compiled but a useful reference.

    Not all backends support all methods or differentiating through all methods.

Returns:

Q – The isometrization / orthogonalization of x.

Return type:

array

quimb.tensor.decomp.squared_op_to_reduced_factor(x2, dl, dr, right=True, method='eigh', **kwargs)[source]

Given the square, x2, of an operator x, compute either the left or right reduced factor matrix of the unsquared operator x with original shape (dl, dr).

If right=True, compute the right factor, s @ Vdag, assuming x2 is given as x2 = dag(x) @ x = V @ s^2 @ Vdag, otherwise compute the left factor, U @ s, assuming x2 = x @ dag(x) = U @ s^2 @ Udag.

Parameters:
  • x2 (array) – The squared operator, either dag(x) @ x or x @ dag(x).

  • dl (int) – The original left dimension of the unsquared operator x.

  • dr (int) – The original right dimension of the unsquared operator x.

  • right (bool, optional) – Whether to compute the right factor (s @ Vdag) or left factor (U @ s).

  • method (str, optional) – The method to use for the decomposition.

  • kwargs – Additional keyword arguments to pass to the decomposition method. For example shift for the cholesky and eigh methods.

Returns:

factor – The reduced factor matrix of the unsquared operator x.

Return type:

array

quimb.tensor.decomp.compute_oblique_projectors(Rl, Rr, max_bond=None, cutoff=0.0, absorb='both', cutoff_mode='rsum2', method='svd', **compress_opts)[source]

Compute the oblique projectors for two reduced factor matrices that describe a gauge on a bond. Concretely, assuming that Rl and Rr are the reduced factor matrices for local operator A, such that:

\[A = Q_L R_L R_R Q_R\]

with Q_L and Q_R isometric matrices, then the optimal inner truncation is given by:

\[A' = Q_L P_L P_R' Q_R\]
Parameters:
  • Rl (array) – The left reduced factor matrix.

  • Rr (array) – The right reduced factor matrix.

  • max_bond (int, optional) – The maximum bond dimension to compress to.

  • cutoff (float, optional) – The singular value cutoff to use.

  • absorb (str or None, optional) –

    Where to absorb the effective singular values into the projectors. The options are:

    • 'both' / 'Usq,sqVH': absorb sqrt(s) into both projectors.

    • 'left' / 'Us,VH': absorb s into the left projector, leaving the right projector isometric (LQ-like).

    • 'right' / 'U,sVH': absorb s into the right projector, leaving the left projector isometric (QR-like).

    • None / 'U,s,VH': return s as a separate middle element.

  • cutoff_mode (str, optional) – The cutoff mode to use when applying the cutoff.

  • method (str, optional) – The method to use for the SVD decomposition when computing the projectors.

  • compress_opts – Additional keyword arguments to pass to the SVD decomposition method.

Returns:

  • Pl (array) – The left oblique projector.

  • Pr (array) – The right oblique projector.

quimb.tensor.decomp.compute_bondenv_projectors(E, max_bond, cutoff=0.0, absorb='both', max_iterations=100, tol=1e-10, solver='solve', solver_maxiter=4, prenormalize=False, condition=True, enforce_pos=True, pos_smudge=1e-10, init='svd', info=None)[source]

Given 4D environment tensor of a bond, iteratively compute projectors that compress the bond dimension to max_bond, minimizing the distance in terms of frobenius norm. If absorb!=”both” and cutoff!=0.0 then a final truncated SVD is also performed on the final projector pair.

N.B. This is experimental and not working for e.g. fermions yet.

Parameters:
  • E (array) – The 4D environment tensor of a bond. The dimensions should be arranged as (ket-left, ket-right, bra-left, bra-right).

  • max_bond (int) – The maximum bond dimension to compress to.

  • cutoff (float, optional) – The singular value cutoff to use.

  • absorb (str or None, optional) –

    Where to absorb the effective singular values into the projectors:

    • 'both' / 'Usq,sqVH': absorb sqrt(s) into both projectors.

    • 'left' / 'Us,VH': absorb s into the left projector, leaving the right projector isometric (LQ-like).

    • 'right' / 'U,sVH': absorb s into the right projector, leaving the left projector isometric (QR-like).

    • None / 'U,s,VH': return s as a separate middle element.

  • max_iterations (int, optional) – The maximum number of iterations to use when fitting the projectors.

  • tol (float, optional) – The target tolerance to reach when fitting the projectors.

  • solver ({'solve', None, str}, optional) – The solver to use inside the fitting loop. If None will use a custom conjugate gradient method. Else can be any of the iterative solvers supported by scipy.sparse.linalg such as ‘gmres’, ‘bicgstab’, etc.

  • solver_maxiter (int, optional) – The maximum number of iterations to use for the inner solver, i.e. per fitting step, only for iterative solver args.

  • prenormalize (bool, optional) – Whether to prenormalize the environment tensor such that its full contraction before compression is 1. Recommended for stability when the normalization does not matter.

  • condition (bool or "iso", optional) – Whether to condition the projectors after each fitting step. If True, their norms will be simply matched. If "iso", then they are gauged each time such that the previous tensor is isometric. Recommended for stability.

  • enforce_pos (bool, optional) – Whether to enforce the environment tensor to be positive semi-definite by symmetrizing and clipping negative eigenvalues. Recommended for stability.

  • pos_smudge (float, optional) – The value to clip negative eigenvalues to when enforcing positivity, relative to the largest eigenvalue.

  • init ({'svd', 'eigh', 'random', 'reduced'}, optional) –

    How to initialize the compression projectors. The options are:

    • ’svd’: use a truncated SVD of the environment tensor with the bra bond traced out.

    • ’eigh’: use a similarity compression of the environment tensor with the bra bond traced out.

    • ’random’: use random projectors.

    • ’reduced’: split the environment into bra and ket parts, then canonize one half left and right to get the reduced factors.

  • info (dict, optional) – If provided, will store information about the fitting process here. The keys ‘iterations’ and ‘distance’ will contain the final number of iterations and distance reached respectively.

Returns:

  • Pl (array) – The left projector.

  • Pr (array) – The right projector.