diff --git a/SL.jl b/SL.jl index 0204fab..93b0561 100644 --- a/SL.jl +++ b/SL.jl @@ -2,92 +2,37 @@ using ArgParse using GroupAlgebras using PropertyT -using Mods -import Primes: isprime +using Nemo 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) - indexing = [(i,j) for i in 1:n for j in 1:n if i≠j] - - S = [E(i,j,N=n) for (i,j) in indexing]; - S = vcat(S, [convert(Array{Int,2},x') for x in S]); - S = vcat(S, [convert(Array{Int,2},inv(x)) for x in S]); - return unique(S) -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) + G = Nemo.MatrixSpace(Nemo.ZZ, n,n) + S = [E(i,j,G) for (i,j) in indexing]; + S = vcat(S, [transpose(x) for x in S]); + S = vcat(S, [inv(x) for x in S]); + return unique(S), one(G) end function SL_generatingset(n::Int, p::Int) p == 0 && return SL_generatingset(n) (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] - 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, [permutedims(x, [2,1]) for x in S]); - return unique(S) + return unique(S), one(G) end function products{T}(U::AbstractVector{T}, V::AbstractVector{T})