Array

class tenpy.linalg.np_conserved.Array(legcharges, dtype=<class 'numpy.float64'>, qtotal=None)[source]

Bases: object

A multidimensional array (=tensor) for using charge conservation.

An Array represents a multi-dimensional tensor, together with the charge structure of its legs (for abelian charges). Further information can be found in Introduction to np_conserved.

The default __init__() (i.e. Array(...)) does not insert any data, and thus yields an Array ‘full’ of zeros, equivalent to zeros(). Further, new arrays can be created with one of from_ndarray_trivial(), from_ndarray(), or from_func(), and of course by copying/tensordot/svd etc.

In-place methods are indicated by a name starting with i. (But is_completely_blocked is not inplace…)

Parameters
legchargeslist of LegCharge

The leg charges for each of the legs. The ChargeInfo is read out from it.

dtypetype or string

The data type of the array entries. Defaults to np.float64.

qtotal1D array of QTYPE

The total charge of the array. Defaults to 0.

Attributes
size

The number of dtype-objects stored.

stored_blocks

The number of (non-zero) blocks stored in _data.

rankint

The rank or “number of dimensions”, equivalent to len(shape).

shapetuple(int)

The number of indices for each of the legs.

dtypenp.dtype

The data type of the entries.

chinfoChargeInfo

The nature of the charge.

qtotal1D array

The total charge of the tensor.

legslist of LegCharge

The leg charges for each of the legs.

labelsdict (string -> int)

Labels for the different legs.

_datalist of arrays

The actual entries of the tensor.

_qdata2D array (len(_data), rank), dtype np.intp

For each of the _data entries the qindices of the different legs.

_qdata_sortedBool

Whether self._qdata is lexsorted. Defaults to True, but must be set to False by algorithms changing _qdata.

Methods

add_charge(self, add_legs[, chinfo, qtotal])

Add charges.

add_leg(self, leg, i[, axis, label])

Add a leg to self, setting the current array as slice for a given index.

add_trivial_leg(self[, axis, label, qconj])

Add a trivial leg (with just one entry) to self.

as_completely_blocked(self)

Gives a version of self which is completely blocked by charges.

astype(self, dtype[, copy])

Return copy with new dtype, upcasting all blocks in _data.

binary_blockwise(self, func, other, \*args, …)

Roughly return func(self, other), block-wise.

change_charge(self, charge, new_qmod[, …])

Change the qmod of one charge in chinfo.

combine_legs(self, combine_legs[, new_axes, …])

Reshape: combine multiple legs into multiple pipes.

complex_conj(self)

Return copy which is complex conjugated without conjugating the charge data.

conj(self[, complex_conj, inplace])

Conjugate: complex conjugate data, conjugate charge data.

copy(self[, deep])

Return a (deep or shallow) copy of self.

drop_charge(self[, charge, chinfo])

Drop (one of) the charges.

extend(self, axis, extra)

Increase the dimension of a given axis, filling the values with zeros.

from_func(func, legcharges[, dtype, qtotal, …])

Create an Array from a numpy func.

from_func_square(func, leg[, dtype, …])

Create an Array from a (numpy) function.

from_ndarray(data_flat, legcharges[, dtype, …])

convert a flat (numpy) ndarray to an Array.

from_ndarray_trivial(data_flat[, dtype])

convert a flat numpy ndarray to an Array with trivial charge conservation.

gauge_total_charge(self, axis[, newqtotal, …])

Changes the total charge by adjusting the charge on a certain leg.

get_block(self, qindices[, insert])

Return the ndarray in _data representing the block corresponding to qindices.

get_leg(self, label)

Return self.legs[self.get_leg_index(label)].

get_leg_index(self, label)

translate a leg-index or leg-label to a leg-index.

get_leg_indices(self, labels)

Translate a list of leg-indices or leg-labels to leg indices.

get_leg_labels(self)

Return list of the leg labels, with None for anonymous legs.

