- UID
- 8476
- 积分
- 442
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-8-4
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
方阵求逆是数值计算中非常重要的一个步骤,包括方程求解,特征值计算等都和
逆矩阵密切相关,数值计算方法有许多,比如可以采用LU分解等原理。
eachy版主编过一个,好像是用于ucs坐标系转换的3*3矩阵的,对于n*n阶的Lisp
代码一时在网上没有找到。FORTRAN和C倒是都有源码库。
本来用lisp来进行这种计算似乎不是很好,网上一些大牛也建议不要用lisp进行
矩阵求逆什么的。
但鉴于对lisp非常喜欢,把j.p. griffith的fortran代码改写成如下的lisp格式
各位帮忙测试有没有错误。
程序不是很完善,应该在那些提示singular matrix的不满秩矩阵中加一段判断
之后就直接退出,不再repeat n
在编写这个的过程中,遇到了不少表和数组有点不同的地方
1)表格式比数组格式当然要自由和方便,但是,对表中某个数值进行修改的时候
似乎特别麻烦,就算本程序中采用了std-setnth的函数,感觉它在修改某个数值的
时候必须先将此位置之前的所有拿到一个表A中,然后添加这个修改的数值,再把
后面那部分的数值添加到表A中,这个思路感觉挺耗时间的。虽然这个std函数号称用了二分法进行查找,但还是觉得不大好。而在fortran中,我们只要设A(i,j)=number,就可以方便的代替某个位置的数值了。
2)对表中某个数字进行数值运算的时候,比如把它乘一个变量的时候,必须先将其
调出,然后修改,然后再用std-setnth修改表中的项。
基于以上原因,请大侠们看看如何比较好的定义这样两个函数
A)a是一个表,func是一个可以用Lambda之类定义的函数,i,j分别是二维表的行列
这个函数用来将二维表a的i行j列元素进行func(比如sin什么的)函数修改
(xd-abcde (func a i j))
B)存不存在直接修改表中第i项,不要其他辅助表的方法
[pcode=lisp,true]
;;; N*N方阵求逆算法
;;;by qjchen at www.xdcad.net
;;;------------------------------------------------------------------------
;;;根据j.p. griffith 6/88的fortran程序改编?
;;;利用了类似gauss-jordan的消元法原理进行编写
;;;缺点:对于不能求逆的矩阵没有很好容错
(defun c:test ()
(setq t1 (list 3.0 3.0 3.0 3.0 3.0))
(setq t2 (list 3.0 4.0 3.0 3.0 3.0))
(setq t3 (list 3.0 3.0 5.0 3.0 3.0))
(setq t4 (list 3.0 3.0 3.0 6.0 3.0))
(setq t5 (list 3.0 3.0 3.0 3.0 8.0))
(setq tt (list t1 t2 t3 t4 t5))
(setq tt1 (matrix_inversion tt))
(princ "\n tt = ") (princ tt);Erase_DV
(getstring "\nPress Enter to continue...");Erase_DV
(princ "\n tt1 = ") (princ tt1);Erase_DV
(getstring "\nPress Enter to continue...");Erase_DV
)
(defun matrix_inversion (a / nmax ipiv indxr indxc n n i j k l ll a-temp
temp big irow icol pivinv
)
(setq nmax 50)
(setq ipiv (create nmax))
(setq indxr (create nmax))
(setq indxc (create nmax))
(setq n (length a))
(setq i 1)
(repeat n
(setq big 0)
(setq j 1)
(repeat n
(if (/= ([n] ipiv j) 1)
(progn
(setq k 1)
(repeat n
(if (= ([n] ipiv k) 0)
(progn
(if (>= (abs ([n,m] a j k)) big)
(progn
(setq big ([n,m] a j k))
(setq irow j)
(setq icol k)
)
(progn
(if (> ([n] ipiv k) 1)
(princ "singular matrix")
)
)
)
)
)
(setq k (1+ k))
)
)
)
(setq j (1+ j))
)
(setq temp (1+ ([n] ipiv icol)))
(setq ipiv (std-setnth temp (1- icol) ipiv))
(if (/= irow icol)
(progn
(setq l 1)
(repeat n
(setq dum ([n,m] a irow l))
(setq a-temp ([n,m] a icol l))
(setq a (qj-setnmth a-temp (1- irow) (1- l) a))
(setq a (qj-setnmth dum (1- icol) (1- l) a))
(setq l (1+ l))
)
)
)
(setq indxr (std-setnth irow (1- i) indxr))
(setq indxc (std-setnth icol (1- i) indxc))
(if (= ([n,m] a icol icol) 0)
(princ "singular matrix")
)
(setq pivinv (/ 1.0 ([n,m] a icol icol)))
(setq a (qj-setnmth 1 (1- icol) (1- icol) a))
(setq l 1)
(repeat n
(setq a-temp (* ([n,m] a icol l) pivinv))
(setq a (qj-setnmth a-temp (1- icol) (1- l) a))
(setq l (1+ l))
)
(setq ll 1)
(repeat n
(if (/= ll icol)
(progn
(setq dum ([n,m] a ll icol))
(setq a (qj-setnmth 0.0 (1- ll) (1- icol) a))
(setq l 1)
(repeat n
(setq a-temp (- ([n,m] a ll l) (* dum ([n,m] a icol l))))
(setq a (qj-setnmth a-temp (1- ll) (1- l) a))
(setq l (1+ l))
)
)
)
(setq ll (1+ ll))
)
(setq i (1+ i))
)
(setq l n)
(repeat n
(if (/= ([n] indxr l) ([n] indxc l))
(progn
(setq k 1)
(repeat n
(setq dum ([n,m] a k ([n] indxr l)))
(setq a-temp ([n,m] a k ([n] indxc l)))
(setq a (qj-setnmth a-temp (1- k) (1- ([n] indxr l)) a))
(setq a (qj-setnmth dum (1- k) (1- ([n] indxc l)) a))
(setq k (1+ k))
)
)
)
(setq l (1- l))
)
a
)
;;创建一个有m个0.0元素的表
(defun create (m / lista) ; (setq m 5)
(setq lista nil)
(repeat m
(setq lista (append
lista
(list 0.0)
)
)
)
lista
)
;创建一个m*m个0.0元素的表
(defun createm (m / lista listb)
(setq m 5)
(setq lista nil)
(repeat m
(setq listb nil)
(repeat m
(setq listb (append
listb
(list 0.0)
)
)
)
(setq lista (append
lista
(list listb)
)
)
)
lista
)
;;; std代替表中第n个元素的函数
(defun std-%setnth (new i lst / fst len)
(cond
((minusp i)
lst
)
((> i (setq len (length lst)))
lst
)
((> i (/ len 2))
(reverse (std-%setnth new (1- (- len i)) (reverse lst)))
)
(t
(append
(progn
(setq fst nil) ; ; possible vl lsa compiler bug
(repeat (rem i 4)
(setq fst (cons (car lst) fst)
lst (cdr lst)
)
)
(repeat (/ i 4)
(setq fst (cons (cadddr lst) (cons (caddr lst) (cons
(cadr lst)
(cons
(car lst)
fst
)
)
)
)
lst (cddddr lst)
)
)
(reverse fst)
)
(if (listp new)
new
(list new)
) ; v0.4001
(cdr lst)
)
)
)
)
(defun std-setnth (new i lst)
(std-%setnth (list new) i lst)
)
;代替二维表中第i行第j列元素的函数(i和j从1开始)
(defun qj-setnmth (new i j lst / listb lista)
(setq listb lst)
(setq lista (nth i lst))
(setq lista (std-setnth new j lista))
(setq listb (std-setnth lista i listb))
listb
)
;;; 获取某个数组表第几项第几项的数值
(defun [n,m] (a n m / i) ; n是行,m是列
(setq i (nth (1- m) (nth (1- n) a)))
i
)
;;; 获取某个单列数组第几项的数值
(defun [n] (a n / i) ; n是行,m是列
(setq i (nth (1- n) a))
i
)
[/pcode] |
|