Maxima/Data structures

"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hasharrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics. "

"Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework. "

Array
Maxima has two array types :
 * Undeclared arrays ( implemented as Lisp hash tables )
 * Declared arrays ( implemented as Lisp arrays )
 * created by the array function
 * created by the make_array function.

Category: Arrays :
 * array
 * arrayapply
 * arrayinfo
 * arraymake
 * arrays - global variable
 * fillarray
 * listarray
 * make_array
 * rearray
 * remarray
 * subvar
 * use_fast_arrays

See also :
 * array functions defined by := and define.

Undeclared array
Assignment creates an undeclared array.

(%i1) c[99] : 789; (%o1)                         789 (%i2) c[99]; (%o2)                         789 (%i3) c; (%o3)                          c (%i4) arrayinfo (c); (%o4)                  [hashed, 1, [99]] (%i5) listarray (c); (%o5)                        [789]

"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. " ( from Maxima CAS doc)

"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. bx+1,u:y would be valid. "( from Maxima CAS doc)

Declared array

 * declare array ( give a name and allocate memmory)
 * fill array
 * process array

array function
Function: array (name, type, dim_1, …, dim_n)

Creates an n-dimensional array. Here :
 * type can be fixnum for integers of limited size or flonum for floating-point numbers
 * 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.

(%i5) array(A,2,2); (%o5)                                 A (%i8) arrayinfo(A); (%o8)                     [declared, 2, [2,2]]

Because subscripts of array A elements are goes from 0 to dim so array A has : ( dim_1 + 1) * (dim_2 + 1) = 3*3 = 9

elements.

The array function can be used to transform an undeclared array into a declared array.

arraymake function
Function: arraymake (A, [i_1, …, i_n])

The result is an unevaluated array reference.

(%i12) arraymake(A,[3,3,3]); (%o12)                   array_make(3, 3, 3) 3, 3, 3 (%i13) arrayinfo(A); arrayinfo: A is not an array.

Function: make_array
Function: make_array (type, dim_1, …, dim_n)

Creates and returns a Lisp array.

Type may be :
 * any
 * flonum
 * fixnum
 * hashed
 * 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:

(%i9) A : array_make(3,3,3); (%o9)                        array_make(3, 3, 3) (%i10) arrayinfo(A); (%o10)                    [declared, 3, [3, 3, 3]]

List
Assignment to an element of a list.

(%i1) b : [1, 2, 3]; (%o1)                      [1, 2, 3] (%i2) b[3] : 456; (%o2)                         456 (%i3) b; (%o3)                     [1, 2, 456]

(%i1) mylist : a,b],[c,d; (%o1) a, b], [c, d

Interesting examples by Burkhard Bunk :

lst: [el1, el2, ...];        contruct list explicitly lst[2];                      reference to element by index starting from 1 cons(expr, alist);           prepend expr to alist endcons(expr, alist);        append expr to alist append(list1, list2, ..);    merge lists makelist(expr, i, i1, i2);   create list with control variable i makelist(expr, x, xlist);     create list with x from another list length(alist);               returns #elements map(fct, list);              evaluate a function of one argument map(fct, list1, list2);      evaluate a function of two arguments

Category: Lists :
 * ]
 * append
 * assoc
 * cons
 * copylist
 * create_list
 * delete
 * eighth
 * endcons
 * fifth
 * first
 * flatten
 * fourth
 * fullsetify
 * join
 * last
 * length
 * listarith
 * listp
 * lmax
 * lmin
 * lreduce
 * makelist
 * member
 * ninth
 * permut
 * permutations
 * pop
 * push
 * random_permutation
 * rest
 * reverse
 * rreduce
 * second
 * setify
 * seventh
 * sixth
 * some
 * sort
 * sublist
 * sublist_indices
 * tenth
 * third
 * tree_reduce
 * xreduce
 * xreduce

product
/* example by Burton Willis */ (%i28) P1(s) := rectform(product(s[i],i, 1, length(s)))$

(%i29) P2(s) := xreduce(lambda([a,b], rectform(a*b)),s)$

