using ArgParse using GroupAlgebras using PropertyT 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] 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!")) 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, G) for (i,j) in indexing] S = vcat(S, [transpose(x) for x in S]) S = vcat(S, [inv(s) for s in S]) return unique(S), one(G) end function products{T}(U::AbstractVector{T}, V::AbstractVector{T}) result = Vector{T}() for u in U for v in V push!(result, u*v) end end return unique(result) end function ΔandSDPconstraints(Id, S; radius::Int=4) k = div(radius,2) lengths = Vector{Int}() S = vcat([Id], S) B = S push!(lengths,length(B)) for i in 2:radius B = products(S, B); push!(lengths, length(B)) end k = div(radius,2) basis = B[1:lengths[k]] product_matrix = PropertyT.create_product_matrix(B,lengths[k]); sdp_constraints = PropertyT.constraints_from_pm(product_matrix, length(B)) L_coeff = PropertyT.splaplacian_coeff(S, basis, length(B)); Δ = GroupAlgebraElement(L_coeff, product_matrix) return Δ, sdp_constraints end #= To use file property(T).jl (specifically: check_property_T function) You need to define: function ΔandSDPconstraints(identity, S):: (Δ, sdp_constraints) =# function cpuinfo_physicalcores() maxcore = -1 for line in eachline("/proc/cpuinfo") if startswith(line, "core id") maxcore = max(maxcore, parse(Int, split(line, ':')[2])) end end maxcore < 0 && error("failure to read core ids from /proc/cpuinfo") return maxcore + 1 end function parse_commandline() s = ArgParseSettings() @add_arg_table s begin "--tol" help = "set numerical tolerance for the SDP solver" arg_type = Float64 default = 1e-9 "--iterations" help = "set maximal number of iterations for the SDP solver" arg_type = Int default = 100000 "--upper-bound" help = "Set an upper bound for the spectral gap" arg_type = Float64 default = Inf "--cpus" help = "Set number of cpus used by solver" arg_type = Int required = false "-N" help = "Consider matrices of size N" arg_type = Int default = 3 "-p" help = "Matrices over filed of p-elements (0 = over ZZ)" arg_type = Int default = 0 end return parse_args(s) end function main() parsed_args = parse_commandline() tol = parsed_args["tol"] iterations = parsed_args["iterations"] solver = SCSSolver(eps=tol, max_iters=iterations, verbose=true) N = parsed_args["N"] upper_bound = parsed_args["upper-bound"] p = parsed_args["p"] if p == 0 name = "SL$(N)Z" else name = "SL$(N)_$p" end name = name*"-$(string(upper_bound))" S() = SL_generatingset(N, p) if parsed_args["cpus"] ≠ nothing if parsed_args["cpus"] > cpuinfo_physicalcores() warn("Number of specified cores exceeds the physical core cound. Performance will suffer.") end Blas.set_num_threads(parsed_args["cpus"]) end @time PropertyT.check_property_T(name, S, solver, upper_bound, tol) return 0 end main()