在 lisp 中创建卡方函数。 [初学者]
Creating a chi square function in lisp. [beginner]
首先,对于这样一个新手问题,我深表歉意。
我的目标不仅仅是创建卡方函数,而是了解如何避免我遇到的一般问题。
我的代码如下所示:
(defun chi-square (expected-list observed-list)
(cond ((not (= (length expected-list) (length observed-list))) (print "Lists do not match in length.~%"))
((and (null expected-list) (null observed-list)) 0)
(+ (/ (square (- (car observed-list) (car expected-list))) (car expected-list))
(chi-square (cdr expected-list) (cdr observed-list)))
)
)
我认为第三个条件工作正常,除非它在 nil 和 nil 上调用卡方时输出只是读取 0。我理解为什么会发生这种情况(因为第二个条件),但我不知道如何避免它。例如,如果我给它一个 (100 50) 的预期列表和一个 (90 60) 的观察列表,我希望它输出 (+ 1 (+ 2 0)) = 3。我怎样才能给出 (chi-square nil nil) 值 0 而不是立即结束函数?
免责声明:我相信有更好的方法可以做到这一点,也许已经有一些功能可以做到这一点。我写这个函数只是为了学习目的。
第三种cond
情况出错:求和前少了t
:
(defun chi-square (expected-list observed-list)
(cond ((not (= (length expected-list) (length observed-list)))
(print "Lists do not match in length.~%"))
((and (null expected-list) (null observed-list)) 0)
(t (+ (/ (square (- (car observed-list) (car expected-list))) (car expected-list))
(chi-square (cdr expected-list) (cdr observed-list))))))
您可以在 specification.
中找到 cond
宏的语法
通常,您希望避免在递归同一列表的过程中调用类似 length
的内容。那是因为 length
的 运行 时间与你给它的列表的长度成正比,你最终会得到一个 O(N^2) 算法,因为你在原始列表。如果您的列表总是很短,那也没关系。最好在例程开始时只测试一次列表长度,或者在列表中的一个是 null
而另一个不是时在最后退出。不管怎样,这里有一些其他的方法来编写这个函数:
;using built-in recursion combinators (mapcar & reduce)
(defun χ² (expected observed)
(reduce #'+ (mapcar (lambda (e o) (/ (square (- o e)) e)) expected observed)))
;using loop
(defun chi-sqr (expected observed)
(loop
for e in expected
for o in observed
summing (/ (square (- o e)) e)))
首先,对于这样一个新手问题,我深表歉意。 我的目标不仅仅是创建卡方函数,而是了解如何避免我遇到的一般问题。
我的代码如下所示:
(defun chi-square (expected-list observed-list)
(cond ((not (= (length expected-list) (length observed-list))) (print "Lists do not match in length.~%"))
((and (null expected-list) (null observed-list)) 0)
(+ (/ (square (- (car observed-list) (car expected-list))) (car expected-list))
(chi-square (cdr expected-list) (cdr observed-list)))
)
)
我认为第三个条件工作正常,除非它在 nil 和 nil 上调用卡方时输出只是读取 0。我理解为什么会发生这种情况(因为第二个条件),但我不知道如何避免它。例如,如果我给它一个 (100 50) 的预期列表和一个 (90 60) 的观察列表,我希望它输出 (+ 1 (+ 2 0)) = 3。我怎样才能给出 (chi-square nil nil) 值 0 而不是立即结束函数?
免责声明:我相信有更好的方法可以做到这一点,也许已经有一些功能可以做到这一点。我写这个函数只是为了学习目的。
第三种cond
情况出错:求和前少了t
:
(defun chi-square (expected-list observed-list)
(cond ((not (= (length expected-list) (length observed-list)))
(print "Lists do not match in length.~%"))
((and (null expected-list) (null observed-list)) 0)
(t (+ (/ (square (- (car observed-list) (car expected-list))) (car expected-list))
(chi-square (cdr expected-list) (cdr observed-list))))))
您可以在 specification.
中找到cond
宏的语法
通常,您希望避免在递归同一列表的过程中调用类似 length
的内容。那是因为 length
的 运行 时间与你给它的列表的长度成正比,你最终会得到一个 O(N^2) 算法,因为你在原始列表。如果您的列表总是很短,那也没关系。最好在例程开始时只测试一次列表长度,或者在列表中的一个是 null
而另一个不是时在最后退出。不管怎样,这里有一些其他的方法来编写这个函数:
;using built-in recursion combinators (mapcar & reduce)
(defun χ² (expected observed)
(reduce #'+ (mapcar (lambda (e o) (/ (square (- o e)) e)) expected observed)))
;using loop
(defun chi-sqr (expected observed)
(loop
for e in expected
for o in observed
summing (/ (square (- o e)) e)))