root/trunk/thirdparty/alexandria/numbers.lisp

Revision 3200, 8.5 kB (checked in by hans, 8 months ago)

pull alexandria from darcs repository

  • Property svn:executable set to *
Line 
1 (in-package :alexandria)
2
3 (declaim (inline clamp))
4 (defun clamp (number min max)
5   "Clamps the NUMBER into [MIN, MAX] range. Returns MIN if NUMBER lesser then
6 MIN and MAX if NUMBER is greater then MAX, otherwise returns NUMBER."
7   (if (< number min)
8       min
9       (if (> number max)
10           max
11           number)))
12
13 (defun gaussian-random (&optional min max)
14   "Returns two gaussian random double floats as the primary and secondary value,
15 optionally constrained by MIN and MAX. Gaussian random numbers form a standard
16 normal distribution around 0.0d0."
17   (labels ((gauss ()
18              (loop
19                 for x1 = (- (random 2.0d0) 1.0d0)
20                 for x2 = (- (random 2.0d0) 1.0d0)
21                 for w = (+ (expt x1 2) (expt x2 2))
22                 when (< w 1.0d0)
23                 do (let ((v (sqrt (/ (* -2.0d0 (log w)) w))))
24                      (return (values (* x1 v) (* x2 v))))))
25            (guard (x min max)
26              (unless (<= min x max)
27                (tagbody
28                 :retry
29                   (multiple-value-bind (x1 x2) (gauss)
30                     (when (<= min x1 max)
31                       (setf x x1)
32                       (go :done))
33                     (when (<= min x2 max)
34                       (setf x x2)
35                       (go :done))
36                     (go :retry))
37                 :done))
38              x))
39     (multiple-value-bind (g1 g2) (gauss)
40       (values (guard g1 (or min g1) (or max g1))
41               (guard g2 (or min g2) (or max g2))))))
42
43 (declaim (inline iota))
44 (defun iota (n &key (start 0) (step 1))
45   "Return a list of n numbers, starting from START (with numeric contagion
46 from STEP applied), each consequtive number being the sum of the previous one
47 and STEP. START defaults to 0 and STEP to 1.
48
49 Examples:
50
51   (iota 4)                      => (0 1 2 3 4)
52   (iota 3 :start 1 :step 1.0)   => (1.0 2.0 3.0)
53   (iota 3 :start -1 :step -1/2) => (-1 -3/2 -2)
54 "
55   (declare (type (integer 0) n) (number start step))
56   (loop repeat n
57      ;; KLUDGE: get numeric contagion right for the first element too
58      for i = (+ start (- step step)) then (+ i step)
59      collect i))
60
61 (declaim (inline map-iota))
62 (defun map-iota (function n &key (start 0) (step 1))
63   "Calls FUNCTION with N numbers, starting from START (with numeric contagion
64 from STEP applied), each consequtive number being the sum of the previous one
65 and STEP. START defaults to 0 and STEP to 1. Returns N.
66
67 Examples:
68
69   (map-iota #'print 3 :start 1 :step 1.0) => 3
70     ;;; 1.0
71     ;;; 2.0
72     ;;; 3.0
73 "
74   (declare (type (integer 0) n) (number start step))
75   (loop repeat n
76         ;; KLUDGE: get numeric contagion right for the first element too
77         for i = (+ start (- step step)) then (+ i step)
78         do (funcall function i))
79   n)
80
81 (declaim (inline lerp))
82 (defun lerp (v a b)
83   "Returns the result of linear interpolation between A and B, using the
84 interpolation coefficient V."
85    (+ a (* v (- b a))))
86
87 (declaim (inline mean))
88 (defun mean (sample)
89   "Returns the mean of SAMPLE. SAMPLE must be a sequence of numbers."
90   (/ (reduce #'+ sample) (length sample)))
91
92 (declaim (inline median))
93 (defun median (sample)
94   "Returns median of SAMPLE. SAMPLE must be a sequence of real numbers."
95   (let* ((vector (sort (copy-sequence 'vector sample) #'<))
96          (length (length vector))
97          (middle (truncate length 2)))
98     (if (oddp length)
99         (aref vector middle)
100         (/ (+ (aref vector middle) (aref vector (1+ middle))) 2))))
101
102 (declaim (inline variance))
103 (defun variance (sample &key (biased t))
104   "Variance of SAMPLE. Returns the biased variance if BIASED is true (the default),
105 and the unbiased estimator of variance if BIASED is false. SAMPLE must be a
106 sequence of numbers."
107   (let ((mean (mean sample)))
108     (/ (reduce (lambda (a b)
109                  (+ a (expt (- b mean) 2)))
110                sample
111                :initial-value 0)
112        (- (length sample) (if biased 0 1)))))
113
114 (declaim (inline standard-deviation))
115 (defun standard-deviation (sample &key (biased t))
116   "Standard deviation of SAMPLE. Returns the biased standard deviation if
117 BIASED is true (the default), and the square root of the unbiased estimator
118 for variance if BIASED is false (which is not the same as the unbiased
119 estimator for standard deviation). SAMPLE must be a sequence of numbers."
120   (sqrt (variance sample :biased biased)))
121
122 (define-modify-macro maxf (&rest numbers) max
123   "Modify-macro for MAX. Sets place designated by the first argument to the
124 maximum of its original value and NUMBERS.")
125
126 (define-modify-macro minf (&rest numbers) min
127   "Modify-macro for MIN. Sets place designated by the first argument to the
128 minimum of its original value and NUMBERS.")
129
130 ;;;; Factorial
131
132 ;;; KLUDGE: This is really dependant on the numbers in question: for
133 ;;; small numbers this is larger, and vice versa. Ideally instead of a
134 ;;; constant we would have RANGE-FAST-TO-MULTIPLY-DIRECTLY-P.
135 (defconstant +factorial-bisection-range-limit+ 8)
136
137 ;;; KLUDGE: This is really platform dependant: ideally we would use
138 ;;; (load-time-value (find-good-direct-multiplication-limit)) instead.
139 (defconstant +factorial-direct-multiplication-limit+ 13)
140
141 (defun %multiply-range (i j)
142   ;; We use a a bit of cleverness here:
143   ;;
144   ;; 1. For large factorials we bisect in order to avoid expensive bignum
145   ;;    multiplications: 1 x 2 x 3 x ... runs into bignums pretty soon,
146   ;;    and once it does that all further multiplications will be with bignums.
147   ;;
148   ;;    By instead doing the multiplication in a tree like
149   ;;       ((1 x 2) x (3 x 4)) x ((5 x 6) x (7 x 8))
150   ;;    we manage to get less bignums.
151   ;;
152   ;; 2. Division isn't exactly free either, however, so we don't bisect
153   ;;    all the way down, but multiply ranges of integers close to each
154   ;;    other directly.
155   ;;
156   ;; For even better results it should be possible to use prime
157   ;; factorization magic, but Nikodemus ran out of steam.
158   ;;
159   ;; KLUDGE: We support factorials of bignums, but it seems quite
160   ;; unlikely anyone would ever be able to use them on a modern lisp,
161   ;; since the resulting numbers are unlikely to fit in memory... but
162   ;; it would be extremely unelegant to define FACTORIAL only on
163   ;; fixnums, _and_ on lisps with 16 bit fixnums this can actually be
164   ;; needed.
165   (labels ((bisect (j k)
166              (declare (type (integer 1 #.most-positive-fixnum) j k))
167              (if (< (- k j) +factorial-bisection-range-limit+)
168                  (multiply-range j k)
169                  (let ((middle (+ j (truncate (- k j) 2))))
170                    (* (bisect j middle)
171                       (bisect (+ middle 1) k)))))
172            (bisect-big (j k)
173              (declare (type (integer 1) j k))
174              (if (= j k)
175                  j
176                  (let ((middle (+ j (truncate (- k j) 2))))
177                    (* (if (<= middle most-positive-fixnum)
178                           (bisect j middle)
179                           (bisect-big j middle))
180                       (bisect-big (+ middle 1) k)))))
181            (multiply-range (j k)
182              (declare (type (integer 1 #.most-positive-fixnum) j k))
183              (do ((f k (* f m))
184                   (m (1- k) (1- m)))
185                  ((< m j) f)
186                (declare (type (integer 0 (#.most-positive-fixnum)) m)
187                         (type unsigned-byte f)))))
188     (bisect i j)))
189
190 (declaim (inline factorial))
191 (defun %factorial (n)
192   (if (< n 2)
193       1
194       (%multiply-range 1 n)))
195
196 (defun factorial (n)
197   "Factorial of non-negative integer N."
198   (check-type n (integer 0))
199   (%factorial n))
200
201 ;;;; Combinatorics
202
203 (defun binomial-coefficient (n k)
204   "Binomial coefficient of N and K, also expressed as N choose K. This is the
205 number of K element combinations given N choises. N must be equal to or
206 greater then K."
207   (check-type n (integer 0))
208   (check-type k (integer 0))
209   (assert (>= n k))
210   (if (or (zerop k) (= n k))
211       1
212       (let ((n-k (- n k)))
213         (if (= 1 n-k)
214             n
215             ;; General case, avoid computing the 1x...xK twice:
216             ;;
217             ;;    N!           1x...xN          (K+1)x...xN
218             ;; --------  =  ---------------- =  ------------, N>1
219             ;; K!(N-K)!     1x...xK x (N-K)!       (N-K)!
220             (/ (%multiply-range (+ k 1) n)
221                (%factorial n-k))))))
222
223 (defun subfactorial (n)
224   "Subfactorial of the non-negative integer N."
225   (check-type n (integer 0))
226   (case n
227     (0 1)
228     (1 0)
229     (otherwise
230      (floor (/ (+ 1 (factorial n)) (exp 1))))))
231
232 (defun count-permutations (n &optional (k n))
233   "Number of K element permutations for a sequence of N objects.
234 R defaults to N"
235   ;; FIXME: Use %multiply-range and take care of 1 and 2, plus
236   ;; check types.
237   (/ (factorial n)
238      (factorial (- n k))))
Note: See TracBrowser for help on using the browser.