Skip to content

Commit 788bb10

Browse files
committed
update
1 parent 5c64ff6 commit 788bb10

File tree

9 files changed

+49
-78
lines changed

9 files changed

+49
-78
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ julia> using GraphTensorNetworks, Random, LightGraphs
4141
julia> graph = (Random.seed!(2); LightGraphs.smallgraph(:petersen))
4242
{10, 15} undirected simple Int64 graph
4343

44-
julia> problem = Independence(graph; optmethod=:tree, sc_target=0, sc_weight=1.0, ntrials=10, βs=0.01:0.1:15.0, niters=20, rw_weight=0.2);
44+
julia> problem = Independence(graph; optimizer=TreeSA(sc_target=0, sc_weight=1.0, ntrials=10, βs=0.01:0.1:15.0, niters=20, rw_weight=0.2));
4545
┌ Warning: target space complexity not found, got: 4.0, with time complexity 7.965784284662087, read-right complexity 8.661778097771988.
4646
└ @ OMEinsumContractionOrders ~/.julia/dev/OMEinsumContractionOrders/src/treesa.jl:71
4747
time/space complexity is (7.965784284662086, 4.0)

notebooks/tropicalwidget_simple.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ graph = unitdisk_graph(locs, 0.23) # SimpleGraph
5050
vizconfig(graph; locs=locs, config=rand(Bool, 12), graphsize=8cm)
5151

5252
# ╔═╡ e068f0b8-7b2c-49b2-94d1-83dead406326
53-
gp = Independence(graph; outputs=(1,2,3,4), optmethod=:greedy)
53+
gp = Independence(graph; outputs=(1,2,3,4))
5454

5555
# ╔═╡ 90c88c7f-e0c7-4845-a8b9-7f7562bd256f
5656
solve(gp, :config_single)

notebooks/tutorial.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ g = unitdisk_graph(locs, 0.2)
2424
vizconfig(g; locs=locs, unit=0.5)
2525

2626
# ╔═╡ b6e916e2-7d43-4085-a3c8-5c57069e8384
27-
gp = Independence(g; optmethod=:auto);
27+
gp = Independence(g, optimizer=TreeSA());
2828

2929
# ╔═╡ 1a58dea3-14fa-4be7-b087-45ed9bad2407
3030
gp

src/GraphTensorNetworks.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using OMEinsum: timespace_complexity, collect_ixs
88
using LightGraphs
99

1010
export timespace_complexity, @ein_str
11+
export GreedyMethod, TreeSA, SABipartite, KaHyParBipartite, MergeVectors, MergeGreedy
1112

1213
project_relative_path(xs...) = normpath(joinpath(dirname(dirname(pathof(@__MODULE__))), xs...))
1314

src/networks.jl

Lines changed: 32 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,59 @@ abstract type GraphProblem end
55

66
"""
77
Independence{CT<:EinTypes} <: GraphProblem
8-
Independence(graph; openvertices=(), optmethod=:greedy, kwargs...)
8+
Independence(graph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
99
10-
Independent set problem. `kwargs` is forwarded to `optimize_code`.
10+
Independent set problem. `openvertices` specifies the output tensor.
11+
`optimizer` and `simplifier` are for tensor network optimization, check `optimize_code` for details.
1112
"""
1213
struct Independence{CT<:EinTypes} <: GraphProblem
1314
code::CT
1415
end
1516

16-
function Independence(g::SimpleGraph; openvertices=(), optmethod=:greedy, kwargs...)
17+
function Independence(g::SimpleGraph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
1718
rawcode = EinCode(([(i,) for i in LightGraphs.vertices(g)]..., # labels for vertex tensors
1819
[minmax(e.src,e.dst) for e in LightGraphs.edges(g)]...), openvertices) # labels for edge tensors
19-
code = optimize_code(rawcode, Val(optmethod); kwargs...)
20+
code = _optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier)
2021
Independence(code)
2122
end
2223

2324
"""
2425
MaxCut{CT<:EinTypes} <: GraphProblem
25-
MaxCut(graph; openvertices=(), optmethod=:greedy, kwargs...)
26+
MaxCut(graph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
2627
27-
Max cut problem (or spin glass problem). `kwargs` is forwarded to `optimize_code`.
28+
Max cut problem (or spin glass problem).
29+
`optimizer` and `simplifier` are for tensor network optimization, check `optimize_code` for details.
2830
"""
2931
struct MaxCut{CT<:EinTypes} <: GraphProblem
3032
code::CT
3133
end
32-
function MaxCut(g::SimpleGraph; openvertices=(), optmethod=:greedy, kwargs...)
34+
function MaxCut(g::SimpleGraph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
3335
rawcode = EinCode(([minmax(e.src,e.dst) for e in LightGraphs.edges(g)]...,), openvertices) # labels for edge tensors
34-
MaxCut(optimize_code(rawcode, Val(optmethod); kwargs...))
36+
MaxCut(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier))
3537
end
3638

