Skip to content

Latest commit

 

History

History
88 lines (65 loc) · 2.91 KB

README.md

File metadata and controls

88 lines (65 loc) · 2.91 KB

incstats

A clojure library that calculates simple statistics incrementally, i.e. with constant memory costs and results can be queried online.

incstats can be used to calculate:

  • Mean (either simple, weighted, or exponentially weighted)
  • Variance (biased variance, either simple, weighted, or exponentially weighted)

Usage

leiningen

[incstats "0.1.2"]

use

(use 'incstats.core)

examples

Let's first define a stopwatch macro for the examples below

(defmacro stopwatch-nanos
  [body]
  `(let [start# (. System (nanoTime))
         ret# ~body]
     (- (. System (nanoTime)) start#)))

Example: Calculate the simple mean of a bunch of stopwatch measurements of (Thread/sleep 0)

(let [stats (atom nil)] ; 'stats' will store the statistical data
  (dotimes [x 5]
    (let [nanos-elapsed (stopwatch-nanos (Thread/sleep 0))]
      (println "nanos elapsed: " nanos-elapsed)
      ;;
      ;; the following line is where a new data point is added and the stats get updated
      ;;
      (swap! stats update-mean (double nanos-elapsed)))
    ;;
    ;; print the stats
    ;;
    (println "mean:" (:mean @stats) " raw results:" @stats)))

Example: Calculate the exponentially weighted mean, using a weight factor of 0.8

(let [stats (atom nil) ; 'stats' will store the statistical data
      alpha 0.8        ; the weight factor
      update-exponentially-weighted-mean (create-update-exponentially-weighted-variance alpha)]
  (dotimes [x 5]
    (let [nanos-elapsed (stopwatch-nanos (Thread/sleep 0))]
      (println "nanos elapsed: " nanos-elapsed)
      ;;
      ;; the following line is where a new data point is added and the stats get updated
      ;;
      (swap! stats update-exponentially-weighted-mean (double nanos-elapsed)))
    ;;
    ;; print the stats
    ;;
    (println "mean:" (:mean @stats) " raw results:" @stats)))

Example: Calculate the weighted mean, variance and standard deviation, using some random weights

(let [stats (atom nil) ; 'stats' will store the statistical data
      some-random-weights [0.1 2.0 2.0 3.0]]
  (doseq [weight some-random-weights]
    (let [nanos-elapsed (stopwatch-nanos (Thread/sleep 0))]
      (println "nanos elapsed: " nanos-elapsed)
      ;;
      ;; the following line is where a new data point is added and the stats get updated
      ;;
      (swap! stats update-weighted-variance [(double nanos-elapsed) weight]))
    ;;
    ;; print the stats
    ;;
    (println "mean:" (:mean @stats) " std dev:" (Math/sqrt (:variance @stats)) " variance:" (:variance @stats))))

License

Copyright © 2013 Eugen Dück

Distributed under the Eclipse Public License, the same as Clojure.

References

This library makes use of the Tony Finch's 2009 paper "Incremental calculation of weighted mean and variance"