#lang scheme/base
(provide (all-defined-out))
(define-values (struct:statistics
statistics-constructor
statistics?
statistics-field-ref
set-statistics-field!)
(make-struct-type 'statistics #f 7 0))
(define statistics-time-dependant?
(make-struct-field-accessor statistics-field-ref 0 'time-dependant?))
(define set-statistics-time-dependant?!
(make-struct-field-mutator set-statistics-field! 0 'time-dependant?))
(define statistics-minimum
(make-struct-field-accessor statistics-field-ref 1 'minimum))
(define set-statistics-minimum!
(make-struct-field-mutator set-statistics-field! 1 'minimum))
(define statistics-maximum
(make-struct-field-accessor statistics-field-ref 2 'maximum))
(define set-statistics-maximum!
(make-struct-field-mutator set-statistics-field! 2 'maximum))
(define statistics-n
(make-struct-field-accessor statistics-field-ref 3 'n))
(define set-statistics-n!
(make-struct-field-mutator set-statistics-field! 3 'n))
(define statistics-sum
(make-struct-field-accessor statistics-field-ref 4 'sum))
(define set-statistics-sum!
(make-struct-field-mutator set-statistics-field! 4 'sum))
(define statistics-sum-of-squares
(make-struct-field-accessor statistics-field-ref 5 'sum-of-squares))
(define set-statistics-sum-of-squares!
(make-struct-field-mutator set-statistics-field! 5 'sum-of-squares))
(define statistics-dimension
(make-struct-field-accessor statistics-field-ref 6 'dimension))
(define set-statistics-dimension!
(make-struct-field-mutator set-statistics-field! 6 'dimension))
(define (make-statistics time-dependant? time)
(statistics-constructor time-dependant? +inf.0 -inf.0 0 0.0 0.0 0))
(define (make-vector-statistics time-dependant? time dimension)
(statistics-constructor time-dependant?
(make-vector dimension +inf.0)
(make-vector dimension -inf.0)
0
(make-vector dimension 0.0)
(make-vector dimension 0.0)
dimension))
(define (statistics-accumulate! statistics value time)
(set-statistics-n!
statistics (+ (statistics-n statistics) time))
(if (= (statistics-dimension statistics) 0)
(begin
(when (< value (statistics-minimum statistics))
(set-statistics-minimum! statistics value))
(when (> value (statistics-maximum statistics))
(set-statistics-maximum! statistics value))
(let ((weighted-value (* value time))
(weighted-value-squared (* value value time)))
(set-statistics-sum!
statistics (+ (statistics-sum statistics) weighted-value))
(set-statistics-sum-of-squares!
statistics (+ (statistics-sum-of-squares statistics)
weighted-value-squared))))
(do ((i 0 (+ i 1)))
((> i (statistics-dimension statistics)) (void))
(when (< (vector-ref value i) (vector-ref (statistics-minimum statistics) i))
(vector-set! (statistics-minimum statistics) i (vector-ref value i)))
(when (> (vector-ref value i) (vector-ref (statistics-maximum statistics) i))
(vector-set! (statistics-maximum statistics) i (vector-ref value i)))
(let ((weighted-value (* (vector-ref value i) time))
(weighted-value-squared (* (vector-ref value i)
(vector-ref value i)
time)))
(vector-set! (statistics-sum statistics) i
(+ (vector-ref (statistics-sum statistics) i)
weighted-value))
(vector-set! (statistics-sum-of-squares statistics) i
(+ (vector-ref (statistics-sum-of-squares statistics) i)
weighted-value-squared))))))
(define (statistics-tally! statistics value)
(statistics-accumulate! statistics value 1))
(define (statistics-mean statistics)
(if (= (statistics-dimension statistics) 0)
(/ (statistics-sum statistics)
(statistics-n statistics))
(let ((n (statistics-n statistics))
(sum (statistics-sum statistics))
(mean (make-vector (statistics-dimension statistics))))
(do ((i 0 (+ i 1)))
((> i (statistics-dimension statistics)) (mean))
(vector-set! mean i
(/ (vector-ref sum i) n))))))
(define (statistics-mean-square statistics)
(if (= (statistics-dimension statistics) 0)
(/ (statistics-sum-of-squares statistics)
(statistics-n statistics))
(let ((n (statistics-n statistics))
(sum-of-squares (statistics-sum-of-squares statistics))
(mean-square (make-vector (statistics-dimension statistics))))
(do ((i 0 (+ i 1)))
((> i (statistics-dimension statistics)) (mean-square))
(vector-set! mean-square i
(/ (vector-ref sum-of-squares i) n))))))
(define (statistics-variance statistics)
(if (= (statistics-dimension statistics) 0)
(- (statistics-mean-square statistics)
(* (statistics-mean statistics)
(statistics-mean statistics)))
(let ((n (statistics-n statistics))
(mean (statistics-mean statistics))
(mean-square (statistics-mean-square statistics))
(variance (make-vector (statistics-dimension statistics))))
(do ((i 0 (+ i 1)))
((> i (statistics-dimension statistics)) (variance))
(vector-set! variance i
(- (vector-ref mean-square i)
(* (vector-ref mean i)
(vector-ref mean i))))))))
(define (statistics-standard-deviation statistics)
(if (= (statistics-dimension statistics) 0)
(sqrt (statistics-variance statistics))
(let ((variance (statistics-variance statistics))
(standard-deviation (make-vector (statistics-dimension statistics))))
(do ((i 0 (+ i 1)))
((> i (statistics-dimension statistics)) (standard-deviation))
(vector-set! standard-deviation i
(sqrt (vector-ref variance i)))))))