3739
"""
3840
MaximalIndependence{CT<:EinTypes} <: GraphProblem
39-
MaximalIndependence(graph; openvertices=(), optmethod=:greedy, kwargs...)
41+
MaximalIndependence(graph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
4042
41-
Maximal independent set problem. `kwargs` is forwarded to `optimize_code`.
43+
Maximal independent set problem.
44+
`optimizer` and `simplifier` are for tensor network optimization, check `optimize_code` for details.
4245
"""
4346
struct MaximalIndependence{CT<:EinTypes} <: GraphProblem
4447
code::CT
4548
end
4649

47-
function MaximalIndependence(g::SimpleGraph; openvertices=(), optmethod=:greedy, kwargs...)
50+
function MaximalIndependence(g::SimpleGraph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
4851
rawcode = EinCode(([(LightGraphs.neighbors(g, v)..., v) for v in LightGraphs.vertices(g)]...,), openvertices)
49-
MaximalIndependence(optimize_code(rawcode, Val(optmethod); kwargs...))
52+
MaximalIndependence(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier))
5053
end
5154

5255
"""
5356
Matching{CT<:EinTypes} <: GraphProblem
54-
Matching(graph; openvertices=(), optmethod=:greedy, kwargs...)
57+
Matching(graph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
5558
56-
Vertex matching problem. `kwargs` is forwarded to `optimize_code`.
59+
Vertex matching problem.
60+
`optimizer` and `simplifier` are for tensor network optimization, check `optimize_code` for details.
5761
The matching polynomial adopts the first definition in wiki page: https://en.wikipedia.org/wiki/Matching_polynomial
5862
```math
5963
m_G(x) := \\sum_{k\\geq 0}m_kx^k,
@@ -64,24 +68,25 @@ struct Matching{CT<:EinTypes} <: GraphProblem
6468
code::CT
6569
end
6670

67-
function Matching(g::SimpleGraph; openvertices=(), optmethod=:greedy, kwargs...)
71+
function Matching(g::SimpleGraph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
6872
rawcode = EinCode(([(minmax(e.src,e.dst),) for e in LightGraphs.edges(g)]..., # labels for edge tensors
6973
[([minmax(i,j) for j in neighbors(g, i)]...,) for i in LightGraphs.vertices(g)]...,), openvertices) # labels for vertex tensors
70-
Matching(optimize_code(rawcode, Val(optmethod); kwargs...))
74+
Matching(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier))
7175
end
7276

7377
"""
7478
Coloring{K,CT<:EinTypes} <: GraphProblem
75-
Coloring{K}(graph; openvertices=(), optmethod=:greedy, kwargs...)
79+
Coloring{K}(graph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
7680
77-
K-Coloring problem. `kwargs` is forwarded to `optimize_code`.
81+
K-Coloring problem.
82+
`optimizer` and `simplifier` are for tensor network optimization, check `optimize_code` for details.
7883
"""
7984
struct Coloring{K,CT<:EinTypes} <: GraphProblem
8085
code::CT
8186
end
8287
Coloring{K}(code::ET) where {K,ET<:EinTypes} = Coloring{K,ET}(code)
8388
# same network layout as independent set.
84-
Coloring{K}(g::SimpleGraph; openvertices=(), optmethod=:greedy, kwargs...) where K = Coloring{K}(Independence(g; openvertices=openvertices, optmethod=optmethod, D=K, kwargs...).code)
89+
Coloring{K}(g::SimpleGraph; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing) where K = Coloring{K}(Independence(g; openvertices=openvertices, optimizer=optimizer, simplifier=simplifier).code)
8590

8691
"""
8792
labels(code)
@@ -100,44 +105,6 @@ function labels(code::EinTypes)
100105
return res
101106
end
102107

103-
"""
104-
optimize_code(code; optmethod=:kahypar, sc_target=17, max_group_size=40, nrepeat=10, imbalances=0.0:0.001:0.8, βs=0.01:0.05:10.0, ntrials=50, niters=1000, sc_weight=2.0, rw_weight=1.0)
105-
106-
Optimize the contraction order.
107-
108-
* `optmethod` can be one of
109-
* `:kahypar`, the kahypar + greedy approach, takes kwargs [`sc_target`, `max_group_size`, `imbalances`, `nrepeat`].
110-
Check `optimize_kahypar` method in package `OMEinsumContractionOrders`.
111-
* `:auto`, also the kahypar + greedy approach, but determines `sc_target` automatically. It is slower!
112-
* `:greedy`, the greedy approach. Check `optimize_greedy` in package `OMEinsum`.
113-
* `:tree`, the approach of running simulated annealing on expression tree, takes kwargs [`sc_target`, `sc_weight`, `rw_weight`, `βs`, `ntrials`, `niters`]. Check `optimize_tree` in package `OMEinsumContractionOrders`.
114-
* `:sa`, the simulated annealing approach, takes kwargs [`rw_weight`, `βs`, `ntrials`, `niters`]. Check `optimize_sa` in package `OMEinsumContractionOrders`.
115-
* `:raw`, do nothing and return the raw EinCode.
116-
"""
117-
function optimize_code(@nospecialize(code::EinTypes), ::Val{optmethod}; sc_target=17, max_group_size=40, nrepeat=10, imbalances=0.0:0.001:0.8, initializer=:random, βs=0.01:0.05:10.0, ntrials=50, niters=1000, sc_weight=2.0, rw_weight=1.0, D=2) where optmethod
118-
if optmethod === :raw
119-
return code
120-
end
121-
size_dict = Dict([s=>D for s in labels(code)])
122-
simplifier, code = merge_vectors(code)
123-
optcode = if optmethod === :kahypar
124-
optimize_kahypar(code, size_dict; sc_target=sc_target, max_group_size=max_group_size, imbalances=imbalances, greedy_nrepeat=nrepeat)
125-
elseif optmethod === :sa
126-
optimize_sa(code, size_dict; sc_target=sc_target, max_group_size=max_group_size, βs=βs, ntrials=ntrials, niters=niters, initializer=initializer, greedy_nrepeat=nrepeat)
127-
elseif optmethod === :greedy
128-
optimize_greedy(code, size_dict; nrepeat=nrepeat)
129-
elseif optmethod === :tree
130-
optimize_tree(code, size_dict; sc_target=sc_target, βs=βs, niters=niters, ntrials=ntrials, sc_weight=sc_weight, initializer=initializer, rw_weight=rw_weight)
131-
elseif optmethod === :auto
132-
optimize_kahypar_auto(code, size_dict; max_group_size=max_group_size, effort=500, greedy_nrepeat=nrepeat)
133-
else
134-
ArgumentError("optimizer `$optmethod` not defined.")
135-
end
136-
optcode = embed_simplifier(optcode, simplifier)
137-
@info "time/space complexity is $(OMEinsum.timespace_complexity(optcode, size_dict))"
138-
return optcode
139-
end
140-
141108
OMEinsum.timespace_complexity(gp::GraphProblem) = timespace_complexity(gp.code, uniformsize(gp.code, bondsize(gp)))
142109

143110
for T in [:Independence, :Matching, :MaximalIndependence, :MaxCut]
@@ -146,25 +113,28 @@ end
146113
bondsize(gp::Coloring{K}) where K = K
147114

148115
"""
149-
set_packing(sets; openvertices=(), optmethod=:greedy, kwargs...)
116+
set_packing(sets; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
150117
151118
Set packing is a generalization of independent set problem to hypergraphs.
152119
Calling this function will return you an `Independence` instance.
153120
`sets` are a vector of vectors, each element being a vertex in the independent set problem.
154-
`kwargs` is forwarded to `optimize_code`.
121+
`optimizer` and `simplifier` are for tensor network optimization, check `optimize_code` for details.
155122
156123
### Example
157124
```julia
158125
julia> sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]; # each set is a vertex
159126
160-
julia> gp = set_packing(sets; optmethod=:auto);
127+
julia> gp = set_packing(sets);
161128
162129
julia> res = best_solutions(gp; all=true)[]
163130
(2, {10010, 00110, 01100})ₜ
164131
```
165132
"""
166-
function set_packing(sets; openvertices=(), optmethod=:greedy, kwargs...)
133+
function set_packing(sets; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
167134
n = length(sets)
168135
code = EinCode(([(i,) for i=1:n]..., [(i,j) for i=1:n,j=1:n if j>i && !isempty(sets[i] sets[j])]...), openvertices)
169-
Independence(optimize_code(code, Val(optmethod); kwargs...))
136+
Independence(_optimize_code(code, uniformsize(code, 2), optimizer, simplifier))
170137
end
138+
139+
_optimize_code(code, size_dict, optimizer::Nothing, simplifier) = code
140+
_optimize_code(code, size_dict, optimizer, simplifier) = optimize_code(code, size_dict, optimizer, simplifier)

test/bounding.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ end
2222
y2 = bounding_contract(code, xs, BitArray(ones(Bool,2,2,2)), xs)
2323
@test y1 y2
2424
end
25-
rawcode = Independence(random_regular_graph(10, 3); optmethod=:raw).code
26-
optcode = Independence(random_regular_graph(10, 3); optmethod=:greedy).code
25+
rawcode = Independence(random_regular_graph(10, 3); optimizer=nothing).code
26+
optcode = Independence(random_regular_graph(10, 3); optimizer=GreedyMethod()).code
2727
xs = map(OMEinsum.getixs(rawcode)) do ix
2828
length(ix)==1 ? GraphTensorNetworks.misv(TropicalF64(1.0)) : GraphTensorNetworks.misb(TropicalF64)
2929
end

test/configurations.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ using TropicalNumbers: CountingTropicalF64
2929
end
3030

3131
@testset "enumerating" begin
32-
rawcode = Independence(random_regular_graph(10, 3); optmethod=:raw)
33-
optcode = Independence(optimize_code(rawcode.code, Val(:greedy)))
32+
rawcode = Independence(random_regular_graph(10, 3); optimizer=nothing)
33+
optcode = Independence(optimize_code(rawcode.code, uniformsize(rawcode.code, 2), GreedyMethod()))
3434
for code in [rawcode, optcode]
3535
res0 = max_size(code)
3636
_, res1 = max_size_count(code)
@@ -58,7 +58,7 @@ end
5858

5959
@testset "set packing" begin
6060
sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]] # each set is a vertex
61-
gp = set_packing(sets; optmethod=:auto)
61+
gp = set_packing(sets; optimizer=GreedyMethod())
6262
res = best_solutions(gp; all=true)[]
6363
@test res.n == 2
6464
@test BitVector(Bool[0,0,1,1,0]) res.c.data
@@ -71,7 +71,7 @@ end
7171
for (i,j) in [(1,2),(2,3),(3,4),(4,1),(1,5),(2,4)]
7272
add_edge!(g, i, j)
7373
end
74-
code = MaxCut(g; optmethod=:greedy)
74+
code = MaxCut(g; optimizer=GreedyMethod())
7575
res = best_solutions(code; all=true)[]
7676
@test length(res.c.data) == 2
7777
@test sum(res.c.data[1]) == 5
@@ -82,18 +82,18 @@ end
8282
for (i,j) in [(1,2),(2,3),(3,4),(4,1),(1,5),(2,4)]
8383
add_edge!(g, i, j)
8484
end
85-
code = Coloring{3}(g; optmethod=:greedy)
85+
code = Coloring{3}(g; optimizer=GreedyMethod())
8686
res = solutions(code, CountingTropicalF64; all=true)[]
8787
@test length(res.c.data) == 12
8888
g = smallgraph(:petersen)
89-
code = Coloring{3}(g; optmethod=:greedy)
89+
code = Coloring{3}(g; optimizer=GreedyMethod())
9090
res = solutions(code, CountingTropicalF64; all=true)[]
9191
@test length(res.c.data) == 120
9292
end
9393