(%i30) s : makelist(random(1.0)+%i*random(1.0),10^4)$

(%i31) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o31) 0.0

(%i32) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o32) 0.0

Matrix
"In Maxima, a matrix is implemented as a nested list (namely a list of rows of the matrix)". E.g. : (($MATRIX) ((MLIST) 1 2 3) ((MLIST) 4 5 6))

Construction of matrices from nested lists :

(%i3) M:matrix([1,2,3],[4,5,6],[0,-1,-2]); [ 1  2    3  ]                                 [             ] (%o3)                           [ 4   5    6  ] [            ]                                 [ 0  - 1  - 2 ]

Interesting examples by Burkhard Bunk :

A: matrix([a, b, c], [d, e, f], [g, h, i]);    /* (3x3) matrix */ u: matrix([x, y, z]);                          /* row vector */ v: transpose(matrix([r, s, t]));               /* column vector */

Reference to elements etc:

u[1,2];                /* second element of u */ v[2,1];                /* second element of v */ A[2,3];  or  A[2][3];  /* (2,3) element */ A[2];                        /* second row of A */ transpose(transpose(A)[2]);  /* second column of A */

Element by element operations:

A + B;     A - B; A * B;       A / B; A ^ s;       s ^ A;

Matrix operations :

A. B;                 /* matrix multiplication */ A ^^ s;                /* matrix exponentiation (including inverse) */ transpose(A); determinant(A); invert(A);

Category: Matrices :
 * addcol
 * addrow
 * adjoint
 * augcoefmatrix
 * cauchy_matrix
 * charpoly
 * coefmatrix
 * col
 * columnvector
 * covect
 * copymatrix
 * determinant
 * detout
 * diag
 * diagmatrix
 * doallmxops
 * domxexpt
 * domxmxops
 * domxnctimes
 * doscmxops
 * doscmxplus
 * echelon
 * eigen
 * ematrix
 * entermatrix
 * genmatrix
 * ident
 * invert
 * list_matrix_entries
 * lmxchar
 * matrix
 * matrix_element_add
 * matrix_element_mult
 * matrix_element_transpose
 * matrixmap
 * matrixp
 * mattrace
 * minor
 * ncharpoly
 * newdet
 * nonscalar
 * nonscalarp
 * permanent
 * rank
 * ratmx
 * row
 * scalarmatrixp
 * scalarp
 * setelmx
 * sparse
 * submatrix
 * tracematrix
 * transpose
 * triangularize
 * zeromatrix

Function: matrix
Function: matrix (row_1, …, row_n)

Returns a rectangular matrix which has the rows row_1, …, row_n. Each row is a list of expressions. All rows must be the same length.

. operator
"The dot operator, for matrix (non-commutative) multiplication. When "." is used in this way, spaces should be left on both sides of it, e.g.

A. B

This distinguishes it plainly from a decimal point in a floating point number.

The operator. represents noncommutative multiplication and scalar product. When the operands are 1-column or 1-row matrices a and b, the expression a.b is equivalent to sum (a[i]*b[i], i, 1, length(a)). If a and b are not complex, this is the scalar product, also called the inner product or dot product, of a and b. The scalar product is defined as conjugate(a).b when a and b are complex; innerproduct in the eigen package provides the complex scalar product.

When the operands are more general matrices, the product is the matrix product a and b. The number of rows of b must equal the number of columns of a, and the result has number of rows equal to the number of rows of a and number of columns equal to the number of columns of b.

To distinguish. as an arithmetic operator from the decimal point in a floating point number, it may be necessary to leave spaces on either side. For example, 5.e3 is 5000.0 but 5. e3 is 5 times e3.

There are several flags which govern the simplification of expressions involving ., namely dot0nscsimp, dot0simp, dot1simp, dotassoc, dotconstrules, dotdistrib, dotexptsimp, dotident, and dotscrules." ( from Maxima CAS doc)

Vectors
Category: Vectors :
 * Vectors
 * eigen
 * express
 * nonscalar
 * nonscalarp
 * scalarp

Category: Package vect
 * vect
 * scalefactors
 * vect_cross
 * vectorpotential
 * vectorsimp