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