2022-11-07 18:45:12 +01:00
|
|
|
using SparseArrays
|
|
|
|
|
2019-06-30 13:19:24 +02:00
|
|
|
@testset "Sq, Adj, Op" begin
|
|
|
|
function isconstant_on_orbit(v, orb)
|
|
|
|
isempty(orb) && return true
|
|
|
|
k = v[first(orb)]
|
|
|
|
return all(v[o] == k for o in orb)
|
|
|
|
end
|
|
|
|
|
|
|
|
@testset "unit tests" begin
|
2024-02-15 22:42:17 +01:00
|
|
|
@test PropertyT.isopposite(PG.perm"(1,2,3)(4)", PG.perm"(1,4,2)")
|
|
|
|
@test PropertyT.isadjacent(PG.perm"(1,2,3)", PG.perm"(1,2)(3)")
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
@test !PropertyT.isopposite(PG.perm"(1,2,3)", PG.perm"(1,2)(3)")
|
|
|
|
@test !PropertyT.isadjacent(PG.perm"(1,4)", PG.perm"(2,3)(4)")
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@test isconstant_on_orbit([1, 1, 1, 2, 2], [2, 3])
|
|
|
|
@test !isconstant_on_orbit([1, 1, 1, 2, 2], [2, 3, 4])
|
2019-06-30 13:19:24 +02:00
|
|
|
end
|
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@testset "Sq, Adj, Op in SL(4,Z)" begin
|
2019-06-30 13:19:24 +02:00
|
|
|
N = 4
|
2022-11-07 18:45:12 +01:00
|
|
|
G = MatrixGroups.SpecialLinearGroup{N}(Int8)
|
2023-03-19 23:28:36 +01:00
|
|
|
@info "running tests for" G
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2023-03-19 23:28:36 +01:00
|
|
|
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2)
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
Δ = let RG = RG, S = S
|
|
|
|
RG(length(S)) - sum(RG(s) for s in S)
|
|
|
|
end
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:N, -1)))
|
|
|
|
Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
|
2022-11-07 18:45:12 +01:00
|
|
|
act = PropertyT.action_by_conjugation(G, Σ)
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
wd = SW.WedderburnDecomposition(
|
2022-11-07 18:45:12 +01:00
|
|
|
Float64,
|
|
|
|
Σ,
|
|
|
|
act,
|
2024-02-15 22:42:17 +01:00
|
|
|
SA.basis(RG),
|
|
|
|
SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
2023-03-19 23:28:36 +01:00
|
|
|
@info wd
|
2024-02-15 22:42:17 +01:00
|
|
|
ivs = SW.invariant_vectors(wd)
|
2019-06-30 13:19:24 +02:00
|
|
|
|
|
|
|
sq, adj, op = PropertyT.SqAdjOp(RG, N)
|
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@test all(
|
|
|
|
isconstant_on_orbit(sq, SparseArrays.nonzeroinds(iv)) for iv in ivs
|
|
|
|
)
|
|
|
|
|
|
|
|
@test all(
|
|
|
|
isconstant_on_orbit(adj, SparseArrays.nonzeroinds(iv)) for iv in ivs
|
|
|
|
)
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@test all(
|
|
|
|
isconstant_on_orbit(op, SparseArrays.nonzeroinds(iv)) for iv in ivs
|
|
|
|
)
|
|
|
|
|
|
|
|
e = one(G)
|
|
|
|
g = G([alphabet(G)[MatrixGroups.ElementaryMatrix{N}(1, 2, Int8(1))]])
|
|
|
|
h = G([alphabet(G)[MatrixGroups.ElementaryMatrix{N}(1, 3, Int8(1))]])
|
|
|
|
k = G([alphabet(G)[MatrixGroups.ElementaryMatrix{N}(3, 4, Int8(1))]])
|
|
|
|
|
|
|
|
@test sq[e] == 120
|
2019-06-30 13:19:24 +02:00
|
|
|
@test sq[g] == sq[h] == -8
|
|
|
|
@test sq[g^2] == sq[h^2] == 1
|
|
|
|
@test sq[g*h] == sq[h*g] == 0
|
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@test adj[e] == 384
|
|
|
|
@test adj[g] == adj[h] == -32
|
2019-06-30 13:19:24 +02:00
|
|
|
@test adj[g^2] == adj[h^2] == 0
|
2022-11-07 18:45:12 +01:00
|
|
|
@test adj[g*h] == adj[h*g] == 2
|
|
|
|
@test adj[k*h] == adj[h*k] == 1
|
2019-06-30 13:19:24 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@test op[e] == 96
|
|
|
|
@test op[g] == op[h] == -8
|
2019-06-30 13:19:24 +02:00
|
|
|
@test op[g^2] == op[h^2] == 0
|
|
|
|
@test op[g*h] == op[h*g] == 0
|
2022-11-07 18:45:12 +01:00
|
|
|
@test op[g*k] == op[k*g] == 2
|
2019-06-30 13:19:24 +02:00
|
|
|
@test op[h*k] == op[k*h] == 0
|
|
|
|
end
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@testset "SAut(F₃)" begin
|
|
|
|
n = 3
|
|
|
|
G = SpecialAutomorphismGroup(FreeGroup(n))
|
2023-03-19 23:28:36 +01:00
|
|
|
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2)
|
2022-11-07 18:45:12 +01:00
|
|
|
sq, adj, op = PropertyT.SqAdjOp(RG, n)
|
|
|
|
|
|
|
|
@test sq(one(G)) == 216
|
|
|
|
@test all(sq(g) == -16 for g in gens(G))
|
|
|
|
@test adj(one(G)) == 384
|
|
|
|
@test all(adj(g) == -32 for g in gens(G))
|
|
|
|
@test iszero(op)
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
2022-11-07 18:45:12 +01:00
|
|
|
end
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@testset "1812.03456 examples" begin
|
|
|
|
@testset "SL(3,Z)" begin
|
|
|
|
n = 3
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
G = MatrixGroups.SpecialLinearGroup{n}(Int8)
|
2023-03-19 23:28:36 +01:00
|
|
|
@info "running tests for" G
|
|
|
|
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2)
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
Δ = RG(length(S)) - sum(RG(s) for s in S)
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
|
|
|
|
Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
|
2022-11-07 18:45:12 +01:00
|
|
|
act = PropertyT.action_by_conjugation(G, Σ)
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
wd = SW.WedderburnDecomposition(
|
2022-11-07 18:45:12 +01:00
|
|
|
Float64,
|
|
|
|
Σ,
|
|
|
|
act,
|
2024-02-15 22:42:17 +01:00
|
|
|
SA.basis(RG),
|
|
|
|
SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
2023-03-19 23:28:36 +01:00
|
|
|
@info wd
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
sq, adj, op = PropertyT.SqAdjOp(RG, n)
|
2019-06-30 13:20:39 +02:00
|
|
|
|
|
|
|
@testset "Sq₃ is SOS" begin
|
2022-11-07 18:45:12 +01:00
|
|
|
elt = sq
|
|
|
|
UB = Inf # λ ≈ 0.1040844
|
|
|
|
|
|
|
|
status, certified, λ_cert = check_positivity(
|
|
|
|
elt,
|
|
|
|
Δ,
|
2023-03-19 23:28:36 +01:00
|
|
|
wd;
|
|
|
|
upper_bound = UB,
|
|
|
|
halfradius = 2,
|
2024-02-15 22:45:21 +01:00
|
|
|
optimizer = scs_optimizer(; accel = -50, alpha = 1.9),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
|
|
|
@test status == JuMP.OPTIMAL
|
|
|
|
@test certified
|
|
|
|
@test λ_cert > 104 // 1000
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
@testset "Adj₃ is SOS" begin
|
2022-11-07 18:45:12 +01:00
|
|
|
elt = adj
|
|
|
|
UB = Inf # λ ≈ 0.15858018
|
|
|
|
|
|
|
|
status, certified, λ_cert = check_positivity(
|
|
|
|
elt,
|
|
|
|
Δ,
|
2023-03-19 23:28:36 +01:00
|
|
|
wd;
|
|
|
|
upper_bound = UB,
|
|
|
|
halfradius = 2,
|
|
|
|
optimizer = cosmo_optimizer(; accel = 50, alpha = 1.9),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
|
|
|
@test status == JuMP.OPTIMAL
|
|
|
|
@test certified
|
|
|
|
@test λ_cert > 1585 // 10000
|
2022-11-08 10:01:31 +01:00
|
|
|
|
|
|
|
m, _ = PropertyT.sos_problem_primal(elt, wd)
|
|
|
|
PropertyT.solve(
|
|
|
|
m,
|
2024-02-15 22:45:21 +01:00
|
|
|
scs_optimizer(; max_iters = 1000, accel = 50, alpha = 1.9),
|
2022-11-08 10:01:31 +01:00
|
|
|
)
|
|
|
|
|
2023-03-19 23:28:36 +01:00
|
|
|
@test JuMP.termination_status(m) in
|
|
|
|
(JuMP.ALMOST_OPTIMAL, JuMP.OPTIMAL, JuMP.ITERATION_LIMIT)
|
2022-11-08 10:01:31 +01:00
|
|
|
@test abs(JuMP.objective_value(m)) < 1e-3
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
@testset "Op₃ is empty, so can not be certified" begin
|
2022-11-07 18:45:12 +01:00
|
|
|
elt = op
|
2022-11-08 10:01:31 +01:00
|
|
|
@test iszero(op)
|
|
|
|
|
2019-06-30 13:20:39 +02:00
|
|
|
UB = Inf
|
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
status, certified, λ_cert = check_positivity(
|
|
|
|
elt,
|
|
|
|
Δ,
|
2023-03-19 23:28:36 +01:00
|
|
|
wd;
|
|
|
|
upper_bound = UB,
|
|
|
|
halfradius = 2,
|
2023-04-05 17:50:12 +02:00
|
|
|
optimizer = scs_optimizer(; accel = 50, alpha = 1.9),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
|
|
|
@test status == JuMP.OPTIMAL
|
|
|
|
@test !certified
|
|
|
|
@test λ_cert < 0
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@testset "SL(4,Z)" begin
|
2022-11-07 18:45:12 +01:00
|
|
|
n = 4
|
|
|
|
|
|
|
|
G = MatrixGroups.SpecialLinearGroup{n}(Int8)
|
2023-03-19 23:28:36 +01:00
|
|
|
@info "running tests for" G
|
|
|
|
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2)
|
2022-11-07 18:45:12 +01:00
|
|
|
|
|
|
|
Δ = RG(length(S)) - sum(RG(s) for s in S)
|
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
|
|
|
|
Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
|
2022-11-07 18:45:12 +01:00
|
|
|
act = PropertyT.action_by_conjugation(G, Σ)
|
|
|
|
|
2024-02-15 22:42:17 +01:00
|
|
|
wd = SW.WedderburnDecomposition(
|
2022-11-07 18:45:12 +01:00
|
|
|
Float64,
|
|
|
|
Σ,
|
|
|
|
act,
|
2024-02-15 22:42:17 +01:00
|
|
|
SA.basis(RG),
|
|
|
|
SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
2023-03-19 23:28:36 +01:00
|
|
|
@info wd
|
2022-11-07 18:45:12 +01:00
|
|
|
|
|
|
|
sq, adj, op = PropertyT.SqAdjOp(RG, n)
|
|
|
|
|
|
|
|
@testset "Sq is SOS" begin
|
|
|
|
elt = sq
|
|
|
|
UB = Inf # λ ≈ 0.31670
|
|
|
|
|
|
|
|
status, certified, λ_cert = check_positivity(
|
|
|
|
elt,
|
|
|
|
Δ,
|
2023-03-19 23:28:36 +01:00
|
|
|
wd;
|
|
|
|
upper_bound = UB,
|
|
|
|
halfradius = 2,
|
|
|
|
optimizer = cosmo_optimizer(; accel = 50, alpha = 1.9),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
|
|
|
@test status == JuMP.OPTIMAL
|
|
|
|
@test certified
|
|
|
|
@test λ_cert > 316 // 1000
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@testset "Adj is SOS" begin
|
|
|
|
elt = adj
|
|
|
|
UB = 0.541 # λ ≈ 0.545710
|
|
|
|
|
|
|
|
status, certified, λ_cert = check_positivity(
|
|
|
|
elt,
|
|
|
|
Δ,
|
2023-03-19 23:28:36 +01:00
|
|
|
wd;
|
|
|
|
upper_bound = UB,
|
|
|
|
halfradius = 2,
|
|
|
|
optimizer = cosmo_optimizer(; accel = 50, alpha = 1.9),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
|
|
|
@test status == JuMP.OPTIMAL
|
|
|
|
@test certified
|
|
|
|
@test λ_cert > 54 // 100
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
@testset "Op is a sum of squares, but not an order unit" begin
|
|
|
|
elt = op
|
|
|
|
UB = Inf
|
2019-06-30 13:20:39 +02:00
|
|
|
|
2022-11-07 18:45:12 +01:00
|
|
|
status, certified, λ_cert = check_positivity(
|
|
|
|
elt,
|
|
|
|
Δ,
|
2023-03-19 23:28:36 +01:00
|
|
|
wd;
|
|
|
|
upper_bound = UB,
|
|
|
|
halfradius = 2,
|
|
|
|
optimizer = cosmo_optimizer(; accel = 50, alpha = 1.9),
|
2022-11-07 18:45:12 +01:00
|
|
|
)
|
|
|
|
@test status == JuMP.OPTIMAL
|
|
|
|
@test !certified
|
|
|
|
@test -1e-2 < λ_cert < 0
|
2019-06-30 13:20:39 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|