1 @c -----------------------------------------------------------------------------
3 @node Arrays, Structures, Lists, Data Types and Structures
5 @c -----------------------------------------------------------------------------
7 Maxima supports 3 array-like constructs:
10 @anchor{hashed arrays}
11 @anchor{undeclared array}
12 @anchor{undeclared arrays}
13 @item If one tries to write to an indexed variable without creating a list first an
14 undeclared array (also named hashed array) is created that grows dynamically and
15 allows numbers, symbols and strings as indices:
50 Since lisp handles hashed arrays and @mref{memoizing functions} similar to arrays
51 many of the functions that can be applied to arrays can be applied to them, as well.
52 @item Lists (see @mref{makelist} allow for fast addition and removal
53 of elements, can be created without knowing their final size.
54 @item Declared arrays that allow fast access to random elements at the cost that their
55 size needs to be known at construction time.
56 (@xref{Performance considerations for Lists}.)
60 * Functions and Variables for Arrays::
63 @c -----------------------------------------------------------------------------
64 @node Functions and Variables for Arrays, , Arrays, Arrays
65 @subsection Functions and Variables for Arrays
66 @c -----------------------------------------------------------------------------
68 @c -----------------------------------------------------------------------------
70 @deffn {Function} array @
71 @fname{array} (@var{name}, @var{dim_1}, @dots{}, @var{dim_n}) @
72 @fname{array} (@var{name}, @var{type}, @var{dim_1}, @dots{}, @var{dim_n}) @
73 @fname{array} ([@var{name_1}, @dots{}, @var{name_m}], @var{dim_1}, @dots{}, @var{dim_n})
75 Creates an @math{n}-dimensional array. @math{n} may be less than or equal to 5.
76 The subscripts for the @math{i}'th dimension are the integers running from 0 to
79 @code{array (@var{name}, @var{dim_1}, ..., @var{dim_n})} creates a general
82 @code{array (@var{name}, @var{type}, @var{dim_1}, ..., @var{dim_n})} creates
83 an array, with elements of a specified type. @var{type} can be @code{fixnum}
84 for integers of limited size or @code{flonum} for floating-point numbers.
86 @code{array ([@var{name_1}, ..., @var{name_m}], @var{dim_1}, ..., @var{dim_n})}
87 creates @math{m} arrays, all of the same dimensions.
88 @c SAME TYPE AS WELL ??
90 See also @mrefcomma{arraymake} @mref{arrayinfo} and @mrefdot{make_array}
92 @opencatbox{Categories:}
97 @c -----------------------------------------------------------------------------
99 @deffn {Function} arrayapply (@var{A}, [@var{i_1}, @dots{}, @var{i_n}])
101 Evaluates @code{@var{A} [@var{i_1}, ..., @var{i_n}]},
102 where @var{A} is an array and @var{i_1}, @dots{}, @var{i_n} are integers.
104 This is reminiscent of @mrefcomma{apply} except the first argument is an array
105 instead of a function.
107 @opencatbox{Categories:}
108 @category{Expressions}
113 @c -----------------------------------------------------------------------------
115 @deffn {Function} arrayinfo (@var{A})
117 Returns information about the array @var{A}.
118 The argument @var{A} may be a declared array, a @mrefcomma{hashed array}
119 a @mrefcomma{memoizing function} or a subscripted function.
121 For declared arrays, @code{arrayinfo} returns a list comprising the atom
122 @code{declared}, the number of dimensions, and the size of each dimension.
123 The elements of the array, both bound and unbound, are returned by
126 For undeclared arrays (hashed arrays), @code{arrayinfo} returns a list
127 comprising the atom @code{hashed}, the number of subscripts,
128 and the subscripts of every element which has a value.
129 The values are returned by @mrefdot{listarray}
131 For @mrefcomma{memoizing functions} @code{arrayinfo} returns a list comprising the atom
132 @code{hashed}, the number of subscripts,
133 and any subscript values for which there are stored function values.
134 The stored function values are returned by @mrefdot{listarray}
136 For subscripted functions, @code{arrayinfo} returns a list comprising the atom
137 @code{hashed}, the number of subscripts,
138 and any subscript values for which there are lambda expressions.
139 The lambda expressions are returned by @mrefdot{listarray}
141 See also @mrefdot{listarray}
145 @code{arrayinfo} and @mref{listarray} applied to a declared array.
156 (%i1) array (aa, 2, 3);
160 (%i2) aa [2, 3] : %pi;
164 (%i3) aa [1, 2] : %e;
168 (%i4) arrayinfo (aa);
169 (%o4) [declared, 2, [2, 3]]
172 (%i5) listarray (aa);
173 (%o5) [#####, #####, #####, #####, #####, #####, %e, #####,
174 #####, #####, #####, %pi]
178 @code{arrayinfo} and @mref{listarray} applied to an undeclared array (@mrefdot{hashed array}).
181 @c bb [FOO] : (a + b)^2;
182 @c bb [BAR] : (c - d)^3;
188 (%i1) bb [FOO] : (a + b)^2;
193 (%i2) bb [BAR] : (c - d)^3;
198 (%i3) arrayinfo (bb);
199 (%o3) [hashed, 1, [BAR], [FOO]]
202 (%i4) listarray (bb);
204 (%o4) [(c - d) , (b + a) ]
208 @code{arrayinfo} and @mref{listarray} applied to a @mrefdot{memoizing function}
211 @c cc [x, y] := y / x;
219 (%i1) cc [x, y] := y / x;
237 (%i4) arrayinfo (cc);
238 (%o4) [hashed, 2, [4, z], [u, v]]
241 (%i5) listarray (cc);
249 Using @code{arrayinfo} in order to convert an undeclared array to a declared array:
252 @c for i:0 thru 10 do a[i]:i^2$
253 @c indices:map(first,rest(rest(arrayinfo(a))));
254 @c array(A,fixnum,length(indices)-1)$
255 @c fillarray(A,map(lambda([x],a[x]),indices))$
259 (%i1) for i:0 thru 10 do a[i]:i^2$
261 (%i2) indices:map(first,rest(rest(arrayinfo(a))));
262 (%o2) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
264 (%i3) array(A,fixnum,length(indices)-1)$
265 (%i4) fillarray(A,map(lambda([x],a[x]),indices))$
268 (%o5) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
272 @code{arrayinfo} and @mref{listarray} applied to a subscripted function.
275 @c dd [x] (y) := y ^ x;
283 (%i1) dd [x] (y) := y ^ x;
291 (%o2) lambda([y], y )
296 (%o3) lambda([y], y )
299 (%i4) arrayinfo (dd);
300 (%o4) [hashed, 1, [b + a], [v - u]]
303 (%i5) listarray (dd);
305 (%o5) [lambda([y], y ), lambda([y], y )]
309 @opencatbox{Categories:}
314 @c -----------------------------------------------------------------------------
316 @deffn {Function} arraymake (@var{A}, [@var{i_1}, @dots{}, @var{i_n}])
318 Returns the expression @code{@var{A}[@var{i_1}, ..., @var{i_n}]}.
319 The result is an unevaluated array reference.
321 @code{arraymake} is reminiscent of @mrefcomma{funmake} except the return value
322 is an unevaluated array reference instead of an unevaluated function call.
326 @c arraymake (A, [1]);
327 @c arraymake (A, [k]);
328 @c arraymake (A, [i, j, 3]);
329 @c array (A, fixnum, 10);
330 @c fillarray (A, makelist (i^2, i, 1, 11));
331 @c arraymake (A, [5]);
333 @c L : [a, b, c, d, e];
334 @c arraymake ('L, [n]);
336 @c A2 : make_array (fixnum, 10);
337 @c fillarray (A2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
338 @c arraymake ('A2, [8]);
343 (%i1) arraymake (A, [1]);
348 (%i2) arraymake (A, [k]);
353 (%i3) arraymake (A, [i, j, 3]);
358 (%i4) array (A, fixnum, 10);
362 (%i5) fillarray (A, makelist (i^2, i, 1, 11));
366 (%i6) arraymake (A, [5]);
375 (%i8) L : [a, b, c, d, e];
376 (%o8) [a, b, c, d, e]
379 (%i9) arraymake ('L, [n]);
388 (%i11) A2 : make_array (fixnum, 10);
389 (%o11) @{Lisp Array: #(0 0 0 0 0 0 0 0 0 0)@}
392 (%i12) fillarray (A2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
393 (%o12) @{Lisp Array: #(1 2 3 4 5 6 7 8 9 10)@}
396 (%i13) arraymake ('A2, [8]);
406 @opencatbox{Categories:}
407 @category{Expressions}
412 @c -----------------------------------------------------------------------------
414 @defvr {System variable} arrays
415 Default value: @code{[]}
417 @code{arrays} is a list of arrays that have been allocated.
418 These comprise arrays declared by @mrefcomma{array} @mref{hashed arrays} that can be
419 constructed by implicit definition (assigning something to an element that isn't yet
420 declared as a list or an array),
421 and @mref{memoizing functions} defined by @code{:=} and @mrefdot{define}
422 Arrays defined by @mref{make_array} are not included.
425 @mrefcomma{array} @mrefcomma{arrayapply} @mrefcomma{arrayinfo}@w{}
426 @mrefcomma{arraymake} @mrefcomma{fillarray} @mrefcomma{listarray} and
428 @c IS THIS AN EXHAUSTIVE LIST ??
434 @c bb [FOO] : (a + b)^2;
436 @c dd : make_array ('any, 7);
441 (%i1) array (aa, 5, 7);
445 (%i2) bb [FOO] : (a + b)^2;
450 (%i3) cc [x] := x/100;
456 (%i4) dd : make_array ('any, 7);
457 (%o4) @{Lisp Array: #(NIL NIL NIL NIL NIL NIL NIL)@}
465 @opencatbox{Categories:}
467 @category{Global variables}
471 @c -----------------------------------------------------------------------------
472 @anchor{arraysetapply}
473 @deffn {Function} arraysetapply (@var{A}, [@var{i_1}, @dots{}, @var{i_n}], @var{x})
475 Assigns @var{x} to @code{@var{A}[@var{i_1}, ..., @var{i_n}]},
476 where @var{A} is an array and @var{i_1}, @dots{}, @var{i_n} are integers.
478 @code{arraysetapply} evaluates its arguments.
480 @opencatbox{Categories:}
481 @category{Expressions}
486 @c -----------------------------------------------------------------------------
488 @deffn {Function} fillarray (@var{A}, @var{B})
490 Fills array @var{A} from @var{B}, which is a list or an array.
492 If a specific type was declared for @var{A} when it was created,
493 it can only be filled with elements of that same type;
494 it is an error if an attempt is made to copy an element of a different type.
496 If the dimensions of the arrays @var{A} and @var{B} are
497 different, @var{A} is filled in row-major order. If there are not enough
498 elements in @var{B} the last element is used to fill out the
499 rest of @var{A}. If there are too many, the remaining ones are ignored.
501 @code{fillarray} returns its first argument.
505 Create an array of 9 elements and fill it from a list.
508 @c array (a1, fixnum, 8);
510 @c fillarray (a1, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
515 (%i1) array (a1, fixnum, 8);
519 (%i2) listarray (a1);
520 (%o2) [0, 0, 0, 0, 0, 0, 0, 0, 0]
523 (%i3) fillarray (a1, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
527 (%i4) listarray (a1);
528 (%o4) [1, 2, 3, 4, 5, 6, 7, 8, 9]
532 When there are too few elements to fill the array,
533 the last element is repeated.
534 When there are too many elements,
535 the extra elements are ignored.
538 @c a2 : make_array (fixnum, 8);
539 @c fillarray (a2, [1, 2, 3, 4, 5]);
540 @c fillarray (a2, [4]);
541 @c fillarray (a2, makelist (i, i, 1, 100));
545 (%i1) a2 : make_array (fixnum, 8);
546 (%o1) @{Lisp Array: #(0 0 0 0 0 0 0 0)@}
549 (%i2) fillarray (a2, [1, 2, 3, 4, 5]);
550 (%o2) @{Lisp Array: #(1 2 3 4 5 5 5 5)@}
553 (%i3) fillarray (a2, [4]);
554 (%o3) @{Lisp Array: #(4 4 4 4 4 4 4 4)@}
557 (%i4) fillarray (a2, makelist (i, i, 1, 100));
558 (%o4) @{Lisp Array: #(1 2 3 4 5 6 7 8)@}
562 Multiple-dimension arrays are filled in row-major order.
565 @c a3 : make_array (fixnum, 2, 5);
566 @c fillarray (a3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
567 @c a4 : make_array (fixnum, 5, 2);
568 @c fillarray (a4, a3);
572 (%i1) a3 : make_array (fixnum, 2, 5);
573 (%o1) @{Lisp Array: #2A((0 0 0 0 0) (0 0 0 0 0))@}
576 (%i2) fillarray (a3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
577 (%o2) @{Lisp Array: #2A((1 2 3 4 5) (6 7 8 9 10))@}
580 (%i3) a4 : make_array (fixnum, 5, 2);
581 (%o3) @{Lisp Array: #2A((0 0) (0 0) (0 0) (0 0) (0 0))@}
584 (%i4) fillarray (a4, a3);
585 (%o4) @{Lisp Array: #2A((1 2) (3 4) (5 6) (7 8) (9 10))@}
589 @opencatbox{Categories:}
594 @c -----------------------------------------------------------------------------
596 @deffn {Function} listarray (@var{A})
598 Returns a list of the elements of the array @var{A}.
599 The argument @var{A} may be an array, an undeclared array (@mref{hashed array}),
600 a @mrefcomma{memoizing function} or a subscripted function.
602 Elements are listed in row-major order.
603 That is, elements are sorted according to the first index, then according to
604 the second index, and so on. The sorting order of index values is the same as
605 the order established by @mrefdot{orderless}
607 For undeclared arrays (@mref{hashed arrays}), @mrefcomma{memoizing functions} and subscripted functions,
608 the elements correspond to the index values returned by @mrefdot{arrayinfo}
610 Unbound elements of general arrays (that is, not @code{fixnum} and not
611 @code{flonum}) are returned as @code{#####}.
612 Unbound elements of @code{fixnum} or @code{flonum} arrays
613 are returned as 0 or 0.0, respectively.
614 Unbound elements of hashed arrays, @mrefcomma{memoizing functions}
615 and subscripted functions are not returned.
619 @code{listarray} and @mref{arrayinfo} applied to a declared array.
630 (%i1) array (aa, 2, 3);
634 (%i2) aa [2, 3] : %pi;
638 (%i3) aa [1, 2] : %e;
642 (%i4) listarray (aa);
643 (%o4) [#####, #####, #####, #####, #####, #####, %e, #####,
644 #####, #####, #####, %pi]
647 (%i5) arrayinfo (aa);
648 (%o5) [declared, 2, [2, 3]]
652 @code{listarray} and @mref{arrayinfo} applied to an undeclared array (@mref{hashed array}).
655 @c bb [FOO] : (a + b)^2;
656 @c bb [BAR] : (c - d)^3;
662 (%i1) bb [FOO] : (a + b)^2;
667 (%i2) bb [BAR] : (c - d)^3;
672 (%i3) listarray (bb);
674 (%o3) [(c - d) , (b + a) ]
677 (%i4) arrayinfo (bb);
678 (%o4) [hashed, 1, [BAR], [FOO]]
682 @code{listarray} and @mref{arrayinfo} applied to a @mrefdot{memoizing function}
685 @c cc [x, y] := y / x;
693 (%i1) cc [x, y] := y / x;
711 (%i4) listarray (cc);
717 (%i5) arrayinfo (cc);
718 (%o5) [hashed, 2, [4, z], [u, v]]
722 @code{listarray} and @mref{arrayinfo} applied to a subscripted function.
725 @c dd [x] (y) := y ^ x;
733 (%i1) dd [x] (y) := y ^ x;
741 (%o2) lambda([y], y )
746 (%o3) lambda([y], y )
749 (%i4) listarray (dd);
751 (%o4) [lambda([y], y ), lambda([y], y )]
754 (%i5) arrayinfo (dd);
755 (%o5) [hashed, 1, [b + a], [v - u]]
759 @opencatbox{Categories:}
764 @c NEEDS CLARIFICATION
766 @c -----------------------------------------------------------------------------
768 @deffn {Function} make_array (@var{type}, @var{dim_1}, @dots{}, @var{dim_n})
770 Creates and returns a Lisp array. @var{type} may
771 be @code{any}, @code{flonum}, @code{fixnum}, @code{hashed} or
773 There are @math{n} indices,
774 and the @math{i}'th index runs from 0 to @math{@var{dim_i} - 1}.
776 The advantage of @code{make_array} over @mref{array} is that the return value
777 doesn't have a name, and once a pointer to it goes away, it will also go away.
778 For example, if @code{y: make_array (...)} then @code{y} points to an object
779 which takes up space, but after @code{y: false}, @code{y} no longer
780 points to that object, so the object can be garbage collected.
782 @c 'FUNCTIONAL ARGUMENT IN MAKE_ARRAY APPEARS TO BE BROKEN
783 @c EVEN AFTER READING THE CODE (SRC/AR.LISP) I CAN'T TELL HOW THIS IS SUPPOSED TO WORK
784 @c COMMENTING OUT THIS STUFF TO PREVENT CONFUSION AND HEARTBREAK
785 @c RESTORE IT WHEN MAKE_ARRAY ('FUNCTIONAL, ...) IS FIXED
786 @c @code{y: make_array ('functional, 'f, 'hashed, 1)} - the second argument to
787 @c @code{make_array} in this case is the function to call to calculate array
788 @c elements, and the rest of the arguments are passed recursively to
789 @c @code{make_array} to generate the "memory" for the array function object.
794 @c A1 : make_array (fixnum, 10);
797 @c A2 : make_array (flonum, 10);
798 @c A2 [2] : 2.718281828;
800 @c A3 : make_array (any, 10);
801 @c A3 [4] : x - y - z;
803 @c A4 : make_array (fixnum, 2, 3, 5);
804 @c fillarray (A4, makelist (i, i, 1, 2*3*5));
809 (%i1) A1 : make_array (fixnum, 10);
810 (%o1) @{Lisp Array: #(0 0 0 0 0 0 0 0 0 0)@}
818 (%o3) @{Lisp Array: #(0 0 0 0 0 0 0 0 1729 0)@}
821 (%i4) A2 : make_array (flonum, 10);
822 (%o4) @{Lisp Array: #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)@}
825 (%i5) A2 [2] : 2.718281828;
831 @{Lisp Array: #(0.0 0.0 2.718281828 0.0 0.0 0.0 0.0 0.0 0.0 0.0)@}
834 (%i7) A3 : make_array (any, 10);
835 (%o7) @{Lisp Array: #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)@}
838 (%i8) A3 [4] : x - y - z;
843 (%o9) @{Lisp Array: #(NIL NIL NIL NIL
844 ((MPLUS SIMP) $X ((MTIMES SIMP) -1 $Y) ((MTIMES S\
846 NIL NIL NIL NIL NIL)@}
849 (%i10) A4 : make_array (fixnum, 2, 3, 5);
850 (%o10) @{Lisp Array: #3A(((0 0 0 0 0) (0 0 0 0 0) (0 0 0 0 0))
851 ((0 0 0 0 0) (0 0 0 0 0) (0 0 0 0 0)))@}
854 (%i11) fillarray (A4, makelist (i, i, 1, 2*3*5));
855 (%o11) @{Lisp Array: #3A(((1 2 3 4 5) (6 7 8 9 10) (11 12 13 14 1\
857 ((16 17 18 19 20) (21 22 23 24 25) (26 27 28 29\
866 @opencatbox{Categories:}
871 @c DOES THIS MODIFY A OR DOES IT CREATE A NEW ARRAY ??
873 @c -----------------------------------------------------------------------------
875 @deffn {Function} rearray (@var{A}, @var{dim_1}, @dots{}, @var{dim_n})
877 Changes the dimensions of an array.
878 The new array will be filled with the elements of the old one in
879 row-major order. If the old array was too small,
880 the remaining elements are filled with
881 @code{false}, @code{0.0} or @code{0},
882 depending on the type of the array. The type of the array cannot be
885 @opencatbox{Categories:}
890 @c -----------------------------------------------------------------------------
892 @deffn {Function} remarray @
893 @fname{remarray} (@var{A_1}, @dots{}, @var{A_n}) @
894 @fname{remarray} (all)
896 Removes arrays and array associated functions and frees the storage occupied.
897 The arguments may be declared arrays, @mrefcomma{hashed arrays} array
898 functions, and subscripted functions.
900 @code{remarray (all)} removes all items in the global list @mrefdot{arrays}
902 It may be necessary to use this function if it is
903 desired to clear the cache of a @mrefdot{memoizing function}
905 @code{remarray} returns the list of arrays removed.
907 @code{remarray} quotes its arguments.
909 @opencatbox{Categories:}
914 @c -----------------------------------------------------------------------------
916 @deffn {Function} subvar (@var{x}, @var{i})
918 Evaluates the subscripted expression @code{@var{x}[@var{i}]}.
920 @code{subvar} evaluates its arguments.
922 @code{arraymake (@var{x}, [@var{i}])} constructs the expression
923 @code{@var{x}[@var{i}]}, but does not evaluate it.
931 @c foo : [aa, bb, cc, dd, ee]$
933 @c arraymake (x, [i]);
944 (%i4) foo : [aa, bb, cc, dd, ee]$
950 (%i6) arraymake (x, [i]);
960 @opencatbox{Categories:}
961 @category{Expressions}
966 @c NEEDS EXPANSION AND EXAMPLES
968 @c -----------------------------------------------------------------------------
970 @deffn {Function} subvarp (@var{expr})
972 Returns @code{true} if @var{expr} is a subscripted variable, for example
975 @opencatbox{Categories:}
976 @category{Predicate functions}
980 @c -----------------------------------------------------------------------------
981 @anchor{use_fast_arrays}
982 @defvr {Option variable} use_fast_arrays
983 Default value: @code{false}
985 When @code{use_fast_arrays} is @code{true},
986 arrays declared by @code{array} are values instead of properties,
987 and undeclared arrays (@mref{hashed arrays}) are implemented as Lisp hashed arrays.
989 When @code{use_fast_arrays} is @code{false},
990 arrays declared by @code{array} are properties,
991 and undeclared arrays are implemented with Maxima's own hashed array implementation.
993 Note that the code @code{use_fast_arrays} switches to is not necessarily faster
994 than the default one; Arrays created by @mref{make_array} are not affected by
995 @code{use_fast_arrays}.
997 See also @mrefdot{translate_fast_arrays}
999 @opencatbox{Categories:}
1001 @category{Global flags}
1005 @c -----------------------------------------------------------------------------
1006 @anchor{translate_fast_arrays}
1007 @defvr {Option variable} translate_fast_arrays
1008 Default value: @code{false}
1010 When @code{translate_fast_arrays} is @code{true},
1011 the Maxima-to-Lisp translator generates code that assumes arrays are values instead of properties,
1012 as if @code{use_fast_arrays} were @code{true}.
1014 When @code{translate_fast_arrays} is @code{false},
1015 the Maxima-to-Lisp translator generates code that assumes arrays are properties,
1016 as if @code{use_fast_arrays} were @code{false}.
1018 @opencatbox{Categories:}
1020 @category{Translation flags and variables}