symmray.sparse.sparse_array_common ================================== .. py:module:: symmray.sparse.sparse_array_common .. autoapi-nested-parse:: Methods that apply to abelian arrays with block sparse structure, both fermionic and bosonic. Attributes ---------- .. autoapisummary:: symmray.sparse.sparse_array_common._fuseinfos symmray.sparse.sparse_array_common._fuseinfo_cache_maxsize symmray.sparse.sparse_array_common._fuseinfo_cache_maxsectors symmray.sparse.sparse_array_common._fi_missed symmray.sparse.sparse_array_common._fi_hit symmray.sparse.sparse_array_common._fi_missed_too_long symmray.sparse.sparse_array_common._CUTOFF_MODE_MAP symmray.sparse.sparse_array_common._DEFAULT_TENSORDOT_MODE Classes ------- .. autoapisummary:: symmray.sparse.sparse_array_common.SparseArrayCommon Functions --------- .. autoapisummary:: symmray.sparse.sparse_array_common.permuted symmray.sparse.sparse_array_common.replace_with_seq symmray.sparse.sparse_array_common.accum_for_split symmray.sparse.sparse_array_common.calc_fuse_group_info symmray.sparse.sparse_array_common.calc_fuse_block_info symmray.sparse.sparse_array_common.print_fuseinfo_cache_stats symmray.sparse.sparse_array_common.cached_fuse_block_info symmray.sparse.sparse_array_common._fuse_blocks_via_insert symmray.sparse.sparse_array_common._fuse_blocks_via_concat symmray.sparse.sparse_array_common.argsort symmray.sparse.sparse_array_common.calc_sub_max_bonds symmray.sparse.sparse_array_common.truncate_svd_result_blocksparse symmray.sparse.sparse_array_common._tensordot_blockwise symmray.sparse.sparse_array_common.drop_misaligned_sectors symmray.sparse.sparse_array_common._tensordot_via_fused symmray.sparse.sparse_array_common.get_default_tensordot_mode symmray.sparse.sparse_array_common.set_default_tensordot_mode symmray.sparse.sparse_array_common.default_tensordot_mode symmray.sparse.sparse_array_common.tensordot_abelian Module Contents --------------- .. py:function:: permuted(it, perm) Return a tuple of the elements in ``it`` (which should be indexable), in the order given by ``perm``. .. rubric:: Examples >>> permuted(['a', 'b', 'c', 'd'], [3, 1, 0, 2]) ('d', 'b', 'a', 'c') .. py:function:: replace_with_seq(it, index, seq) Return a tuple, with the item at ``index`` in ``it`` replaced by the items in ``seq``. .. py:function:: accum_for_split(sizes) Take a sequence of block sizes and return the sequence of linear partitions, suitable for use with the ``split`` function. .. py:function:: calc_fuse_group_info(axes_groups, duals) Calculate the fusing information just to do with axes groups (not any specific blocks). .. py:function:: calc_fuse_block_info(self, axes_groups) Calculate fusing information for a specific set of sectors/blocks. .. py:data:: _fuseinfos .. py:data:: _fuseinfo_cache_maxsize .. py:data:: _fuseinfo_cache_maxsectors .. py:data:: _fi_missed :value: 0 .. py:data:: _fi_hit :value: 0 .. py:data:: _fi_missed_too_long :value: 0 .. py:function:: print_fuseinfo_cache_stats() .. py:function:: cached_fuse_block_info(self, axes_groups) Calculating fusing block information is expensive, so cache the results. This is a LRU cache that also skips caching if there are too many sectors. .. py:function:: _fuse_blocks_via_insert(sector_block_pairs, num_groups, group_singlets, perm, position, new_indices, blockmap, _transpose, _reshape, _zeros, zeros_kwargs) Perform the actual block fusing by inserting blocks into a new array. .. py:function:: _fuse_blocks_via_concat(old_indices, sector_block_pairs, num_groups, group_singlets, perm, position, axes_before, axes_after, new_axes, new_indices, blockmap, backend, _transpose, _reshape, _zeros, zeros_kwargs) Perform the actual block fusing, by recusively concatenating blocks (more compatible with e.g. autodiff since requires no inplace updates). .. py:class:: SparseArrayCommon .. py:method:: _init_abelian(indices, charge=None, blocks=(), symmetry=None, label=None) .. py:method:: _new_with_abelian(indices, charge, blocks, label=None) .. py:method:: _copy_abelian() Copy this abelian block sparse array. .. py:method:: _copy_with_abelian(indices=None, charge=None, blocks=None) A copy of this block array with some attributes replaced. Note that checks are not performed on the new properties, this is intended for internal use. .. py:method:: _modify_abelian(indices=None, charge=None, blocks=None) Modify this block array in place with some attributes replaced. Note that checks are not performed on the new properties, this is intended for internal use. .. py:method:: _to_pytree_abelian() .. py:property:: label The label of the array, possibly used for ordering odd parity fermionic modes. .. py:property:: sizes The sizes of each index. .. py:property:: charges The possible charges of each index. .. py:property:: charge The total charge of the array. .. py:property:: shape The shape of the array, i.e. product of total size of each index. .. py:property:: size The number of possible elements in this array, if it was dense. .. py:property:: ndim The number of dimensions/indices. .. py:method:: sync_charges(inplace=False) Given the blocks currently present, adjust the index chargemaps to match only those charges present in at least one sector. .. py:method:: is_valid_sector(sector) Check if a sector is valid for the block array, i.e., whether the total symmetry charge is satisfied. .. py:method:: gen_valid_sectors() Generate all valid sectors for the block array. .. py:method:: get_sparsity() Return the sparsity of the array, i.e. the number of blocks divided by the number of possible blocks. .. py:method:: get_block_shape(sector) Get the shape of the block corresponding to a given sector. .. py:method:: fill_missing_blocks() Insert any missing blocks for valid sectors with zeros, resulting in a sparsity of 1. .. py:method:: drop_missing_blocks() Drop any present blocks that are all zero, resulting in a sparsity possibly less that 1. .. py:method:: from_fill_fn(fill_fn, indices, charge=None, symmetry=None, **kwargs) :classmethod: Generate a block array from a filling function. Every valid sector will be filled with the result of the filling function. :param fill_fn: The filling function, with signature ``fill_fn(shape)``. :type fill_fn: callable :param indices: The indices of the array. :type indices: tuple[BlockIndex] :param charge: The total charge of the array. If not given, it will be taken as the identity / zero element. :type charge: hashable :param symmetry: The symmetry of the array, if not using a specific symmetry class. :type symmetry: str or Symmetry, optional :rtype: SparseArrayCommon .. py:method:: random(indices, charge=None, seed=None, dist='normal', dtype='float64', scale=1.0, loc=0.0, symmetry=None, **kwargs) :classmethod: Create a block array with random values. :param indices: The indices of the array. :type indices: tuple[BlockIndex] :param charge: The total charge of the array. If not given, it will be taken as the identity / zero element. :type charge: hashable :param seed: The random seed or generator to use. :type seed: None, int or numpy.random.Generator :param dist: The distribution to use. Can be one of ``"normal"``, ``"uniform"``, etc., see :func:`numpy.random.default_rng` for details. :type dist: str :param symmetry: The symmetry of the array, if not using a specific symmetry class. :type symmetry: str or Symmetry, optional :rtype: SparseArrayCommon .. py:method:: check() Check that all the block sizes and charges are consistent. .. py:method:: check_chargemaps_aligned() Check that the chargemaps of the indices are consistent with the block sectors. .. py:method:: check_with(other, *args) Check that this block array is compatible with another, that is, that the indices match and the blocks are compatible. :param other: The other array or vector to compare to. :type other: SparseArrayCommon or BlockVector :param \*args: The axes to compare, if ``other`` is a vector, the axis to compare with. If ``other`` is an array, then `axes_a` and `axes_b` should be given as if for a tensordot. .. py:method:: _allclose_abelian(other, **allclose_opts) Test whether this ``SparseArrayCommon`` is close to another, i.e. has all the same sectors, and corresponding arrays are close. :param other: The other array to compare to. :type other: SparseArrayCommon :param allclose_opts: Keyword arguments to pass to `allclose`. :rtype: bool .. py:method:: _test_allclose_abelian(other, **allclose_opts) Assert that this ``SparseArrayCommon`` is close to another, that is, has all the same sectors, and the corresponding arrays are close. Unlike `allclose`, this raises an AssertionError with details if not. :param other: The other array to compare to. :type other: SparseArrayCommon :param allclose_opts: Keyword arguments to pass to `allclose`. :raises AssertionError: If the arrays are not close. .. py:method:: from_blocks(blocks, duals, charge=None, symmetry=None, **kwargs) :classmethod: Create a block array from a dictionary of blocks and sequence of duals. :param blocks: A mapping of each 'sector' (tuple of charges) to the data array. :type blocks: dict[tuple[hashable], array_like] :param duals: The dual-ness of each index, or an explicitly given sequence of already constructed block sparse indices. Note in the latter case no checks for consistency are performed. :type duals: tuple[bool] or tuple[BlockIndex] :param charge: The total charge of the array. If not given, it will be taken computed from the first sector, or set to the identity / zero element if no sectors are given. :type charge: hashable :param symmetry: The symmetry of the array, if not using a specific symmetry class. :type symmetry: str or Symmetry, optional :param kwargs: Additional keyword arguments to pass to the constructor. :rtype: SparseArrayCommon .. py:method:: from_dense(array, index_maps, duals, charge=None, symmetry=None, invalid_sectors='warn', **kwargs) :classmethod: Create a block array from a dense array by supplying a mapping for each axis that labels each linear index with a particular charge. :param array: The dense array. :type array: array_like :param index_maps: For each dimension, the sequence mapping linear index to charge sector. There should be ``ndim`` such mappings, each of length ``shape[i]``. :type index_maps: Sequence[Sequence[hashable]] :param duals: The dualness of each index. :type duals: tuple[bool] :param charge: The total charge of the array. If not given, it will be taken as the identity / zero element. :type charge: hashable :param symmetry: The symmetry of the array, if not using a specific symmetry class. :type symmetry: str or Symmetry, optional :param invalid_sectors: How to handle invalid sectors that have non-zero entries. :type invalid_sectors: {"warn", "raise", "ignore"}, optional :rtype: SparseArrayCommon .. py:method:: _transpose_abelian(axes=None, inplace=False) Transpose this block sparse abelian array. :param axes: A permutation of the axes to transpose the array by. If None, the axes will be reversed. :type axes: tuple[int, ...] | None, optional :param inplace: Whether to perform the operation inplace or return a new array. :type inplace: bool, optional :rtype: SparseArrayCommon .. py:method:: _conj_abelian(inplace=False) -> SparseArrayCommon Return the complex conjugate of this block array, including the indices. .. py:method:: select_charge(axis, charge, subselect=None, inplace=False) Drop all but the specified charge along the specified axis. Note the axis is not removed, it is simply restricted to a single charge. :param axis: The axis along which to select the charge. :type axis: int :param charge: The charge to select along the specified axis. :type charge: int :param subselect: If provided, a range of indices within the selected charge block to keep. If not provided, the entire block is kept. :type subselect: slice or array_like, optional :param inplace: Whether to perform the operation inplace or return a new array. :type inplace: bool, optional :rtype: SparseArrayCommon .. py:method:: _squeeze_abelian(axis=None, inplace=False) Squeeze the block array, removing axes of size 1. :param axis: The axes to squeeze. If not given, all axes of size 1 will be removed. :type axis: int or sequence of int, optional :param inplace: Whether to perform the operation inplace. :type inplace: bool, optional :rtype: SparseArrayCommon .. py:method:: isel(axis, idx, inplace=False) Select a single (linear) index along the specified axis. The linear index is first converted to the corresponding charge and offset within that charge sector. :param axis: The axis to select along. :type axis: int :param idx: The linear index to select. :type idx: int :param inplace: Whether to perform the operation inplace or return a new array. :type inplace: bool, optional .. py:method:: expand_dims(axis, c=None, dual=None, inplace=False) Expand the shape of an abelian array. :param axis: The position along which to expand. :type axis: int :param c: The charge to insert at the new axis. If not given, a zero charge will be inserted. :type c: hashable, optional :param dual: The dual-ness of the new index. If not given, it will be inherited from the axis before or after, if any. If there is no axis before or after, it will default to `False`. :type dual: bool, optional :param inplace: Whether to perform the operation inplace. :type inplace: bool, optional :rtype: SparseArrayCommon .. py:method:: _fuse_core_abelian(*axes_groups, mode='auto', inplace=False) -> SparseArrayCommon .. py:method:: _unfuse_abelian(axis, inplace=False) .. py:method:: _matmul_abelian(other, preserve_array=False) .. py:method:: _trace_abelian() Compute the trace of the block array, assuming it is a square matrix. .. py:method:: multiply_diagonal(v: symmray.sparse.sparse_vector.BlockVector, axis, power=1, inplace=False) Multiply this block array by a vector as if contracting a diagonal matrix along the given axis. :param v: The vector to contract with. :type v: BlockVector :param axis: The axis along which to contract. :type axis: int :param power: The power to raise the diagonal elements to. :type power: int or float, optional :param inplace: Whether to perform the operation inplace. :type inplace: bool, optional :rtype: SparseArrayCommon .. py:method:: ldmul(v: symmray.sparse.sparse_vector.BlockVector, inplace=False) .. py:method:: rdmul(v: symmray.sparse.sparse_vector.BlockVector, inplace=False) .. py:method:: lddiv(v: symmray.sparse.sparse_vector.BlockVector, inplace=False) .. py:method:: rddiv(v: symmray.sparse.sparse_vector.BlockVector, inplace=False) .. py:method:: align_axes(other, axes) Align the axes of this block array with another, by dropping any sectors that are not aligned along the given axes, these can then be fused into a single axis that matches on both arrays. :param other: The other array to align with. :type other: SparseArrayCommon :param axes: The pairs of axes to align, given as tuples of the corresponding axes in this and the other array, a la tensordot. :type axes: tuple[tuple[int]] .. py:method:: _einsum_abelian(eq, preserve_array=False) Einsum for abelian arrays, currently only single term. :param eq: The einsum equation, e.g. "abcb->ca". The output indices must be specified and only trace and permutations are allowed. :type eq: str :param preserve_array: If tracing to a scalar, whether to return an AbelainArray object with no indices, or simply scalar itself (the default). :type preserve_array: bool, optional :rtype: SparseArrayCommon or scalar .. py:method:: _tensordot_abelian(other, axes=2, mode='auto', preserve_array=False) Tensordot between two block sparse abelian symmetric arrays. :param a: The arrays to be contracted. :type a: SparseArrayCommon :param b: The arrays to be contracted. :type b: SparseArrayCommon :param axes: The axes to contract. If an integer, the last ``axes`` axes of ``a`` will be contracted with the first ``axes`` axes of ``b``. If a tuple, the axes to contract in ``a`` and ``b`` respectively. :type axes: int or tuple[int] :param mode: The mode to use for the contraction. If "auto", it will choose between "fused" and "blockwise" based on the number of axes to contract. :type mode: {"auto", "fused", "blockwise"} :param preserve_array: Whether to return a scalar if the result is a scalar. :type preserve_array: bool, optional .. py:method:: _to_dense_abelian() Convert this block array to a dense array. .. py:method:: to_flat() Convert this block sparse backend abelian or fermionic array to a flat backend abelian or fermionic array. .. py:method:: _split_abelian_full_spectrum(*, fn=None, charge_side='auto', **kwargs) Helper method for decomposition methods involving dynamic truncation, which require the full spectrum to be computed first since truncation sizes will depend on all blocks. .. py:method:: _split_abelian(*, fn=None, charge_side='auto', **kwargs) Main driver method for decomposing sparse abelian arrays. This handles mapping the split function over the blocks, and then wrapping the output blocks back into new SparseArray objects. :param fn: A custom function to perform the split on each block, which should take an array and return a tuple of (left, s, right) arrays. If not given, :func:`quimb.tensor.array_split` will be used. :type fn: callable, optional :param charge_side: Which side the array charge and label should be associated with. If "auto", it will be chosen based on the value of `absorb` to be the isometric side (e.g. "right" for LQ-like absorb="left") else "left" by default. :type charge_side: {"left", "right", "auto"}, optional :param kwargs: Additional keyword arguments to pass to the split function. :returns: * **left** (*SparseArrayCommon or None*) -- The left factor, if any. * **s** (*BlockVector or None*) -- The singular (or possibly eigen) values, if any. * **right** (*SparseArrayCommon or None*) -- The right factor, if any. .. py:method:: _eigh_abelian() -> tuple[symmray.sparse.sparse_vector.BlockVector, SparseArrayCommon] .. py:method:: _cholesky_abelian(upper=False, shift=True, **kwargs) -> SparseArrayCommon Cholesky decomposition of a 2D block-sparse abelian array. :param upper: Whether to return the upper triangular Cholesky factor. Default is False, returning the lower triangular factor. :type upper: bool, optional :param shift: Diagonal regularization shift. If True or negative, auto-compute from dtype machine epsilon. The shift is always applied as a relative shift scaled by the trace of each block. Default is True. :type shift: float, optional :returns: **l_or_r** -- The Cholesky factor. :rtype: SparseArrayCommon .. py:method:: _solve_abelian(b: SparseArrayCommon) -> SparseArrayCommon .. py:function:: argsort(seq) .. py:function:: calc_sub_max_bonds(sizes, max_bond) .. py:data:: _CUTOFF_MODE_MAP .. py:function:: truncate_svd_result_blocksparse(U: SparseArrayCommon, s: symmray.sparse.sparse_vector.BlockVector, VH: SparseArrayCommon, cutoff: float, cutoff_mode: int, max_bond: int, absorb: int | str | None, renorm: int, backend: str = None, use_abs: bool = False) -> tuple[SparseArrayCommon, symmray.sparse.sparse_vector.BlockVector, SparseArrayCommon] .. py:function:: _tensordot_blockwise(a: SparseArrayCommon, b: SparseArrayCommon, left_axes: tuple[int, Ellipsis], axes_a: tuple[int, Ellipsis], axes_b: tuple[int, Ellipsis], right_axes: tuple[int, Ellipsis]) Perform a tensordot between two block arrays, performing the contraction of each pair of aligned blocks separately. .. py:function:: drop_misaligned_sectors(a: SparseArrayCommon, b: SparseArrayCommon, axes_a: tuple[int, Ellipsis], axes_b: tuple[int, Ellipsis], inplace=False) -> tuple[SparseArrayCommon, SparseArrayCommon] Eagerly drop misaligned sectors of ``a`` and ``b`` so that they can be contracted via fusing. :param a: The arrays to be contracted. :type a: SparseArrayCommon :param b: The arrays to be contracted. :type b: SparseArrayCommon :param axes_a: The axes that will be contracted, defined like in `tensordot`. :type axes_a: tuple[int] :param axes_b: The axes that will be contracted, defined like in `tensordot`. :type axes_b: tuple[int] :returns: **a, b** -- The new arrays with misaligned sectors dropped. :rtype: SparseArrayCommon .. py:function:: _tensordot_via_fused(a, b, left_axes, axes_a, axes_b, right_axes) Perform a tensordot between two block arrays, by first fusing both into matrices and unfusing afterwards. :param a: The arrays to be contracted. :type a: SparseArrayCommon :param b: The arrays to be contracted. :type b: SparseArrayCommon :param left_axes: The axes of ``a`` that will not be contracted. :type left_axes: tuple[int] :param axes_a: The axes that will be contracted, defined like in `tensordot`. :type axes_a: tuple[int] :param axes_b: The axes that will be contracted, defined like in `tensordot`. :type axes_b: tuple[int] :param right_axes: The axes of ``b`` that will not be contracted. :type right_axes: tuple[int] .. py:data:: _DEFAULT_TENSORDOT_MODE :value: 'auto' .. py:function:: get_default_tensordot_mode() Get the current default tensordot mode. .. py:function:: set_default_tensordot_mode(mode) Set the default tensordot mode. :param mode: The mode to use for the contraction. None is no-op. :type mode: {"auto", "fused", "blockwise", None} .. py:function:: default_tensordot_mode(mode) Context manager to temporarily change the default tensordot mode. :param mode: The mode to use for the contraction. :type mode: {"auto", "fused", "blockwise"} .. py:function:: tensordot_abelian(a, b, axes=2, mode='auto', preserve_array=False) Tensordot between two block sparse abelian symmetric arrays. :param a: The arrays to be contracted. :type a: SparseArrayCommon :param b: The arrays to be contracted. :type b: SparseArrayCommon :param axes: The axes to contract. If an integer, the last ``axes`` axes of ``a`` will be contracted with the first ``axes`` axes of ``b``. If a tuple, the axes to contract in ``a`` and ``b`` respectively. :type axes: int or tuple[int] :param mode: The mode to use for the contraction. If "auto", it will choose between "fused" and "blockwise" based on the number of axes to contract. :type mode: {"auto", "fused", "blockwise"} :param preserve_array: Whether to return a scalar if the result is a scalar. :type preserve_array: bool, optional