stderr.lisp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. ;; standard error of mean
  2. ;; - generally only recommended if sample size is >= 30
  3. ;; use mean-with-stderr-below to automatically run a generator function until the standard-error drops below a required value
  4. ;; e.g. generating random numbers with #'(lambda () (random 10))
  5. ;;
  6. ;; * (mean-with-stderr-below #'(lambda () (random 10)) 3)
  7. ;; Here it produces a sample of size 30
  8. ;; (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)
  9. ;; 58/15
  10. ;; * (mean-with-stderr-below #'(lambda () (random 10)) 0.1)
  11. ;; Here it fails to reach the requirement, and produces a sample of size 100
  12. ;; (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)
  13. ;; 87/20
  14. ;; * (mean-with-stderr-below #'(lambda () (random 10)) 0.5)
  15. ;; Here the requirement forces it to produce a sample of size 32
  16. ;; (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)
  17. ;; 135/32
  18. ;;
  19. (require :asdf)
  20. (require :alexandria)
  21. (defun standard-error-of-mean (sample)
  22. "Computes the standard error of the mean of given sample"
  23. (if (zerop (length sample))
  24. 0.0
  25. (/ (alexandria:standard-deviation sample)
  26. (sqrt (length sample)))))
  27. (defun mean-with-stderr-below (generator target-standard-error &key (minimum-size 30) (maximum-size 100))
  28. "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."
  29. (let ((sample '()))
  30. ; do minimum number of samples
  31. (dotimes (i minimum-size)
  32. (push (funcall generator) sample))
  33. ; collect more samples until maximum number or stderr condition reached
  34. (do ()
  35. ((or (= (length sample) maximum-size)
  36. (< (standard-error-of-mean sample) target-standard-error))
  37. (alexandria:mean sample)) ; return the sample mean
  38. (push (funcall generator) sample))))
  39. ;; some tests
  40. (defun check (query error-message)
  41. (if query
  42. (format t ".")
  43. (format t "~&Error: ~a~&" error-message)))
  44. (defun eq-nums-p (num-1 num-2 &optional (tolerance 0.001))
  45. "Check if two floats are within tolerance"
  46. (< (abs (- num-1 num-2)) tolerance))
  47. (defun run-tests ()
  48. (check (eq-nums-p 0.0 (standard-error-of-mean '())) "empty list")
  49. (check (eq-nums-p 0.0 (standard-error-of-mean '(1))) "single list")
  50. (check (eq-nums-p 0.03162278
  51. (standard-error-of-mean '(0.1 0.2 0.3 0.25 0.15)))
  52. "small list")
  53. )