Skip to content

Commit 2e56149

Browse files
committed
Major code reorganization
- DROP 0.4 SUPPORT - Import most of base/combinatorics.jl (Ref: JuliaLang/julia#13897) - Move most of the special numbers to numbers.jl - Put combinations, permutations and partitions in their own files - Rename special numbers with ~num suffix. This renaming is particularly important for catalannum to avoid clashing with the Base.catalan irrational constant.
1 parent d67c151 commit 2e56149

File tree

9 files changed

+766
-167
lines changed

9 files changed

+766
-167
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Combinatorics
22

3-
[![Combinatorics](http://pkg.julialang.org/badges/Combinatorics_0.3.svg)](http://pkg.julialang.org/?pkg=Combinatorics&ver=0.3)
43
[![Combinatorics](http://pkg.julialang.org/badges/Combinatorics_0.4.svg)](http://pkg.julialang.org/?pkg=Combinatorics&ver=0.4)
54
[![Build Status](https://travis-ci.org/JuliaLang/Combinatorics.jl.svg?branch=master)](https://travis-ci.org/JuliaLang/Combinatorics.jl)
65
[![Coverage Status](https://coveralls.io/repos/JuliaLang/Combinatorics.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/JuliaLang/Combinatorics.jl?branch=master)

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
julia 0.4
1+
julia 0.5-
22
Compat
33
Polynomials
44
Iterators

src/Combinatorics.jl

Lines changed: 5 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -2,158 +2,11 @@ module Combinatorics
22

33
using Compat, Polynomials, Iterators
44

5-
import Base:combinations
6-
7-
export bell,
8-
derangement,
9-
doublefactorial,
10-
fibonacci,
11-
hyperfactorial,
12-
jacobisymbol,
13-
lassalle,
14-
legendresymbol,
15-
lucas,
16-
multifactorial,
17-
multinomial,
18-
primorial,
19-
stirlings1,
20-
subfactorial
21-
5+
include("numbers.jl")
6+
include("factorials.jl")
7+
include("combinations.jl")
8+
include("permutations.jl")
229
include("partitions.jl")
2310
include("youngdiagrams.jl")
2411

25-
# Returns the n-th Bell number
26-
function bell(bn::Integer)
27-
if bn < 0
28-
throw(DomainError())
29-
else
30-
n = BigInt(bn)
31-
end
32-
list = Array(BigInt, div(n*(n+1), 2))
33-
list[1] = 1
34-
for i = 2:n
35-
beg = div(i*(i-1),2)
36-
list[beg+1] = list[beg]
37-
for j = 2:i
38-
list[beg+j] = list[beg+j-1]+list[beg+j-i]
39-
end
40-
end
41-
return list[end]
42-
end
43-
44-
# Returns the n-th Catalan number
45-
function catalan(bn::Integer)
46-
if bn<0
47-
throw(DomainError())
48-
else
49-
n = BigInt(bn)
50-
end
51-
div(binomial(2*n, n), (n + 1))
52-
end
53-
54-
#generate combinations of all orders, chaining of order iterators is eager,
55-
#but sequence at each order is lazy
56-
combinations(a) = chain([combinations(a,k) for k=1:length(a)]...)
57-
58-
# The number of permutations of n with no fixed points (subfactorial)
59-
function derangement(sn::Integer)
60-
n = BigInt(sn)
61-
return num(factorial(n)*sum([(-1)^k//factorial(k) for k=0:n]))
62-
end
63-
subfactorial(n::Integer) = derangement(n)
64-
65-
function doublefactorial(n::Integer)
66-
if n < 0
67-
throw(DomainError())
68-
end
69-
z = BigInt()
70-
ccall((:__gmpz_2fac_ui, :libgmp), Void,
71-
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
72-
return z
73-
end
74-
75-
function fibonacci(n::Integer)
76-
if n < 0
77-
throw(DomainError())
78-
end
79-
z = BigInt()
80-
ccall((:__gmpz_fib_ui, :libgmp), Void,
81-
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
82-
return z
83-
end
84-
85-
# Hyperfactorial
86-
hyperfactorial(n::Integer) = prod([i^i for i = BigInt(2):n])
87-
88-
function jacobisymbol(a::Integer, b::Integer)
89-
ba = BigInt(a)
90-
bb = BigInt(b)
91-
return ccall((:__gmpz_jacobi, :libgmp), Cint,
92-
(Ptr{BigInt}, Ptr{BigInt}), &ba, &bb)
93-
end
94-
95-
#Computes Lassalle's sequence
96-
#OEIS entry A180874
97-
function lassalle(m::Integer)
98-
A = ones(BigInt,m)
99-
for n=2:m
100-
A[n]=(-1)^(n-1) * (catalan(n) + sum([(-1)^j*binomial(2n-1, 2j-1)*A[j]*catalan(n-j) for j=1:n-1]))
101-
end
102-
A[m]
103-
end
104-
105-
function legendresymbol(a::Integer, b::Integer)
106-
ba = BigInt(a)
107-
bb = BigInt(b)
108-
return ccall((:__gmpz_legendre, :libgmp), Cint,
109-
(Ptr{BigInt}, Ptr{BigInt}), &ba, &bb)
110-
end
111-
112-
function lucas(n::Integer)
113-
if n < 0
114-
throw(DomainError())
115-
end
116-
z = BigInt()
117-
ccall((:__gmpz_lucnum_ui, :libgmp), Void,
118-
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
119-
return z
120-
end
121-
122-
function multifactorial(n::Integer, m::Integer)
123-
if n < 0
124-
throw(DomainError())
125-
end
126-
z = BigInt()
127-
ccall((:__gmpz_mfac_uiui, :libgmp), Void,
128-
(Ptr{BigInt}, UInt, UInt), &z, @compat(UInt(n)), @compat(UInt(m)))
129-
return z
130-
end
131-
132-
# Multinomial coefficient where n = sum(k)
133-
function multinomial(k...)
134-
s = 0
135-
result = 1
136-
for i in k
137-
s += i
138-
result *= binomial(s, i)
139-
end
140-
result
141-
end
142-
143-
function primorial(n::Integer)
144-
if n < 0
145-
throw(DomainError())
146-
end
147-
z = BigInt()
148-
ccall((:__gmpz_primorial_ui, :libgmp), Void,
149-
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
150-
return z
151-
end
152-
153-
# Returns s(n, k), the signed Stirling number of first kind
154-
function stirlings1(n::Integer, k::Integer)
155-
p = poly(0:(n-1))
156-
p[n - k + 1]
157-
end
158-
159-
end # module
12+
end #module

src/combinations.jl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
export combinations
2+
3+
4+
#The Combinations iterator
5+
import Base: start, next, done, length
6+
7+
immutable Combinations{T}
8+
a::T
9+
t::Int
10+
end
11+
12+
start(c::Combinations) = [1:c.t;]
13+
function next(c::Combinations, s)
14+
comb = [c.a[si] for si in s]
15+
if c.t == 0
16+
# special case to generate 1 result for t==0
17+
return (comb,[length(c.a)+2])
18+
end
19+
s = copy(s)
20+
for i = length(s):-1:1
21+
s[i] += 1
22+
if s[i] > (length(c.a) - (length(s)-i))
23+
continue
24+
end
25+
for j = i+1:endof(s)
26+
s[j] = s[j-1]+1
27+
end
28+
break
29+
end
30+
(comb,s)
31+
end
32+
done(c::Combinations, s) = !isempty(s) && s[1] > length(c.a)-c.t+1
33+
34+
length(c::Combinations) = binomial(length(c.a),c.t)
35+
36+
eltype{T}(::Type{Combinations{T}}) = Vector{eltype(T)}
37+
38+
39+
40+
function combinations(a, t::Integer)
41+
if t < 0
42+
# generate 0 combinations for negative argument
43+
t = length(a)+1
44+
end
45+
Combinations(a, t)
46+
end
47+
48+
#generate combinations of all orders, chaining of order iterators is eager,
49+
#but sequence at each order is lazy
50+
combinations(a) = chain([combinations(a,k) for k=1:length(a)]...)
51+

src/factorials.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#Factorials and elementary coefficients
2+
3+
export
4+
derangement,
5+
subfactorial,
6+
doublefactorial,
7+
hyperfactorial,
8+
multifactorial,
9+
gamma,
10+
primorial,
11+
multinomial
12+
13+
# The number of permutations of n with no fixed points (subfactorial)
14+
function derangement(sn::Integer)
15+
n = BigInt(sn)
16+
return num(factorial(n)*sum([(-1)^k//factorial(k) for k=0:n]))
17+
end
18+
subfactorial(n::Integer) = derangement(n)
19+
20+
function doublefactorial(n::Integer)
21+
if n < 0
22+
throw(DomainError())
23+
end
24+
z = BigInt()
25+
ccall((:__gmpz_2fac_ui, :libgmp), Void,
26+
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
27+
return z
28+
end
29+
30+
# Hyperfactorial
31+
hyperfactorial(n::Integer) = prod([i^i for i = BigInt(2):n])
32+
33+
function multifactorial(n::Integer, m::Integer)
34+
if n < 0
35+
throw(DomainError())
36+
end
37+
z = BigInt()
38+
ccall((:__gmpz_mfac_uiui, :libgmp), Void,
39+
(Ptr{BigInt}, UInt, UInt), &z, @compat(UInt(n)), @compat(UInt(m)))
40+
return z
41+
end
42+
43+
function primorial(n::Integer)
44+
if n < 0
45+
throw(DomainError())
46+
end
47+
z = BigInt()
48+
ccall((:__gmpz_primorial_ui, :libgmp), Void,
49+
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
50+
return z
51+
end
52+
53+
#Multinomial coefficient where n = sum(k)
54+
function multinomial(k...)
55+
s = 0
56+
result = 1
57+
for i in k
58+
s += i
59+
result *= binomial(s, i)
60+
end
61+
result
62+
end
63+
64+

src/numbers.jl

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#Special named numbers and symbols
2+
3+
export bellnum,
4+
catalannum,
5+
fibonaccinum,
6+
jacobisymbol,
7+
lassallenum,
8+
legendresymbol,
9+
lucasnum,
10+
stirlings1
11+
12+
# Returns the n-th Bell number
13+
function bellnum(bn::Integer)
14+
if bn < 0
15+
throw(DomainError())
16+
else
17+
n = BigInt(bn)
18+
end
19+
list = Array(BigInt, div(n*(n+1), 2))
20+
list[1] = 1
21+
for i = 2:n
22+
beg = div(i*(i-1),2)
23+
list[beg+1] = list[beg]
24+
for j = 2:i
25+
list[beg+j] = list[beg+j-1]+list[beg+j-i]
26+
end
27+
end
28+
return list[end]
29+
end
30+
31+
# Returns the n-th Catalan number
32+
function catalannum(bn::Integer)
33+
if bn<0
34+
throw(DomainError())
35+
else
36+
n = BigInt(bn)
37+
end
38+
div(binomial(2*n, n), (n + 1))
39+
end
40+
41+
function fibonaccinum(n::Integer)
42+
if n < 0
43+
throw(DomainError())
44+
end
45+
z = BigInt()
46+
ccall((:__gmpz_fib_ui, :libgmp), Void,
47+
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
48+
return z
49+
end
50+
51+
52+
function jacobisymbol(a::Integer, b::Integer)
53+
ba = BigInt(a)
54+
bb = BigInt(b)
55+
return ccall((:__gmpz_jacobi, :libgmp), Cint,
56+
(Ptr{BigInt}, Ptr{BigInt}), &ba, &bb)
57+
end
58+
59+
#Computes Lassalle's sequence
60+
#OEIS entry A180874
61+
function lassallenum(m::Integer)
62+
A = ones(BigInt,m)
63+
for n=2:m
64+
A[n]=(-1)^(n-1) * (catalannum(n) + sum([(-1)^j*binomial(2n-1, 2j-1)*A[j]*catalannum(n-j) for j=1:n-1]))
65+
end
66+
A[m]
67+
end
68+
69+
function legendresymbol(a::Integer, b::Integer)
70+
ba = BigInt(a)
71+
bb = BigInt(b)
72+
return ccall((:__gmpz_legendre, :libgmp), Cint,
73+
(Ptr{BigInt}, Ptr{BigInt}), &ba, &bb)
74+
end
75+
76+
function lucasnum(n::Integer)
77+
if n < 0
78+
throw(DomainError())
79+
end
80+
z = BigInt()
81+
ccall((:__gmpz_lucnum_ui, :libgmp), Void,
82+
(Ptr{BigInt}, UInt), &z, @compat(UInt(n)))
83+
return z
84+
end
85+
86+
# Returns s(n, k), the signed Stirling number of first kind
87+
function stirlings1(n::Integer, k::Integer)
88+
p = poly(0:(n-1))
89+
p[n - k + 1]
90+
end
91+

0 commit comments

Comments
 (0)