symmray.sparse.sparse_array_common

Methods that apply to abelian arrays with block sparse structure, both fermionic and bosonic.

Attributes

Classes

Functions

permuted(it, perm)

Return a tuple of the elements in it (which should be indexable),

replace_with_seq(it, index, seq)

Return a tuple, with the item at index in it replaced by the

accum_for_split(sizes)

Take a sequence of block sizes and return the sequence of linear

calc_fuse_group_info(axes_groups, duals)

Calculate the fusing information just to do with axes groups

calc_fuse_block_info(self, axes_groups)

Calculate fusing information for a specific set of sectors/blocks.

print_fuseinfo_cache_stats()

cached_fuse_block_info(self, axes_groups)

Calculating fusing block information is expensive, so cache the results.

_fuse_blocks_via_insert(sector_block_pairs, ...)

Perform the actual block fusing by inserting blocks into a new array.

_fuse_blocks_via_concat(old_indices, ...)

Perform the actual block fusing, by recusively concatenating blocks

argsort(seq)

calc_sub_max_bonds(sizes, max_bond)

truncate_svd_result_blocksparse(...)

_tensordot_blockwise(a, b, left_axes, axes_a, axes_b, ...)

Perform a tensordot between two block arrays, performing the contraction

drop_misaligned_sectors(→ tuple[SparseArrayCommon, ...)

Eagerly drop misaligned sectors of a and b so that they can be

_tensordot_via_fused(a, b, left_axes, axes_a, axes_b, ...)

Perform a tensordot between two block arrays, by first fusing both into

get_default_tensordot_mode()

Get the current default tensordot mode.

set_default_tensordot_mode(mode)

Set the default tensordot mode.

default_tensordot_mode(mode)

Context manager to temporarily change the default tensordot mode.

tensordot_abelian(a, b[, axes, mode, preserve_array])

Tensordot between two block sparse abelian symmetric arrays.

Module Contents

symmray.sparse.sparse_array_common.permuted(it, perm)[source]

Return a tuple of the elements in it (which should be indexable), in the order given by perm.

Examples

>>> permuted(['a', 'b', 'c', 'd'], [3, 1, 0, 2])
('d', 'b', 'a', 'c')
symmray.sparse.sparse_array_common.replace_with_seq(it, index, seq)[source]

Return a tuple, with the item at index in it replaced by the items in seq.

symmray.sparse.sparse_array_common.accum_for_split(sizes)[source]

Take a sequence of block sizes and return the sequence of linear partitions, suitable for use with the split function.

symmray.sparse.sparse_array_common.calc_fuse_group_info(axes_groups, duals)[source]

Calculate the fusing information just to do with axes groups (not any specific blocks).

symmray.sparse.sparse_array_common.calc_fuse_block_info(self, axes_groups)[source]

Calculate fusing information for a specific set of sectors/blocks.

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 = 0
symmray.sparse.sparse_array_common._fi_hit = 0
symmray.sparse.sparse_array_common._fi_missed_too_long = 0
symmray.sparse.sparse_array_common.print_fuseinfo_cache_stats()[source]
symmray.sparse.sparse_array_common.cached_fuse_block_info(self, axes_groups)[source]

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.

symmray.sparse.sparse_array_common._fuse_blocks_via_insert(sector_block_pairs, num_groups, group_singlets, perm, position, new_indices, blockmap, _transpose, _reshape, _zeros, zeros_kwargs)[source]

Perform the actual block fusing by inserting blocks into a new array.

symmray.sparse.sparse_array_common._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)[source]

Perform the actual block fusing, by recusively concatenating blocks (more compatible with e.g. autodiff since requires no inplace updates).

class symmray.sparse.sparse_array_common.SparseArrayCommon[source]
_init_abelian(indices, charge=None, blocks=(), symmetry=None, label=None)[source]
_new_with_abelian(indices, charge, blocks, label=None)[source]
_copy_abelian()[source]

Copy this abelian block sparse array.

_copy_with_abelian(indices=None, charge=None, blocks=None)[source]

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.

_modify_abelian(indices=None, charge=None, blocks=None)[source]

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.

_to_pytree_abelian()[source]
property label

The label of the array, possibly used for ordering odd parity fermionic modes.

property sizes

The sizes of each index.

property charges

The possible charges of each index.

property charge

The total charge of the array.

property shape

The shape of the array, i.e. product of total size of each index.

property size

The number of possible elements in this array, if it was dense.

property ndim

The number of dimensions/indices.

