## `_index` -- indexed access

#### Introduction

`x[i]` and `x[i1, i2, ...]` yield the entries of `x` corresponding to the indices `i` and `i1, i2, ...`, respectively.

#### Call(s)

x[i] `_index(x, i)`
x[i1, i2, ...] `_index(x, i1, i2, ...)`

#### Parameters

`x` | - | an arbitrary MuPAD object. In particular, a ``container object'': a list, a finite set, an array, a matrix, a table, an expression sequence, or a character string.
`i, i1, i2, ...` | - | indices. For most ``containers'' `x`, indices must be integers. If `x` is a table, arbitrary MuPAD objects can be used as indices.

#### Returns

the entry of `x` corresponding to the index. If `x` is not a list, a set, an array etc., an indexed object of type `"_index"` is returned.

### Overloadable:

`x`

#### Related Functions

`:=`, `_assign`, `array`, `contains`, `DOM_ARRAY`, `DOM_LIST`, `DOM_SET`, `DOM_STRING`, `DOM_TABLE`, `indexval`, `op`, `slot`, `table`

#### Details

- `x[i]` and `x[i1, i2, ...]` are equivalent to `_index(`x, i`)` and `_index(`x, i1, i2, ...`)`, respectively.
- Any MuPAD object `x` allows an indexed call of the form `x[i]` or `x[i1, i2, ...]`. If `x` is not a ``container object'' (a list, a set, an array etc.), a symbolic indexed object is returned. In particular, ``indexed identifiers'' are returned if `x` is an identifier. In this case, indices may be arbitrary MuPAD objects. Cf. example 1.
- For lists, finite sets, and expression sequences, the index `i` is restricted to the integers from `1` through `nops(x)`. For lists and sequences, `x[i] = op(x, i)` holds.

- For finite sets, `x[i]` returns the `i`-th element as printed on the screen. Note, however, that the function `op` refers to the internal ordering of the elements: in general, `x[i] <> op(x, i)` for sets. Before screen output and indexed access, the elements of sets are sorted via the slot `DOM_SET::sort`.

- For arrays, appropriate indices `i` or multi-indices `i1, i2, ...` from the index range defined by `array` must be used. If any specified index is an integer outside the admissible range, an error occurs. If any specified index is not an integer (e.g., a symbol `i`), then `x[i]` or `x[i1, i2,...]` is returned symbolically. For one-dimensional arrays `x := array(1..n, [...])`, the entries correspond to the operands: `x[i] = op(x, i)`.
- For matrices, appropriate indices `i` or multi-indices `i1, i2, ...` from the index range defined by `matrix` must be used. Indices outside this range or symbolic indices lead to an error. For a one-dimensional matrix representing a column vector, `x[i] = x[i, 1] = op(x, i)` holds. For a one-dimensional matrix representing a row vector, `x[i] = x[1, i] = op(x, i)` holds.
- For tables, any index may be used. If there is no corresponding entry in the table, `x[i]` or `x[i1, i2, ...]` is returned symbolically.

- For character strings, the index `i` is restricted to the integers from `0` through `length(x) - 1`. Note that the first character of a string carries the index `0`!

- Usually, the entry returned by an indexed call is fully evaluated.

  Only matrices behave differently: `x[i]` and `x[i1, i2, ...]` return the value of the entry, but not its full evaluation. Cf. example 5.

  For arrays and tables, evaluation can be suppressed in indexed calls via `indexval`.

- Note, that an indexed assignment such as `x[i] := value` implicitly turns `x` into a table with a single entry, if `x` is not one of the ``container'' types above.

- `_index` is a function of the system kernel.

#### Example 1

Indexed identifiers are useful when solving equations in many unknowns:

    >> n := 4:
       equations := {x[i-1] - 2*x[i] + x[i+1] = 1 $ i = 1..n}:
       unknowns := {x[i] $ i = 1..n}:
       linsolve(equations, unknowns)

          --        4 x[0]   x[5]             3 x[0]   2 x[5]
          |  x[1] = ------ + ---- - 2, x[2] = ------ + ------ - 3,
          --          5       5                 5        5

                    2 x[0]   3 x[5]             x[0]   4 x[5]     --
             x[3] = ------ + ------ - 3, x[4] = ---- + ------ - 2  |
                      5        5                 5       5        --

Symbolic indexed objects are of type `"_index"`:

    >> type(x[i])

                                     "_index"

    >> delete n, equations, unknowns:

#### Example 2

Lists, arrays and tables are typical containers allowing indexed access to their elements:

    >> L := [1, 2, [3, 4]]:
       A := array(1..2, 2..3, [[a12, a13], [a22, a23]]):
       T := table( 1 = T1, x = Tx, (1, 2) = T12):

    >> L[1], L[3][2], A[2, 3], T[1], T[x], T[1, 2]

                              1, 4, a23, T1, Tx, T12

The entries can be changed via indexed assignments:

    >> L[2] := 22: L[3][2]:= 32: A[2, 3]:= 23: T[x] := T12: L, A, T

                                   +-          -+  table(
                                   |  a12, a13  |    (1, 2) = T12,
                 [1, 22, [3, 32]], |            |,   x = T12,
                                   |  a22,  23  |    1 = T1
                                   +-          -+  )

    >> delete L, A, T:

#### Example 3

For finite sets, an indexed call `x[i]` returns the `i`-th element as printed on the screen. This element does not necessarily coincide with the `i`-th (internal) operand as returned by `op`:

    >> S := {1, 2, 3, x}

                                   {x, 1, 2, 3}

    >> S[i] $ i = 1..4

                                    x, 1, 2, 3

    >> op(S, i) $ i = 1..4

                                    x, 3, 2, 1

    >> delete S:

#### Example 4

The index operator also operates on character strings. Note that the characters are enumerated from 0:

    >> "ABCDEF"[0], "ABCDEF"[5]

                                     "A", "F"

#### Example 5

Usually, indexed calls evaluate the returned entry:

    >> delete a: x := [a, b]: a := c: x[1] = eval(x[1])

                                       c = c

    >> delete a: x := table(1 = a, 2 = b): a := c: x[1] = eval(x[1])

                                       c = c

    >> delete a: x := array(1..2, [a, b]): a := c: x[1] = eval(x[1])

                                       c = c

Matrices behave differently:

    >> delete a: x := matrix([a, b]): a := c: x[1], eval(x[1])

                                       a, c

    >> delete x, a:

#### Changes

- no changes

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000