Skip to content

Commit

Permalink
Merge pull request #38 from kalmarek/enh/minimal_projection_system
Browse files Browse the repository at this point in the history
Enh/minimal projection system
  • Loading branch information
Marek Kaluba authored Sep 14, 2021
2 parents 3131a76 + e3290a5 commit dbbb167
Show file tree
Hide file tree
Showing 40 changed files with 2,602 additions and 1,185 deletions.
8 changes: 6 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PermutationGroups = "8bc5a954-2dfc-11e9-10e6-cd969bffa420"
Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StarAlgebras = "0c0c59c1-dc5f-42e9-9a8b-b5dc384a6cd1"

[compat]
Cyclotomics = "0.2.2"
Cyclotomics = "0.2.3"
GroupsCore = "0.3.1"
PermutationGroups = "0.3"
Primes = "0.4, 0.5"
StarAlgebras = "0.1.5"
julia = "1"

[extras]
DynamicPolynomials = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "DynamicPolynomials", "Random", "Pkg"]
test = ["Test", "DynamicPolynomials", "JuMP", "Pkg", "Random", "SCS"]
40 changes: 37 additions & 3 deletions examples/action_polynomials.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,44 @@
struct PermutingVariables <: SymbolicWedderburn.ByPermutations end
using DynamicPolynomials
MP = DynamicPolynomials.MultivariatePolynomials
using GroupsCore
using PermutationGroups

function SymbolicWedderburn.action(a::PermutingVariables, g::PermutationGroups.AbstractPerm, m::Monomial)
struct VariablePermutation <: SymbolicWedderburn.ByPermutations end

function SymbolicWedderburn.action(a::VariablePermutation, g::PermutationGroups.AbstractPerm, m::Monomial)
v = variables(m)
return m(v => SymbolicWedderburn.action(a, g, v))
end

function SymbolicWedderburn.action(::PermutingVariables, g::PermutationGroups.AbstractPerm, v::AbstractVector)
function SymbolicWedderburn.action(::VariablePermutation, g::PermutationGroups.AbstractPerm, v::AbstractVector)
return map(i -> v[i^g], eachindex(v))
end

abstract type OnMonomials <: SymbolicWedderburn.ByLinearTransformation end

function SymbolicWedderburn.action(
a::Union{VariablePermutation,OnMonomials},
el::GroupElement,
term::MP.AbstractTerm,
)
return MP.coefficient(term) * SymbolicWedderburn.action(a, el, MP.monomial(term))
end
function SymbolicWedderburn.action(
a::Union{VariablePermutation,OnMonomials},
el::GroupElement,
poly::MP.AbstractPolynomial,
)
return sum([SymbolicWedderburn.action(a, el, term) for term in MP.terms(poly)])
end

function SymbolicWedderburn.decompose(
k::MP.AbstractPolynomialLike,
hom::SymbolicWedderburn.InducedActionHomomorphism,
)
# correct only if features(hom) == monomials

indcs = [hom[mono] for mono in MP.monomials(k)]
coeffs = MP.coefficients(k)

return indcs, coeffs
end
66 changes: 66 additions & 0 deletions examples/dihedral.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import GroupsCore

struct DihedralGroup <: GroupsCore.Group
n::Int
end

struct DihedralElement <: GroupsCore.GroupElement
n::Int
reflection::Bool
id::Int
end

Base.one(G::DihedralGroup) = DihedralElement(G.n, false, 0)

Base.eltype(::DihedralGroup) = DihedralElement
function Base.iterate(G::DihedralGroup, prev::DihedralElement=DihedralElement(G.n, false, -1))
if prev.id + 1 >= G.n
if prev.reflection
return nothing
else
next = DihedralElement(G.n, true, 0)
end
else
next = DihedralElement(G.n, prev.reflection, prev.id + 1)
end
return next, next
end
Base.IteratorSize(::Type{DihedralGroup}) = Base.HasLength()

GroupsCore.order(::Type{T}, G::DihedralGroup) where {T} = convert(T, 2G.n)
GroupsCore.gens(G::DihedralGroup) = [DihedralElement(G.n, false, 1), DihedralElement(G.n, true, 0)]

# Base.rand not needed for our purposes here

Base.parent(g::DihedralElement) = DihedralGroup(g.n)
function Base.:(==)(g::DihedralElement, h::DihedralElement)
return g.n == h.n && g.reflection == h.reflection && g.id == h.id
end

