#| class11.lsp - Moving averages (simple smoother to write) - Animation with slider - Basic foreign functions |# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Moving average simulation ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;--- Function to generate test data (saves truth as side effect) (defun SINE-GEN (n sigma) (+ (setf TRUTH (sin (rseq 0 (* 2 pi) n))) (* sigma (normal-rand n)) )) ;--- Pick parameters (def n 1000) (def noiseSD .5) ;--- Plot data and true function to estimate (def xax (iseq n)) (def p (plot-points xax (setf DATA (sine-gen n noiseSD)) )) (send p :add-lines xax truth :color 'magenta) ;--- Moving average estimator (defun MOVING-AVERAGE (x width) "Smooths assuming input x is equally spaced." (unless (oddp width) (format t "Width needs to be odd integer.~%") (setf width (let ((rw (round width)) ) (if (oddp rw) rw (1+ rw)))) ) (let ((half (/ (1- width) 2)) ; invariants done once (n-1 (1- (length x))) (smth ()) ) (flet ((avg (i) (mean (select x (iseq (max 0 (- i half)) (min n-1 (+ i half))))) )) (dotimes (i (length x)) (push (avg i) smth)) (nreverse smth) ))) ;--- Add smoothed data to plot, varying width of smoother (send p :add-lines xax (moving-average data 15)) (send p :add-lines (lowess xax data) :color 'green) (send p :clear-points) ;--- Smooth the smooth, "twicing" (send p :add-lines xax (moving-average (moving-average data 30) 20) :color 'blue) (plot-lines xax (moving-average (moving-average data 30) 50) :color 'blue) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Slider animation ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;--- Fun with animation, slider (def sin (sample (iseq n) 100)) ; dont crowd the figure (def p2 (plot-points (select xax sin) (select data sin))) (apropos 'slider) ; see page 226 of text (defun draw (x) (send p2 :add-lines xax (moving-average data x)) (send p2 :clear-lines)) )) (interval-slider-dialog '(10 50) ; limits on interval :points 25 ; divisions of interval :action #'draw) (dolist (i '(3 5 10 15 20 25 30 35)) (draw i)) ;--- Too slow to be effective... Try the compiler (compile 'moving-average) ;--- Better, but still pretty slow. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Foreign functions ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;--- Build C function with all passed as pointers look at mean.c ;--- Compile this C function cc -c +O3 -Aa +Z mean.c ld -o mean.CR -b mean.o ;--- Load the definition of this function into Lisp (set-working-directory "/users/bob/html/stat540") (dyn-load "/users/bob/html/stat540/mean.CR") ;--- Template (call-cfun name arg1 arg2 ... ) ;--- Call cfun (CALL-CFUN "myMean" (float (iseq 10)) 10 7.7)