Skip to content

Commit fcdaee1

Browse files
committed
New permanent algorithm
1 parent 63f0003 commit fcdaee1

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "LinearAlgebraX"
22
uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88"
3-
version = "0.2.5"
3+
version = "0.2.6"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

src/perm.jl

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,43 @@
11
export permanent
2+
3+
_enlarge(x::T) where {T<:Union{IntegerX,RationalX}} = big(x)
4+
_enlarge(x) = x
5+
26
"""
37
permanent(A)
48
5-
Compute the permanent of the square matrix `A`. Works best if `A`
6-
is relatively sparse. For a dense matrix, this will be slow.
9+
Compute the permanent of the square matrix `A`.
710
"""
8-
function permanent(A::AbstractMatrix{T}) where {T<:Union{IntegerX,RationalX}}
11+
function permanent(A::AbstractMatrix{T}) where {T} # code by Daniel Scheinerman
12+
A = _enlarge.(A)
13+
m, n = size(A)
14+
s = _enlarge(zero(T)) #to accumulate the permanent
15+
x = UInt64(0) #gray code state
16+
v = zeros(Int64, n) #current subset sum
17+
for i = 1:2^n-1
18+
t = trailing_zeros(i) #next bit flip
19+
b = (x >> t) & 1 #if 1 then add row, else subtract
20+
x = xor(x, 1 << t)
21+
if b == 0
22+
v += A[t+1, :]
23+
else
24+
v -= A[t+1, :]
25+
end
26+
s += (-1)^(i & 1) * prod(v)
27+
end
28+
s *= (-1)^n
29+
return s
30+
end
31+
32+
33+
# Old code available as LinearAlgebraX.old_permanent
34+
35+
function old_permanent(A::AbstractMatrix{T}) where {T<:Union{IntegerX,RationalX}}
936
A = big.(A)
1037
return perm_work(A)
1138
end
1239

13-
function permanent(A::AbstractMatrix{T})::T where {T}
40+
function old_permanent(A::AbstractMatrix{T})::T where {T}
1441
perm_work(A)
1542
end
1643

0 commit comments

Comments
 (0)