SyTen

## ◆ STensor

 using syten::STensor = typedef STensorImpl::STensor

‘Smart’ tensor class.

Main features compared to the plain syten::Tensor:

• Hides the tensor rank behind a std::variant
• attempts to implement the graded algebra needed for fermionic tensor networks. The fermionic ordering of legs does not have to coincide with the computational ordering.
• Stores a complete, named STensorImpl::SBasis for every leg. Information about zero blocks is not lost.
• basic support for autodifferentiation (see STensorImpl::Autodiff)

Incoming indices are bras, outgoing indices are kets. Rank-2 tensors can always be contracted with a single leg of any other (even) tensor as long as their outgoing leg comes fermionically first and their incoming leg comes fermionically second.

Remarks
Implemented in the syten::STensorImpl namespace with all associated functions.
To enable compilation of this class, define the SYTEN_STENSOR macro. By default, syten::STensor objects up to and including rank-5 can then be used. To change this maximal rank, define the new maximal rank via SYTEN_STENSOR_MAX_RANK and also define SYTEN_STENSOR_RANKS to a comma-separated list of the valid ranks, starting at 0 and going up to SYTEN_STENSOR_MAX_RANK.
In the pretty-printing of an STensor, rank and autodifferentiation ID are given in brackets directly following the word STensor, e.g. STensor[3;0] signifies a rank-3 STensor with autodiff ID 0 (disabled), STensor[0;5] signifies an STensor with rank 0 and autodiff ID 5. The address of the STensor in memory is given next as a hexadecimal number. Subsequently, for higher-rank tensors, the bases on the (arbitrarily numbered) legs and the fermionic order of those legs are given together with the nonzero blocks of the tensor. Rank-0 tensors are presented only by their numerical value, where the imaginary part is left off if it is non-zero.
syten::STensor objects are multiplied implicitly by matching basis IDs together. This is convenient, but also means that a small mistake there might go unnoticed (and the result tensor simply have more IDs/higher rank than expected). To avoid this problem to some extend, you may use the syten::STensorImpl::e() member functions which throw an assertion if the actual rank is not the same as the expected rank.