Symmetric tensors in Cc4s
Table of Contents
1. Symmetries of tensors reading and writing
The storage and loading time of tensors can be reduced if the elements exhibit symmetries. If symmetries are considered the layout of the elements changes such that only symmetrically distinct elements are stored. The remaining elements are generated automatically by the given symmetry operation. Element-wise symmetry operations can be complex rotations, including the identity, and complex conjugations. A tensor can have multiple symmetries. The product of all powers form the entire symmetry group.
The storage layout of the elements in the tensor elements file, in binary or text, derives from the usual storage layout, ordered by the global index \(g = i_0 + L_0 (i_1 + L_1 i_2 \ldots )\) where \(i_0,\ldots\) are the tensor indices from left to right and \(L_0,\ldots\) are the corresponding index lengths. Let \(g'_\tau(g)\) be the image of the global index \(g\) under under the permutation \(\tau\) applied to the indices \(i_0,\ldots\), encoded in \(g\). The only elements kept in the storage layout are those with the smallest global index \(g'_\tau\) under all symmetry operation \(\tau\). The elements of these indices are the representative elements. The elements of the other indices are automatically generated.
For example, consider the following anti-symmetric \(3\times3\) matrix
\begin{equation*} A = \left( \begin{array}{rrr} 0 & -1 & +3 \\ +1 & 0 & -2 \\ -3 & +2 & 0 \end{array} \right). \end{equation*}Using the Fortran convention for the matrix-vector product \(A[i,j]*v[j]\) we have a column-major layout and the global indices are as follows:
\begin{equation*} \left( \begin{array}{rrr} 0 & 3 & 6 \\ 1 & 4 & 7 \\ 2 & 5 & 8 \end{array} \right). \end{equation*}The elements with the following global indices are related by the anti-sytmmetry: \(0\leftrightarrow 0\), \(1\leftrightarrow 3\), \(2\leftrightarrow 6\), \(4\leftrightarrow 4\), \(5\leftrightarrow 7\), and \(8\leftrightarrow 8\). Taking always the smallest global index, we arrive at the sorted global index list of the representative elements: \(0,1,2,4,5,8\). Thus, the six elements corresponding to these indices are stored and the elements file contains the numbers \(0,+1,-3,0,+2,0\), i.e. the lower-left part of the matrix. Note that also the zero elements are stored, although the value can only be 0, the only fixpoint of a 180 degrees rotation. In general, the set of fixpoints can be non-trivial, e.g. the real axis for complex conjugation. The additional memory consumption is negligible for larger tensors.
To tell Cc4s that the elements of a tensor are packed with respect
to a symmetry, the symmetries must be entered in the symmetries
entries
in the descriptive yaml file. For the above anti-symmetric matrix
there would be one entry:
symmetries: # generators of symmetries respected for storing - indexPermutation: [1,0] # transposition the two indices order: 2 # redundant, only used for checking elementsOperation: complexRotation # rotate by 2nd roots of unity: -1 operationPower: 1 # use 1st power for each permutation: -1 # use power 0 if symmetric not anti-symmetric
As a more complicated example, consider the anti-symmetry of the unrestricted doubles-amplitudes. This tensor is anti-symmetric with respect to the transposition of the first two indices and with respect to the transposition of the last two indices. There are two generators of the symmetry and the entries in the descriptive yaml file would be
symmetries: # generators of symmetries respected for storing - indexPermutation: [1,0,2,3] # transposition the first two indices order: 2 # redundant, only used for checking elementsOperation: complexRotation # rotate by 2nd roots of unity: -1 operationPower: 1 # use 1st power for each permutation: -1 - indexPermutation: [0,1,3,2] # transposition the last two indices order: 2 # redundant, only used for checking elementsOperation: complexRotation # rotate by 2nd roots of unity: -1 operationPower: 1 # use 1st power for each permutation: -1
The entire symmetry group has 4 elements and consists of the four permutations \((0,1,2,3), (1,0,2,3), (0,1,3,2), (1,0,3,2)\) with the multiplication operations \(+1,-1,-1,+1\), respectively. Only a bit more than a fourth of the elements is stored, the other elements follow by symmetry.
As a last example, consider the symmetry of the closed-shell doubles-amplitudes. This tensor is symmetric only with respect to the simultaneous transposition of the first two indices and the last two indices. There is one generator of the symmetry and the entries in the descriptive yaml file would be
symmetries: # generators of symmetries respected for storing - indexPermutation: [1,0,3,2] # simultaneous transposition two pairs of indices order: 2 # redundant, only used for checking elementsOperation: complexRotation # rotate by 2nd roots of unity: -1 operationPower: 0 # use 0th power for each permutation: +1
Index permutations with higher orders are possible, for example order three of the permutation \((1,2,0)\). They are only supported for the complexRotation operation corresponding to a complex rotation by 120 degrees, i.e. a multiplication by a third root of unity.
Each symmetry generator is described by the following fields
indexPermutation
- The image of each index under the permutation under consideration. E.g. a 1 as the first element indicates that the first index (0) will be mapped to the second index (1) by the permutation.
order
- The order \(n\) is the lowest non-zero number of repeated
applications of the given
indexPermutation
to arrive at the identity permutation \((0,1,\ldots)\). Althoughorder
can be computed from theindexPermutation
it must be given for redundancy. elementOperation
- Specifies how the tensor elements transform
under the given
indexPermutation
. Can becomplexRotation
orcomplexConjugation
. ForcomplexConjugation
the elements transform as \(z \mapsto \overline{z}\) for odd powers as specified below and the order of the permutations must be \(2\), i.e. a transposition. ForcomplexRotation
the order \(n\) can be arbitrary and the generally complex operation is given by \(z \mapsto z\, e^{2\pi i k/n}\), where \(k\) is theoperationPower
. operationPower
- Specifies the power \(k\) in the above equation
for
complexRotation
. For the operationcomplexConjugation
any odd power corresponds to the complex conjugation \(z \mapsto \overline{z}\) while every even power corresponds to the identity \(z \mapsto z\). Common combinations ofelementOperation
andoperationPower
\(k\) are: eithercomplexRotation
orcomplexConjugation
with \(k=0\) for symmetric tensors,complexRotation
with \(k=1\) for anti-symmetric tensors, andcomplexConjugation
with \(k=1\) for hermitian tensors.
2. Reading symmetry packed tensors
The following sanity checks are currently NOT done while reading symmetry packed tensors:
- The size of the elements file corresponds to the number of representative elements. E.g. 6 doubles for a \(3\times 3\) anti-symmetric of 64 bit doubles. Loading may crash otherwise.
- The lengths and types of permuted index dimensions agree. Loading may crash otherwise.
- The order of the given permutation agrees with the specified order. The specified order is ignored.
- Complex rotations with orders \(n\) greater two are only applicable to complex tensor types. Currently, a multiplication with the real part of \(e^{2\pi i k/n}\) is used for real tensors, which does not yield the identity after \(n\) applications.
- Elements of fix points of the index permutation are in the set of fix points of the specified symmetry operation. E.g. elements on the diagonal of a hermitian matrix are expected to be real. If they are not the read tensor will not exhibit the specified symmetry.
3. Writing symmetry packed tensors
When writing a tensor exhibiting symmetries you need to specify the symmetries that should be taken into consideration for storing as argument of the =Write+ algorithm. The following sanity checks are currently NOT done while writing symmetry packed tensors.