Using Nemo instead of Mods
much faster for finite fields; a bit slower for Z
This commit is contained in:
parent
4c55783a37
commit
6570c99300
93
SL.jl
93
SL.jl
@ -2,92 +2,37 @@ using ArgParse
|
|||||||
using GroupAlgebras
|
using GroupAlgebras
|
||||||
using PropertyT
|
using PropertyT
|
||||||
|
|
||||||
using Mods
|
using Nemo
|
||||||
import Primes: isprime
|
|
||||||
|
|
||||||
import SCS.SCSSolver
|
import SCS.SCSSolver
|
||||||
|
|
||||||
|
|
||||||
|
function E(i::Int, j::Int, M::Nemo.MatSpace)
|
||||||
|
@assert i≠j
|
||||||
|
m = one(M)
|
||||||
|
m[i,j] = m[1,1]
|
||||||
|
return m
|
||||||
|
end
|
||||||
|
|
||||||
function SL_generatingset(n::Int)
|
function SL_generatingset(n::Int)
|
||||||
|
|
||||||
indexing = [(i,j) for i in 1:n for j in 1:n if i≠j]
|
indexing = [(i,j) for i in 1:n for j in 1:n if i≠j]
|
||||||
|
G = Nemo.MatrixSpace(Nemo.ZZ, n,n)
|
||||||
S = [E(i,j,N=n) for (i,j) in indexing];
|
S = [E(i,j,G) for (i,j) in indexing];
|
||||||
S = vcat(S, [convert(Array{Int,2},x') for x in S]);
|
S = vcat(S, [transpose(x) for x in S]);
|
||||||
S = vcat(S, [convert(Array{Int,2},inv(x)) for x in S]);
|
S = vcat(S, [inv(x) for x in S]);
|
||||||
return unique(S)
|
return unique(S), one(G)
|
||||||
end
|
|
||||||
|
|
||||||
function E(i::Int, j::Int; val=1, N::Int=3, mod=Inf)
|
|
||||||
@assert i≠j
|
|
||||||
m = eye(Int, N)
|
|
||||||
m[i,j] = val
|
|
||||||
if mod == Inf
|
|
||||||
return m
|
|
||||||
else
|
|
||||||
return [Mod(x,mod) for x in m]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function cofactor(i,j,M)
|
|
||||||
z1 = ones(Bool,size(M,1))
|
|
||||||
z1[i] = false
|
|
||||||
|
|
||||||
z2 = ones(Bool,size(M,2))
|
|
||||||
z2[j] = false
|
|
||||||
|
|
||||||
return M[z1,z2]
|
|
||||||
end
|
|
||||||
|
|
||||||
import Base.LinAlg.det
|
|
||||||
|
|
||||||
function det(M::Array{Mod,2})
|
|
||||||
if size(M,1) ≠ size(M,2)
|
|
||||||
d = Mod(0,M[1,1].mod)
|
|
||||||
elseif size(M,1) == 1
|
|
||||||
d = M[1,1]
|
|
||||||
elseif size(M,1) == 2
|
|
||||||
d = M[1,1]*M[2,2] - M[1,2]*M[2,1]
|
|
||||||
else
|
|
||||||
d = zero(eltype(M))
|
|
||||||
for i in 1:size(M,1)
|
|
||||||
d += (-1)^(i+1)*M[i,1]*det(cofactor(i,1,M))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# @show (M, d)
|
|
||||||
return d
|
|
||||||
end
|
|
||||||
|
|
||||||
function adjugate(M)
|
|
||||||
K = similar(M)
|
|
||||||
for i in 1:size(M,1), j in 1:size(M,2)
|
|
||||||
K[j,i] = (-1)^(i+j)*det(cofactor(i,j,M))
|
|
||||||
end
|
|
||||||
return K
|
|
||||||
end
|
|
||||||
|
|
||||||
import Base: inv, one, zero, *
|
|
||||||
|
|
||||||
one(::Type{Mod}) = 1
|
|
||||||
zero(::Type{Mod}) = 0
|
|
||||||
zero(x::Mod) = Mod(x.mod)
|
|
||||||
|
|
||||||
function inv(M::Array{Mod,2})
|
|
||||||
d = det(M)
|
|
||||||
d ≠ 0*d || throw(ArgumentError("Matrix is not invertible! $M"))
|
|
||||||
return inv(det(M)).*adjugate(M)
|
|
||||||
return adjugate(M)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function SL_generatingset(n::Int, p::Int)
|
function SL_generatingset(n::Int, p::Int)
|
||||||
p == 0 && return SL_generatingset(n)
|
p == 0 && return SL_generatingset(n)
|
||||||
(p > 1 && n > 0) || throw(ArgumentError("Both n and p should be positive integers!"))
|
(p > 1 && n > 0) || throw(ArgumentError("Both n and p should be positive integers!"))
|
||||||
isprime(p) || throw(ArgumentError("p should be a prime number!"))
|
F = Nemo.ResidueRing(Nemo.ZZ, p)
|
||||||
|
G = Nemo.MatrixSpace(F, n,n)
|
||||||
indexing = [(i,j) for i in 1:n for j in 1:n if i≠j]
|
indexing = [(i,j) for i in 1:n for j in 1:n if i≠j]
|
||||||
S = [E(i,j, N=n, mod=p) for (i,j) in indexing]
|
S = [E(i, j, G) for (i,j) in indexing]
|
||||||
|
S = vcat(S, [transpose(x) for x in S])
|
||||||
S = vcat(S, [inv(s) for s in S])
|
S = vcat(S, [inv(s) for s in S])
|
||||||
S = vcat(S, [permutedims(x, [2,1]) for x in S]);
|
return unique(S), one(G)
|
||||||
return unique(S)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function products{T}(U::AbstractVector{T}, V::AbstractVector{T})
|
function products{T}(U::AbstractVector{T}, V::AbstractVector{T})
|
||||||
|
Loading…
Reference in New Issue
Block a user