sync_charges(inplace=False)[source]

Given the blocks currently present, adjust the index chargemaps to match only those charges present in at least one sector.

is_valid_sector(sector)[source]

Check if a sector is valid for the block array, i.e., whether the total symmetry charge is satisfied.

gen_valid_sectors()[source]

Generate all valid sectors for the block array.

get_sparsity()[source]

Return the sparsity of the array, i.e. the number of blocks divided by the number of possible blocks.

get_block_shape(sector)[source]

Get the shape of the block corresponding to a given sector.

fill_missing_blocks()[source]

Insert any missing blocks for valid sectors with zeros, resulting in a sparsity of 1.

drop_missing_blocks()[source]

Drop any present blocks that are all zero, resulting in a sparsity possibly less that 1.

classmethod from_fill_fn(fill_fn, indices, charge=None, symmetry=None, **kwargs)[source]

Generate a block array from a filling function. Every valid sector will be filled with the result of the filling function.

Parameters:
  • fill_fn (callable) – The filling function, with signature fill_fn(shape).

  • indices (tuple[BlockIndex]) – The indices of the array.

  • charge (hashable) – The total charge of the array. If not given, it will be taken as the identity / zero element.

  • symmetry (str or Symmetry, optional) – The symmetry of the array, if not using a specific symmetry class.

Return type:

SparseArrayCommon

classmethod random(indices, charge=None, seed=None, dist='normal', dtype='float64', scale=1.0, loc=0.0, symmetry=None, **kwargs)[source]

Create a block array with random values.

Parameters:
  • indices (tuple[BlockIndex]) – The indices of the array.

  • charge (hashable) – The total charge of the array. If not given, it will be taken as the identity / zero element.

  • seed (None, int or numpy.random.Generator) – The random seed or generator to use.

  • dist (str) – The distribution to use. Can be one of "normal", "uniform", etc., see numpy.random.default_rng() for details.

  • symmetry (str or Symmetry, optional) – The symmetry of the array, if not using a specific symmetry class.

Return type:

SparseArrayCommon

check()[source]

Check that all the block sizes and charges are consistent.

check_chargemaps_aligned()[source]

Check that the chargemaps of the indices are consistent with the block sectors.

check_with(other, *args)[source]

Check that this block array is compatible with another, that is, that the indices match and the blocks are compatible.

Parameters:
  • other (SparseArrayCommon or BlockVector) – The other array or vector to compare to.

  • *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.

_allclose_abelian(other, **allclose_opts)[source]

Test whether this SparseArrayCommon is close to another, i.e. has all the same sectors, and corresponding arrays are close.

Parameters:
  • other (SparseArrayCommon) – The other array to compare to.

  • allclose_opts – Keyword arguments to pass to allclose.

Return type:

bool

_test_allclose_abelian(other, **allclose_opts)[source]

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.

Parameters:
  • other (SparseArrayCommon) – The other array to compare to.

  • allclose_opts – Keyword arguments to pass to allclose.

Raises:

AssertionError – If the arrays are not close.

classmethod from_blocks(blocks, duals, charge=None, symmetry=None, **kwargs)[source]

Create a block array from a dictionary of blocks and sequence of duals.

Parameters:
  • blocks (dict[tuple[hashable], array_like]) – A mapping of each ‘sector’ (tuple of charges) to the data array.

  • duals (tuple[bool] or tuple[BlockIndex]) – 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.

  • charge (hashable) – 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.

  • symmetry (str or Symmetry, optional) – The symmetry of the array, if not using a specific symmetry class.

  • kwargs – Additional keyword arguments to pass to the constructor.

Return type:

SparseArrayCommon

classmethod from_dense(array, index_maps, duals, charge=None, symmetry=None, invalid_sectors='warn', **kwargs)[source]

Create a block array from a dense array by supplying a mapping for each axis that labels each linear index with a particular charge.

Parameters:
  • array (array_like) – The dense array.

  • index_maps (Sequence[Sequence[hashable]]) – For each dimension, the sequence mapping linear index to charge sector. There should be ndim such mappings, each of length shape[i].

  • duals (tuple[bool]) – The dualness of each index.

  • charge (hashable) – The total charge of the array. If not given, it will be taken as the identity / zero element.

  • symmetry (str or Symmetry, optional) – The symmetry of the array, if not using a specific symmetry class.

  • invalid_sectors ({"warn", "raise", "ignore"}, optional) – How to handle invalid sectors that have non-zero entries.

Return type:

