Skip to content

Instantly share code, notes, and snippets.

@aiba
Last active October 17, 2019 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aiba/53237d6015f2b58de1314b3c19a78d71 to your computer and use it in GitHub Desktop.
Save aiba/53237d6015f2b58de1314b3c19a78d71 to your computer and use it in GitHub Desktop.
linear interpolation transducer
(defn linear-interpolate
([]
(fn [rf]
(let [rrf (#'clojure.core/preserving-reduced rf)
skipped (volatile! 0) ;; n of contiguous nils
prev (volatile! nil)] ;; most recent value seen
(fn
([] (rf)) ;; init
([result] ;; completion -- skipped stay nils since no endpoint
(rf (reduce rf result (repeat @skipped nil))))
([result x] ;; step
(if (nil? x)
(if (nil? @prev)
(rf result nil)
(do (vswap! skipped inc)
result))
(if (or (zero? @skipped) (nil? @prev))
(do (vreset! prev x)
(rf result (double x)))
(let [delta (/ (- x @prev) (inc @skipped))
xs (->> (iterate #(+ % delta) @prev)
(drop 1)
(take @skipped))]
(do (vreset! skipped 0)
(vreset! prev x)
(reduce rrf result (map double (concat xs [x]))))))))))))
([coll]
(sequence (linear-interpolate) coll)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment