(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))