has_label(self, label)

Check whether a given label exists.

iadd_prefactor_other(self, prefactor, other)

self += prefactor * other for scalar prefactor and Array other.

ibinary_blockwise(self, func, other, \*args, …)

Roughly self = func(self, other), block-wise; in place.

iconj(self[, complex_conj])

Wraper around self.conj() with inplace=True.

idrop_labels(self[, old_labels])

Remove leg labels from self; in place.

iproject(self, mask, axes)

Applying masks to one or multiple axes; in place.

ipurge_zeros(self[, cutoff, norm_order])

Removes self._data blocks with norm less than cutoff; in place.

ireplace_label(self, old_label, new_label)

Replace the leg label old_label with new_label; in place.

ireplace_labels(self, old_labels, new_labels)

Replace leg label old_labels[i] with new_labels[i]; in place.

is_completely_blocked(self)

Return bool whether all legs are blocked by charge.

iscale_axis(self, s[, axis])

Scale with varying values along an axis; in place.

iscale_prefactor(self, prefactor)

self *= prefactor for scalar prefactor.

iset_leg_labels(self, labels)

Set labels for the different axes/legs; in place.

isort_qdata(self)

(Lexiographically) sort self._qdata; in place.

iswapaxes(self, axis1, axis2)

Similar as np.swapaxes; in place.

itranspose(self[, axes])

Transpose axes like np.transpose; in place.

iunary_blockwise(self, func, \*args, \*\*kwargs)

Roughly self = f(self), block-wise; in place.

make_pipe(self, axes, \*\*kwargs)

Generates a LegPipe for specified axes.

matvec(self, other)

This function is used by the Lanczos algorithm needed for DMRG.

norm(self[, ord, convert_to_float])

Norm of flattened data.

permute(self, perm, axis)

Apply a permutation in the indices of an axis.

replace_label(self, old_label, new_label)

Return a shallow copy with the leg label old_label replaced by new_label.

replace_labels(self, old_labels, new_labels)

Return a shallow copy with old_labels[i] replaced by new_labels[i].

scale_axis(self, s[, axis])

Same as iscale_axis(), but return a (deep) copy.

sort_legcharge(self[, sort, bunch])

Return a copy with one or all legs sorted by charges.

sparse_stats(self)

Returns a string detailing the sparse statistics.

split_legs(self[, axes, cutoff])

Reshape: opposite of combine_legs: split (some) legs which are LegPipes.

squeeze(self[, axes])

Like np.squeeze.

take_slice(self, indices, axes)

Return a copy of self fixing indices along one or multiple axes.

test_sanity(self)

Sanity check.

to_ndarray(self)

Convert self to a dense numpy ndarray.

transpose(self[, axes])

Like itranspose(), but on a deep copy.

unary_blockwise(self, func, \*args, \*\*kwargs)

Roughly return func(self), block-wise.

zeros_like(self)

Return a copy of self with only zeros as entries, containing no _data.

copy(self, deep=True)[source]

Return a (deep or shallow) copy of self.

Both deep and shallow copies will share chinfo and the LegCharges in legs.

In contrast to a deep copy, the shallow copy will also share the tensor entries, namely the same instances of _qdata and _data and labels (and other ‘immutable’ properties like the shape or dtype).

Note

Shallow copies are not recommended unless you know the consequences! See the following examples illustrating some of the pitfalls.

Examples

Be (very!) careful when making non-deep copies: In the following example, the original a is changed if and only if the corresponding block existed in a before. >>> b = a.copy(deep=False) # shallow copy >>> b[1, 2] = 4.

Other inplace operations might have no effect at all (although we don’t guarantee that):

>>> a *= 2  # has no effect on `b`
>>> b.iconj()  # nor does this change `a`
classmethod from_ndarray_trivial(data_flat, dtype=None)[source]

convert a flat numpy ndarray to an Array with trivial charge conservation.

Parameters
data_flatarray_like

The data to be converted to a Array.

