# Tensor tools

`ElemCo.TensorTools`

— Moduletensor tools, e.g., access to integrals, load/save intermediates...

## I/O functions

`ElemCo.TensorTools.save!`

— Function`save!(EC::ECInfo, fname::String, a::AbstractArray...; description="tmp", overwrite=true)`

Save array or tuple of arrays `a`

to file `fname`

in EC.scr directory. Add file to `EC.files`

with `description`

.

`ElemCo.TensorTools.load`

— Function`load(EC::ECInfo, fname::String)`

Load array from file `fname`

in EC.scr directory.

`ElemCo.TensorTools.mmap`

— Function`mmap(EC::ECInfo, fname::String)`

Memory-map an existing file for reading. Return a pointer to the file and the mmaped array.

`ElemCo.TensorTools.newmmap`

— Function`newmmap(EC::ECInfo, fname::String, Type, dims::Tuple{Vararg{Int}}; description="tmp")`

Create a new memory-map file for writing (overwrites existing file). Add file to `EC.files`

with `description`

. Return a pointer to the file and the mmaped array.

`ElemCo.TensorTools.closemmap`

— Function`closemmap(EC::ECInfo, file, array)`

Close memory-map file and flush to disk.

## Integral extraction

`ElemCo.TensorTools.ints1`

— Function`ints1(EC::ECInfo, spaces::String, spincase = nothing)`

Return subset of 1e⁻ integrals according to spaces.

The `spincase`

∈{`:α`

,`:β`

} can explicitly be given, or will be deduced from upper/lower case of spaces specification.

`ElemCo.TensorTools.ints2`

— Function`ints2(EC::ECInfo, spaces::String, spincase = nothing, detri = true)`

Return subset of 2e⁻ integrals according to spaces.

The `spincase`

∈{`:α`

,`:β`

} can explicitly be given, or will be deduced from upper/lower case of spaces specification. If the last two indices are stored as triangular and detri - make them full, otherwise return as a triangular cut.

## Tensor manipulation

`ElemCo.TensorTools.sqrtinvchol`

— Function`sqrtinvchol(A::AbstractMatrix; tol = 1e-8, verbose = false)`

Return NON-SYMMETRIC (pseudo)sqrt-inverse of a hermitian matrix using Cholesky decomposition.

Starting from $A^{-1} = A^{-1} L (A^{-1} L)^† = M M^†$ with $A = L L^†$. By solving the equation $L^† M = 1$ (for low-rank: using QR decomposition). Return `M`

.

`ElemCo.TensorTools.invchol`

— Function`invchol(A::AbstractMatrix; tol = 1e-8, verbose = false)`

Return (pseudo)inverse of a hermitian matrix using Cholesky decomposition .

The inverse is calculated as $A^{-1} = A^{-1} L (A^{-1} L)^† = M M^†$ with $A = L L^†$. By solving the equation $L^† M = 1$ (for low-rank: using QR decomposition)

`ElemCo.TensorTools.rotate_eigenvectors_to_real!`

— Function`rotate_eigenvectors_to_real!(evecs::AbstractMatrix, evals::AbstractVector)`

In-place transform complex eigenvectors of a real matrix to a real space such that they block-diagonalize the matrix.

## Other exported functions

`ElemCo.TensorTools.detri_int2`

— Method`detri_int2(allint2, norb, sp1, sp2, sp3, sp4)`

Return full 2e⁻ integrals <sp1 sp2 | sp3 sp4> from allint2 with last two indices as a triangular index.

`ElemCo.TensorTools.get_spaceblocks`

— Function`get_spaceblocks(space, maxblocksize=100, strict=false)`

Generate ranges for block indices for space (for loop over blocks).

`space`

is a range or an array of indices. Even if `space`

is non-contiguous, the blocks will be contiguous. If `strict`

is true, the blocks will be of size `maxblocksize`

(except for the last block and non-contiguous index-ranges). Otherwise the actual block size will be as close as possible to `blocksize`

such that the resulting blocks are of similar size.

`ElemCo.TensorTools.print_nonzeros`

— Method`print_nonzeros(tensor::AbstractArray; ϵ=1.e-12, fname::String="")`

Print cartesian index alongside value of array for elements with absolute value greater or equal than ϵ either to stdout or to a file.

## Internal functions

`ElemCo.TensorTools.triinds`

— Function`triinds(norb, sp1::AbstractArray{Int}, sp2::AbstractArray{Int}, reverseCartInd = false)`

Generate set of CartesianIndex for addressing the lhs and a bitmask for the rhs for transforming a triangular index from 1:norb to two original indices in spaces sp1 and sp2. If `reverse`

: the cartesian indices are reversed.