# SimpleIndices

### Basics

SimpleIndices represents indices of SimpleTensor and TensorField. It inherits all properties of Indices but does not sort indices., so indices in SimpleIndices appear exactly in that order as defined by the user:

def indices = '_pqrs^sp'.si
println indices

   > _pqrs^sp

On the other hand, since indices of different types have different mathematical nature, SimpleIndices are sorted according to the type (preserving relative ordering of indices of same type):
println '_{mn}^{\\beta\\alpha}_{ba\\alpha}'.si

   > _{mnba}^{\beta\alpha}_{\alpha}


All properties and methods of SimpleIndices leaves the relative ordering of indices unchanged.

SimpleIndices has .symmetries property which allows to define their permutational symmetries.

### Features

Since SimpleIndices is a subtype of Indices, it inherits all its properties. However, in contrast to Indices, SimpleIndices and all its properties and methods preserve the relative ordering of indices.

Consider examples. Parse SimpleIndices from string:

def indices = '^an_ab^m_pq^b'.si
println indices

   > ^{an}_{ab}^{m}_{pq}^{b}

Get just free indices:
println indices.free

   > ^{nm}_{pq}

Invert indices:
println indices.inverted

   > _{an}^{ab}_{m}^{pq}_{b}

Get only contravariant indices:
println indices.upper

   > ^{anmb}

Get only covariant indices:
println indices.lower

   > _{abpq}


Parse indices with multiple types:

def indices = '^AB_pqrs^C_A^sp'.si
println indices

   > _{pqrs}^{spABC}_{A}

Get just Latin upper case:
println indices.getOfType(LatinUpper)

   > ^{ABC}_{A}

Get first index:
println indices[0].toStringIndex()

   > _{p}

Get first Latin upper index:
println indices[LatinUpper, 0].toStringIndex()

   > ^{A}

Get several indices at a time:
println indices[1, 3, 4]

   > _{qs}^{s}

Get range:
println indices[1..4]

   > _{qrs}^{s}


As one can see, all methods in the above examples return indices which have same relative ordering as in the initial object.

### Symmetries

Symmetries can be attached to a single SimpleIndices object by using .symmetry property:

def indices = '_abcdef'.si
println indices.symmetries.permutationGroup.order()

   > 60

Symmetries of simple indices can be used in transformations like Symmetrize or other methods like GenerateTensor or Reduce.

The .symmetries property return a container of permutations and a corresponding PermutationGroup. The latter can be accessed by taking .permutationGroup property.

It should be noted, that when specifying symmetries of simple tensors like

'f_abc'.t.indices.symmetries.addSymmetry( [1, 0].p )

these symmetries will be automatically attached to indices of all instances of tensor f_abc, i. e. f_pqr or f_a^a_y etc.:
println 'f_pq^i'.t.indices.symmetries.permutationGroup

   > Group( +[[0, 1]] )


On the other hand, when specifying symmetries of “detached” indices:

def ind = '_abc'.si

they will be attached just to the particular object (ind in the above example).