dtypenp.dtype

The data type of the array entries. Defaults to dtype of data_flat.

Returns
resArray

An Array with data of data_flat.

classmethod from_ndarray(data_flat, legcharges, dtype=None, qtotal=None, cutoff=None)[source]

convert a flat (numpy) ndarray to an Array.

Parameters
data_flatarray_like

The flat ndarray which should be converted to a npc Array. The shape has to be compatible with legcharges.

legchargeslist of LegCharge

The leg charges for each of the legs. The ChargeInfo is read out from it.

dtypenp.dtype

The data type of the array entries. Defaults to dtype of data_flat.

qtotalNone | charges

The total charge of the new array.

cutofffloat

Blocks with np.max(np.abs(block)) > cutoff are considered as zero. Defaults to QCUTOFF.

Returns
resArray

An Array with data of data_flat.

See also

detect_qtotal

used to detect qtotal if not given.

classmethod from_func(func, legcharges, dtype=None, qtotal=None, func_args=(), func_kwargs={}, shape_kw=None)[source]

Create an Array from a numpy func.

This function creates an array and fills the blocks compatible with the charges using func, where func is a function returning a array_like when given a shape, e.g. one of np.ones or np.random.standard_normal.

Parameters
funccallable

A function-like object which is called to generate the data blocks. We expect that func returns a flat array of the given shape convertible to dtype. If no shape_kw is given, it is called like func(shape, *fargs, **fkwargs), otherwise as func(*fargs, `shape_kw`=shape, **fkwargs). shape is a tuple of int.

legchargeslist of LegCharge

The leg charges for each of the legs. The ChargeInfo is read out from it.

dtypeNone | type | string

The data type of the output entries. Defaults to np.float64. Defaults to None: obtain it from the return value of the function. Note that this argument is not given to func, but rather a type conversion is performed afterwards. You might want to set a dtype in func_kwargs as well.

qtotalNone | charges

The total charge of the new array. Defaults to charge 0.

func_argsiterable

Additional arguments given to func.

func_kwargsdict

Additional keyword arguments given to func.

shape_kwNone | str

If given, the keyword with which shape is given to func.

Returns
resArray

An Array with blocks filled using func.

classmethod from_func_square(func, leg, dtype=None, func_args=(), func_kwargs={}, shape_kw=None)[source]

Create an Array from a (numpy) function.

This function creates an array and fills the blocks compatible with the charges using func, where func is a function returning a array_like when given a shape, e.g. one of np.ones or np.random.standard_normal or the functions defined in random_matrix.

Parameters
funccallable

A function-like object which is called to generate the data blocks. We expect that func returns a flat array of the given shape convertible to dtype. If no shape_kw is given, it is called like func(shape, *fargs, **fkwargs), otherwise as func(*fargs, `shape_kw`=shape, **fkwargs). shape is a tuple of int.

legLegCharge

The leg charges for the first leg; the second leg is set to leg.conj(). The ChargeInfo is read out from it.

dtypeNone | type | string

The data type of the output entries. Defaults to None: obtain it from the return value of the function. Note that this argument is not given to func, but rather a type conversion is performed afterwards. You might want to set a dtype in func_kwargs as well.

func_argsiterable

Additional arguments given to func.

func_kwargsdict

Additional keyword arguments given to func.

shape_kwNone | str

If given, the keyword with which shape is given to func.

Returns
resArray

An Array with blocks filled using func.

zeros_like(self)[source]

Return a copy of self with only zeros as entries, containing no _data.

test_sanity(self)[source]

Sanity check.

Raises ValueErrors, if something is wrong.

property size

The number of dtype-objects stored.

property stored_blocks

The number of (non-zero) blocks stored in _data.

get_leg_index(self, label)[source]

translate a leg-index or leg-label to a leg-index.

Parameters
labelint | string

The leg-index directly or a label (string) set before.

Returns
leg_indexint

The index of the label.

See also

