1
0
mirror of https://github.com/kalmarek/PropertyT.jl.git synced 2024-07-17 10:55:30 +02:00
PropertyT.jl/SL3Z.jl

180 lines
4.5 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using JLD
using JuMP
import Primes: isprime
import SCS: SCSSolver
import Mosek: MosekSolver
using Mods
using Groups
using ProgressMeter
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) == 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 || thow(ArgumentError("Matrix is not invertible!"))
return inv(det(M))*adjugate(M)
return adjugate(M)
end
function prepare_Δ_sdp_constraints(identity, S)
@show length(S)
B₁ = vcat([identity], S)
B₂ = products(B₁, B₁);
B₃ = products(B₁, B₂);
B₄ = products(B₁, B₃);
@assert B₄[1:length(B₂)] == B₂
product_matrix = create_product_matrix(B₄,length(B₂));
sdp_constraints = constraints_from_pm(product_matrix, length(B₄))
L_coeff = splaplacian_coeff(S, B₂, length(B₄));
Δ = GroupAlgebraElement(L_coeff, product_matrix)
return Δ, sdp_constraints
end
function load_Δ_sdp_constraints(name::String;cached=true)
pm_filename = "$name.product_matrix.jld"
Δ_coeff_filename = "$name.delta.coefficients.jld"
f₁ = isfile(pm_filename)
f₂ = isfile(Δ_coeff_filename)
if cached && f₁ && f₂
println("Loading precomputed pm, Δ, sdp_constraints...")
product_matrix = load(pm_filename, "pm")
L = load(Δ_coeff_filename, "Δ")[:, 1]
Δ = GroupAlgebraElement(L, Array{Int,2}(product_matrix))
sdp_constraints = constraints_from_pm(product_matrix)
else
println("Computing pm, Δ, sdp_constraints...")
ID = eye(Int, 3)
S = SL₃_generatingset()
Δ, sdp_constraints = prepare_Δ_sdp_constraints(ID, S)
save(pm_filename, "pm", Δ.product_matrix)
save(Δ_coeff_filename, "Δ", Δ.coefficients)
end
return Δ, sdp_constraints
end
function compute_κ_A(name::String, Δ, sdp_constraints;
cached = true,
tol = 1e-7,
verbose = false,
# solver = MosekSolver(INTPNT_CO_TOL_REL_GAP=tol, QUIET=!verbose))
solver = SCSSolver(eps=tol, max_iters=20000, cg_rate=3, verbose=verbose))
f₁ = isfile("$name.kappa")
f₂ = isfile("$name.SDPmatrixA")
if cached && f₁ && f₂
println("Loading precomputed κ, A...")
A = readdlm("$name.SDPmatrixA")
κ = readdlm("$name.kappa")[1]
else
println("Solving SDP problem maximizing κ...")
κ, A = solve_SDP(sdp_constraints, Δ, solver, verbose=verbose)
# writedlm("$name.kappa", kappa)
# writedlm("$name.SDPmatrixA", A)
end
return κ, A
end
function main()
const NAME = "SL3Z"
const VERBOSE = true
const TOL=1e-7
const Δ, sdp_constraints = load_Δ_sdp_constraints(NAME)
const κ, A = compute_κ_A(NAME, Δ, sdp_constraints, cached=false, verbose=VERBOSE)
if maximum(A) < 1e-2
warn("Solver might not solved the problem successfully and the positive solution is due to floating-point error, proceeding anyway...")
end
if κ > 0
@assert A == Symmetric(A)
const A_sqrt = real(sqrtm(A))
T = _distance_to_positive_cone(Δ, κ, A, tol=TOL, verbose=VERBOSE)
if T < 0
println("$NAME HAS property (T)!")
else
println("$NAME may NOT HAVE property (T)!")
end
else
println(" < 0: $NAME may NOT HAVE property (T)!")
end
end
@everywhere push!(LOAD_PATH, "./")
using GroupAlgebras
include("property(T).jl")
main()