Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add WIP Schreier evaluation of extension homomorphisms #69

Merged
merged 16 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ AbstractPermutations = "0.3"
Cyclotomics = "0.3"
GroupsCore = "0.5"
DynamicPolynomials = "0.6"
PermutationGroups = "0.6.2"
PermutationGroups = "0.6.3"
PrecompileTools = "1"
PrettyTables = "2"
Primes = "0.4, 0.5"
Expand Down
5 changes: 1 addition & 4 deletions examples/action_polynomials.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using DynamicPolynomials
const DP = DynamicPolynomials
using GroupsCore

const SW = SymbolicWedderburn
import DynamicPolynomials as DP

# Defining action on polynomials by acting on terms and monomials:
function SW.action(a::SW.Action, el::GroupElement, poly::DP.AbstractPolynomial)
Expand Down
3 changes: 3 additions & 0 deletions examples/dihedral.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,6 @@ function GroupsCore.order(T::Type, el::DihedralElement)
iszero(el.id) && return T(1)
return T(div(el.n, gcd(el.n, el.id)))
end

# this is needed for using them in StarAlgebra:
SA.comparable(::Type{DihedralElement}) = (a, b) -> hash(a) < hash(b)
11 changes: 3 additions & 8 deletions examples/ex_C2_linear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ using Test
@testset "Decompose in basis" begin
g = gens(G, 1)

basis = StarAlgebras.FixedBasis(
monomials([x, y], 0:4),
StarAlgebras.DiracMStructure(*),
)
basis = SA.FixedBasis(monomials([x, y], 0:4), SA.DiracMStructure(*))
k = SymbolicWedderburn.action(By90Rotation(), g, basis[2])
ehom = SymbolicWedderburn.ExtensionHomomorphism(By90Rotation(), basis)
idcs, vals = SymbolicWedderburn.decompose(k, ehom)
Expand All @@ -60,10 +57,8 @@ end

@testset "induced Matrix Representation" begin
g = gens(G, 1)
monomial_basis = StarAlgebras.FixedBasis(
monomials([x, y], 0:4),
StarAlgebras.DiracMStructure(*),
)
monomial_basis =
SA.FixedBasis(monomials([x, y], 0:4), SA.DiracMStructure(*))
ehom =
SymbolicWedderburn.ExtensionHomomorphism(By90Rotation(), monomial_basis)
m = droptol!(SymbolicWedderburn.induce(By90Rotation(), ehom, g), 1e-15)
Expand Down
9 changes: 0 additions & 9 deletions examples/ex_S4.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
using SymbolicWedderburn
using PermutationGroups

using DynamicPolynomials

include(joinpath(@__DIR__, "action_polynomials.jl"))
include(joinpath(@__DIR__, "sos_problem.jl"))
include(joinpath(@__DIR__, "solver.jl"))

const N = 4
@polyvar x[1:N]

Expand Down
2 changes: 1 addition & 1 deletion examples/ex_robinson_form.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ using LinearAlgebra
using SparseArrays

using SymbolicWedderburn
using SymbolicWedderburn.StarAlgebras
import SymbolicWedderburn.SA as SA
using DynamicPolynomials

# definitions of general actions on polynomials:
Expand Down
17 changes: 17 additions & 0 deletions examples/run_examples.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
using Pkg
Pkg.activate(@__DIR__)
Pkg.instantiate()

module Examples
using LinearAlgebra
using SparseArrays

using GroupsCore
import SymbolicWedderburn as SW
import SymbolicWedderburn.StarAlgebras as SA
using PermutationGroups
import PermutationGroups.AP as AP

include(joinpath(@__DIR__, "action_polynomials.jl"))
include(joinpath(@__DIR__, "sos_problem.jl"))
include(joinpath(@__DIR__, "solver.jl"))

include(joinpath(@__DIR__, "ex_C2_linear.jl"))
include(joinpath(@__DIR__, "ex_S4.jl"))
include(joinpath(@__DIR__, "ex_motzkin.jl"))
include(joinpath(@__DIR__, "ex_robinson_form.jl"))

end
1 change: 0 additions & 1 deletion examples/solver.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using JuMP
import SCS

