123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- ;; Jason K. MacDuffie
- ;; I dedicate this to the public domain, for the benefit of all
- ;; due to the triviality of the library.
- (define pi 3.141592653589793)
- (define e 2.718281828459045)
- (define i 0+i)
- (define (deg->rad d)
- (/ (* d pi) 180))
- (define (rad->deg r)
- (/ (* r 180) pi))
- (define (dsin d)
- (sin (deg->rad d)))
- (define (dcos d)
- (cos (deg->rad d)))
- (define (dtan d)
- (tan (deg->rad d)))
- (define (dasin a)
- (rad->deg (asin a)))
- (define (dacos a)
- (rad->deg (acos a)))
- (define (datan a)
- (rad->deg (atan a)))
- (define (integrate f minval maxval dx)
- ;; simple integration
- (let loop ((x minval)
- (sum 0.0))
- (if (<= x maxval)
- (loop (+ x dx)
- (+ sum (* dx (f x))))
- sum)))
- (define (factorial x)
- ;; Technically this is a continuation of factorial
- ;; But it is convenient sometimes
- (if (and (exact? x) (integer? x) (not (negative? x)))
- (let loop ((i 1)
- (p 1))
- (if (<= i x)
- (loop (+ i 1) (* p i))
- p))
- (gamma (+ x 1))))
- (define (stirling-gamma z)
- (* (sqrt (* 2 pi (/ z)))
- (expt (* (/ e) (+ z (/ (- (* 12 z) (/ 1/10 z)))))
- z)))
- (define (gamma z)
- (define a (- (real-part z) (floor (real-part z))))
- (define b (imag-part z))
- (cond
- ((and (integer? z)
- (positive? z))
- (let loop ((i 1)
- (p 1.0))
- (if (< i z)
- (loop (+ i 1) (* i p))
- p)))
- ((< (real-part z) 150)
- (let loop ((i z)
- (p (stirling-gamma (+ 150 a (* 0+i b)))))
- (if (< (real-part i) 150)
- (loop (+ i 1)
- (/ p i))
- p)))
- ((< (real-part z) 151)
- (stirling-gamma z))
- (else
- (let loop ((i z)
- (p (stirling-gamma (+ 150 a (* 0+i b)))))
- (if (> (real-part i) 151)
- (loop (- i 1)
- (* p (- i 1)))
- p)))))
- (define (inverse-gamma x)
- (if (<= x 0.8856032)
- (error "inverse-gamma" "x must be greater than 0.8856032"))
- (if (>= x 2e300)
- (error "inverse-gamma" "x must be less than 2.0e300"))
- (let ((upper-bound (let loop ((u 1.46164))
- (if (< (gamma u) x)
- (loop (+ u 1))
- u))))
- (let loop ((frac 0.5)
- (prev 0.0)
- (r (- upper-bound 0.5)))
- (if (not (= prev r))
- (loop (* frac 0.5)
- r
- (if (< (gamma r) x)
- (+ r frac)
- (- r frac)))
- (if (= x (gamma (round r)))
- (round r)
- r)))))
- (define (inverse-factorial x)
- (let ((y (- (inverse-gamma x) 1)))
- (if (and (exact? x) (integer? y))
- (exact y)
- y)))
- ;; Inverse of the function (* n (log n))
- (define (anti-nlogn x)
- (define (nlogn n)
- (* n (log n)))
- (let ((stopat
- (cond
- ((< x 2.75)
- (error "value must be at least 2.75"))
- ((< x 10.0)
- 2000)
- (else
- 100))))
- (let loop ((guess x)
- (i 0))
- (if (or (= i stopat)
- (= (nlogn guess) x))
- guess
- (loop (/ x (log guess))
- (+ i 1))))))
- ;; Some statistics functions
- (define (mean l)
- (/ (apply + l) (length l)))
- (define (variance l . sample-option)
- (define sample? (and (not (null? sample-option))
- (eq? (car sample-option) 'sample)))
- (define a (square (apply + l)))
- (define b (apply + (map square l)))
- (define n (length l))
- (define ss (- b (/ a n)))
- (/ ss (if sample? (- n 1) n)))
- (define (deviation l . sample-option)
- (define sample? (and (not (null? sample-option))
- (eq? (car sample-option) 'sample)))
- (sqrt (apply variance
- (list l (if sample? 'sample 'population)))))
- (define (z-scores l)
- (define sd (deviation l))
- (define m (mean l))
- (map (lambda (x)
- (/ (- x m) sd))
- l))
- (define (normal-pmf mu sigsq)
- (define C (/ (sqrt (* 2 sigsq pi))))
- (lambda (x)
- (* C (exp (- (/ (square (- x mu))
- (* 2 sigsq)))))))
- (define (normal-cdf mu sigsq)
- ;; For simplicity, make internal mu 0
- (define f (normal-pmf 0 sigsq))
- (define (simple-cdf x)
- (if (< x -10)
- 0.0
- (integrate f (* -4 sigsq) x (* 5.0e-5 sigsq))))
- (lambda (x)
- (if (< x mu)
- (simple-cdf (- x mu))
- (- 1 (simple-cdf (- mu x))))))
- (define (primes upto-minus-one)
- ;; Sieve of Eratosthenes
- (cond
- ((> upto-minus-one 10000000)
- (error "primes"
- "Cannot calculate for values greater than 10000000"
- upto-minus-one))
- ((< upto-minus-one 2)
- '())
- (else
- (let ((upto (+ upto-minus-one 1)))
- (define stop-at (exact (floor (sqrt upto))))
- (define sieve-vector (make-vector upto #t))
- (define (believed-prime? x)
- (vector-ref sieve-vector x))
- (vector-set! sieve-vector 0 #f)
- (vector-set! sieve-vector 1 #f)
- (let loop1 ((i 2))
- (if (<= i stop-at)
- (if (believed-prime? i)
- (let loop2 ((j (* i 2)))
- (if (< j upto)
- (begin
- (vector-set! sieve-vector j #f)
- (loop2 (+ j i)))
- (loop1 (+ i 1))))
- (loop1 (+ i 1)))
- ;; now return a list of primes
- (let make-primes ((out '())
- (j (- upto 1)))
- (if (>= j 0)
- (if (believed-prime? j)
- (make-primes (cons j out) (- j 1))
- (make-primes out (- j 1)))
- out))))))))
- (define (prime? n)
- (define upto
- (floor (exact (sqrt n))))
- (if (< n 2)
- #f
- (let loop ((next (primes upto)))
- (cond
- ((null? next)
- #t)
- ((= 0 (modulo n (car next)))
- #f)
- (else
- (loop (cdr next)))))))
- (define (approx-equal a b eps)
- (< (abs (- (/ a b) 1)) eps))
- (define (~= x y . rest)
- (and (approx-equal x y 1e-13)
- (or (null? rest)
- (apply ~= x rest))))
- (define (percent-scale l)
- (let ((total (apply + l)))
- (map (lambda (i) (* 100 (/ i total))) l)))
|