SparseArrayCommon

_transpose_abelian(axes=None, inplace=False)[source]

Transpose this block sparse abelian array.

Parameters:
  • axes (tuple[int, ...] | None, optional) – A permutation of the axes to transpose the array by. If None, the axes will be reversed.

  • inplace (bool, optional) – Whether to perform the operation inplace or return a new array.

Return type:

SparseArrayCommon

_conj_abelian(inplace=False) SparseArrayCommon[source]

Return the complex conjugate of this block array, including the indices.

select_charge(axis, charge, subselect=None, inplace=False)[source]

Drop all but the specified charge along the specified axis. Note the axis is not removed, it is simply restricted to a single charge.

Parameters:
  • axis (int) – The axis along which to select the charge.

  • charge (int) – The charge to select along the specified axis.

  • subselect (slice or array_like, optional) – If provided, a range of indices within the selected charge block to keep. If not provided, the entire block is kept.

  • inplace (bool, optional) – Whether to perform the operation inplace or return a new array.

Return type:

SparseArrayCommon

_squeeze_abelian(axis=None, inplace=False)[source]

Squeeze the block array, removing axes of size 1.

Parameters:
  • axis (int or sequence of int, optional) – The axes to squeeze. If not given, all axes of size 1 will be removed.

  • inplace (bool, optional) – Whether to perform the operation inplace.

Return type:

SparseArrayCommon

isel(axis, idx, inplace=False)[source]

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.

Parameters:
  • axis (int) – The axis to select along.

  • idx (int) – The linear index to select.

  • inplace (bool, optional) – Whether to perform the operation inplace or return a new array.

expand_dims(axis, c=None, dual=None, inplace=False)[source]

Expand the shape of an abelian array.

Parameters:
  • axis (int) – The position along which to expand.

  • c (hashable, optional) – The charge to insert at the new axis. If not given, a zero charge will be inserted.

  • dual (bool, optional) – 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.

  • inplace (bool, optional) – Whether to perform the operation inplace.

Return type:

SparseArrayCommon

_fuse_core_abelian(*axes_groups, mode='auto', inplace=False) SparseArrayCommon[source]
_unfuse_abelian(axis, inplace=False)[source]
_matmul_abelian(other, preserve_array=False)[source]
_trace_abelian()[source]

Compute the trace of the block array, assuming it is a square matrix.

multiply_diagonal(v: symmray.sparse.sparse_vector.BlockVector, axis, power=1, inplace=False)[source]

Multiply this block array by a vector as if contracting a diagonal matrix along the given axis.

Parameters:
  • v (BlockVector) – The vector to contract with.

  • axis (int) – The axis along which to contract.

  • power (int or float, optional) – The power to raise the diagonal elements to.

  • inplace (bool, optional) – Whether to perform the operation inplace.

Return type:

SparseArrayCommon

ldmul(v: symmray.sparse.sparse_vector.BlockVector, inplace=False)[source]
rdmul(v: symmray.sparse.sparse_vector.BlockVector, inplace=False)[source]
lddiv(v: symmray.sparse.sparse_vector.BlockVector, inplace=False)[source]
rddiv(v: symmray.sparse.sparse_vector.BlockVector, inplace=False)[source]
align_axes(other, axes)[source]

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.

Parameters:
  • other (SparseArrayCommon) – The other array to align with.

  • axes (tuple[tuple[int]]) – The pairs of axes to align, given as tuples of the corresponding axes in this and the other array, a la tensordot.

_einsum_abelian(eq, preserve_array=False)[source]

Einsum for abelian arrays, currently only single term.

Parameters:
  • eq (str) – The einsum equation, e.g. “abcb->ca”. The output indices must be specified and only trace and permutations are allowed.

  • preserve_array (bool, optional) – If tracing to a scalar, whether to return an AbelainArray object with no indices, or simply scalar itself (the default).

Return type:

SparseArrayCommon or scalar

_tensordot_abelian(other, axes=2, mode='auto', preserve_array=False)[source]

Tensordot between two block sparse abelian symmetric arrays.

Parameters:
  • a (SparseArrayCommon) – The arrays to be contracted.

  • b (SparseArrayCommon) – The arrays to be contracted.

  • axes (int or tuple[int]) – 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.

  • mode ({"auto", "fused", "blockwise"}) – The mode to use for the contraction. If “auto”, it will choose between “fused” and “blockwise” based on the number of axes to contract.

  • preserve_array (bool, optional) – Whether to return a scalar if the result is a scalar.

