Skip to content

Commit

Permalink
Merge pull request #25 from AlgebraicJulia/integrate
Browse files Browse the repository at this point in the history
Integrate `JunctionsTrees` and `Decompositions`
  • Loading branch information
samuelsonric authored Nov 20, 2024
2 parents d48029e + b49486f commit 70c5f1f
Show file tree
Hide file tree
Showing 21 changed files with 1,316 additions and 1,532 deletions.
6 changes: 5 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@ Catlab = "134e5e36-593f-5add-ad60-77f754baafbe"
CuthillMcKee = "17f17636-5e38-52e3-a803-7ae3aaaf3da9"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LinkedLists = "70f5e60a-1556-5f34-a19e-a48b3e4aaee9"
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b"
PartialFunctions = "570af359-4316-4cb7-8c74-252c00c2016b"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
TreeWidthSolver = "7d267fc5-9ace-409f-a54c-cd2374872a55"

[compat]
AbstractTrees = "0.4"
AMD = "0.5"
AbstractTrees = "0.4"
Catlab = "0.16"
CuthillMcKee = "0.1"
DataStructures = "0.18"
LinkedLists = "0.1"
MLStyle = "0.4"
Metis = "1"
PartialFunctions = "1.1"
TreeWidthSolver = "0.3"
julia = "1.7"
165 changes: 165 additions & 0 deletions src/Decompositions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@ export StructuredDecomposition, StrDecomp,
𝐃, bags, adhesions, adhesionSpans,

using ..JunctionTrees
using ..JunctionTrees: EliminationAlgorithm, SupernodeType, DEFAULT_ELIMINATION_ALGORITHM, DEFAULT_SUPERNODE_TYPE

using PartialFunctions
using MLStyle

using AbstractTrees
using Base.Threads
using Catlab
using Catlab.CategoricalAlgebra
using Catlab.Graphs
using Catlab.ACSetInterface
using Catlab.CategoricalAlgebra.Diagrams

import Catlab.CategoricalAlgebra.Diagrams: ob_map, hom_map, colimit, limit


#####################
# DATA
#####################
Expand Down Expand Up @@ -180,4 +187,162 @@ function 𝐃(f, d ::StructuredDecomposition, t::DecompType = d.decomp_type)::St
StrDecomp(d.decomp_shape, Q, t)
end


##################################
# Integration with JunctionTrees #
##################################


"""
StrDecomp(graph::AbstractSymmetricGraph[, ealg::Union{Order, EliminationAlgorithm}[, stype::SupernodeType]])
Construct a structured decomposition of a simple graph, optionally specifying an elimination algorithm and
supernode type.
"""
function StrDecomp(
graph::AbstractSymmetricGraph,
ealg::Union{Order, EliminationAlgorithm}=DEFAULT_ELIMINATION_ALGORITHM,
stype::SupernodeType=DEFAULT_SUPERNODE_TYPE)

merge_decompositions(decompositions(graph, ealg, stype))
end


# Construct a tree decomposition.
# ----------------------------------------
# graph simple connected graph
# jtree junction tree
# ----------------------------------------
function StrDecomp(graph::AbstractSymmetricGraph, jtree::JunctionTree)
n = length(jtree)
tree = Graph(n)

for i in 1:n - 1
add_edge!(tree, i, parentindex(jtree, i))
end

diagram = FinDomFunctor(homomorphisms(graph, jtree)..., (tree))
StrDecomp(tree, diagram, Decomposition, dom(diagram))
end


function merge_decompositions(decomposition::AbstractVector)
tree = apex(coproduct(map(d -> d.decomp_shape, decomposition)))
l = length(decomposition)
m = nv(tree)
subgraph = Vector(undef, 2m - l)
homomorphism = Vector(undef, 2m - 2l)

i = 0

for j in 1:l
n = nv(decomposition[j].decomp_shape)

for k in 1:n
subgraph[i + k] = ob_map(decomposition[j].diagram, k)
end

for k in 1:n - 1
subgraph[i - j + k + m + 1] = ob_map(decomposition[j].diagram, k + n)
end

for k in 1:n - 1
homomorphism[i - j + k + 1] = hom_map(decomposition[j].diagram, k)
end

for k in 1:n - 1
homomorphism[i - j + k - l + m + 1] = hom_map(decomposition[j].diagram, k + n - 1)
end

