# Indices

### Basics

Indices represents indices of tensor. Indices is a simple container of single indices. For all types of tensors except SimpleTensor and TensorField, Indices are always sorted in some predefined way (e.g. first upper then lower, first Latin then Greek, in each group indices sorted in lexicographical order etc.):

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

   > ^{psABC}_{pqrsA}


The indices of SimpleTensor and TensorField are SimpleIndices — a subtype of Indices that are not sorted.

At the low-level, Redberry stores each single index as 32-bit integer that encodes all information about index: state, type and name (serial number in the alphabet). Within a particular index type, there are $2^{16}$ possible names, which can be inputted using the subscript:

def indices = 'X_{\\mu_3 a_{122} a_1 b_9}'.i
println indices

   > _{a_{1}b_{9}a_{122}\mu_{3}}


### Features

Here is a list of common Indices properties and methods:

 .free free indices .inverted inverted indices .upper contravariant indices .lower covariant indices .getOfType(type) sub-indices of specified type .size() number of indices [i] i-th index [i..j] indices from i-th (inclusive) to j-th (exclusive) [i, j, k] i, j, k-th indices etc. [type, i] i-th index of type type

Consider examples. Parse indices from string:

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

   > ^{abmn}_{abpq}

Get just free indices:
println indices.free

   > ^{mn}_{pq}

Invert indices:
println indices.inverted

   > ^{abpq}_{abmn}

Get only contra variant indices:
println indices.upper

   > ^{abmn}

Get only covariant indices:
println indices.lower

   > _{abpq}


Parse indices with multiple types:

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

   > ^{psABC}_{pqrsA}

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

   > ^{ABC}_{A}

Get first index:
println indices.toStringIndex()

   > ^{p}

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

   > ^{A}

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

   > ^{sBC}

Get range:
println indices[1..4]

   > ^{sABC}


As one can see, all methods in the above examples return also sorted indices.

### Creating indices

Get indices of tensor:

println 't_ba*f^dc'.t.indices

   > ^cd_ab

Parse indices from string using .i property:
println '_ba^dc'.i

   > ^cd_ab

Convert array of single indices into Indices:
println( [0, 1, 2, 3.invert()] as Indices )

   > ^d_abc

Concatenate several Indices objects:
println ( '_abc'.i + '^cad'.i )

   > ^{acd}_{abc}