Hi all,
I'm trying to calculate the moving average of a certain window size.
One straight forward approach is:
(defn lazy-avg [coll]
  (let [[sum cnt] (reduce
                   (fn [[v c] val] [(+ val v) (inc c)])
                   [0 0]
                   coll)]
    (if (zero? cnt) 0 (/ sum cnt))))

(let [window-size 5
      n 1000000]
  (map lazy-avg (partition window-size 1 (range 0 n)))

This takes about 2 seconds for 10^6 elements on my box. How can I
improve the runtime?
A slightly more performant (not much) approach keeping a rolling sum
would be:

(defn partialsums [start lst]
  (lazy-seq
    (if-let [lst (seq lst)]
          (cons start (partialsums (+ start (first lst)) (rest lst)))
          (list start))))

(defn sliding-window-moving-average [window lst]
  (map #(/ % window)
       (let [start   (apply + (take window lst))
             diffseq (map - (drop window lst) lst)]
         (partialsums start diffseq))))

However, this causes the jvm to run out of heap space for n > 10^6

Is ~ 2 seconds the best I can do?

Cheers
Andreas

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to