i += n
end

diagram = FinDomFunctor(subgraph, homomorphism, (tree))
StrDecomp(tree, diagram, Decomposition, dom(diagram))
end


function decompositions(graph::AbstractSymmetricGraph, ealg::EliminationAlgorithm, stype::SupernodeType)
component = connected_components(graph)

n = length(component)
decomposition = Vector(undef, n)

@threads for i in 1:n
subgraph = induced_subgraph(graph, component[i])
decomposition[i] = StrDecomp(subgraph, JunctionTree(subgraph, ealg, stype))
end

decomposition
end


function decompositions(graph::AbstractSymmetricGraph, order::Order, stype::SupernodeType)
component = connected_components(graph)

n = length(component)
decomposition = Vector(undef, n)

@threads for i in 1:n
subgraph = induced_subgraph(graph, component[i])
decomposition[i] = StrDecomp(subgraph, JunctionTree(subgraph, induced_order(order, component[i]), stype))
end

decomposition
end


function homomorphisms(graph::AbstractSymmetricGraph, jtree::JunctionTree)
n = length(jtree)
subgraph = Vector{Any}(undef, 2n - 1)
homomorphism = Vector{Any}(undef, 2n - 2)

for i in 1:n
# clique(i)
subgraph[i] = induced_subgraph(graph, clique(jtree, i))
end

for i in 1:n - 1
# seperator(i)
subgraph[n + i] = induced_subgraph(graph, seperator(jtree, i))
end

for i in 1:n - 1
# seperator(i) → clique(parent(i))
j = parentindex(jtree, i)
homomorphism[i] = induced_homomorphism(subgraph[n + i], subgraph[j], seperator_to_parent(jtree, i))
end

for i in 1:n - 1
# seperator(i) → clique(i)
homomorphism[n + i - 1] = induced_homomorphism(subgraph[n + i], subgraph[i], seperator_to_self(jtree, i))
end

subgraph, homomorphism
end


function induced_order(order::Order, elements::AbstractVector)
Order(sortperm(inverse(order, elements)))
end


function induced_homomorphism(domain::AbstractSymmetricGraph, codomain::AbstractSymmetricGraph, V::AbstractVector)
index = Dict{Tuple{Int, Int}, Int}()
sizehint!(index, ne(codomain))

for e in edges(codomain)
index[src(codomain, e), tgt(codomain, e)] = e
end

E = Vector{Int}(undef, ne(domain))

for e in edges(domain)
E[e] = index[V[src(domain, e)], V[tgt(domain, e)]]
end

ACSetTransformation(domain, codomain; V, E)
end


end
43 changes: 43 additions & 0 deletions src/JunctionTrees.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module JunctionTrees


import AMD
import CuthillMcKee
import LinkedLists
import Metis
import TreeWidthSolver

using AbstractTrees
using Catlab.BasicGraphs
using DataStructures
using SparseArrays


# Orders
export Order, inverse


# Elimination Algorithms
export AMDJL_AMD, CuthillMcKeeJL_RCM, MetisJL_ND, TreeWidthSolverJL_BT, MCS


# Supernode Types
export Node, Maximal, Fundamental


# Junction Trees
export JunctionTree, width, height, seperator, residual, clique, seperator_to_parent, seperator_to_self


include("junction_trees/orders.jl")
include("junction_trees/elimination_algorithms.jl")
include("junction_trees/ordered_graphs.jl")
include("junction_trees/trees.jl")
include("junction_trees/postorder_trees.jl")
include("junction_trees/elimination_trees.jl")
include("junction_trees/supernode_types.jl")
include("junction_trees/supernode_trees.jl")
include("junction_trees/junction_trees.jl")


end
3 changes: 1 addition & 2 deletions src/StructuredDecompositions.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
module StructuredDecompositions


include("JunctionTrees.jl")
include("Decompositions.jl")
include("FunctorUtils.jl")
include("DecidingSheaves.jl")
include("junction_trees/JunctionTrees.jl")
include("nested_uwds/NestedUWDs.jl")


end
83 changes: 0 additions & 83 deletions src/junction_trees/JunctionTrees.jl

This file was deleted.

Loading

0 comments on commit 70c5f1f

Please sign in to comment.