Skip to content

Commit

Permalink
Merge pull request #34 from DanielBrosch:Nauty
Browse files Browse the repository at this point in the history
Speedups, bugfixes, free variables
  • Loading branch information
DanielBrosch authored Nov 7, 2024
2 parents 8b09cb9 + 0f60ad8 commit fc94d9b
Show file tree
Hide file tree
Showing 21 changed files with 1,634 additions and 472 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ version = "0.1.2"

[deps]
AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
ClusteredLowRankSolver = "cadeb640-247c-4e6d-a8b8-270aef5e1f95"
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Expand Down
23 changes: 18 additions & 5 deletions src/FlagAlgebras/AbstractFlagAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ end
function glueFinite_internal(N, F::T, G::T, p::AbstractVector{Int}; labelFlags=true) where {T<:Flag}
if N == :limit
res = glue(F, G, p)
if res === nothing
return QuantumFlag{T, Rational{Int64}}()
end
if labelFlags
return labelCanonically(res)
end
Expand Down Expand Up @@ -285,7 +288,7 @@ end
Returns the sub-Flag indexed by `vertices`, which is a subset of `1:size(F)`.
"""
function subFlag(F::T, vertices::AbstractVector{Int})::T where {T<:Flag}
error("subFlag is not defined for Flag type $T")
error("subFlag is not defined for Flag type T")
return missing
end

Expand Down Expand Up @@ -315,13 +318,13 @@ function findUnknownPredicates(
F::T, fixed::Vector{U}=Vector{Int}[], predLimits::Vector = Int[]
) where {T<:Flag,U<:AbstractVector{Int}}
error("findUnknownPredicates is not defined for Flag type $T")
return missing
return nothing
end

function findUnknownGenerationPredicates(
F::T, fixed::Vector{U}=Vector{Int}[], predLimits::Vector = Int[]
) where {T<:Flag,U<:AbstractVector{Int}}
return nothing
) where {T<:Flag,U<:AbstractVector{Int}}
return predicateType(T)[]
end

"""
Expand All @@ -336,7 +339,7 @@ function countEdges(F::T)::Vector{Int} where {T<:Flag}
end

"""
isolatedVertices(F::T)::Vector{Int} where{T<:Flag}
isolatedVertices(F::T)::BitVector where{T<:Flag}
Returns the indicator vector of isolated vertices of `F`.
"""
Expand Down Expand Up @@ -457,6 +460,15 @@ function allowMultiEdges(::Type{T}) where {T<:Flag}
return false
end

import Base.^
function ^(F::T, i::Int) where {T<:Flag}
@assert i >= 0
if i == 0
return one(T)
end
return F * F^(i-1)
end

include("InducedFlags.jl")
include("Graphs.jl")
include("ConstantWeightCodes.jl")
Expand All @@ -467,4 +479,5 @@ include("EdgeMarkedFlags.jl")
include("SymmetricFunctions.jl")
include("HarmonicFlags.jl")
include("ProductFlag.jl")
include("FreeVariables.jl")
include("PartiallyColoredFlags.jl")
4 changes: 2 additions & 2 deletions src/FlagAlgebras/BinaryTrees.jl
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ function isSym(g::BinaryTreeFlag, v1::Int, v2::Int)::Bool
return isSym(g.tree, v1p, v2p)
end

function subFlag(F::BinaryTree, vertices::AbstractVector{Int})
function subFlag(F::BinaryTree, vertices::AbstractVector{Int})::BinaryTree
if length(vertices) == 0
return BinaryTree()
end
Expand Down Expand Up @@ -879,7 +879,7 @@ function subFlag(F::BinaryTree, vertices::AbstractVector{Int})
end


function subFlag(F::BinaryTreeFlag, vertices::AbstractVector{Int})
function subFlag(F::BinaryTreeFlag, vertices::AbstractVector{Int})::BinaryTreeFlag

