(defpackage matched-filterer (:nicknames mf)
 (:documentation "
A group of us damgud cyberchatters are making a matched filter
in common lisp.
")

(in-package mf)

(defclass pathed ()
 ((path-of :type 'pathname :initarg :path-of :accessor path-of))
 (:default-initargs :path-of #p""))

(defclass filed-list (pathed)
 ((retrieved :type 'list :initform '() :accessor retrieved)))

(defmethod retrieve ((obj filed-list))
 (with-open-file (in (path-of obj))
  (setf (retrieved obj) (read in))))

(defmethod stow ((obj filed-list))
 (with-open-file (out (path-of obj) :direction :output
 		  :if-exists :supersede
		  :if-does-not-exist :create)
  (prin1 (retrieved obj) out)))

(defclass discrete-signal (filed-list) ())

(defmethod transform (function (obj discrete-signal))
 (funcall function (retrieved obj)))
   
(defun naieve-dft (list)
 (loop for k from 0 below (length list)
  collecting
  (loop for x-n in list
       for n from 0
       summing (* x-n (exp (* 2 pi k n #c(0 -1)
       	       	             (/ (length list))))))))

(defun naieve+dft (list)
 (loop for k from 0 below (length list)
  collecting
  (loop for x-n in list
       for n from 0
       summing (* x-n (exp (* 2 pi #c(0 1)
       	       	             (/ (length list))
			     k n))))))

(defun eg-0 ()
 (print "Set list, written to foo.txt")
 (let ((d-s (make-instance 'discrete-signal :path-of #p"foo.txt")))
  (setf (retrieved d-s) '(1 2 3 4 5))
  (stow d-s)
  (print (retrieved d-s)))
 (print "Read foo.txt, transformed and writter bar.txt")
 (let ((d-s (make-instance 'discrete-signal :path-of #p"foo.txt")))
  (retrieve d-s)
  (let ((result (mf::transform #'mf::naieve-dft d-s))
        (f-s (make-instance 'discrete-signal :path-of #p"bar.txt")))
   (setf (retrieved f-s) result)
   (stow f-s)
   (print (retrieved f-s))
   (terpri)))
 (print "read, +i transformed bar.txt (scaled by (length list) times)")
 (let ((f-s (make-instance 'discrete-signal :path-of #p"bar.txt")))
  (retrieve f-s)
  (format t "~{~d~^ ~}~%"
   (mapcar 'round
    (mapcar 'realpart
     (transform 'naieve+dft f-s)))))
 (terpri))