Maxima/数据结构
"我必须说,Maxima 当前的数组/矩阵语义很混乱,至少有四种不同类型的对象(哈希数组、显式列表、显式矩阵和 Lisp 数组)支持带有不同语义的下标。" [1]
"Maxima 的数组、列表和矩阵的概念非常混乱,因为在该项目的多年发展过程中,各种想法逐渐累积...是的,这确实很乱。对此我表示歉意。这些都是有趣的想法,但没有统一的框架。" [2]
Maxima 有两种数组类型:[3]
- 未声明数组(以 Lisp 哈希表实现)
- 已声明数组(以 Lisp 数组实现)
- 由 array 函数创建
- 由 make_array 函数创建。
类别:数组
- array
- arrayapply
- arrayinfo
- arraymake
- arrays - 全局变量
- fillarray
- listarray
- make_array
- rearray
- remarray
- subvar
- use_fast_arrays
另请参阅
- 由 := 和 define 定义的数组函数。
赋值会创建一个未声明数组。
(%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]
"如果用户在声明相应的数组之前对下标变量赋值,则会创建一个未声明数组。未声明数组,也称为哈希数组(因为对下标进行哈希编码),比已声明数组更通用。用户不需要声明其最大大小,并且随着分配更多元素的值,它们会通过哈希动态增长。未声明数组的下标甚至不需要是数字。但是,除非数组非常稀疏,否则在可能的情况下声明它可能比不声明它更有效。"(来自 Maxima CAS 文档)
"如果执行以下操作,则会创建:"
b[x+1]:y^2
"(并且 b 尚未是数组、列表或矩阵 - 如果它是其中之一,则会导致错误,因为 x+1 对于 art-q 数组、列表或矩阵而言不是有效的下标)。
它的索引(也称为键)可以是任何对象。它一次只接受一个键(b[x+1,u]:y 会忽略 u)。引用是通过 b[x+1] ==> y^2 完成的。当然,键可以是列表,例如
b[[x+1,u]]:y
是有效的。"(来自 Maxima CAS 文档)
- 声明数组(给出名称并分配内存)
- 填充数组
- 处理数组
Function: array (name, type, dim_1, …, dim_n)
创建一个 n 维数组。这里
- type 可以是 fixnum(用于有限大小的整数)或 flonum(用于浮点数)
- n 可以小于或等于 5。第 i 维的下标是从小到大运行的整数,从 0 到 dim_i。
(%i5) array(A,2,2); (%o5) A (%i8) arrayinfo(A); (%o8) [declared, 2, [2,2]]
因为数组 A 元素的下标从 0 到 dim,所以数组 A 有
( dim_1 + 1) * (dim_2 + 1) = 3*3 = 9
个元素。
array 函数可以用于将未声明数组转换为已声明数组。
Function: arraymake (A, [i_1, …, i_n])
结果是一个未计算的数组引用。
(%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 (type, dim_1, …, dim_n)
创建并返回一个 Lisp 数组。
Type 可以是
- 任何
- flonum
- fixnum
- hashed
- functional。
有 n 个索引,第 i 个索引从小到大运行,从 0 到 dim_i - 1。
make_array 相对于 array 的优势在于,返回值没有名称,并且一旦指向它的指针消失,它也会消失。例如,如果 y: make_array (...),那么 y 指向一个占用空间的对象,但在 y: false 之后,y 不再指向该对象,因此该对象可以被垃圾回收。
示例
(%i9) A : array_make(3,3,3); (%o9) array_make(3, 3, 3) (%i10) arrayinfo(A); (%o10) [declared, 3, [3, 3, 3]]
对列表元素的赋值。
(%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]]
由 Burkhard Bunk 提供的有趣示例:[4]
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
类别:列表
- [
- ]
- 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
/* 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
"在 Maxima 中,矩阵是以嵌套列表(即矩阵的行列表)实现的"。例如:[5]
(($MATRIX) ((MLIST) 1 2 3) ((MLIST) 4 5 6))
从嵌套列表构建矩阵
(%i3) M:matrix([1,2,3],[4,5,6],[0,-1,-2]); [ 1 2 3 ] [ ] (%o3) [ 4 5 6 ] [ ] [ 0 - 1 - 2 ]
由 Burkhard Bunk 提供的有趣示例:[6]
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 */
对元素的引用等
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 */
逐元素运算
A + B; A - B; A * B; A / B; A ^ s; s ^ A;
矩阵运算
A . B; /* matrix multiplication */ A ^^ s; /* matrix exponentiation (including inverse) */ transpose(A); determinant(A); invert(A);
类别:矩阵:[7]
- 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 (row_1, …, row_n)
返回一个矩形矩阵,该矩阵具有行 row_1、…、row_n。每行都是表达式列表。所有行必须具有相同的长度。
"点运算符,用于矩阵(非交换)乘法。当 "." 以这种方式使用时,应该在两侧留出空格,例如
A . B
这清楚地区分了它与浮点数中的小数点。
. 运算符表示非交换乘法和标量积。当操作数是 1 列或 1 行矩阵 a 和 b 时,表达式 a.b 等效于 sum (a[i]*b[i], i, 1, length(a))。如果 a 和 b 不是复数,则这是 a 和 b 的标量积,也称为内积或点积。标量积定义为 conjugate(a).b,其中 a 和 b 是复数;eigen 包中的 innerproduct 提供复数标量积。
当操作数是更一般的矩阵时,乘积是矩阵乘积 a 和 b。b 的行数必须等于 a 的列数,结果的行数等于 a 的行数,列数等于 b 的列数。
为了将 . 作为算术运算符与浮点数中的小数点区分开来,可能需要在两边留出空格。例如,5.e3 为 5000.0,而 5 . e3 为 5 乘以 e3。
有几个标志控制着涉及 . 的表达式的简化,它们分别是 dot0nscsimp、dot0simp、dot1simp、dotassoc、dotconstrules、dotdistrib、dotexptsimp、dotident 和 dotscrules。(来自 Maxima CAS 文档)
类别:向量
- 向量
- eigen
- 表达式
- nonscalar
- nonscalarp
- scalarp
类别:包 vect[8]
- vect
- 缩放因子
- vect_cross
- vectorpotential
- vectorsimp