9494
@testset "enumerating - matching" begin
9595
g = smallgraph(:petersen)
96-
code = Matching(g; optmethod=:greedy)
96+
code = Matching(g; optimizer=GreedyMethod())
9797
res = solutions(code, CountingTropicalF64; all=true)[]
9898
@test res.n == 5
9999
@test length(res.c.data) == 6

test/graph_polynomials.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ end
4646

4747
@testset "counting maximal IS" begin
4848
g = random_regular_graph(20, 3)
49-
gp = MaximalIndependence(g, optmethod=:kahypar)
49+
gp = MaximalIndependence(g, optimizer=KaHyParBipartite(sc_target=20))
5050
cs = graph_polynomial(gp, Val(:fft); r=1.0)[]
51-
gp = MaximalIndependence(g, optmethod=:sa)
51+
gp = MaximalIndependence(g, optimizer=SABipartite(sc_target=20))
5252
cs2 = graph_polynomial(gp, Val(:polynomial))[]
53-
gp = MaximalIndependence(g, optmethod=:greedy)
53+
gp = MaximalIndependence(g, optimizer=GreedyMethod())
5454
cs3 = graph_polynomial(gp, Val(:finitefield))[]
5555
cg = complement(g)
5656
cliques = maximal_cliques(cg)

test/interfaces.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ using LightGraphs, Test
33

44
@testset "independence problem" begin
55
g = LightGraphs.smallgraph("petersen")
6-
gp = Independence(g; optmethod=:greedy)
6+
gp = Independence(g; optimizer=GreedyMethod())
77
res1 = solve(gp, "size max")[]
88
res2 = solve(gp, "counting sum")[]
99
res3 = solve(gp, "counting max")[]

0 commit comments

Comments
 (0)