Skip to content

Commit e61f298

Browse files
committed
get 'er done
1 parent 4a19d8a commit e61f298

29 files changed

Lines changed: 1719 additions & 1419 deletions

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ Matrix decompositions and linear system solving:
104104
Comprehensive matrix operations:
105105
- Matrix creation (identity, diagonal, Toeplitz, random)
106106
- Specialized types (symmetric, triangular, sparse, positive-definite)
107+
- Note: Sparse matrix support is limited to conversion utilities (`sparse->matrix`, `matrix->sparse`). Full sparse algebra is not implemented; convert to dense for operations.
107108
- Matrix multiplication, transpose, Kronecker product
108109
- Slicing, filtering, and partitioning
109110
- Row/column manipulation (insert, remove, update)
@@ -211,6 +212,6 @@ Specialized 1D tensor operations:
211212

212213
## License
213214

214-
Copyright 2018 Provisdom
215+
Copyright © 2018-2026 Provisdom Corp.
215216

216217
Distributed under the GNU Lesser General Public License version 3.0.

deps.edn

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{:paths ["src"]
22
:deps {provisdom/utility-belt {:git/url "https://github.com/Provisdom/utility-belt.git"
3-
:git/sha "e243ee983c531d4d10b11b4ff6746572f0f39852"}}
3+
:git/sha "11c36ef106965acff9e69149bdbcd226ac5a4da9"}}
44
:aliases {:dev {:extra-paths ["siderail"]}
55
:local {:override-deps {provisdom/test {:local/root "../test"}
66
provisdom/utility-belt {:local/root "../utility-belt"}}}
@@ -11,7 +11,7 @@
1111

1212
provisdom/test
1313
{:git/url "https://github.com/Provisdom/test.git"
14-
:git/sha "4196a90c13403324602bfabad9bb3006c8f32ebb"}}}
14+
:git/sha "82a9039d2527a382139c8a06ca507af96c071785"}}}
1515
:test-clj-runner {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}
1616
lambdaisland/kaocha-junit-xml {:mvn/version "1.17.101"}}
1717
:main-opts ["-m" "kaocha.runner"]}}}

src/provisdom/math/combinatorics.clj

Lines changed: 45 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,21 @@
4040
::m/int-non-
4141
#(gen/large-integer* {:min 0 :max mdl})))
4242

43+
(defn- n-no-less-than-k?
44+
[{:keys [k n]}]
45+
(>= n k))
4346

4447
;;;CONSTANTS
4548
(def ^:private ^:const subfactorials
4649
"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])
5153

5254
(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,
5758
49631246523618756274])
5859

5960
;;;FACTORIALS
@@ -237,24 +238,19 @@
237238
[k n]
238239
(let [diff (- n k)]
239240
(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))))))
253250

254251
(s/fdef choose-k-from-n
255252
: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-)
258254
n-no-less-than-k?)
259255
#(gen/bind
260256
(s/gen ::m/int-non-)
@@ -272,10 +268,8 @@
272268
(m/maybe-long-able (choose-k-from-n k n)))
273269

274270
(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?)
279273
:ret ::m/num)
280274

281275
(defn log-choose-k-from-n
@@ -299,10 +293,8 @@
299293
(log-factorial (- n k))))))
300294

301295
(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?)
306298
:ret ::m/num)
307299

308300
(defn multinomial-coefficient
@@ -321,8 +313,7 @@
321313
(multinomial-coefficient [1 1 1]) ;=> 6.0 (3! permutations)"
322314
[ks]
323315
(let [n (reduce + 0 ks)]
324-
(/ (factorial n)
325-
(reduce * 1.0 (map factorial ks)))))
316+
(/ (factorial n) (reduce * 1.0 (map factorial ks)))))
326317

327318
(s/fdef multinomial-coefficient
328319
:args (s/cat :ks (s/coll-of ::m/int-non-))
@@ -337,9 +328,8 @@
337328
(log-multinomial-coefficient [2 3 1]) ;=> 4.0943... (ln(60))
338329
(log-multinomial-coefficient [50 50]) ;=> 66.7838... (ln(C(100,50)))"
339330
[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)))))
343333

344334
(s/fdef log-multinomial-coefficient
345335
:args (s/cat :ks (s/coll-of ::m/non-))
@@ -353,17 +343,14 @@
353343
(* (/ (factorial k))
354344
(ccr/fold
355345
+ (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))))
360349
(range (inc k))))))
361350

362351
(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?)
367354
:ret ::m/number)
368355