# @show F
# @show vertices
Expand Down
1 change: 1 addition & 0 deletions src/FlagAlgebras/DirectedGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function glue(

# res = BitMatrix(zeros(Bool, n, n))
res = BitMatrix(undef, n, n)
res .= 0
@views res[1:n2, 1:n2] = g2.A
@views res[p[1:n1], p[1:n1]] .|= g1.A

Expand Down
30 changes: 17 additions & 13 deletions src/FlagAlgebras/EdgeMarkedFlags.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@ struct EdgeMarkedFlag{T,P} <: Flag
# function EdgeMarkedFlag{T}(F::T, marked::Vector) where {T<:Flag}
# return new{T,predicateType(T)}(F, marked)
# end
function EdgeMarkedFlag{T}(F::T, marked::Vector{Vector{P}}) where {T<:Flag,P}
return new{T,predicateType(T)}(F, vcat(marked...))
end
function EdgeMarkedFlag{T}(F::T, marked::Vector{Vector}) where {T<:Flag}
return new{T,predicateType(T)}(F, vcat(marked...))
end
# function EdgeMarkedFlag{T}(F::T, marked::Vector{Vector{P}}) where {T<:Flag,P}
# allMarks::Vector{predicateType(T)} = vcat(marked...)
# return new{T,predicateType(T)}(F, allMarks)
# end
# function EdgeMarkedFlag{T}(F::T, marked::Vector{Vector}) where {T<:Flag}
# return new{T,predicateType(T)}(F, vcat(marked...))
# end
function EdgeMarkedFlag{T}(F::T, marked::Vector{P}) where {T<:Flag,P}
return new{T,predicateType(T)}(F, marked)
if P <: Vector
return new{T,predicateType(T)}(F, vcat(marked...))
else
return new{T,predicateType(T)}(F, marked)
end
end
end

Expand All @@ -62,7 +67,7 @@ end
function findUnknownPredicates(
F::EdgeMarkedFlag, fixed::Vector{U}, predLimits::Vector
) where {U<:AbstractVector{Int}}
return findUnknownPredicates(F.F, fixed, predLimits[1:end-1]), predLimits::Vector
return findUnknownPredicates(F.F, fixed, predLimits[1:(end - 1)]), predLimits::Vector
end

function predicateType(::Type{EdgeMarkedFlag{T,P}}) where {T<:Flag,P}
Expand All @@ -83,9 +88,7 @@ function addPredicates(
return EdgeMarkedFlag{T,predicateType(T)}(addPredicates(G.F, preds), G.marked)
end

function permute(
F::EdgeMarkedFlag{T,P}, p::AbstractVector{Int}
) where {T<:Flag,P}
function permute(F::EdgeMarkedFlag{T,P}, p::AbstractVector{Int}) where {T<:Flag,P}
return EdgeMarkedFlag{T}(permute(F.F, p), P[permute(e, p) for e in F.marked])
end

Expand All @@ -107,7 +110,7 @@ function countEdges(F::EdgeMarkedFlag)
return vcat(countEdges(F.F), [length(F.marked)])
end

function isolatedVertices(F::EdgeMarkedFlag)
function isolatedVertices(F::EdgeMarkedFlag)::BitVector
return BitVector([false for i in 1:size(F)])
end

Expand Down Expand Up @@ -178,6 +181,7 @@ function moebius(F::EdgeMarkedFlag{T,P}; label=false) where {T<:Flag,P<:Predicat
tmp2 = Dict{EdgeMarkedFlag{T,P},Int}()

for flippedEdges in 0:k
# @show flippedEdges
for (F2, c2) in tmp
res += c2 * (-1)^flippedEdges * F2.F
for (F3, c3) in allWaysToAddOneMarked(F2)
Expand Down Expand Up @@ -208,7 +212,7 @@ function zeta(
) where {T<:Flag,D,P<:Predicate}
# res = moebius(F; label=label)
# map!(abs, values(res.coeff))
res = sum(c*zeta(f) for (f,c) in F.coeff)
res = sum(c * zeta(f) for (f, c) in F.coeff)
return res
end

Expand Down
115 changes: 115 additions & 0 deletions src/FlagAlgebras/FreeVariables.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Sometimes one may want to add free variables to the model, for example to model sqrt(edge density). To make this possible, we model them as a "fake flag algebra", with only finite sized models and no S_infty symmetries

export FreeVariable, FreeVariables

struct FreeVariable <: Flag
exponent::Int
FreeVariable() = new(0)
FreeVariable(exponent::Int) = new(exponent)
end

FreeVariables{N} = ProductFlag{NTuple{N,FreeVariable}}

struct IncreaseDegreePredicate <: Predicate
end

function permute(pred::IncreaseDegreePredicate, p::AbstractVector{Int})
return pred
end

function Base.show(io::IO, T::FreeVariable)
return print(io, "x^$(T.exponent)")
end

function ==(A::FreeVariable, B::FreeVariable)
return A.exponent == B.exponent
end

function hash(A::FreeVariable, h::UInt)
return hash(A.exponent, hash(:FreeVariable, h))
end

function distinguish(P::IncreaseDegreePredicate, v::Int, W::BitVector)::UInt
return UInt(1)
end


Base.one(::Type{FreeVariable})::FreeVariable = FreeVariable()

Base.one(::FreeVariable)::FreeVariable = FreeVariable()

Base.size(F::FreeVariable)::Int = 0

function labelCanonically(F::FreeVariable)::FreeVariable
return F
end

function countEdges(F::FreeVariable)::Vector{Int}
return [F.exponent]
end

function maxPredicateArguments(::Type{FreeVariable})
return 1
end

function subFlag(F::FreeVariable, vertices::Vector{Int})::FreeVariable
return F
end

function glue(F::FreeVariable, G::FreeVariable, p::AbstractVector{Int})
return FreeVariable(F.exponent + G.exponent)
end

function distinguish(F::FreeVariable, v::Int, W::BitVector)::UInt
return UInt(1)
end

function isolatedVertices(F::FreeVariable)::BitVector
return [true;]
end

function predicateType(::Type{FreeVariable})
return IncreaseDegreePredicate
end

function addPredicates(F::FreeVariable, preds::Vector{IncreaseDegreePredicate})
return FreeVariable(F.exponent + length(preds))
end

function permute(F::FreeVariable, p::AbstractVector{Int})
return F
end

function findUnknownPredicates(
F::FreeVariable, fixed::Vector{U}, predLimits::Vector
) where {U<:AbstractVector{Int}}
if any(1 in f for f in fixed)
return [IncreaseDegreePredicate[]]
end
return [IncreaseDegreePredicate[IncreaseDegreePredicate()]]
end

function findUnknownGenerationPredicates(
F::FreeVariable, fixed::Vector{U}, predLimits::Vector
) where {U<:AbstractVector{Int}}
return findUnknownPredicates(F, fixed, predLimits)
end

function isSym(F::FreeVariable, v1::Int, v2::Int)::Bool
return v1 == v2
end

function allowMultiEdges(::Type{FreeVariable})
return true
end

# function generateAll(
# ::Type{FreeVariable{F}}, maxVertices::Int, maxPredicates::Vector{Int}
# ) where {F<:Flag}
# tmp = generateAll(F, maxVertices, maxPredicates)
# return [FreeVariable{F}(f) for f in tmp]
# end

# function eliminateIsolated(F::FreeVariable)
# return FreeVariable(filter(x -> x.second != 0, F.exponent))
# end
Loading

0 comments on commit fc94d9b

Please sign in to comment.