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

Speedups, bugfixes, free variables #34

Merged
merged 3 commits into from
Nov 7, 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
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
Loading