apply、mapcar、lambda在矩阵运算中的应用小结(AutoLISP)

最近在学习Autolisp编程,程序中用到了矩阵运算,如果像C语言(或C++)语言编程那样一个个处理矩阵中的元素,那程序要写很长,而且很容易出错。在论坛中,网上搜索发现,mapcar、lambda和apply三个函数用好了,对矩阵运算非常方便。于是查手册,看看三个函数的用法:

 Apply: (apply 'function list)
 将参数表传给指定的函数
参数:
         ' function ——函数,可以是表示defun或lambda表达式的符号。
          list           ——表。如果函数不接收参数,则该参数为nil。

返回值:
    函数调用的结果。---------注意该函数返回值为一个值,数值、字符串等。
例如:   (apply '+ '(1 2 3))     结果为 6
  这个函数看似不难用,理解也比较容易。
Mapcar:(mapcar function list1 ……listn)

将作为本函数参数的一个或多个表的各个元素提供给指定函数进行求值,并将由求值结果构成的表返回。

参数:

function ——函数。

list1……listn——一个或多个表。

返回值:

表。--------注意返回值是一个表。

例如:(mapcar '1+ '(10 11 12))    结果为 (11 12 13)

这个函数看起来也不难理解,注意返回结果为表就行了。

再看第三个——

Lambda:(lambda arguments expr……)

在经常使用某一个表达式,而又觉得把它定义成一个新函数开销太大时,可以使用lambda函数。lambda将定义的函数放在要使用它的位置,还可以使程序员的意图表达得更清楚。lambda函数返回它最后一个expr的值。它常与apply和(或)mapcar函数连用,以便对表中的元素执行某个运算。

参数:

        argument——传给表达式的参数

        expr        ——Autolisp表达式。

返回值

最后一个expr的值。

这个函数光看这个解释有点不知所云了,还是看个例子吧。

例如:(apply '(lambda ( x y z) (* x (- y z))) '(5  20 14))    结果 30

能不能看出来函数是如何计算的? 5*(20-14)=30。其中 (lambda ( x y z) (* x (- y z))) 是定义的无名函数, 也就是apply函数的第一个参数,'(5 20 14 )apply的第二个参数表。这么一拆分也就理解了。

好了,熟悉了三个函数的使用方法,回到正题。如何在矩阵运算中应用这三个函数呢,能怎么帮我们简化代码呢?!

Lee Mac Programming: Custom Programs for AutoCAD找到了这样一段代码:

;; Matrix x Vector - Vladimir Nesterovsky
;; Args: m - nxn matrix, v - vector in R^n

(defun mxv ( m v )
    (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
)

功能是求n阶方阵和n维列向量的乘法,代码太简洁了。

不知道你是不是看懂了函数是如何运算的,把它分解一下(mapcar  '(……) m),其中'(……)是无名函数,他要对表m的每一个元素进行计算,m的元素是什么?n维向量!

再看看这个无名函数(lambda (r) (……))其中参数r是什么?对!m的每一个元素。

(……)这个运算是什么呢?(apply ‘+ (mapcar ’* r v))  r中每个元素和v中每个元素相乘的形成的表再求和。

最后的结果是什么?mapcar在最外层,肯定是个表,对了,n维向量!不知道你看明白了没有。

好了,我的程序中要求矩阵的特征值和特征向量。计算过程中用到了协方差的计算,涉及到了m×n维矩阵与m维向量的乘法,m×n维矩阵与n×m维矩阵的运算,下面把我写的代码发一下,大家慢慢理解吧:

(setq lst (mapcar '(lambda (c) (mapcar '(lambda (r) (apply '+ (mapcar '* r c))) matrix)) matrix))

其中:matrix是m×n阶矩阵,结果是n×n阶方阵,赋值给lst。

(setq covMx (mapcar '(lambda (r) (mapcar '(lambda (x) (/ x num)) r)) lst))

将上一步计算所得的方阵每个元素都除以num(一个数)。

希望我的代码能帮到你!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星光依旧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值