Functions and Variables for Arrays
==================================

 -- Function: array (NAME, DIM_1, ..., DIM_N)
 -- Function: array (NAME, TYPE, DIM_1, ..., DIM_N)
 -- Function: array ([NAME_1, ..., NAME_M], DIM_1, ..., DIM_N)

     Creates an n-dimensional array. n may be less than or equal to 5. The subscripts for the i'th dimension are the integers running from 0 to DIM_I.

     array (NAME, DIM_1, ..., DIM_N) creates a general array.

     array (NAME, TYPE, DIM_1, ..., DIM_N) creates an array, with elements of a specified type. TYPE can be fixnum for integers of limited size or flonum for floating-point numbers.

     array ([NAME_1, ..., NAME_M], DIM_1, ..., DIM_N) creates m arrays, all of the same dimensions.

     If the user assigns to a subscripted variable before declaring the corresponding array, an undeclared array is created. Undeclared arrays, otherwise known as hashed arrays (because hash coding is done on the subscripts), are more general than declared arrays.  The user does not declare their maximum size, and they grow dynamically by hashing as more elements are assigned values.  The subscripts of undeclared arrays need not even be numbers.  However, unless an array is rather sparse, it is probably more efficient to declare it when possible than to leave it undeclared.  The array function can be used to transform an undeclared array into a declared array.

 -- Function: arrayapply (A, [I_1, ..., I_N])
     Evaluates A [I_1, ..., I_N], where A is an array and I_1, ..., I_N are integers.

     This is reminiscent of apply, except the first argument is an array instead of a function.

 -- Function: arrayinfo (A)
     Returns information about the array A. The argument A may be a declared array, an undeclared (hashed) array, an array function, or a subscripted function.

     For declared arrays, arrayinfo returns a list comprising the atom declared, the number of dimensions, and the size of each dimension. The elements of the array, both bound and unbound, are returned by listarray.

     For undeclared arrays (hashed arrays), arrayinfo returns a list comprising the atom hashed, the number of subscripts, and the subscripts of every element which has a value. The values are returned by listarray.

     For array functions, arrayinfo returns a list comprising the atom hashed, the number of subscripts, and any subscript values for which there are stored function values. The stored function values are returned by listarray.

     For subscripted functions, arrayinfo returns a list comprising the atom hashed, the number of subscripts, and any subscript values for which there are lambda expressions. The lambda expressions are returned by listarray.

     Examples:

     arrayinfo and listarray applied to a declared array.

          (%i1) array (aa, 2, 3);
          (%o1)                          aa
          (%i2) aa [2, 3] : %pi;
          (%o2)                          %pi
          (%i3) aa [1, 2] : %e;
          (%o3)                          %e
          (%i4) arrayinfo (aa);
          (%o4)                 [declared, 2, [2, 3]]
          (%i5) listarray (aa);
          (%o5) [#####, #####, #####, #####, #####, #####, %e, #####,
                                                  #####, #####, #####, %pi]

     arrayinfo and listarray applied to an undeclared (hashed) array.

          (%i1) bb [FOO] : (a + b)^2;
                                             2
          (%o1)                       (b + a)
          (%i2) bb [BAR] : (c - d)^3;
                                             3
          (%o2)                       (c - d)
          (%i3) arrayinfo (bb);
          (%o3)               [hashed, 1, [BAR], [FOO]]
          (%i4) listarray (bb);
                                        3         2
          (%o4)                 [(c - d) , (b + a) ]

     arrayinfo and listarray applied to an array function.

          (%i1) cc [x, y] := y / x;
                                               y
          (%o1)                      cc     := -
                                       x, y    x
          (%i2) cc [u, v];
                                          v
          (%o2)                           -
                                          u
          (%i3) cc [4, z];
                                          z
          (%o3)                           -
                                          4
          (%i4) arrayinfo (cc);
          (%o4)              [hashed, 2, [4, z], [u, v]]
          (%i5) listarray (cc);
                                        z  v
          (%o5)                        [-, -]
                                        4  u

     arrayinfo and listarray applied to a subscripted function.

          (%i1) dd [x] (y) := y ^ x;
                                               x
          (%o1)                     dd (y) := y
                                      x
          (%i2) dd [a + b];
                                              b + a
          (%o2)                  lambda([y], y     )
          (%i3) dd [v - u];
                                              v - u
          (%o3)                  lambda([y], y     )
          (%i4) arrayinfo (dd);
          (%o4)             [hashed, 1, [b + a], [v - u]]
          (%i5) listarray (dd);
                                   b + a                v - u
          (%o5)      [lambda([y], y     ), lambda([y], y     )]

 -- Function: arraymake (A, [I_1, ..., I_N])
     Returns the expression A[I_1, ..., I_N]. The result is an unevaluated array reference.

     arraymake is reminiscent of funmake, except the return value is an unevaluated array reference instead of an unevaluated function call.

     Examples:

          (%i1) arraymake (A, [1]);
          (%o1)                          A
                                          1
          (%i2) arraymake (A, [k]);
          (%o2)                          A
                                          k
          (%i3) arraymake (A, [i, j, 3]);
          (%o3)                       A
                                       i, j, 3
          (%i4) array (A, fixnum, 10);
          (%o4)                           A
          (%i5) fillarray (A, makelist (i^2, i, 1, 11));
          (%o5)                           A
          (%i6) arraymake (A, [5]);
          (%o6)                          A
                                          5
          (%i7) ''%;
          (%o7)                          36
          (%i8) L : [a, b, c, d, e];
          (%o8)                    [a, b, c, d, e]
          (%i9) arraymake ('L, [n]);
          (%o9)                          L
                                          n
          (%i10) ''%, n = 3;
          (%o10)                          c
          (%i11) A2 : make_array (fixnum, 10);
          (%o11)          {Array:  #(0 0 0 0 0 0 0 0 0 0)}
          (%i12) fillarray (A2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
          (%o12)          {Array:  #(1 2 3 4 5 6 7 8 9 10)}
          (%i13) arraymake ('A2, [8]);
          (%o13)                         A2
                                           8
          (%i14) ''%;
          (%o14)                          9

 -- System variable: arrays
     Default value: []

     arrays is a list of arrays that have been allocated. These comprise arrays declared by array, hashed arrays constructed by implicit definition (assigning something to an array element), and array functions defined by := and define. Arrays defined by make_array are not included.

     See also array, arrayapply, arrayinfo, arraymake, fillarray, listarray, and rearray.

     Examples:

          (%i1) array (aa, 5, 7);
          (%o1)                          aa
          (%i2) bb [FOO] : (a + b)^2;
                                             2
          (%o2)                       (b + a)
          (%i3) cc [x] := x/100;
                                             x
          (%o3)                      cc  := ---
                                       x    100
          (%i4) dd : make_array ('any, 7);
          (%o4)       {Array:  #(NIL NIL NIL NIL NIL NIL NIL)}
          (%i5) arrays;
          (%o5)                     [aa, bb, cc]

 -- Function: bashindices (EXPR)
     Transforms the expression EXPR by giving each summation and product a unique index. This gives changevar greater precision when it is working with summations or products.  The form of the unique index is jNUMBER. The quantity NUMBER is determined by referring to gensumnum, which can be changed by the user.  For example, gensumnum:0$ resets it.

 -- Function: fillarray (A, B)
     Fills array A from B, which is a list or an array.

     If a specific type was declared for A when it was created, it can only be filled with elements of that same type; it is an error if an attempt is made to copy an element of a different type.

     If the dimensions of the arrays A and B are different, A is filled in row-major order.  If there are not enough elements in B the last element is used to fill out the rest of A.  If there are too many, the remaining ones are ignored.

     fillarray returns its first argument.

     Examples:

     Create an array of 9 elements and fill it from a list.

          (%i1) array (a1, fixnum, 8);
          (%o1)                          a1
          (%i2) listarray (a1);
          (%o2)              [0, 0, 0, 0, 0, 0, 0, 0, 0]
          (%i3) fillarray (a1, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
          (%o3)                          a1
          (%i4) listarray (a1);
          (%o4)              [1, 2, 3, 4, 5, 6, 7, 8, 9]

     When there are too few elements to fill the array, the last element is repeated. When there are too many elements, the extra elements are ignored.

          (%i1) a2 : make_array (fixnum, 8);
          (%o1)             {Array:  #(0 0 0 0 0 0 0 0)}
          (%i2) fillarray (a2, [1, 2, 3, 4, 5]);
          (%o2)             {Array:  #(1 2 3 4 5 5 5 5)}
          (%i3) fillarray (a2, [4]);
          (%o3)             {Array:  #(4 4 4 4 4 4 4 4)}
          (%i4) fillarray (a2, makelist (i, i, 1, 100));
          (%o4)             {Array:  #(1 2 3 4 5 6 7 8)}

     Multple-dimension arrays are filled in row-major order.

          (%i1) a3 : make_array (fixnum, 2, 5);
          (%o1)        {Array:  #2A((0 0 0 0 0) (0 0 0 0 0))}
          (%i2) fillarray (a3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
          (%o2)        {Array:  #2A((1 2 3 4 5) (6 7 8 9 10))}
          (%i3) a4 : make_array (fixnum, 5, 2);
          (%o3)     {Array:  #2A((0 0) (0 0) (0 0) (0 0) (0 0))}
          (%i4) fillarray (a4, a3);
          (%o4)     {Array:  #2A((1 2) (3 4) (5 6) (7 8) (9 10))}

 -- Function: listarray (A)
     Returns a list of the elements of the array A. The argument A may be a declared array, an undeclared (hashed) array, an array function, or a subscripted function.

     Elements are listed in row-major order. That is, elements are sorted according to the first index, then according to the second index, and so on. The sorting order of index values is the same as the order established by orderless.

     For undeclared arrays, array functions, and subscripted functions, the elements correspond to the index values returned by arrayinfo.

     Unbound elements of declared general arrays (that is, not fixnum and not flonum) are returned as #####. Unbound elements of declared fixnum or flonum arrays are returned as 0 or 0.0, respectively. Unbound elements of undeclared arrays, array functions, and subscripted functions are not returned.

     Examples:

     listarray and arrayinfo applied to a declared array.

          (%i1) array (aa, 2, 3);
          (%o1)                          aa
          (%i2) aa [2, 3] : %pi;
          (%o2)                          %pi
          (%i3) aa [1, 2] : %e;
          (%o3)                          %e
          (%i4) listarray (aa);
          (%o4) [#####, #####, #####, #####, #####, #####, %e, #####,
                                                  #####, #####, #####, %pi]
          (%i5) arrayinfo (aa);
          (%o5)                 [declared, 2, [2, 3]]

     listarray and arrayinfo applied to an undeclared (hashed) array.

          (%i1) bb [FOO] : (a + b)^2;
                                             2
          (%o1)                       (b + a)
          (%i2) bb [BAR] : (c - d)^3;
                                             3
          (%o2)                       (c - d)
          (%i3) listarray (bb);
                                        3         2
          (%o3)                 [(c - d) , (b + a) ]
          (%i4) arrayinfo (bb);
          (%o4)               [hashed, 1, [BAR], [FOO]]

     listarray and arrayinfo applied to an array function.

          (%i1) cc [x, y] := y / x;
                                               y
          (%o1)                      cc     := -
                                       x, y    x
          (%i2) cc [u, v];
                                          v
          (%o2)                           -
                                          u
          (%i3) cc [4, z];
                                          z
          (%o3)                           -
                                          4
          (%i4) listarray (cc);
                                        z  v
          (%o4)                        [-, -]
                                        4  u
          (%i5) arrayinfo (cc);
          (%o5)              [hashed, 2, [4, z], [u, v]]

     listarray and arrayinfo applied to a subscripted function.

          (%i1) dd [x] (y) := y ^ x;
                                               x
          (%o1)                     dd (y) := y
                                      x
          (%i2) dd [a + b];
                                              b + a
          (%o2)                  lambda([y], y     )
          (%i3) dd [v - u];
                                              v - u
          (%o3)                  lambda([y], y     )
          (%i4) listarray (dd);
                                   b + a                v - u
          (%o4)      [lambda([y], y     ), lambda([y], y     )]
          (%i5) arrayinfo (dd);
          (%o5)             [hashed, 1, [b + a], [v - u]]

 -- Function: make_array (TYPE, DIM_1, ..., DIM_N)
     Creates and returns a Lisp array.  TYPE may be any, flonum, fixnum, hashed or functional. There are n indices, and the i'th index runs from 0 to DIM_I - 1.

     The advantage of make_array over array is that the return value doesn't have a name, and once a pointer to it goes away, it will also go away. For example, if y: make_array (...) then y points to an object which takes up space, but after y: false, y no longer points to that object, so the object can be garbage collected.

     Examples:

          (%i1) A1 : make_array (fixnum, 10);
          (%o1)           {Array:  #(0 0 0 0 0 0 0 0 0 0)}
          (%i2) A1 [8] : 1729;
          (%o2)                         1729
          (%i3) A1;
          (%o3)          {Array:  #(0 0 0 0 0 0 0 0 1729 0)}
          (%i4) A2 : make_array (flonum, 10);
          (%o4) {Array:  #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}
          (%i5) A2 [2] : 2.718281828;
          (%o5)                      2.718281828
          (%i6) A2;
          (%o6)
               {Array:  #(0.0 0.0 2.718281828 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}
          (%i7) A3 : make_array (any, 10);
          (%o7) {Array:  #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)}
          (%i8) A3 [4] : x - y - z;
          (%o8)                      - z - y + x
          (%i9) A3;
          (%o9) {Array:  #(NIL NIL NIL NIL ((MPLUS SIMP) $X ((MTIMES SIMP)\
           -1 $Y) ((MTIMES SIMP) -1 $Z))
            NIL NIL NIL NIL NIL)}
          (%i10) A4 : make_array (fixnum, 2, 3, 5);
          (%o10) {Array:  #3A(((0 0 0 0 0) (0 0 0 0 0) (0 0 0 0 0)) ((0 0 \
          0 0 0) (0 0 0 0 0) (0 0 0 0 0)))}
          (%i11) fillarray (A4, makelist (i, i, 1, 2*3*5));
          (%o11) {Array:  #3A(((1 2 3 4 5) (6 7 8 9 10) (11 12 13 14 15))
              ((16 17 18 19 20) (21 22 23 24 25) (26 27 28 29 30)))}
          (%i12) A4 [0, 2, 1];
          (%o12)                         12

 -- Function: rearray (A, DIM_1, ..., DIM_N)
     Changes the dimensions of an array. The new array will be filled with the elements of the old one in row-major order.  If the old array was too small, the remaining elements are filled with false, 0.0 or 0, depending on the type of the array.  The type of the array cannot be changed.

 -- Function: remarray (A_1, ..., A_N)
 -- Function: remarray (all)
     Removes arrays and array associated functions and frees the storage occupied. The arguments may be declared arrays, undeclared (hashed) arrays, array functions, and subscripted functions.

     remarray (all) removes all items in the global list arrays.

     It may be necessary to use this function if it is desired to redefine the values in a hashed array.

     remarray returns the list of arrays removed.

 -- Function: subvar (X, I)
     Evaluates the subscripted expression X[I].

     subvar evaluates its arguments.

     arraymake (X, [I] constructs the expression X[I], but does not evaluate it.

     Examples:

          (%i1) x : foo $

          (%i2) i : 3 $

          (%i3) subvar (x, i);
          (%o3)                         foo
                                           3
          (%i4) foo : [aa, bb, cc, dd, ee]$

          (%i5) subvar (x, i);
          (%o5)                          cc
          (%i6) arraymake (x, [i]);
          (%o6)                         foo
                                           3
          (%i7) ''%;
          (%o7)                          cc

 -- Option variable: use_fast_arrays
     - if true then only two types of arrays are recognized.

     1) The art-q array (t in Common Lisp) which may have several dimensions indexed by integers, and may hold any Lisp or Maxima object as an entry.  To construct such an array, enter a:make_array(any,3,4); then a will have as value, an array with twelve slots, and the indexing is zero based.

     2) The Hash_table array which is the default type of array created if one does b[x+1]:y^2 (and b is not already an array, a list, or a matrix -- if it were one of these an error would be caused since x+1 would not be a valid subscript for an art-q array, a list or a matrix). Its indices (also known as keys) may be any object. It only takes one key at a time (b[x+1,u]:y would ignore the u). Referencing is done by b[x+1] ==> y^2.  Of course the key may be a list, e.g. b[[x+1,u]]:y would be valid.  This is incompatible with the old Maxima hash arrays, but saves consing.

     An advantage of storing the arrays as values of the symbol is that the usual conventions about local variables of a function apply to arrays as well.  The Hash_table type also uses less consing and is more efficient than the old type of Maxima hashar.  To obtain consistent behaviour in translated and compiled code set translate_fast_arrays to be true.