123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- ;; standard error of mean
- ;; - generally only recommended if sample size is >= 30
- ;; use mean-with-stderr-below to automatically run a generator function until the standard-error drops below a required value
- ;; e.g. generating random numbers with #'(lambda () (random 10))
- ;;
- ;; * (mean-with-stderr-below #'(lambda () (random 10)) 3)
- ;; Here it produces a sample of size 30
- ;; (4 8 1 8 5 2 0 3 1 4 6 1 9 1 4 4 3 4 6 0 5 6 5 8 3 2 2 1 8 2)
- ;; 58/15
- ;; * (mean-with-stderr-below #'(lambda () (random 10)) 0.1)
- ;; Here it fails to reach the requirement, and produces a sample of size 100
- ;; (0 8 8 3 4 3 6 5 4 0 7 3 4 7 6 6 0 0 9 7 4 2 5 7 1 5 3 8 0 8 1 9 0 9 5 9 0 7 3 2 6 1 5 2 6 5 8 6 9 1 1 2 8 4 3 6 8 2 3 4 3 5 0 0 8 2 2 3 0 2 9 5 8 7 4 0 8 6 9 2 9 3 0 7 2 3 3 5 2 1 9 7 2 7 0 6 8 6 4 0)
- ;; 87/20
- ;; * (mean-with-stderr-below #'(lambda () (random 10)) 0.5)
- ;; Here the requirement forces it to produce a sample of size 32
- ;; (5 1 2 4 3 1 5 2 9 4 8 4 7 2 6 0 0 2 0 5 9 2 9 6 7 5 5 3 7 3 8 1)
- ;; 135/32
- ;;
- (require :asdf)
- (require :alexandria)
- (defun standard-error-of-mean (sample)
- "Computes the standard error of the mean of given sample"
- (if (zerop (length sample))
- 0.0
- (/ (alexandria:standard-deviation sample)
- (sqrt (length sample)))))
- (defun mean-with-stderr-below (generator target-standard-error &key (minimum-size 30) (maximum-size 100))
- "Runs generator at least minimum-size times, stopping when standard error is less than target or reaches maximum-size. Returns the mean value from generator."
- (let ((sample '()))
- ; do minimum number of samples
- (dotimes (i minimum-size)
- (push (funcall generator) sample))
- ; collect more samples until maximum number or stderr condition reached
- (do ()
- ((or (= (length sample) maximum-size)
- (< (standard-error-of-mean sample) target-standard-error))
- (alexandria:mean sample)) ; return the sample mean
- (push (funcall generator) sample))))
- ;; some tests
- (defun check (query error-message)
- (if query
- (format t ".")
- (format t "~&Error: ~a~&" error-message)))
- (defun eq-nums-p (num-1 num-2 &optional (tolerance 0.001))
- "Check if two floats are within tolerance"
- (< (abs (- num-1 num-2)) tolerance))
- (defun run-tests ()
- (check (eq-nums-p 0.0 (standard-error-of-mean '())) "empty list")
- (check (eq-nums-p 0.0 (standard-error-of-mean '(1))) "single list")
- (check (eq-nums-p 0.03162278
- (standard-error-of-mean '(0.1 0.2 0.3 0.25 0.15)))
- "small list")
- )
|