学习LISP-定义stdev函数

学习LISP-定义stdev函数,lisp,common-lisp,Lisp,Common Lisp,我对LISP非常陌生(请原谅我犯的愚蠢错误),今年的第一个实验室指出: 定义一个函数,STDEV,用于计算数字列表的标准偏差(查找公式) 我写了这段代码,但我不知道为什么它拒绝工作: (defun stdev (x) (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x) (length x))) 2)) (le

我对LISP非常陌生(请原谅我犯的愚蠢错误),今年的第一个实验室指出:

定义一个函数,STDEV,用于计算数字列表的标准偏差(查找公式)

我写了这段代码,但我不知道为什么它拒绝工作:

(defun stdev (x)
  (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                   (length x)))
                           2))
           (length x))))


(setq a '(1 2 3 4 5))

(STDEV a)
但在运行时它会产生错误:“(1 2 3 4 5)不是一个数字”


我相信我已经正确地模拟了标准偏差公式(尽管我不会让自己犯一个愚蠢的错误),但是为什么我的程序不喜欢我给它评估的数字列表呢?这很可能是一个简单的错误,输入这种新的编码风格,但任何和所有的帮助是非常感谢

您正在使用
-a…
,而
a
是您的列表


这不是一个完整的答案,因为这是一个家庭作业,但是:如果你想先计算平均值,你可以实现一个求和函数,你需要两次,一次折叠,你可以使用一个映射对列表中的每个元素应用一个帮助函数或lambda表达式。

a
是你的列表时,你要取
-a…


这不是一个完整的答案,因为这是一个家庭作业,但是:如果您想先计算平均值,您可以实现一个sum函数,需要使用一个fold函数执行两次,并且您可以使用映射将helper函数或lambda表达式应用于列表的每个元素。

使用缩进。我编辑了你的问题:

(defun stdev (x)
  (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                   (length x)))
                           2))
           (length x))))
expt
返回一个数字。你呼叫
(应用'+一些号码)

也可以从列表中减去一个数字

为什么?

一般来说,我建议使用Lisp侦听器(又称REPL)来获取工作代码:

计算平均值:

CL-USER 21 > (let ((l (list 1 2 3 4 5)))
               (/ (reduce #'+ l)
                  (length l)))
3
使用以下公式减去平均值和平方:

将方差计算为上述的平均值:

CL-USER 23 > (let ((l (list 4 1 0 1 4)))
               (/ (reduce #'+ l)
                  (length l)))
2
取平方根得到标准偏差:


然后您只需要将其组合成几个函数:
平均值
方差
标准偏差
,使用缩进。我编辑了你的问题:

(defun stdev (x)
  (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                   (length x)))
                           2))
           (length x))))
expt
返回一个数字。你呼叫
(应用'+一些号码)

也可以从列表中减去一个数字

为什么?

一般来说,我建议使用Lisp侦听器(又称REPL)来获取工作代码:

计算平均值:

CL-USER 21 > (let ((l (list 1 2 3 4 5)))
               (/ (reduce #'+ l)
                  (length l)))
3
使用以下公式减去平均值和平方:

将方差计算为上述的平均值:

CL-USER 23 > (let ((l (list 4 1 0 1 4)))
               (/ (reduce #'+ l)
                  (length l)))
2
取平方根得到标准偏差:


然后你只需要把它组合成几个函数:
平均值
方差
标准差

我的推理是我需要对x的每个实例求平方-平均值:(xi-xmean)^2。然后把所有的结果加起来。因为正如您所说,expt返回一个数字,也许我需要在lambda表达式中执行expt,以实现对列表中的每个实例进行平方运算的目标。@JohnBucher:但是
apply
不会这样做。请参见
mapcar
。我对LISP非常陌生,因此只对mapcar、lambda和defun进行了介绍,也没有深入了解。我怎样才能使程序接受一个列表而不是使用代码中给出的列表呢。第一个很简单,应该是:(defun avg(x)(/(reduce'+x)(length x)))。但第二部分给了我问题。我不知道(项目)是什么,它是重要的还是仅仅是一个保留名称。然后我试着把它替换成A列表中的(列表12345),但它似乎不喜欢我现在的做法(列表'x)/('x)/(x),那些不喜欢work@JohnBucher:至少做三个函数:平均值、方差和标准差。我的问题就快解决了。我的三条语句是:(setqa'(123445)),(defun avg(x)(/(reduce'+x)(length x)),和(defun STDEV(x)(sqrt(/(reduce'+(mapcar(lambda(x)(expt(-x(avg a))2))(length x)),它们将工作并产生正确的输出,但这仅仅是因为a被硬编码到STDEV中,如这里所示:(expt(-x(avg a))2))。我试着将a改为x,然后改为'x,但程序不喜欢这样,并抛出错误。如何使程序在运行时使用给定的列表而不是硬编码的列表?我的推理是,我需要对x实例的每个实例求平方-平均值:(xi-xmean)^2。然后把所有的结果加起来。因为正如您所说,expt返回一个数字,也许我需要在lambda表达式中执行expt,以实现对列表中的每个实例进行平方运算的目标。@JohnBucher:但是
apply
不会这样做。请参见
mapcar
。我对LISP非常陌生,因此只对mapcar、lambda和defun进行了介绍,也没有深入了解。我怎样才能使程序接受一个列表而不是使用代码中给出的列表呢。第一个很简单,应该是:(defun avg(x)(/(reduce'+x)(length x)))。但第二部分给了我问题。我不知道(项目)是什么,它是重要的还是仅仅是一个保留名称。然后我试着把它替换成A列表中的(列表12345),但它似乎不喜欢我现在的做法(列表'x)/('x)/(x),那些不喜欢work@JohnBucher:至少做三个函数:平均值、方差和标准差。我的问题就快解决了。我的三条语句是:(setqa'(123445)),(defun avg(x)(/(reduce'+x)(length x)),和(defun STDEV(x)(sqrt(/(reduce'+(mapcar(lambda(x)(expt(-x(avg a))2))(length x)),它们将工作并产生正确的输出,但这仅仅是因为a被硬编码到STDEV中,如这里所示:(expt(-x(avg a))2))。我试着将a改为x,然后改为'x,但程序不喜欢这样,并抛出错误。如何使程序在运行时使用给定的列表而不是硬编码的列表?