# 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"