get_leg_indices

calls get_leg_index for a list of labels.

iset_leg_labels

set the labels of different legs.

get_leg_indices(self, labels)[source]

Translate a list of leg-indices or leg-labels to leg indices.

Parameters
labelsiterable of string/int

The leg-labels (or directly indices) to be translated in leg-indices.

Returns
leg_indiceslist of int

The translated labels.

See also

get_leg_index

used to translate each of the single entries.

iset_leg_labels

set the labels of different legs.

iset_leg_labels(self, labels)[source]

Set labels for the different axes/legs; in place.

Introduction to leg labeling can be found in Introduction to np_conserved.

Parameters
labelsiterable (strings | None), len=self.rank

One label for each of the legs. An entry can be None for an anonymous leg.

See also

get_leg

translate the labels to indices.

get_leg_labels(self)[source]

Return list of the leg labels, with None for anonymous legs.

has_label(self, label)[source]

Check whether a given label exists.

get_leg(self, label)[source]

Return self.legs[self.get_leg_index(label)].

Convenient function returning the leg corresponding to a leg label/index.

ireplace_label(self, old_label, new_label)[source]

Replace the leg label old_label with new_label; in place.

replace_label(self, old_label, new_label)[source]

Return a shallow copy with the leg label old_label replaced by new_label.

ireplace_labels(self, old_labels, new_labels)[source]

Replace leg label old_labels[i] with new_labels[i]; in place.

replace_labels(self, old_labels, new_labels)[source]

Return a shallow copy with old_labels[i] replaced by new_labels[i].

idrop_labels(self, old_labels=None)[source]

Remove leg labels from self; in place.

Parameters
old_labelslist of str|int

The leg labels/indices for which the label should be removed. By default (None), remove all labels.

sparse_stats(self)[source]

Returns a string detailing the sparse statistics.

to_ndarray(self)[source]

Convert self to a dense numpy ndarray.

get_block(self, qindices, insert=False)[source]

Return the ndarray in _data representing the block corresponding to qindices.

Parameters
qindices1D array of np.intp

The qindices, for which we need to look in _qdata.

insertbool

If True, insert a new (zero) block, if qindices is not existent in self._data. Otherwise just return None.

Returns
block: ndarray | None

The block in _data corresponding to qindices. If insert`=False and there is not block with qindices, return ``None`.

Raises
IndexError

If qindices are incompatible with charge and raise_incomp_q.

take_slice(self, indices, axes)[source]

Return a copy of self fixing indices along one or multiple axes.

For a rank-4 Array A.take_slice([i, j], [1,2]) is equivalent to A[:, i, j, :].

Parameters
indices(iterable of) int

The (flat) index for each of the legs specified by axes.

axes(iterable of) str/int

Leg labels or indices to specify the legs for which the indices are given.

Returns
sliced_selfArray

A copy of self, equivalent to taking slices with indices inserted in axes.

See also

add_leg

opposite action of inserting a new leg.

add_trivial_leg(self, axis=0, label=None, qconj=1)[source]

Add a trivial leg (with just one entry) to self.

Parameters
axisint

The new leg is inserted before index axis.

labelstr | None

If not None, use it as label for the new leg.

qconj+1 | -1

The direction of the new leg.

Returns
extendedArray

A (possibly) shallow copy of self with an additional leg of ind_len 1 and charge 0.

add_leg(self, leg, i, axis=0, label=None)[source]

Add a leg to self, setting the current array as slice for a given index.

Parameters
legLegCharge

The charge data of the leg to be added.

iint

Index within the leg for which the data of self should be set.

axisaxis

The new leg is inserted before this current axis.

labelstr | None

If not None, use it as label for the new leg.

Returns
extendedArray

A copy of self with the new leg at axis axis , such that extended.take_slice(i, axis) returns a copy of self.

See also

take_slice

opposite action reducing the number of legs.

extend(self, axis, extra)[source]

Increase the dimension of a given axis, filling the values with zeros.

Parameters
axisint | str

The axis (or axis-label) to be extended.

extraLegCharge | int

By what to extend, i.e. the charges to be appended to the leg of axis. An int stands for extending the length of the array by a single new block of that size with zero charges.

Returns
extendedArray

A copy of self with the specified axis increased.

gauge_total_charge(self, axis, newqtotal=None, new_qconj=None)[source]

Changes the total charge by adjusting the charge on a certain leg.

The total charge is given by finding a nonzero entry [i1, i2, …] and calculating:

qtotal = self.chinfo.make_valid(
    np.sum([l.get_charge(l.get_qindex(qi)[0])
            for i, l in zip([i1,i2,...], self.legs)], axis=0))

Thus, the total charge can be changed by redefining (= shifting) the LegCharge of a single given leg. This is exaclty what this function does.

Parameters
axisint or string

The new leg (index or label), for which the charge is changed.

newqtotalcharge values, defaults to 0

The new total charge.

new_qconj: {+1, -1, None}

Whether the new LegCharge points inward (+1) or outward (-1) afterwards. By default (None) use the previous self.legs[leg].qconj.

Returns
copyArray

A shallow copy of self with copy.qtotal == newqtotal and new copy.legs[leg]. The new leg will be a :class`LegCharge`, even if the old leg was a LegPipe.

add_charge(self, add_legs, chinfo=None, qtotal=None)[source]

Add charges.

Parameters
add_legsiterable of LegCharge

One LegCharge for each axis of self, to be added to the one in legs.

chargeinfoChargeInfo

The ChargeInfo for all charges; create new if None.

qtotalNone | charges

The total charge with respect to add_legs. If None, derive it from non-zero entries of self.

Returns
charges_addedArray

A copy of self, where the LegCharges add_legs where added to self.legs. Note that the LegCharges are neither bunched or sorted; you might want to use sort_legcharge().

drop_charge(self, charge=None, chinfo=None)[source]

Drop (one of) the charges.

Parameters
chargeint | str

Number or name of the charge (within chinfo) which is to be dropped. None means dropping all charges.

chinfoChargeInfo

The ChargeInfo with charge dropped; create a new one if None.

Returns
droppedArray

A copy of self, where the specified charge has been removed. Note that the LegCharges are neither bunched or sorted; you might want to use sort_legcharge().

change_charge(self, charge, new_qmod, new_name='', chinfo=None)[source]

Change the qmod of one charge in chinfo.

Parameters
chargeint | str

Number or name of the charge (within chinfo) which is to be changed. None means dropping all charges.

new_qmodint

The new qmod to be set.

new_namestr

The new name of the charge.

chinfoChargeInfo

The ChargeInfo with qmod of charge changed; create a new one if None.

Returns
changedArray

A copy of self, where the qmod of the specified charge has been changed. Note that the LegCharges are neither bunched or sorted; you might want to use sort_legcharge().

is_completely_blocked(self)[source]

Return bool whether all legs are blocked by charge.

sort_legcharge(self, sort=True, bunch=True)[source]

Return a copy with one or all legs sorted by charges.

Sort/bunch one or multiple of the LegCharges. Legs which are sorted and bunched are guaranteed to be blocked by charge.

Parameters
sortTrue | False | list of {True, False, perm}

A single bool holds for all legs, default=True. Else, sort should contain one entry for each leg, with a bool for sort/don’t sort, or a 1D array perm for a given permuation to apply to a leg.

bunchTrue | False | list of {True, False}

A single bool holds for all legs, default=True. Whether or not to bunch at each leg, i.e. combine contiguous blocks with equal charges.

Returns
permtuple of 1D arrays

The permutation applied to each of the legs, such that cp.to_ndarray() = self.to_ndarray()[np.ix_(*perm)].

resultArray

A shallow copy of self, with legs sorted/bunched.

isort_qdata(self)[source]

(Lexiographically) sort self._qdata; in place.

