2016-07-20 5 views
1

まず最初にこのような初心者の質問をお詫び申し上げます。 私の目標はカイ2乗関数を作成するだけでなく、私が経験している一般的な問題を回避する方法を理解することです。lispでカイ二乗関数を作成する。 [初心者]

私のコードは次のようになります。

(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を読み込みます2番目の条件のため)、私はそれを避ける方法を知らない。たとえば、期待値リスト(100 50)と観測リスト(90 60)を出力すると(+ 1(+ 2 0))= 3になります。 nil nil)0の値は関数を終了するだけで、そこには存在しません。

免責事項:私はこれを行うためのよりよい方法があると確信しています。私は学習目的のためだけにこの関数を書いています。

答えて

3

第三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)))))) 

あなたはspecificationcondマクロの構文を見つけることができます。

+0

私の質問に答える時間を取ってくれてありがとう。これは私の問題を解決しました。 –

0

一般的に、同じリストを再帰させる手順の中にlengthのようなものを呼び出さないようにします。これは、実行時間がlengthであるため、それを与えるリストの長さに比例し、元のリストのすべての末尾に呼び出すので、O(N^2)アルゴリズムになります。あなたのリストがいつも短いならOKです。ルーチンの開始時にリストの長さを一度だけテストする方が良いか、リストの1つがnullで、もう1つがリストの長さに達していないときに終了する方がいいです。とにかく、その機能を書くためのいくつかの方法があります:

;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))) 
関連する問題