function scs_optimizer(;
Expand Down
76 changes: 27 additions & 49 deletions examples/sos_problem.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
using LinearAlgebra
using SparseArrays

using GroupsCore

using DynamicPolynomials
using SymbolicWedderburn
import SymbolicWedderburn.StarAlgebras

using JuMP

function DynamicPolynomials.coefficients(p, b::StarAlgebras.FixedBasis)
return DynamicPolynomials.coefficients(p, b.elts)
function DP.coefficients(p, b::SA.FixedBasis)
return DP.coefficients(p, b.elts)
end

function invariant_constraint!(
Expand All @@ -28,19 +19,13 @@ function invariant_constraint!(
end

function sos_problem(poly::AbstractPolynomial)
vars = DynamicPolynomials.variables(poly)
vars = DP.variables(poly)

basis_psd = DynamicPolynomials.monomials(
vars,
0:DynamicPolynomials.maxdegree(poly)÷2,
)
basis_psd = DP.monomials(vars, 0:DP.maxdegree(poly)÷2)

basis_constraints = StarAlgebras.FixedBasis(
DynamicPolynomials.monomials(
vars,
0:DynamicPolynomials.maxdegree(poly),
),
StarAlgebras.DiracMStructure(*),
basis_constraints = SA.FixedBasis(
DP.monomials(vars, 0:DP.maxdegree(poly)),
SA.DiracMStructure(*),
)

M = [basis_constraints[x*y] for x in basis_psd, y in basis_psd]
Expand All @@ -54,7 +39,7 @@ function sos_problem(poly::AbstractPolynomial)

objective = poly - t
for (idx, b) in enumerate(basis_constraints)
c = DynamicPolynomials.coefficient(objective, b)
c = DP.coefficient(objective, b)
JuMP.@constraint sos_model LinearAlgebra.dot(P, M .== idx) == c
end

Expand All @@ -64,7 +49,7 @@ end
function sos_problem(
poly::AbstractPolynomial,
invariant_vs::AbstractVector,
basis_constraints::StarAlgebras.AbstractBasis,
basis_constraints::SA.AbstractBasis,
basis_psd,
T=Float64,
)
Expand All @@ -80,7 +65,7 @@ function sos_problem(
# preallocating
M_orb = similar(M, T)

C = DynamicPolynomials.coefficients(poly - t, basis_constraints)
C = DP.coefficients(poly - t, basis_constraints)

for iv in invariant_vs
c = dot(C, iv)
Expand All @@ -94,18 +79,18 @@ end

function sos_problem(
poly::AbstractPolynomial,
wedderburn::SymbolicWedderburn.WedderburnDecomposition,
wedderburn::SW.WedderburnDecomposition,
basis_psd;
)
m = JuMP.Model()

M = let basis_constraints = SymbolicWedderburn.basis(wedderburn)
M = let basis_constraints = SA.basis(wedderburn)
[basis_constraints[x*y] for x in basis_psd, y in basis_psd]
end

JuMP.@variable m t
JuMP.@objective m Max t
psds = map(SymbolicWedderburn.direct_summands(wedderburn)) do ds
psds = map(SW.direct_summands(wedderburn)) do ds
dim = size(ds, 1)
P = JuMP.@variable m [1:dim, 1:dim] Symmetric
JuMP.@constraint m P in PSDCone()
Expand All @@ -116,15 +101,13 @@ function sos_problem(
# Mπs = zeros.(eltype(wedderburn), size.(psds))
M_orb = similar(M, eltype(wedderburn))

C = DynamicPolynomials.coefficients(
poly - t,
SymbolicWedderburn.basis(wedderburn),
)
C = DP.coefficients(poly - t, SW.basis(wedderburn))

for iv in invariant_vectors(wedderburn)
c = dot(C, iv)
M_orb = invariant_constraint!(M_orb, M, iv)
# Mπs = SymbolicWedderburn.diagonalize!(Mπs, M_orb, wedderburn)
Mπs = SymbolicWedderburn.diagonalize(M_orb, wedderburn)
# Mπs = SW.diagonalize!(Mπs, M_orb, wedderburn)
Mπs = SW.diagonalize(M_orb, wedderburn)

JuMP.@constraint m sum(
dot(Mπ, Pπ) for (Mπ, Pπ) in zip(Mπs, psds) if !iszero(Mπ)
Expand All @@ -136,18 +119,19 @@ end
function sos_problem(
poly::AbstractPolynomial,
G::Group,
action::SymbolicWedderburn.Action,
action::SW.Action,
T=Float64;
decompose_psd=true,
semisimple=false
)
max_deg = DynamicPolynomials.maxdegree(poly)
vars = DynamicPolynomials.variables(poly)
basis_psd = DynamicPolynomials.monomials(vars, 0:max_deg÷2)
basis_constraints = DynamicPolynomials.monomials(vars, 0:max_deg)
max_deg = DP.maxdegree(poly)
vars = DP.variables(poly)
basis_psd = DP.monomials(vars, 0:max_deg÷2)
basis_constraints = DP.monomials(vars, 0:max_deg)

if decompose_psd == true
wedderburn, symmetry_adaptation_time = @timed WedderburnDecomposition(
wedderburn, symmetry_adaptation_time =
@timed SW.WedderburnDecomposition(
T,
G,
action,
Expand All @@ -160,15 +144,9 @@ function sos_problem(
@timed sos_problem(poly, wedderburn, basis_psd)
else
(invariant_vs, basis_cnstr), symmetry_adaptation_time = @timed let G = G
basis = StarAlgebras.FixedBasis(
basis_constraints,
StarAlgebras.DiracMStructure(*),
)

tblG = SymbolicWedderburn.Characters.CharacterTable(
Rational{Int},
G,
)
basis = SA.FixedBasis(basis_constraints, SA.DiracMStructure(*))

tblG = SW.Characters.CharacterTable(Rational{Int}, G)
iv = invariant_vectors(tblG, action, basis)
iv, basis
end
Expand Down
2 changes: 2 additions & 0 deletions src/SymbolicWedderburn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import AbstractPermutations as AP
import AbstractPermutations: degree
import PermutationGroups as PG
using StarAlgebras
import StarAlgebras as SA

export symmetry_adapted_basis, WedderburnDecomposition
export basis,
Expand All @@ -25,6 +26,7 @@ import .Characters: row_echelon_form!
import .Characters.FiniteFields

include("ext_homomorphisms.jl")
include("ext_hom_schreier.jl")
include("actions.jl")
include("group_action_error.jl")
include("action_characters.jl")
Expand Down
Loading
Loading