Lexsort self._qdata and self._data and set self._qdata_sorted = True.

make_pipe(self, axes, **kwargs)[source]

Generates a LegPipe for specified axes.

Parameters
axesiterable of str|int

The leg labels for the axes which should be combined. Order matters!

**kwargs :

Additional keyword arguments given to LegPipe.

Returns
pipeLegPipe

A pipe of the legs specified by axes.

combine_legs(self, combine_legs, new_axes=None, pipes=None, qconj=None)[source]

Reshape: combine multiple legs into multiple pipes. If necessary, transpose before.

Parameters
combine_legs(iterable of) iterable of {str|int}

Bundles of leg indices or labels, which should be combined into a new output pipes. If multiple pipes should be created, use a list fore each new pipe.

new_axesNone | (iterable of) int

The leg-indices, at which the combined legs should appear in the resulting array. Default: for each pipe the position of its first pipe in the original array, (taking into account that some axes are ‘removed’ by combining). Thus no transposition is perfomed if combine_legs contains only contiguous ranges.

pipesNone | (iterable of) {LegPipes | None}

Optional: provide one or multiple of the resulting LegPipes to avoid overhead of computing new leg pipes for the same legs multiple times. The LegPipes are conjugated, if that is necessary for compatibility with the legs.

qconj(iterable of) {+1, -1}

Specify whether new created pipes point inward or outward. Defaults to +1. Ignored for given pipes, which are not newly calculated.

Returns
reshapedArray

A copy of self, whith some legs combined into pipes as specified by the arguments.

See also

split_legs

inverse reshaping splitting LegPipes.

Notes

Labels are inherited from self. New pipe labels are generated as '(' + '.'.join(*leglabels) + ')'. For these new labels, previously unlabeled legs are replaced by '?#', where # is the leg-index in the original tensor self.

Examples

>>> oldarray.iset_leg_labels(['a', 'b', 'c', 'd', 'e'])
>>> c1 = oldarray.combine_legs([1, 2], qconj=-1)  # only single output pipe
>>> c1.get_leg_labels()
['a', '(b.c)', 'd', 'e']

Indices of combine_legs refer to the original array. If transposing is necessary, it is performed automatically:

>>> c2 = oldarray.combine_legs([[0, 3], [4, 1]], qconj=[+1, -1]) # two output pipes
>>> c2.get_leg_labels()
['(a.d)', 'c', '(e.b)']
>>> c3 = oldarray.combine_legs([['a', 'd'], ['e', 'b']], new_axes=[2, 1],
>>>                            pipes=[c2.legs[0], c2.legs[2]])
>>> c3.get_leg_labels()
['c', '(e.b)', '(a.d)']
split_legs(self, axes=None, cutoff=0.0)[source]

Reshape: opposite of combine_legs: split (some) legs which are LegPipes.

Reverts combine_legs() (except a possibly performed transpose). The splited legs are replacing the LegPipes at their position, see the examples below. Labels are split reverting what was done in combine_legs(). ‘?#’ labels are replaced with None.

Parameters
axes(iterable of) int|str

Leg labels or indices determining the axes to split. The corresponding entries in self.legs must be LegPipe instances. Defaults to all legs, which are LegPipe instances.

cutofffloat

Splitted data blocks with np.max(np.abs(block)) > cutoff are considered as zero. Defaults to 0.

Returns
reshapedArray

A copy of self where the specified legs are splitted.

See also

combine_legs

this is reversed by split_legs.

Examples

Given a rank-5 Array old_array, you can combine it and split it again:

>>> old_array.iset_leg_labels(['a', 'b', 'c', 'd', 'e'])
>>> comb_array = old_array.combine_legs([[0, 3], [2, 4]] )
>>> comb_array.get_leg_labels()
['(a.d)', 'b', '(c.e)']
>>> split_array = comb_array.split_legs([0, 2])
>>> split_array.get_leg_labels()
['a', 'd', 'b', 'c', 'e']
as_completely_blocked(self)[source]

