[], _index

Indexed access

MuPAD® notebooks will be removed in a future release. Use MATLAB® live scripts instead.

MATLAB live scripts support most MuPAD functionality, though there are some differences. For more information, see Convert MuPAD Notebooks to MATLAB Live Scripts.

Syntax

x[ i ]
x[ i1,i2,... ]
x[ i1..i2 ]
x[ [i1,i2,...] ]
x[ [i1,i2,...], [k1,k2,...] ]
_index( x, i )
_index( x, i1,i2,... )
_index( x, i1..i2 )
_index( x, [i1,i2,...] )
_index( x, [i1,i2,...], [k1,k2,...] )

Description

_index is a functional form of the [] operator. The calls x[...] and _index(x,...) are equivalent.

x[i] returns the entry of x corresponding to the index i. Any MuPAD® object x allows an indexed call of the form x[i]. If x is not a container object (such as sets, lists, vectors, arrays, hfarrays, tables, matrices), then x[i] returns a symbolic indexed object. In particular, if x is an identifier, then x[i] returns an “indexed identifier”. In this case, indices can be arbitrary MuPAD objects. See Example 1.

x[i1,i2,...] returns the entries of x corresponding to the indices i1,i2,..., specified as a sequence. For example, if x is a matrix, then x[2, 3] returns the third element of the second row of x.

x[i1..i2] returns the entries of x corresponding to integer indices in the range [i1..i2], including x[i1] and x[i2]. In particular, this applies to lists, sets, expression sequences, and strings. See Example 7.

x[[i1,i2,...]] returns the entries of x corresponding to the specified indices, given as a list of integers. Here, x must be a list, matrix, or vector.

  • If x is a list, then x[[i1,i2,...]] returns the list [x[i] $ i in [i1,i2,...]]. See Example 8.

  • If x is a row vector, then x[[i1,i2,...]] returns the row vector matrix(1, nops([i1,i2,...]), [x[i] $ i in [i1,i2,...]]).

  • If x is a column vector, then x[[i1,i2,...]] returns the column vector matrix(nops([i1,i2,...]), 1, [x[i] $ i in [i1,i2,...]]).

x[[i1,i2,...],[k1,k2,...]] returns the matrix matrix([[x[i,k] $ k in [k1,k2,...]] $ i in [i1,i2,...]]). Here, x must be a matrix. See Example 9.

Depending on the type of x, these restrictions apply to the indices:

  • For lists, finite sets, or expression sequences, the index i can only be an integer from 1 to nops(x), or-nops(x) to -1, or a range of these numbers.

  • For arrays and hfarrays, use appropriate indices i or multiple indices i1,i2,... from the index range defined by array or hfarray. Integers outside this range cause an error. If any specified index is not an integer (for example, a symbol i), then x[i] or x[i1,i2,...] is returned symbolically.

  • For matrices, use appropriate indices i or double indices i1,i2 from the index range defined by matrix. Indices outside this range or symbolic indices cause an error.

  • For tables, you can use any object as an index. If there is no corresponding entry in the table, then x[i] or x[i1,i2,...] is returned symbolically.

  • For character strings, the index i must be an integer from 1 to length(x).

_index uses the order in which the entries appear on the screen, and op uses the internal order of the entries. For some container objects, these orders differ. In particular:

  • For lists and sequences, x[i] = op(x,i) for positive indices. For negative indices, x[i] = op(x, nops(x) + 1 + i).

  • For finite sets, x[i] returns the ith element as printed on the screen. Before screen output and indexed access, the elements of sets are sorted via the slot DOM_SET::sort. In general, x[i] <> op(x, i) for finite sets x.

  • For one-dimensional arrays x := array(1..n, [...]) or x := hfarray(1..n, [...]), the entries correspond to the operands, x[i] = op(x,i).

  • For a one-dimensional matrix representing a column vector, x[i] = x[i, 1] = op(x, i). For a one-dimensional matrix representing a row vector, x[i] = x[1, i] = op(x, i).

The entry returned by an indexed call is fully evaluated. For lists, matrices, arrays, and tables, you can suppress evaluation in indexed calls by using indexval. See Example 10.

Indexed access to expressions and numbers is implemented via library callbacks. Do not use _index in program files to access the operands of expressions and numbers. Use op instead for more efficiency.

If x is not a container object (such as sets, lists, vectors, arrays, hfarrays, tables, matrices), then indexed assignments (such as x[i] := value) implicitly convert x into a table with a single entry.

Examples

Example 1

Solve these equations specifying variables as indexed identifiers:

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)

Symbolic indexed objects are of type "_index":

type(x[i])

delete n, equations, unknowns:

Example 2

Use indices to access the entries of typical container objects, such as lists, arrays, hardware floating-point arrays, and tables:

L := [1, 2, [3, 4]]:
A := array(1..2, 2..3, [[a12, a13], [a22, a23]]):
B := hfarray(1..2, 2..3, [[12.0, 13.0], [22.0, 23.0]]):
T := table(1 = T1, x = Tx, (1, 2) = T12):
L[1], L[3][2], A[2, 3], B[2, 3], T[1], T[x], T[1, 2]

Use indexed assignments to change the entries:

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

delete L, A, B, T:

Example 3

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

S := {3, 2, 1}

S[i] $ i = 1..3

op(S, i) $ i = 1..3

delete S:

Example 4

The index operator also operates on character strings. The characters are enumerated starting from 1:

"ABCDEF"[1], "ABCDEF"[6]

Example 5

The index operator also operates on mathematical expressions containing operators, such as +, -, *, and so on:

X := a - b + c - 2;
X[2], X[3..-1];
delete X:

For expressions with _plus- and _mult operators, the output of _index corresponds to the output order of the operands. If an expression with _mult is printed as a fraction, you can access the nominator and the denominator via indices 1 and 2:

X := ((a/2 + b) * c * 2)/(e-f)/x^2;
X[1], X[2], X[1][3];
delete X:

Example 6

The index operator also operates on rational and complex numbers. For rational numbers, index 1 refers to the numerator, and index 2 refers to the denominator:

(2/3)[1], (2/3)[2]

For complex numbers, indices 1 and 2 refer to the real and imaginary parts, respectively:

(3*I)[1], (1-I)[2]

Example 7

You can use a range as an index. For lists, sets, expression sequences, and strings, this operation returns a “subexpression” consisting of the entries within the range, according to _index:

L := [1, 2, 3, 4, 5]:
S := {1, 2, 3, 4, 5}:
Str := "abcde":
L[3..4];
S[3..4];
Str[3..4]

This includes ranges with negative numbers. When you use negative indices i for container type objects x, such as lists and sets, the call x[i] returns x[nops(x) + 1 + i]. Thus, you access elements counting indices from the end of x: the index -1 refers to the last element of x, the index -2 refers to the second element from the end, and so on.

L[3..-1];
S[1..-2]

When you use negative indices i for strings, _index internally replaces Str[i] with indices op(Str, i + 1 + length(Str)):

Str[3..-1]

You also can use this form of indexing to assign values to elements of lists and strings:

L[2..4] := [234]: L;
Str[3..-1] := " ??": Str;

As seen above, this operation can change the number of elements in a list or the length of a string. If necessary, new places are filled with NIL or spaces, respectively:

L[42..42] := [42]: L;
Str[10..11] := "the end.": Str

Example 8

Use the following indexed call to return a permutation of the list L. Here, the index list perm specifies the permutation.

L := [a, b, c, d, e]:
perm := [5, 3, 1, 2, 4]:
L[perm]

Example 9

Use two lists of indices to pick and return a particular submatrix of a matrix:

A := matrix([[a11, a12, a13], [a21, a22, a23], [a31,a32, a33]]):
l1 := [1,2]: l2 := [2,3]:
A[l1, l2]

Example 10

Indexed calls evaluate the returned entry. Use indexval to suppress full evaluation:

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

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

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

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

delete x, a:

Example 11

Indexed access is not implemented for some kernel domains:

12343[3]
Error: Invalid operand. [_index]

Define a method implementing the indexed access to integer numbers:

unprotect(DOM_INT):
DOM_INT::_index := (n, i) -> text2expr(expr2text(n)[i]):
12343[3];
delete DOM_INT::_index: protect(DOM_INT):

Parameters

x

An arbitrary MuPAD object. In particular, a container object: a list, a finite set, an array, an hfarray, a matrix, a table, an expression sequence, an expression in operator notation, a rational number, a complex number, or a character string.

i

An index. For most container objects x, indices must be integers. If x is a table, you can use arbitrary MuPAD objects as indices.

i1,i2,...

Multiple indices for matrices and multidimensional arrays. For these containers, the indices must be integers. For tables, you can also use multiple indices given by arbitrary MuPAD objects.

i1..i2

Indices, specified as a range.

[i1,i2,...]

Indices, specified as a list of integers. In this case, x must be a list, matrix, or vector. (In MuPAD, a vector is a 1⨉n or n×1 matrix.)

[i1,i2...], [k1,k2...]

Indices, specified as two lists of integers. In this case, x must be a matrix.

Return Values

Entry of x corresponding to the index. Calls with lists of indices can return a sequence, a list, a vector, or a matrix of entries corresponding to the indices. If x is not a list, a set, an array, or any other container object, then the return value is an indexed object of type "_index".

Overloaded By

x