## `array` -- create an array

#### Introduction

`array(`m1..n1, m2..n2, ...`)` creates an array with uninitialized entries, where the first index runs from m1 to n1, the second index runs from m2 to n2, etc.

`array(`m1..n1, m2..n2, ..., list`)` creates an array with entries initialized from `list`.

#### Call(s)

`array(m1..n1 <, m2..n2, ...>)`
`array(m1..n1, <m2..n2, ...,> index1 = entry1, index2 = entry2, ...)`
`array(m1..n1, <m2..n2, ...,> list)`

#### Parameters

`m1, n1, m2, n2, ...` | - | the boundaries: integers
`index1, index2, ...` | - | a sequence of integers defining a valid array index
`entry1, entry2, ...` | - | arbitrary objects
`list` | - | a list, possibly nested

#### Returns

an object of type `DOM_ARRAY`.

#### Related Functions

`_assign`, `_index`, `assignElements`, `delete`, `DOM_ARRAY`, `DOM_LIST`, `DOM_TABLE`, `indexval`, `matrix`, `table`

#### Details

- Arrays are container objects for storing data. In contrast to `tables`, the indices must be sequences of integers. While `tables` may grow in size dynamically, the number of entries in an array is fixed.
- For an array `A`, say, and a sequence of integers `index` forming a valid array index, an indexed call `A[index]` returns the corresponding entry. If the entry is uninitialized, then the indexed expression `A[index]` is returned. See examples 1 and 4.
- An indexed assignment of the form `A[index]:=entry` initializes or overwrites the entry corresponding to `index`. See examples 1 and 4.
- `array` creates an array. The boundaries must satisfy m1 <= n1, m2 <= n2, etc. The dimension of the resulting array is the number of given range arguments; at least one range argument is mandatory. The total number of entries of the resulting array is (m1 - n1 + 1)*(m2 - n2 + 1)*....

- If only index range arguments are given, then an array with uninitialized entries is created. See example 1.
- If equations of the form `index=entry` are present, then the array entry corresponding to `index` is initialized with `entry`. This is useful for selectively initializing some particular array entries.

  Each index must be a valid array index of the form `i1` for one-dimensional arrays and `(i1,i2,..)` for higher-dimensional arrays, where `i1,i2,...` are integers within the valid boundaries, satisfying m1 <= i1 <= n1, m2 <= i2 <= n2, etc., and the number of integers in `index` matches the dimension of the array.

- If the argument `list` is present, then the resulting array is initialized with the entries from `list`. This is useful for initializing all array entries at once. The structure of the list must match the structure of the array exactly, such that the nesting depth of the list is greater or equal to the dimension of the array and the number of list entries at the kth nesting level is equal to the size of the kth index range. Cf. example 6.
- A call of the form `delete A[index]` deletes the entry corresponding to `index`, so that it becomes uninitialized again. See example 4.

- Internally, uninitialized array entries have the value `NIL`. Thus assigning `NIL` to an array entry has the same effect as deleting it via `delete`, and afterwards an indexed call of the form `A[index]` returns the symbolic expression `A[index]`, and not `NIL`, as one might expect. See example 4.

- A one-dimensional array is printed as a row vector. The index corresponds to the column number.
- A two-dimensional array is printed as a matrix. The first index corresponds to the row number and the second index corresponds to the column number.
- A one- or two-dimensional array that is so big that it would exceed the maximal output width `TEXTWIDTH` is printed in the form
  `array(`m1..n1, m2..n2, ..., index1 = entry1, index2 = entry2, ...`)`
  See example 8. The same is true for arrays of dimension greater than two. See examples 5 and 6.
- Arithmetic operations are not defined for arrays. Use `matrix` to create one-dimensional vectors and two-dimensional matrices in the mathematical sense.
- If an array is evaluated, it is only returned. The evaluation does not map recursively on the array entries. This is due to performance reasons. You have to `map` the function `eval` explicitly on the array in order to fully evaluate its entries. See example 7.
- `array` is a function of the system kernel.

#### Example 1

We create an uninitialized one-dimensional array with indices ranging from 2 to 4:

    >> A := array(2..4)

                               +-                -+
                               | ?[2], ?[3], ?[4] |
                               +-                -+

The question marks in the output indicate that the array entries are not initialized. We set the middle entry to 5 and last entry to `"MuPAD"`:

    >> A[3] := 5: A[4] := "MuPAD": A

                               +-                -+
                               | ?[2], 5, "MuPAD" |
                               +-                -+

You can access array entries via indexed calls. Since the entry `A[2]` is not initialized, the symbolic expression `A[2]` is returned:

    >> A[2], A[3], A[4]

                                 A[2], 5, "MuPAD"

We can initialize an array already when creating it by passing initialization equations to `array`:

    >> A := array(2..4, 3 = 5, 4 = "MuPAD")

                               +-                -+
                               | ?[2], 5, "MuPAD" |
                               +-                -+

We can initialize all entries of an array when creating it by passing a list of initial values to `array`:

    >> array(2..4, [PI, 5, "MuPAD"])

                                +-              -+
                                | PI, 5, "MuPAD" |
                                +-              -+

#### Example 2

