|
40 | 40 | ::m/int-non- |
41 | 41 | #(gen/large-integer* {:min 0 :max mdl}))) |
42 | 42 |
|
| 43 | +(defn- n-no-less-than-k? |
| 44 | + [{:keys [k n]}] |
| 45 | + (>= n k)) |
43 | 46 |
|
44 | 47 | ;;;CONSTANTS |
45 | 48 | (def ^:private ^:const subfactorials |
46 | 49 | "also called 'recontres numbers' or 'derangements'" |
47 | | - [1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961, 14684570, 176214841, |
48 | | - 2290792932, 32071101049, 481066515734, 7697064251745, 130850092279664, |
49 | | - 2355301661033953, 44750731559645106, 895014631192902121, |
50 | | - 18795307255050944540]) |
| 50 | + [1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961, 14684570, 176214841, 2290792932, |
| 51 | + 32071101049, 481066515734, 7697064251745, 130850092279664, 2355301661033953, 44750731559645106, |
| 52 | + 895014631192902121, 18795307255050944540]) |
51 | 53 |
|
52 | 54 | (def ^:private ^:const bell-numbers |
53 | | - [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, |
54 | | - 27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159, |
55 | | - 5832742205057, 51724158235372, 474869816156751, 4506715738447323, |
56 | | - 44152005855084346, 445958869294805289, 4638590332229999353, |
| 55 | + [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322, |
| 56 | + 1382958545, 10480142147, 82864869804, 682076806159, 5832742205057, 51724158235372, |
| 57 | + 474869816156751, 4506715738447323, 44152005855084346, 445958869294805289, 4638590332229999353, |
57 | 58 | 49631246523618756274]) |
58 | 59 |
|
59 | 60 | ;;;FACTORIALS |
|
237 | 238 | [k n] |
238 | 239 | (let [diff (- n k)] |
239 | 240 | (cond (or (zero? diff) (zero? k)) 1.0 |
240 | | - (or (m/one? k) (m/one? diff)) (double n) |
241 | | - (> k (/ n 2)) (choose-k-from-n diff n) |
242 | | - :else (reduce (fn [acc i] |
243 | | - (let [acc (* acc (/ (+ diff i) i))] |
244 | | - (if (m/inf+? acc) |
245 | | - (reduced acc) |
246 | | - acc))) |
247 | | - 1.0 |
248 | | - (range 1 (inc k)))))) |
249 | | - |
250 | | -(defn n-no-less-than-k? |
251 | | - [{:keys [k n]}] |
252 | | - (>= n k)) |
| 241 | + (or (m/one? k) (m/one? diff)) (double n) |
| 242 | + (> k (/ n 2)) (choose-k-from-n diff n) |
| 243 | + :else (reduce (fn [acc i] |
| 244 | + (let [acc (* acc (/ (+ diff i) i))] |
| 245 | + (if (m/inf+? acc) |
| 246 | + (reduced acc) |
| 247 | + acc))) |
| 248 | + 1.0 |
| 249 | + (range 1 (inc k)))))) |
253 | 250 |
|
254 | 251 | (s/fdef choose-k-from-n |
255 | 252 | :args (s/with-gen |
256 | | - (s/and (s/cat :k ::m/int-non- |
257 | | - :n ::m/int-non-) |
| 253 | + (s/and (s/cat :k ::m/int-non- :n ::m/int-non-) |
258 | 254 | n-no-less-than-k?) |
259 | 255 | #(gen/bind |
260 | 256 | (s/gen ::m/int-non-) |
|
272 | 268 | (m/maybe-long-able (choose-k-from-n k n))) |
273 | 269 |
|
274 | 270 | (s/fdef choose-k-from-n' |
275 | | - :args (s/and (s/cat :k ::m/int-non- |
276 | | - :n ::m/int-non-) |
277 | | - (fn [{:keys [k n]}] |
278 | | - (>= n k))) |
| 271 | + :args (s/and (s/cat :k ::m/int-non- :n ::m/int-non-) |
| 272 | + n-no-less-than-k?) |
279 | 273 | :ret ::m/num) |
280 | 274 |
|
281 | 275 | (defn log-choose-k-from-n |
|
299 | 293 | (log-factorial (- n k)))))) |
300 | 294 |
|
301 | 295 | (s/fdef log-choose-k-from-n |
302 | | - :args (s/and (s/cat :k ::m/non- |
303 | | - :n ::m/non-) |
304 | | - (fn [{:keys [k n]}] |
305 | | - (>= n k))) |
| 296 | + :args (s/and (s/cat :k ::m/non- :n ::m/non-) |
| 297 | + n-no-less-than-k?) |
306 | 298 | :ret ::m/num) |
307 | 299 |
|
308 | 300 | (defn multinomial-coefficient |
|
321 | 313 | (multinomial-coefficient [1 1 1]) ;=> 6.0 (3! permutations)" |
322 | 314 | [ks] |
323 | 315 | (let [n (reduce + 0 ks)] |
324 | | - (/ (factorial n) |
325 | | - (reduce * 1.0 (map factorial ks))))) |
| 316 | + (/ (factorial n) (reduce * 1.0 (map factorial ks))))) |
326 | 317 |
|
327 | 318 | (s/fdef multinomial-coefficient |
328 | 319 | :args (s/cat :ks (s/coll-of ::m/int-non-)) |
|
337 | 328 | (log-multinomial-coefficient [2 3 1]) ;=> 4.0943... (ln(60)) |
338 | 329 | (log-multinomial-coefficient [50 50]) ;=> 66.7838... (ln(C(100,50)))" |
339 | 330 | [ks] |
340 | | - (let [n (reduce + 0 ks)] |
341 | | - (- (log-factorial n) |
342 | | - (reduce + 0.0 (map log-factorial ks))))) |
| 331 | + (let [n (reduce + 0.0 ks)] |
| 332 | + (- (log-factorial n) (reduce + 0.0 (map log-factorial ks))))) |
343 | 333 |
|
344 | 334 | (s/fdef log-multinomial-coefficient |
345 | 335 | :args (s/cat :ks (s/coll-of ::m/non-)) |
|
353 | 343 | (* (/ (factorial k)) |
354 | 344 | (ccr/fold |
355 | 345 | + (fn [tot e] |
356 | | - (+ tot |
357 | | - (* (m/pow (- 1) e) |
358 | | - (choose-k-from-n e k) |
359 | | - (m/pow (- k e) n)))) |
| 346 | + (+ tot (* (m/pow (- 1) e) |
| 347 | + (choose-k-from-n e k) |
| 348 | + (m/pow (- k e) n)))) |
360 | 349 | (range (inc k)))))) |
361 | 350 |
|
362 | 351 | (s/fdef stirling-number-of-the-second-kind |
363 | | - :args (s/and (s/cat :k ::m/long-non- |
364 | | - :n ::m/long) |
365 | | - (fn [{:keys [k n]}] |
366 | | - (>= n k))) |
| 352 | + :args (s/and (s/cat :k ::m/long-non- :n ::m/long) |
| 353 | + n-no-less-than-k?) |
367 | 354 | :ret ::m/number) |
368 | 355 |
|
369 | 356 | (defn stirling-number-of-the-second-kind' |
|
374 | 361 |
|
375 | 362 | (s/fdef stirling-number-of-the-second-kind' |
376 | 363 | :args (s/and (s/cat :k ::m/long-non- :n ::m/long) |
377 | | - (fn [{:keys [k n]}] |
378 | | - (>= n k))) |
| 364 | + n-no-less-than-k?) |
379 | 365 | :ret ::m/number) |
380 | 366 |
|
381 | 367 | (defn log-stirling-number-of-the-second-kind |
|
409 | 395 |
|
410 | 396 | (s/fdef log-stirling-number-of-the-second-kind |
411 | 397 | :args (s/and (s/cat :k ::m/long-non- :n ::m/long-non-) |
412 | | - (fn [{:keys [k n]}] |
413 | | - (>= n k))) |
| 398 | + n-no-less-than-k?) |
414 | 399 | :ret ::m/num) |
415 | 400 |
|
416 | 401 | (defn stirling-number-of-the-first-kind |
|
440 | 425 | (fn [row curr-k] |
441 | 426 | (assoc row curr-k |
442 | 427 | (+ (* (dec curr-n) (get prev-row curr-k 0.0)) |
443 | | - (get prev-row (dec curr-k) 0.0)))) |
| 428 | + (get prev-row (dec curr-k) 0.0)))) |
444 | 429 | {} |
445 | 430 | (range 1 (inc (min curr-n k))))) |
446 | 431 | {0 1.0} |
|
450 | 435 | (s/fdef stirling-number-of-the-first-kind |
451 | 436 | :args (s/with-gen |
452 | 437 | (s/and (s/cat :k ::m/long-non- :n ::m/long-non-) |
453 | | - (fn [{:keys [k n]}] |
454 | | - (>= n k))) |
| 438 | + n-no-less-than-k?) |
455 | 439 | #(gen/bind |
456 | 440 | (gen/large-integer* {:min 0 :max 15}) |
457 | 441 | (fn [k] |
|
467 | 451 | (s/fdef stirling-number-of-the-first-kind' |
468 | 452 | :args (s/with-gen |
469 | 453 | (s/and (s/cat :k ::m/long-non- :n ::m/long-non-) |
470 | | - (fn [{:keys [k n]}] |
471 | | - (>= n k))) |
| 454 | + n-no-less-than-k?) |
472 | 455 | #(gen/bind |
473 | 456 | (gen/large-integer* {:min 0 :max 15}) |
474 | 457 | (fn [k] |
|
480 | 463 | "Returns the number of partitions of a set of size `n`." |
481 | 464 | [n] |
482 | 465 | (cond (> n 170) m/nan |
483 | | - (and (m/non-? n) (< n 27)) (bell-numbers (long n)) |
484 | | - :else (ccr/fold + (fn [tot e] |
485 | | - (+ tot (stirling-number-of-the-second-kind e n))) |
486 | | - (range (inc n))))) |
| 466 | + (and (m/non-? n) (< n 27)) (bell-numbers (long n)) |
| 467 | + :else (ccr/fold + (fn [tot e] |
| 468 | + (+ tot (stirling-number-of-the-second-kind e n))) |
| 469 | + (range (inc n))))) |
487 | 470 |
|
488 | 471 | (s/fdef bell-number |
489 | 472 | :args (s/cat :n ::m/long) |
|
754 | 737 | (list ()) |
755 | 738 | (let [cnt (count items)] |
756 | 739 | (cond (> n cnt) nil |
757 | | - (= n cnt) (list (seq items)) |
758 | | - :else (map #(map v-items %) |
759 | | - (index-combinations n cnt)))))))) |
| 740 | + (= n cnt) (list (seq items)) |
| 741 | + :else (map #(map v-items %) |
| 742 | + (index-combinations n cnt)))))))) |
760 | 743 |
|
761 | 744 | (s/fdef combinations |
762 | 745 | :args (s/cat :items ::items |
|
815 | 798 | (distinct (combinations (apply interleave (repeat n items)))))) |
816 | 799 |
|
817 | 800 | (s/fdef distinct-combinations-with-replacement |
818 | | - :args (s/cat :items ::items |
819 | | - :n ::replacement-count) |
| 801 | + :args (s/cat :items ::items :n ::replacement-count) |
820 | 802 | :ret ::groups-of-items) |
821 | 803 |
|
822 | 804 | ;;;ORDERED COMBINATIONS |
|
911 | 893 | (take n (repeat items)))) |
912 | 894 |
|
913 | 895 | (s/fdef selections |
914 | | - :args (s/cat :items ::items |
915 | | - :n ::replacement-count) |
| 896 | + :args (s/cat :items ::items :n ::replacement-count) |
916 | 897 | :ret ::groups-of-items) |
917 | 898 |
|
918 | 899 | ;;;DIRECT ACCESS |
|
0 commit comments