369356
(defn stirling-number-of-the-second-kind'
@@ -374,8 +361,7 @@
374361

375362
(s/fdef stirling-number-of-the-second-kind'
376363
: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?)
379365
:ret ::m/number)
380366

381367
(defn log-stirling-number-of-the-second-kind
@@ -409,8 +395,7 @@
409395

410396
(s/fdef log-stirling-number-of-the-second-kind
411397
: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?)
414399
:ret ::m/num)
415400

416401
(defn stirling-number-of-the-first-kind
@@ -440,7 +425,7 @@
440425
(fn [row curr-k]
441426
(assoc row curr-k
442427
(+ (* (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))))
444429
{}
445430
(range 1 (inc (min curr-n k)))))
446431
{0 1.0}
@@ -450,8 +435,7 @@
450435
(s/fdef stirling-number-of-the-first-kind
451436
:args (s/with-gen
452437
(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?)
455439
#(gen/bind
456440
(gen/large-integer* {:min 0 :max 15})
457441
(fn [k]
@@ -467,8 +451,7 @@
467451
(s/fdef stirling-number-of-the-first-kind'
468452
:args (s/with-gen
469453
(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?)
472455
#(gen/bind
473456
(gen/large-integer* {:min 0 :max 15})
474457
(fn [k]
@@ -480,10 +463,10 @@
480463
"Returns the number of partitions of a set of size `n`."
481464
[n]
482465
(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)))))
487470

488471
(s/fdef bell-number
489472
:args (s/cat :n ::m/long)
@@ -754,9 +737,9 @@
754737
(list ())
755738
(let [cnt (count items)]
756739
(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))))))))
760743

761744
(s/fdef combinations
762745
:args (s/cat :items ::items
@@ -815,8 +798,7 @@
815798
(distinct (combinations (apply interleave (repeat n items))))))
816799

817800
(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)
820802
:ret ::groups-of-items)
821803

822804
;;;ORDERED COMBINATIONS
@@ -911,8 +893,7 @@
911893
(take n (repeat items))))
912894

913895
(s/fdef selections
914-
:args (s/cat :items ::items
915-
:n ::replacement-count)
896+
:args (s/cat :items ::items :n ::replacement-count)
916897
:ret ::groups-of-items)
917898

918899
;;;DIRECT ACCESS

src/provisdom/math/core.clj

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
(def ^:const ^double two-div-pi (* 2.0 inv-pi))
8989
(def ^:const ^double inv-sqrt-two-pi (* inv-sqrt-two inv-sqrt-pi))
9090

91+
;; High precision: 0.57721566490153286060651209008240243104215933593992M
92+
(def ^:const ^double euler-mascheroni-constant 0.5772156649015329)
93+
9194
;;;TEST FOR NUMERIC TYPES
9295
(defn- long-range?
9396
"Returns true if x is within the range representable by a long."
@@ -1206,8 +1209,7 @@
12061209
number)))
12071210

12081211
(s/fdef round'
1209-
:args (s/cat :number ::number
1210-
:round-type ::round-type)
1212+
:args (s/cat :number ::number :round-type ::round-type)
12111213
:ret ::number)
12121214

12131215
(def round
@@ -1459,8 +1461,7 @@
14591461
(quot numerator divisor))))))
14601462

14611463
(s/fdef quot'
1462-
:args (s/cat :numerator ::number
1463-
:divisor ::number)
1464+
:args (s/cat :numerator ::number :divisor ::number)
14641465
:ret ::number)
14651466

14661467
(defn mod'
@@ -1477,8 +1478,7 @@
14771478
(mod numerator divisor))))))
14781479

14791480
(s/fdef mod'
1480-
:args (s/cat :numerator ::number
1481-
:divisor ::number)
1481+
:args (s/cat :numerator ::number :divisor ::number)
14821482
:ret ::number)
14831483

14841484
(defn rem'
@@ -1539,8 +1539,7 @@
15391539
(recur b (mod' a b)))))
15401540

15411541
(s/fdef gcd
1542-
:args (s/cat :long1 ::long
1543-
:long2 ::long)
1542+
:args (s/cat :long1 ::long :long2 ::long)
15441543
:ret ::long-non-)
15451544

15461545
(defn lcm'
@@ -1557,8 +1556,7 @@
15571556
(maybe-long-able (* (double (quot' a (gcd a b))) b)))))
15581557

15591558
(s/fdef lcm'
1560-
:args (s/cat :long1 ::long
1561-
:long2 ::long)
1559+
:args (s/cat :long1 ::long :long2 ::long)
15621560
:ret ::non-)
15631561

15641562
;;;ANGLES

0 commit comments

Comments
 (0)