Gives a version of self which is completely blocked by charges.

Functions like svd() or eigh() require a complete blocking by charges. This can be achieved by encapsulating each leg which is not completely blocked into a LegPipe (containing only that single leg). The LegPipe will then contain all necessary information to revert the blocking.

Returns
encapsulated_axeslist of int

The leg indices which have been encapsulated into Pipes.

blocked_selfArray

Self (if len(encapsulated_axes) = 0) or a copy of self, which is completely blocked.

squeeze(self, axes=None)[source]

Like np.squeeze.

If a squeezed leg has non-zero charge, this charge is added to qtotal.

Parameters
axesNone | (iterable of) {int|str}

Labels or indices of the legs which should be ‘squeezed’, i.e. the legs removed. The corresponding legs must be trivial, i.e., have ind_len 1.

Returns
squeezed:class:Array | scalar

A scalar of self.dtype, if all axes were squeezed. Else a copy of self with reduced rank as specified by axes.

astype(self, dtype, copy=True)[source]

Return copy with new dtype, upcasting all blocks in _data.

Parameters
dtypeconvertible to a np.dtype

The new data type. If None, deduce the new dtype as common type of self._data.

copybool

Whether to make a copy of the blocks even if the type didn’t change.

Returns
copyArray

Deep copy of self with new dtype.

ipurge_zeros(self, cutoff=2.220446049250313e-15, norm_order=None)[source]

Removes self._data blocks with norm less than cutoff; in place.

Parameters
cutofffloat

Blocks with norm <= cutoff are removed. defaults to QCUTOFF.

norm_order :

A valid ord argument for np.linalg.norm. Default None gives the Frobenius norm/2-norm for matrices/everything else. Note that this differs from other methods, e.g. from_ndarray(), which use the maximum norm.

iproject(self, mask, axes)[source]

Applying masks to one or multiple axes; in place.

This function is similar as np.compress with boolean arrays For each specified axis, a boolean 1D array mask can be given, which chooses the indices to keep.

Warning

Although it is possible to use an 1D int array as a mask, the order is ignored! If you need to permute an axis, use permute() or sort_legcharge().

Parameters
mask(list of) 1D array(bool|int)

For each axis specified by axes a mask, which indices of the axes should be kept. If mask is a bool array, keep the indices where mask is True. If mask is an int array, keep the indices listed in the mask, ignoring the order or multiplicity.

axes(list of) int | string

The i`th entry in this list specifies the axis for the `i`th entry of `mask, either as an int, or with a leg label. If axes is just a single int/string, specify just a single mask.

Returns
map_qindlist of 1D arrays

The mapping of qindices for each of the specified axes.

block_masks: list of lists of 1D bool arrays

block_masks[a][qind] is a boolen mask which indices to keep in block qindex of axes[a].

permute(self, perm, axis)[source]

Apply a permutation in the indices of an axis.

Similar as np.take with a 1D array. Roughly equivalent to res[:, ...] = self[perm, ...] for the corresponding axis. Note: This function is quite slow, and usually not needed!

Parameters
permarray_like 1D int

The permutation which should be applied to the leg given by axis.

axisstr | int

A leg label or index specifying on which leg to take the permutation.

Returns
resArray

A copy of self with leg axis permuted, such that res[i, ...] = self[perm[i], ...] for i along axis.

See also

sort_legcharge

can also be used to perform a general permutation. Preferable, since it is faster for permutations which don’t mix charge blocks.

itranspose(self, axes=None)[source]

Transpose axes like np.transpose; in place.

Parameters
axes: iterable (int|string), len ``rank`` | None

The new order of the axes. By default (None), reverse axes.

transpose(self, axes=None)[source]

Like itranspose(), but on a deep copy.

iswapaxes(self, axis1, axis2)[source]

Similar as np.swapaxes; in place.

iscale_axis(self, s, axis=-1)[source]