_to_dense_abelian()[source]

Convert this block array to a dense array.

to_flat()[source]

Convert this block sparse backend abelian or fermionic array to a flat backend abelian or fermionic array.

_split_abelian_full_spectrum(*, fn=None, charge_side='auto', **kwargs)[source]

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.

_split_abelian(*, fn=None, charge_side='auto', **kwargs)[source]

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.

Parameters:
  • fn (callable, optional) – 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, quimb.tensor.array_split() will be used.

  • charge_side ({"left", "right", "auto"}, optional) – 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.

  • 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.

_eigh_abelian() tuple[symmray.sparse.sparse_vector.BlockVector, SparseArrayCommon][source]
_cholesky_abelian(upper=False, shift=True, **kwargs) SparseArrayCommon[source]

Cholesky decomposition of a 2D block-sparse abelian array.

Parameters:
  • upper (bool, optional) – Whether to return the upper triangular Cholesky factor. Default is False, returning the lower triangular factor.

  • shift (float, optional) – 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.

Returns:

l_or_r – The Cholesky factor.

Return type:

SparseArrayCommon

_solve_abelian(b: SparseArrayCommon) SparseArrayCommon[source]
symmray.sparse.sparse_array_common.argsort(seq)[source]
symmray.sparse.sparse_array_common.calc_sub_max_bonds(sizes, max_bond)[source]
symmray.sparse.sparse_array_common._CUTOFF_MODE_MAP
symmray.sparse.sparse_array_common.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][source]
symmray.sparse.sparse_array_common._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])[source]

Perform a tensordot between two block arrays, performing the contraction of each pair of aligned blocks separately.

symmray.sparse.sparse_array_common.drop_misaligned_sectors(a: SparseArrayCommon, b: SparseArrayCommon, axes_a: tuple[int, Ellipsis], axes_b: tuple[int, Ellipsis], inplace=False) tuple[SparseArrayCommon, SparseArrayCommon][source]

Eagerly drop misaligned sectors of a and b so that they can be contracted via fusing.

Parameters:
  • a (SparseArrayCommon) – The arrays to be contracted.

  • b (SparseArrayCommon) – The arrays to be contracted.

  • axes_a (tuple[int]) – The axes that will be contracted, defined like in tensordot.

  • axes_b (tuple[int]) – The axes that will be contracted, defined like in tensordot.

Returns:

a, b – The new arrays with misaligned sectors dropped.

Return type:

SparseArrayCommon

symmray.sparse.sparse_array_common._tensordot_via_fused(a, b, left_axes, axes_a, axes_b, right_axes)[source]

Perform a tensordot between two block arrays, by first fusing both into matrices and unfusing afterwards.

Parameters:
  • a (SparseArrayCommon) – The arrays to be contracted.

  • b (SparseArrayCommon) – The arrays to be contracted.

  • left_axes (tuple[int]) – The axes of a that will not be contracted.

  • axes_a (tuple[int]) – The axes that will be contracted, defined like in tensordot.

  • axes_b (tuple[int]) – The axes that will be contracted, defined like in tensordot.

  • right_axes (tuple[int]) – The axes of b that will not be contracted.

symmray.sparse.sparse_array_common._DEFAULT_TENSORDOT_MODE = 'auto'
symmray.sparse.sparse_array_common.get_default_tensordot_mode()[source]

Get the current default tensordot mode.

symmray.sparse.sparse_array_common.set_default_tensordot_mode(mode)[source]

Set the default tensordot mode.

Parameters:

mode ({"auto", "fused", "blockwise", None}) – The mode to use for the contraction. None is no-op.

symmray.sparse.sparse_array_common.default_tensordot_mode(mode)[source]

Context manager to temporarily change the default tensordot mode.

Parameters:

mode ({"auto", "fused", "blockwise"}) – The mode to use for the contraction.

symmray.sparse.sparse_array_common.tensordot_abelian(a, b, axes=2, mode='auto', preserve_array=False)[source]

Tensordot between two block sparse abelian symmetric arrays.

Parameters:
  • a (SparseArrayCommon) – The arrays to be contracted.

  • b (SparseArrayCommon) – The arrays to be contracted.

  • axes (int or tuple[int]) – 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.

  • mode ({"auto", "fused", "blockwise"}) – The mode to use for the contraction. If “auto”, it will choose between “fused” and “blockwise” based on the number of axes to contract.

  • preserve_array (bool, optional) – Whether to return a scalar if the result is a scalar.