function Base.inv(el::DihedralElement)
if el.reflection || iszero(el.id)
return el
else
return DihedralElement(el.n, false, el.n - el.id)
end
end
function Base.:*(a::DihedralElement, b::DihedralElement)
a.n == b.n || error("Cannot multiply elements from different Dihedral groups")
id = mod(a.reflection ? a.id - b.id : a.id + b.id, a.n)
return DihedralElement(a.n, a.reflection != b.reflection, id)
end

Base.copy(a::DihedralElement) = DihedralElement(a.n, a.reflection, a.id)

# optional functions:
function GroupsCore.order(T::Type, el::DihedralElement)
if el.reflection
return T(2)
else
if iszero(el.id)
return T(1)
else
return T(div(el.n, gcd(el.n, el.id)))
end
end
end
28 changes: 14 additions & 14 deletions examples/ex_C2_linear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ G = CyclicGroup(2)
x,y = @polyvar x y
# (x, y) → (x+y, x-y)

struct MyAction <: SymbolicWedderburn.ByLinearTransformation end
struct By90Rotation <: SymbolicWedderburn.ByLinearTransformation end
# x -> linear combination of basis elements;

SymbolicWedderburn.coeff_type(m::MyAction) = Float64
function SymbolicWedderburn.action(a::MyAction, g::CyclicGroupElement, m::Monomial)
SymbolicWedderburn.coeff_type(::By90Rotation) = Float64
function SymbolicWedderburn.action(::By90Rotation, g::CyclicGroupElement, m::Monomial)
isone(g) && return m
x, y = variables(m)
return m(x => (x+y)/sqrt(2), y => (x-y)/sqrt(2)) # action must be orthogonal
return m(x => (x+y)/sqrt(2), y => (x-y)/sqrt(2)) # we need the action to be orthogonal
end

function SymbolicWedderburn.decompose(k::AbstractPolynomial, hom::SymbolicWedderburn.InducedActionHomomorphism)
Expand All @@ -36,13 +36,13 @@ using Test
g = gens(G, 1)

basis = monomials([x,y], 0:4)
k = SymbolicWedderburn.action(MyAction(), g, basis[2])
ehom = SymbolicWedderburn.ExtensionHomomorphism(MyAction(), basis)
k = SymbolicWedderburn.action(By90Rotation(), g, basis[2])
ehom = SymbolicWedderburn.ExtensionHomomorphism(By90Rotation(), basis)
idcs, vals = SymbolicWedderburn.decompose(k, ehom)
@test sum(c*basis[i] for (c,i) in zip(vals, idcs)) == k

for b in basis
k = SymbolicWedderburn.action(MyAction(), g, b)
k = SymbolicWedderburn.action(By90Rotation(), g, b)
idcs, vals = SymbolicWedderburn.decompose(k, ehom)
@test sum(c*basis[i] for (c,i) in zip(vals, idcs)) == k
end
Expand All @@ -52,17 +52,17 @@ end

@testset "induced Matrix Representation" begin
g = gens(G, 1)
basis = monomials([x,y], 0:4)
ehom = SymbolicWedderburn.ExtensionHomomorphism(MyAction(), basis)
m = droptol!(SymbolicWedderburn.induce(MyAction(), ehom, g), 1e-15)
monomial_basis = monomials([x,y], 0:4)
ehom = SymbolicWedderburn.ExtensionHomomorphism(By90Rotation(), monomial_basis)
m = droptol!(SymbolicWedderburn.induce(By90Rotation(), ehom, g), 1e-15)
@test eltype(m) == Float64

@test !(m one(m))
@test m^2 one(m)

ssimple_basis = SymbolicWedderburn.symmetry_adapted_basis(G, basis, MyAction());
ssimple_basis = SymbolicWedderburn.symmetry_adapted_basis(Float64, G, By90Rotation(), monomial_basis);
degs = SymbolicWedderburn.degree.(ssimple_basis)
mlts = SymbolicWedderburn.multiplicity.(ssimple_basis)
@test sum(d*m for (d,m) in zip(degs, mlts)) == length(basis)
@test sum(firstsizeSymbolicWedderburn.basis, ssimple_basis) == length(basis)
mlts = multiplicity.(ssimple_basis)
@test sum(d*m for (d,m) in zip(degs, mlts)) == length(monomial_basis)
@test sum(firstsize, ssimple_basis) == length(monomial_basis)
end
69 changes: 0 additions & 69 deletions examples/ex_C4.jl

This file was deleted.

Loading

0 comments on commit dbbb167

Please sign in to comment.