Scale with varying values along an axis; in place.

Rescale to new_self[i1, ..., i_axis, ...] = s[i_axis] * self[i1, ..., i_axis, ...].

Parameters
s1D array, len=self.shape[axis]

The vector with which the axis should be scaled.

axisstr|int

The leg label or index for the axis which should be scaled.

See also

iproject

can be used to discard indices for which s is zero.

scale_axis(self, s, axis=-1)[source]

Same as iscale_axis(), but return a (deep) copy.

iunary_blockwise(self, func, *args, **kwargs)[source]

Roughly self = f(self), block-wise; in place.

Applies an unary function func to the non-zero blocks in self._data.

Note

Assumes implicitly that func(np.zeros(...), *args, **kwargs) gives 0, since we don’t let func act on zero blocks!

Parameters
funcfunction

A function acting on flat arrays, returning flat arrays. It is called like new_block = func(block, *args, **kwargs).

*args :

Additional arguments given to function after the block.

**kwargs :

Keyword arguments given to the function.

Examples

>>> a.iunaray_blockwise(np.real)  # get real part
>>> a.iunaray_blockwise(np.conj)  # same data as a.iconj(), but doesn't charge conjugate.
unary_blockwise(self, func, *args, **kwargs)[source]

Roughly return func(self), block-wise. Copies.

Same as iunary_blockwise(), but makes a shallow copy first.

iconj(self, complex_conj=True)[source]

Wraper around self.conj() with inplace=True.

conj(self, complex_conj=True, inplace=False)[source]

Conjugate: complex conjugate data, conjugate charge data.

Conjugate all legs, set negative qtotal.

Labeling: takes ‘a’ -> ‘a*’, ‘a*’-> ‘a’ and ‘(a,(b*,c))’ -> ‘(a*, (b, c*))’

Parameters
complex_conjbool

Whether the data should be complex conjugated.

inplacebool

Whether to apply changes to self, or to return a deep copy.

complex_conj(self)[source]

Return copy which is complex conjugated without conjugating the charge data.

norm(self, ord=None, convert_to_float=True)[source]

Norm of flattened data.

See norm() for details.

ibinary_blockwise(self, func, other, *args, **kwargs)[source]

Roughly self = func(self, other), block-wise; in place.

Applies a binary function ‘block-wise’ to the non-zero blocks of self._data and other._data, storing result in place. Assumes that other is an Array as well, with the same shape and compatible legs. If leg labels of other and self are same up to permutations, other gets transposed accordingly before the action.

Note

Assumes implicitly that func(np.zeros(...), np.zeros(...), *args, **kwargs) gives 0, since we don’t let func act on zero blocks!

Parameters
funcfunction

Binary function, called as new_block = func(block_self, block_other, *args, **kwargs) for blocks (=Numpy arrays) of equal shape.

otherArray

Other Array from which to the blocks.

*args, **kwargs:

Extra (keyword) arguments given to func.

Examples

>>> a.ibinary_blockwise(np.add, b)  # equivalent to ``a += b``, if ``b`` is an `Array`.
>>> a.ibinary_blockwise(np.max, b)  # overwrites ``a`` to ``a = max(a, b)``
binary_blockwise(self, func, other, *args, **kwargs)[source]

Roughly return func(self, other), block-wise. Copies.

Same as ibinary_blockwise(), but makes a shallow copy first.

matvec(self, other)[source]

This function is used by the Lanczos algorithm needed for DMRG.

It is supposed to calculate the matrix - vector - product for a rank-2 matrix self and a rank-1 vector other.

iadd_prefactor_other(self, prefactor, other)[source]

self += prefactor * other for scalar prefactor and Array other.

Note that we allow the type of self to change if necessary. Moreover, if self and other have the same labels in different order, other gets transposed before the action.

iscale_prefactor(self, prefactor)[source]

self *= prefactor for scalar prefactor.

Note that we allow the type of self to change if necessary.