Skip to content

Commit

Permalink
group methods by name in src/actions.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
kalmarek committed Apr 23, 2024
1 parent 7601f01 commit 28ec244
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 131 deletions.
221 changes: 102 additions & 119 deletions src/actions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,6 @@ of elements in `S` one can then represent `g` as a permutation of degree `|S|`.
"""
abstract type ByPermutations <: Action end

function action(
::ByPermutations,
g::AP.AbstractPermutation,
v::AbstractVector,
)
return [v[i^g] for i in eachindex(v)]
end

"""
action(hom::InducedActionHomomorphism, g::GroupElement, x)
Return the result of `g` acting on `x` through action homomorphism `hom`.
This can be understood as first evaluating the homomorphism: `h = hom(g)` and
then computing `x^h`, the action of the result on `x`.
"""
function action(
hom::InducedActionHomomorphism{<:ByPermutations},
g::GroupElement,
v::AbstractVector,
)
return action(action(hom), induce(hom, g), v)
end

coeff_type(::ByPermutations) = Int

function induce(::ByPermutations, hom::ExtensionHomomorphism, g::GroupElement)
I = _int_type(hom)
return PG.Perm{I}(
vec(I[hom[action(action(hom), g, f)] for f in basis(hom)]),
)
end

"""
ByLinearTransformation <: Action
A type of action where a group acts through linear transformations on an
Expand All @@ -59,48 +27,6 @@ implemented to return a (possibly sparse) decomposition of `v` in `B`.
"""
abstract type ByLinearTransformation <: Action end

function action(
hom::InducedActionHomomorphism{<:ByLinearTransformation},
g::GroupElement,
v::AbstractVector,
)
return induce(hom, g) * v
end

function coeff_type(ac::ByLinearTransformation)
throw("No fallback is provided for $(typeof(ac)). You need to implement
`coeff_type(::$(typeof(ac)))`.")
end

function induce(
ac::ByLinearTransformation,
hom::InducedActionHomomorphism,
g::GroupElement,
)
I = Int[]
J = Int[]
V = coeff_type(ac)[]

for (i, f) in enumerate(basis(hom))
k = action(action(hom), g, f)
idcs, vals = decompose(k, hom)
append!(I, fill(i, length(idcs)))
append!(J, idcs)
append!(V, vals)
end
n = length(basis(hom))
return sparse(I, J, V, n, n)
end

# disabmiguation:
function induce(
ac::ByLinearTransformation,
hom::CachedExtensionHomomorphism,
g::GroupElement,
)
return _induce(ac, hom, g)
end

"""
decompose(v, hom::InducedActionHomomorphism)
Decompose element `v` in basis `basis(hom)` provided by `hom`.
Expand Down Expand Up @@ -144,8 +70,88 @@ action(act::BySignedPermutations, g, eₖ) == (eₗ, u)
"""
abstract type BySignedPermutations <: ByLinearTransformation end

## coeff_types
coeff_type(::ByPermutations) = Int
function coeff_type(ac::ByLinearTransformation)
throw("No fallback is provided for $(typeof(ac)). You need to implement
`coeff_type(::$(typeof(ac)))`.")
end
coeff_type(::BySignedPermutations) = Int # lets not worry about roots of unity

## actions on AbstractVectors

function action(::ByPermutations, g::AP.AbstractPermutation, v::AbstractVector)
# permuting coordinates
return [v[i^g] for i in eachindex(v)]
end

"""
action(hom::InducedActionHomomorphism, g::GroupElement, x)
Return the result of `g` acting on `x` through action homomorphism `hom`.
This can be understood as first evaluating the homomorphism: `h = hom(g)` and
then computing `x^h`, the action of the result on `x`.
"""
function action(
hom::InducedActionHomomorphism{<:ByPermutations},
g::GroupElement,
v::AbstractVector,
)
return action(action(hom), induce(hom, g), v)
end

function action(
hom::InducedActionHomomorphism{<:ByLinearTransformation},
g::GroupElement,
v::AbstractVector,
)
return induce(hom, g) * v
end

# Inducing action via action homomorphism

function induce(hom::InducedActionHomomorphism, g::GroupElement)
return induce(action(hom), hom, g)
end

function induce(ac::Action, hom::InducedActionHomomorphism, g::GroupElement)
return throw(
"""No fallback is provided for $(typeof(ac)).
You need to implement
`induce(::$(typeof(ac)), ::$(typeof(hom)), ::$(typeof(g)))`.""",
)
end

function induce(
::ByPermutations,
hom::InducedActionHomomorphism,
g::GroupElement,
)
I = _int_type(hom)
v = vec(I[hom[action(action(hom), g, f)] for f in basis(hom)])
return PG.Perm{I}(v; check = false)
end

function induce(
ac::ByLinearTransformation,
hom::InducedActionHomomorphism,
g::GroupElement,
)
I = Int[]
J = Int[]
V = coeff_type(ac)[]

for (i, f) in enumerate(basis(hom))
k = action(action(hom), g, f)
idcs, vals = decompose(k, hom)
append!(I, fill(i, length(idcs)))
append!(J, idcs)
append!(V, vals)
end
n = length(basis(hom))
return sparse(I, J, V, n, n)
end

function induce(
ac::BySignedPermutations,
hom::InducedActionHomomorphism,
Expand All @@ -165,6 +171,15 @@ function induce(
return sparse(I, J, V, n, n)
end

# disabmiguation methods for custom implementations of InducedActionHomomorphism
function induce(
ac::ByLinearTransformation,
hom::CachedExtensionHomomorphism,
g::GroupElement,
)
return _induce(ac, hom, g)
end

# disabmiguation
function induce(
ac::BySignedPermutations,
Expand All @@ -175,57 +190,25 @@ function induce(
end

function induce(
ac::Union{<:ByPermutations,<:ByLinearTransformation},
schr_hom::SchreierExtensionHomomorphism,
ac::ByPermutations,
shom::SchreierExtensionHomomorphism,
g::GroupElement,
)
if g in keys(schr_hom.cache)
return schr_hom.cache[g]
else
h, s = schr_hom.schreier_tree[g]
sI = induce(ac, schr_hom, s)
hI = induce(ac, schr_hom, h)
gI = hI * sI

if schr_hom.memoize
lock(schr_hom.lock) do
return schr_hom.cache[g] = gI
end
end

if length(schr_hom.schreier_tree) == length(schr_hom.cache)
# we no longer need to store the schreier tree
empty!(schr_hom.schreier_tree)
end

return gI
end
return _induce(ac, shom, g)
end

function induce(
ac::ByLinearTransformation,
shom::SchreierExtensionHomomorphism,
g::GroupElement,
)
return _induce(ac, shom, g)
end

function induce(
ac::BySignedPermutations,
schr_hom::SchreierExtensionHomomorphism,
shom::SchreierExtensionHomomorphism,
g::GroupElement,
)
if g in keys(schr_hom.cache)
return schr_hom.cache[g]
else
s, h = schr_hom.schreier_tree[g]
sI = induce(ac, schr_hom, s)
hI = induce(ac, schr_hom, h)
gI = first(hI) * first(sI), last(hI) * last(sI)

if schr_hom.memoize
lock(schr_hom.lock) do
return schr_hom.cache[g] = gI
end
end

if length(schr_hom.schreier_tree) == length(schr_hom.cache)
# we no longer need to store the schreier tree
empty!(schr_hom.schreier_tree)
end

return gI
end
return _induce(ac, shom, g)
end
31 changes: 31 additions & 0 deletions src/ext_hom_schreier.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,35 @@ function SchreierExtensionHomomorphism(

return sehom
end

function memoize!(sehom::SchreierExtensionHomomorphism, val, g, lck = true)
if lck
lock(sehom.lock) do
return sehom.cache[g] = val
end
else
sehom.cache[g] = val
end
return sehom
end

function _induce(
ac::Action,
sehom::SchreierExtensionHomomorphism,
g::GroupElement,
)
if g in keys(sehom.cache)
return sehom.cache[g]
else
s = sehom.schreier_tree.representatives[g]
sI = induce(ac, sehom, s)
hI = induce(ac, sehom, g * inv(s))
gI = hI * sI

if sehom.memoize
memoize!(sehom, gI, g)
end

return gI
end
end
12 changes: 0 additions & 12 deletions src/ext_homomorphisms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,6 @@ _int_type(hom::InducedActionHomomorphism) = _int_type(basis(hom))
_int_type(::Type{<:Action}) = UInt32
_int_type(ac::Action) = _int_type(typeof(ac))

function induce(hom::InducedActionHomomorphism, g::GroupElement)
return induce(action(hom), hom, g)
end

function induce(ac::Action, hom::InducedActionHomomorphism, g::GroupElement)
return throw(
"""No fallback is provided for $(typeof(ac)).
You need to implement
`induce(::$(typeof(ac)), ::$(typeof(hom)), ::$(typeof(g)))`.""",
)
end

struct ExtensionHomomorphism{A<:Action,T,B<:StarAlgebras.ExplicitBasis{T}} <:
InducedActionHomomorphism{A,T}
action::A
Expand Down

0 comments on commit 28ec244

Please sign in to comment.