quimb.tensor.decomp =================== .. py:module:: quimb.tensor.decomp .. autoapi-nested-parse:: 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 ---------- .. autoapisummary:: quimb.tensor.decomp.get_U_s_VH quimb.tensor.decomp.get_s quimb.tensor.decomp.get_Usq quimb.tensor.decomp.get_VH quimb.tensor.decomp.get_Us quimb.tensor.decomp.get_Us_VH quimb.tensor.decomp.get_Usq_sqVH quimb.tensor.decomp.get_U_sVH quimb.tensor.decomp.get_U quimb.tensor.decomp.get_sVH quimb.tensor.decomp.get_sqVH 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 quimb.tensor.decomp.cutoff_mode_rel quimb.tensor.decomp.cutoff_mode_sum2 quimb.tensor.decomp.cutoff_mode_rsum2 quimb.tensor.decomp.cutoff_mode_sum1 quimb.tensor.decomp.cutoff_mode_rsum1 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._SPLIT_FNS quimb.tensor.decomp._SPLIT_VALUES_FNS quimb.tensor.decomp._DENSE_ONLY_METHODS quimb.tensor.decomp._DEFAULT_ABSORB quimb.tensor.decomp._similarity_compress_fns quimb.tensor.decomp._ISOMETRIZE_METHODS Functions --------- .. autoapisummary:: quimb.tensor.decomp.array_split quimb.tensor.decomp.array_svals quimb.tensor.decomp.parse_method quimb.tensor.decomp.parse_method_absorb quimb.tensor.decomp.parse_split_opts quimb.tensor.decomp.parse_split_left_right_isom quimb.tensor.decomp.register_split_driver quimb.tensor.decomp.register_svals_driver quimb.tensor.decomp.dag_numba quimb.tensor.decomp.safe_inverse quimb.tensor.decomp.safe_inverse_numba quimb.tensor.decomp.rdmul quimb.tensor.decomp.rdmul_numba quimb.tensor.decomp.rddiv quimb.tensor.decomp.rddiv_numba quimb.tensor.decomp.ldmul quimb.tensor.decomp.ldmul_numba quimb.tensor.decomp.lddiv quimb.tensor.decomp.lddiv_numba quimb.tensor.decomp.sgn quimb.tensor.decomp.sgn_numba quimb.tensor.decomp.sgn_tf quimb.tensor.decomp._do_absorb quimb.tensor.decomp._do_absorb_numba quimb.tensor.decomp._trim_and_renorm_svd_result quimb.tensor.decomp.svd_truncated quimb.tensor.decomp._compute_number_svals_to_keep_numba quimb.tensor.decomp._compute_svals_renorm_factor_numba quimb.tensor.decomp._trim_and_renorm_svd_result_numba quimb.tensor.decomp.svd_truncated_numba quimb.tensor.decomp.svd_truncated_numpy quimb.tensor.decomp.svd_truncated_lazy quimb.tensor.decomp.svdvals quimb.tensor.decomp.svd_via_eig quimb.tensor.decomp.svd_via_eig_truncated quimb.tensor.decomp._svd_via_eig_numba quimb.tensor.decomp._svd_via_eig_truncated_numba quimb.tensor.decomp.svd_via_eig_truncated_numpy quimb.tensor.decomp.svdvals_eig quimb.tensor.decomp.svd_rand_truncated quimb.tensor.decomp._with_diag_shift quimb.tensor.decomp._with_diag_shift_numba quimb.tensor.decomp.eigh_truncated quimb.tensor.decomp.eigh_truncated_numba quimb.tensor.decomp.eigh_truncated_numpy quimb.tensor.decomp.qr_stabilized quimb.tensor.decomp._qr_stabilized_numba quimb.tensor.decomp._lq_stabilized_numba quimb.tensor.decomp.qr_stabilized_numpy quimb.tensor.decomp.qr_stabilized_lazy quimb.tensor.decomp._cholesky_maybe_with_diag_shift quimb.tensor.decomp.cholesky_regularized quimb.tensor.decomp._cholesky_regularized_numba quimb.tensor.decomp.cholesky_regularized_numpy quimb.tensor.decomp.qr_via_cholesky quimb.tensor.decomp._choose_k quimb.tensor.decomp.svds quimb.tensor.decomp.isvd quimb.tensor.decomp._rsvd_numpy quimb.tensor.decomp.rsvd quimb.tensor.decomp.eigsh quimb.tensor.decomp.lu_truncated quimb.tensor.decomp.polar_right quimb.tensor.decomp.polar_right_numba quimb.tensor.decomp.polar_left quimb.tensor.decomp.polar_left_numba quimb.tensor.decomp._similarity_compress_eig quimb.tensor.decomp._similarity_compress_eig_numba quimb.tensor.decomp._similarity_compress_eigh quimb.tensor.decomp._similarity_compress_eigh_numba quimb.tensor.decomp._similarity_compress_svd quimb.tensor.decomp._similarity_compress_svd_numba quimb.tensor.decomp._similarity_compress_biorthog quimb.tensor.decomp._similarity_compress_biorthog_numba quimb.tensor.decomp.similarity_compress quimb.tensor.decomp.isometrize_qr quimb.tensor.decomp.isometrize_svd quimb.tensor.decomp.isometrize_exp quimb.tensor.decomp.isometrize_cayley quimb.tensor.decomp.isometrize_modified_gram_schmidt quimb.tensor.decomp.isometrize_householder quimb.tensor.decomp.isometrize_torch_householder quimb.tensor.decomp.isometrize quimb.tensor.decomp.squared_op_to_reduced_factor quimb.tensor.decomp.compute_oblique_projectors quimb.tensor.decomp.compute_bondenv_projectors Module Contents --------------- .. py:function:: array_split(x, method='auto', absorb='auto', max_bond=None, cutoff=1e-10, cutoff_mode='rsum2', renorm=None, info=None, **kwargs) 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. :param x: The array or batch of arrays to split, of shape ``(..., m, n)``. :type x: array_like :param method: 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 :mod:`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. :type method: str, optional :param absorb: 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``. :type absorb: str or None, optional :param max_bond: The maximum bond dimension (number of singular values) to keep. ``None`` means no limit. :type max_bond: int or None, optional :param cutoff: Threshold for discarding singular values, only used by methods that support dynamic truncation. :type cutoff: float, optional :param cutoff_mode: 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. :type cutoff_mode: {'rsum2', 'rel', 'abs', 'sum2', 'rsum1', 'sum1'}, optional :param renorm: 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``. :type renorm: int or bool, optional :param info: 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"}``. :type info: dict or None, optional :param \*\*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``. .. py:function:: array_svals(x, method='svd', **kwargs) Compute the singular values of a 2D array without forming the full decomposition, using a registered singular value driver. :param x: The 2D array whose singular values to compute. :type x: array_like :param method: The method to use. Must have a registered singular value driver (e.g. ``'svd'`` or ``'svd:eig'``). :type method: str, optional :param \*\*kwargs: Additional keyword arguments passed to the underlying driver. :returns: **s** -- The singular values in descending order. :rtype: array .. py:data:: get_U_s_VH :value: None .. py:data:: get_s :value: 2 .. py:data:: get_Usq :value: -12 .. py:data:: get_VH :value: -11 .. py:data:: get_Us :value: -10 .. py:data:: get_Us_VH :value: -1 .. py:data:: get_Usq_sqVH :value: 0 .. py:data:: get_U_sVH :value: 1 .. py:data:: get_U :value: 10 .. py:data:: get_sVH :value: 11 .. py:data:: get_sqVH :value: 12 .. py:data:: _ABSORB_MAP .. py:data:: _ABSORB_TRANSPOSE_MAP .. py:data:: _RETURNS_LEFT_ABSORBS .. py:data:: _RETURNS_RIGHT_ABSORBS .. py:data:: cutoff_mode_abs :value: 1 .. py:data:: cutoff_mode_rel :value: 2 .. py:data:: cutoff_mode_sum2 :value: 3 .. py:data:: cutoff_mode_rsum2 :value: 4 .. py:data:: cutoff_mode_sum1 :value: 5 .. py:data:: cutoff_mode_rsum1 :value: 6 .. py:data:: _CUTOFF_MODE_MAP .. py:data:: _MAX_BOND_LOOKUP .. py:data:: _CUTOFF_LOOKUP .. py:data:: _RENORM_LOOKUP .. py:function:: parse_method(method) .. py:function:: parse_method_absorb(method='auto', absorb='auto', truncation=True) Parse the method and absorb options. Possibly resolve "auto" settings to defaults, and convert from string aliases to numeric codes. .. py:function:: parse_split_opts(method='auto', absorb='auto', max_bond=None, cutoff=1e-10, cutoff_mode='rsum2', renorm=None) Automatically select method and absorb, convert defaults and settings to numeric type for numba, and only supply valid options for given method. .. py:function:: parse_split_left_right_isom(method='auto', absorb='auto') Based on split method and absorb mode, determine whether the left and right factors are isometric, and can be marked as such. .. py:data:: _SPLIT_FNS .. py:data:: _SPLIT_VALUES_FNS .. py:data:: _DENSE_ONLY_METHODS .. py:data:: _DEFAULT_ABSORB .. py:function:: register_split_driver(name, sparse=False, default_absorb=get_Usq_sqVH) 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``. :param name: The name of the method, corresponding to the ``method`` argument of ``array_split``. :type name: str :param truncation: 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`). :type truncation: {"none", "static", "dynamic"}, optional :param sparse: Whether the method can handle sparse arrays directly. :type sparse: bool, optional .. py:function:: register_svals_driver(name) Decorator to register functions which can compute the singular values of a matrix without computing the full decomposition, which is used in ``array_svals``. :param name: The name of the method, corresponding to the ``method`` argument of ``array_svals``. :type name: str .. py:function:: dag_numba(x) .. py:function:: safe_inverse(s, cutoff) .. py:function:: safe_inverse_numba(s, cutoff) .. py:function:: rdmul(x, d) Right-multiplication a matrix by a vector representing a diagonal. .. py:function:: rdmul_numba(x, d) .. py:function:: rddiv(x, d) Right-multiplication of a matrix by a vector representing an inverse diagonal. .. py:function:: rddiv_numba(x, d) .. py:function:: ldmul(d, x) Left-multiplication a matrix by a vector representing a diagonal. .. py:function:: ldmul_numba(d, x) .. py:function:: lddiv(d, x) Left-multiplication of a matrix by a vector representing an inverse diagonal. .. py:function:: lddiv_numba(d, x) .. py:function:: sgn(x) Get the 'sign' of ``x``, such that ``x / sgn(x)`` is real and non-negative. .. py:function:: sgn_numba(x) .. py:function:: sgn_tf(x) .. py:function:: _do_absorb(U, s, VH, absorb=None, xp=None) .. py:function:: _do_absorb_numba(U, s, VH, absorb) .. py:function:: _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) Give full SVD decomposion result ``U``, ``s``, ``VH``, optionally trim, renormalize, and absorb the singular values. See ``svd_truncated`` for details. .. py:function:: svd_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None) Singular value decomposition of raw 2d array ``x``, with optional truncation based on `max_bond` and/or dynamically on `cutoff`. :param cutoff: Singular value cutoff threshold, if ``cutoff <= 0.0``, then only ``max_bond`` is used. :type cutoff: float, optional :param cutoff_mode: 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``. :type cutoff_mode: {1, 2, 3, 4, 5, 6}, optional :param max_bond: An explicit maximum bond dimension, use -1 for none. :type max_bond: int, optional :param absorb: 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. :type absorb: int or None, optional :param renorm: Whether to renormalize the kept singular values. ``0`` means no renormalization, ``1`` maintains the trace norm, ``2`` maintains the Frobenius norm. :type renorm: int, optional :param info: If a dict is passed, store truncation info in the dict. Currently only supports the key 'error' for the truncation error. :type info: dict or None, optional :returns: * **left** (*array_like or None*) * **s** (*array_like or None*) * **right** (*array_like or None*) .. py:function:: _compute_number_svals_to_keep_numba(s, cutoff, cutoff_mode) Find the number of singular values to keep of ``s`` given ``cutoff`` and ``cutoff_mode``. .. py:function:: _compute_svals_renorm_factor_numba(s, n_chi, renorm) 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. .. py:function:: _trim_and_renorm_svd_result_numba(U, s, VH, cutoff, cutoff_mode, max_bond, absorb, renorm, use_abs=False, calc_error=False) Accelerated version of ``_trim_and_renorm_svd_result``. .. py:function:: svd_truncated_numba(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, calc_error=False) Accelerated version of ``svd_truncated`` for numpy arrays. .. py:function:: svd_truncated_numpy(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None) Numpy version of ``svd_truncated``, trying the accelerated version first, then falling back to the more stable scipy version. .. py:function:: svd_truncated_lazy(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) .. py:function:: svdvals(x) SVD-decomposition, but return singular values only. .. py:function:: svd_via_eig(x, absorb=None, max_bond=-1, descending=True, right=None) 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. :param x: The 2d array to decompose. :type x: array-like :param absorb: 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. :type absorb: str or None, optional :param max_bond: An explicit maximum bond dimension, use -1 for no truncation. :type max_bond: int, optional :param descending: Whether to return singular values in descending order, default False. :type descending: bool, optional :param right: 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``. :type right: bool, optional :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. .. py:function:: svd_via_eig_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, info=None) 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`. :param cutoff: Singular value cutoff threshold, if ``cutoff <= 0.0``, then only ``max_bond`` is used. :type cutoff: float, optional :param cutoff_mode: 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``. :type cutoff_mode: {1, 2, 3, 4, 5, 6}, optional :param max_bond: An explicit maximum bond dimension, use -1 for none. :type max_bond: int, optional :param absorb: 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. :type absorb: int or None, optional :param renorm: Whether to renormalize the kept singular values. ``0`` means no renormalization, ``1`` maintains the trace norm, ``2`` maintains the Frobenius norm. :type renorm: int, optional :param info: If a dict is passed, store truncation info in the dict. Currently only supports the key 'error' for the truncation error. :type info: dict or None, optional :returns: * **left** (*array_like or None*) * **s** (*array_like or None*) * **right** (*array_like or None*) .. py:function:: _svd_via_eig_numba(x, absorb=get_U_s_VH, max_bond=-1, descending=True, right=None) 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``. :param x: The 2d array to decompose. :type x: array-like :param absorb: Numeric absorb code controlling what to compute / return. :type absorb: int or None, optional :param max_bond: An explicit maximum bond dimension, use -1 for no truncation. :type max_bond: int, optional :param descending: Whether to return singular values in descending order. :type descending: bool, optional :returns: * **U** (*array or None*) * **s** (*array or None*) * **VH** (*array or None*) .. py:function:: _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) SVD-split via eigen-decomposition, with optional dynamic truncation. Uses ``_svd_via_eig_numba`` shortcuts when the full spectrum is not needed. .. py:function:: 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) .. py:function:: svdvals_eig(x) SVD-decomposition via eigen, but return singular values only. .. py:function:: 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) 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. :param x: The 2d array to decompose. :type x: array_like :param max_bond: 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. :type max_bond: int :param absorb: 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. :type absorb: str or None, optional :param oversample: Extra dimensions for the random sketch to improve accuracy, default 10. :type oversample: int, optional :param num_iterations: Number of power iterations to improve accuracy, default 2. :type num_iterations: int, optional :param method_reduced: The decomposition method to use for the reduced matrix, e.g. ``'svd'``, ``'svd:eig'``, etc. Default is ``'svd'``. :type method_reduced: str, optional :param method_lorthog: The decomposition method to use for forming the orthonormal basis of the random sketch, e.g. ``'qr'``, ``'svd:eig'``, ``'svd'``, etc. Default is ``'qr'``. :type method_lorthog: str, optional :param right: Whether to sketch from the right or left. If None (default), then will choose based on value of ``absorb``. :type right: bool, optional :param lorthog_opts: Extra options to pass to the decomposition method for forming the orthonormal basis of the random sketch. :type lorthog_opts: dict or None, optional :param reduced_opts: Extra options to pass to the decomposition method for the reduced matrix. :type reduced_opts: dict or None, optional :param seed: Random seed or existing generator for reproducibility. :type seed: int, Generator or None, optional :returns: * **left** (*array_like or None*) * **s** (*array_like or None*) * **right** (*array_like or None*) .. py:function:: _with_diag_shift(x, xp, shift=0.0) .. py:function:: _with_diag_shift_numba(x, shift=0.0) .. py:function:: eigh_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0, positive=0, shift=False) SVD-like decomposition using hermitian eigen-decomposition, only works if ``x`` is hermitian. :param shift: 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``. :type shift: bool or float, optional :returns: * **left** (*array_like or None*) * **s** (*array_like or None*) * **right** (*array_like or None*) .. py:function:: 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) SVD-decomposition, using hermitian eigen-decomposition, only works if ``x`` is hermitian. .. py:function:: 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) .. py:function:: qr_stabilized(x, absorb=get_U_sVH, stabilized=True, **kwargs) QR-decomposition, with stabilized R factor. :param x: The 2d array to decompose. :type x: array_like :param absorb: 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. :type absorb: str or int, optional :param stabilized: 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. :type stabilized: bool, optional :param 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). .. py:function:: _qr_stabilized_numba(x, absorb=get_U_sVH, stabilized=True) .. py:function:: _lq_stabilized_numba(x, absorb=get_Us_VH, stabilized=True) .. py:function:: qr_stabilized_numpy(x, absorb=get_U_sVH, stabilized=True, **kwargs) .. py:function:: qr_stabilized_lazy(x, absorb=get_U_sVH, **kwargs) .. py:function:: _cholesky_maybe_with_diag_shift(x, absorb=get_Usq_sqVH, shift=0.0) .. py:function:: cholesky_regularized(x, absorb=get_Usq_sqVH, shift=True) Cholesky decomposition, only works if ``x`` is positive definite. The ``shift`` parameter controls optional regularization for close to singular matrices. :param x: The 2D array to decompose. :type x: array_like :param absorb: 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) :type absorb: int, optional :param shift: 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``. :type shift: "auto", bool or float, optional :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). .. py:function:: _cholesky_regularized_numba(x, absorb=get_Usq_sqVH, shift=-1.0) .. py:function:: cholesky_regularized_numpy(x, absorb=get_Usq_sqVH, shift=True) .. py:function:: qr_via_cholesky(x, absorb=get_Us_VH, shift=True, solve_triangular=True) Perform a QR-like or LQ-like decomposition via Cholesky decomposition of the Gram matrix. .. py:function:: _choose_k(x, cutoff, max_bond) Choose the number of singular values to target. .. py:function:: svds(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) 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*) .. py:function:: isvd(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) 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*) .. py:function:: _rsvd_numpy(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) .. py:function:: rsvd(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) 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*) .. py:function:: eigsh(x, cutoff=0.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) 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*) .. py:function:: lu_truncated(x, cutoff=-1.0, cutoff_mode=cutoff_mode_rsum2, max_bond=-1, absorb=get_Usq_sqVH, renorm=0) 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). .. py:function:: polar_right(x) 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). .. py:function:: polar_right_numba(x) .. py:function:: polar_left(x) 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). .. py:function:: polar_left_numba(x) .. py:function:: _similarity_compress_eig(X, max_bond, renorm) .. py:function:: _similarity_compress_eig_numba(X, max_bond, renorm) .. py:function:: _similarity_compress_eigh(X, max_bond, renorm) .. py:function:: _similarity_compress_eigh_numba(X, max_bond, renorm) .. py:function:: _similarity_compress_svd(X, max_bond, renorm, asymm) .. py:function:: _similarity_compress_svd_numba(X, max_bond, renorm, asymm) .. py:function:: _similarity_compress_biorthog(X, max_bond, renorm) .. py:function:: _similarity_compress_biorthog_numba(X, max_bond, renorm) .. py:data:: _similarity_compress_fns .. py:function:: similarity_compress(X, max_bond, renorm=False, method='eigh') .. py:function:: isometrize_qr(x) Perform isometrization using the QR decomposition. .. py:function:: isometrize_svd(x) Perform isometrization using the SVD decomposition. .. py:function:: isometrize_exp(x) Perform isometrization using anti-symmetric matrix exponentiation. .. math:: U_A = \exp \left( X - X^\dagger \right) If ``x`` is rectangular it is completed with zeros first. .. py:function:: isometrize_cayley(x) Perform isometrization using an anti-symmetric Cayley transform. .. math:: U_A = (I + \dfrac{A}{2})(I - \dfrac{A}{2})^{-1} where :math:`A = X - X^\dagger`. If ``x`` is rectangular it is completed with zeros first. .. py:function:: isometrize_modified_gram_schmidt(A) Perform isometrization explicitly using the modified Gram Schmidt procedure (this is slow but a useful reference). .. py:function:: isometrize_householder(X) .. py:function:: isometrize_torch_householder(x) Isometrize ``x`` using the Householder reflection method, as implemented by the ``torch_householder`` package. .. py:data:: _ISOMETRIZE_METHODS .. py:function:: isometrize(x, method='qr') Generate an isometric (or unitary if square) / orthogonal matrix from array ``x``. :param x: The matrix to project into isometrix form. :type x: array :param method: 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. :type method: str, optional :returns: **Q** -- The isometrization / orthogonalization of ``x``. :rtype: array .. py:function:: squared_op_to_reduced_factor(x2, dl, dr, right=True, method='eigh', **kwargs) 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``. :param x2: The squared operator, either ``dag(x) @ x`` or ``x @ dag(x)``. :type x2: array :param dl: The original left dimension of the unsquared operator ``x``. :type dl: int :param dr: The original right dimension of the unsquared operator ``x``. :type dr: int :param right: Whether to compute the right factor (``s @ Vdag``) or left factor (``U @ s``). :type right: bool, optional :param method: The method to use for the decomposition. :type method: str, optional :param 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``. :rtype: array .. py:function:: compute_oblique_projectors(Rl, Rr, max_bond=None, cutoff=0.0, absorb='both', cutoff_mode='rsum2', method='svd', **compress_opts) 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: .. math:: 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: .. math:: A' = Q_L P_L P_R' Q_R :param Rl: The left reduced factor matrix. :type Rl: array :param Rr: The right reduced factor matrix. :type Rr: array :param max_bond: The maximum bond dimension to compress to. :type max_bond: int, optional :param cutoff: The singular value cutoff to use. :type cutoff: float, optional :param absorb: 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. :type absorb: str or None, optional :param cutoff_mode: The cutoff mode to use when applying the cutoff. :type cutoff_mode: str, optional :param method: The method to use for the SVD decomposition when computing the projectors. :type method: str, optional :param 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. .. py:function:: 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) 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. :param E: The 4D environment tensor of a bond. The dimensions should be arranged as (ket-left, ket-right, bra-left, bra-right). :type E: array :param max_bond: The maximum bond dimension to compress to. :type max_bond: int :param cutoff: The singular value cutoff to use. :type cutoff: float, optional :param absorb: 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. :type absorb: str or None, optional :param max_iterations: The maximum number of iterations to use when fitting the projectors. :type max_iterations: int, optional :param tol: The target tolerance to reach when fitting the projectors. :type tol: float, optional :param solver: 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. :type solver: {'solve', None, str}, optional :param solver_maxiter: The maximum number of iterations to use for the *inner* solver, i.e. per fitting step, only for iterative `solver` args. :type solver_maxiter: int, optional :param prenormalize: Whether to prenormalize the environment tensor such that its full contraction before compression is 1. Recommended for stability when the normalization does not matter. :type prenormalize: bool, optional :param condition: 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. :type condition: bool or "iso", optional :param enforce_pos: Whether to enforce the environment tensor to be positive semi-definite by symmetrizing and clipping negative eigenvalues. Recommended for stability. :type enforce_pos: bool, optional :param pos_smudge: The value to clip negative eigenvalues to when enforcing positivity, relative to the largest eigenvalue. :type pos_smudge: float, optional :param init: 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. :type init: {'svd', 'eigh', 'random', 'reduced'}, optional :param info: 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. :type info: dict, optional :returns: * **Pl** (*array*) -- The left projector. * **Pr** (*array*) -- The right projector.