Array boundaries may be negative integers as well:

    >> A := array(-1..1, [2, sin(x), FAIL])

                                +-               -+
                                | 2, sin(x), FAIL |
                                +-               -+

    >> A[-1], A[0], A[1]

                                  2, sin(x), FAIL

#### Example 3

The `$` operator may be used to create a sequence of initialization equations:

    >> array(1..8, i = i^2 $ i = 1..8)

                          +-                           -+
                          | 1, 4, 9, 16, 25, 36, 49, 64 |
                          +-                           -+

Equivalently, you can use the `$` operator to create an initialization list:

    >> array(1..8, [i^2 $ i = 1..8])

                          +-                           -+
                          | 1, 4, 9, 16, 25, 36, 49, 64 |
                          +-                           -+

#### Example 4

We create a 2 by 2 matrix as a two-dimensional array:

    >> A := array(1..2, 1..2, (1, 2) = 42, (2, 1) = 1 + I)

                              +-                  -+
                              |  ?[1, 1],    42    |
                              |                    |
                              |   1 + I,  ?[2, 2]  |
                              +-                  -+

Internally, array entries are stored in a linearized form. They can be accessed in this form via `op`. Uninitialized entries internally have the value `NIL`:

    >> op(A, 1), op(A, 2), op(A, 3), op(A, 4)

                                NIL, 42, 1 + I, NIL

Note the difference to the indexed access:

    >> A[1, 1], A[1, 2], A[2, 1], A[2, 2]

                            A[1, 1], 42, 1 + I, A[2, 2]

We can modify an array entry by an indexed assignment:

    >> A[1, 1] := 0: A[1, 2] := 5: A

                               +-                -+
                               |    0,      5     |
                               |                  |
                               |  1 + I, ?[2, 2]  |
                               +-                -+

You can delete the value of an array entry via `delete`. Afterwards, it is uninitialized again:

    >> delete A[2, 1]: A[2, 1], op(A, 3)

                                   A[2, 1], NIL

Assigning `NIL` to an array entry has the same effect as deleting it:

    >> A[1, 2] := NIL: A[1, 2], op(A, 2)

                                   A[1, 2], NIL

#### Example 5

We define a three-dimensional array with index values between 1 and 8 in each of the three dimensions and initialize two of the entries via initialization equations:

    >> A := array(1..8, 1..8, 1..8,
                  (1, 1, 1) = 111,
                  (8, 8, 8) = 888)

                              array(1..8, 1..8, 1..8,
                                (1, 1, 1) = 111,
                                (8, 8, 8) = 888
                              )

    >> A[1, 1, 1], A[1, 1, 2]

                                  111, A[1, 1, 2]

#### Example 6

A nested list may be used to initialize a two-dimensional array. The inner lists are the rows of the created matrix:

    >> array(1..2, 1..3, [[1, 2, 3], [4, 5, 6]])

                                   +-         -+
                                   |  1, 2, 3  |
                                   |           |
                                   |  4, 5, 6  |
                                   +-         -+

We create a three-dimensional array and initialize it from a nested list of depth three. The outer list has two entries for the first dimension. Each of these entries is a list with three entries for the second dimension. Finally, the innermost lists each have one entry for the third dimension:

    >> array(2..3, 1..3, 1..1,
             [
               [ [1], [2], [3] ],
               [ [4], [5], [6] ]
             ])

                              array(2..3, 1..3, 1..1,
                                (2, 1, 1) = 1,
                                (2, 2, 1) = 2,
                                (2, 3, 1) = 3,
                                (3, 1, 1) = 4,
                                (3, 2, 1) = 5,
                                (3, 3, 1) = 6
                              )

#### Example 7

If an array is evaluated, it is only returned. The evaluation does not map recursively on the array entries. Here, the entries `a` and `b` are not evaluated:

    >> A := array(1..2, [a, b]):
       a := 1:  b := 2:
       A, eval(A)

                                +-    -+  +-    -+
                                | a, b |, | a, b |
                                +-    -+  +-    -+

Due to the special evaluation of arrays the index operator evaluates array entries after extracting them from the array:

    >> A[1], A[2]

                                       1, 2

You have to `map` the function `eval` explicitly on the array in order to fully evaluate its entries:

    >> map(A, eval)

                                     +-    -+
                                     | 1, 2 |
                                     +-    -+

#### Example 8

A two-dimensional array is usually printed in matrix form:

    >> A := array(1..4, 1..4,
                  (1, 1) = 11,
                  (4, 4) = 44)

                     +-                                    -+
                     |     11,   ?[1, 2], ?[1, 3], ?[1, 4]  |
                     |                                      |
                     |  ?[2, 1], ?[2, 2], ?[2, 3], ?[2, 4]  |
                     |                                      |
                     |  ?[3, 1], ?[3, 2], ?[3, 3], ?[3, 4]  |
                     |                                      |
                     |  ?[4, 1], ?[4, 2], ?[4, 3],    44    |
                     +-                                    -+

If the output does not fit into `TEXTWIDTH`, a more compact output is used:

    >> TEXTWIDTH := 20:
       A;
       delete TEXTWIDTH:

           array(1..4, 1..4,
             (1, 1) = 11,
             (4, 4) = 44
           )

#### Changes

- Divided arrays are no longer supported.
- Negative integers are now allowed as boundaries.

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