Skip to content

Commit 9d6098f

Browse files
authored
Redo weighted map (#30)
* update * save * save * save * redo trace center * update docs
1 parent e7cba47 commit 9d6098f

File tree

12 files changed

+301
-139
lines changed

12 files changed

+301
-139
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
name = "UnitDiskMapping"
22
uuid = "1b61a8d9-79ed-4491-8266-ef37f39e1727"
33
authors = ["QuEra Computing Inc."]
4-
version = "0.1.0"
4+
version = "0.1.1"
55

66
[deps]
77
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
88

99
[compat]
10-
Graphs = "1.4"
10+
Graphs = "1.6"
1111
julia = "1"
1212

1313
[extras]

README.md

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,16 @@ The generic tensor network approach for solving MIS works best for graphs with s
8686
```julia
8787
julia> using GraphTensorNetworks
8888

89-
julia> gp = Independence(SimpleGraph(res.grid_graph); optimizer=TreeSA(ntrials=1, niters=10), simplifier=MergeGreedy());
89+
julia> gp = IndependentSet(SimpleGraph(res.grid_graph); optimizer=TreeSA(ntrials=1, niters=10), simplifier=MergeGreedy());
9090

91-
julia> misconfig = solve(gp, "config max")[].c;
91+
julia> misconfig = solve(gp, SingleConfigMax())[].c.data
92+
10110001000110000111000001010101011000001111000001101010101010000101110100000010010101010101010001000000100111010000001001101000101010001110010001000101110100111010100010110100100110101010110100011100101010101010100011
9293

9394
# create a grid mask as the solution, where occupied locations are marked as value 1.
9495
julia> c = zeros(Int, size(res.grid_graph.content));
9596

9697
julia> for (i, loc) in enumerate(findall(!isempty, res.grid_graph.content))
97-
c[loc] = misconfig.data[i]
98+
c[loc] = misconfig[i]
9899
end
99100

100101
julia> print_config(res, c)
@@ -131,7 +132,7 @@ julia> print_config(res, c)
131132

132133
#### Step 3: solve the MIS solution back an MIS of the source graph
133134
```julia
134-
julia> original_configs = map_configs_back(res, [c])
135+
julia> original_configs = map_configs_back(res, [misconfig])
135136
1-element Vector{Vector{Int64}}:
136137
[1, 0, 0, 1, 0, 0, 1, 1, 0, 0]
137138

@@ -150,31 +151,74 @@ julia> w_res = map_graph(Weighted(), g, vertex_order=Branching());
150151
julia> println(w_res.grid_graph)
151152
152153
153-
154-
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
155-
156-
157-
158-
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●● ●
159-
● ● ● ● ● ●
160-
161-
162-
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
163-
● ● ● ● ● ●
164-
165-
166-
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
167-
● ● ● ● ● ●
168-
169-
170-
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
171-
● ● ● ● ● ● ● ● ●
172-
173-
174-
● ● ● ● ● ● ● ● ●
175-
154+
155+
● ● ● ● ● ● ● ● ●
156+
157+
158+
159+
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
160+
● ● ●
161+
162+
163+
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
164+
● ● ● ● ● ● ● ● ●
165+
166+
167+
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
168+
● ● ● ● ● ●
169+
170+
171+
● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
172+
● ● ● ● ● ●
173+
174+
175+
● ● ● ● ● ● ● ● ● ● ● ○
176+
176177
177178
178179
179-
180+
181+
```
182+
183+
Here, `` is a vertex having weight 3, `` is a vertex having weight 2 and `` is a vertex having weight 1.
184+
One can add some weights in range 0~1 by typing
185+
186+
```julia
187+
julia> source_weights = 0.05:0.1:0.95
188+
0.05:0.1:0.95
189+
190+
julia> mapped_weights = map_weights(w_res, source_weights)
191+
218-element Vector{Float64}:
192+
1.85
193+
2.0
194+
1.95
195+
2.0
196+
2.0
197+
2.0
198+
1.0
199+
200+
2.0
201+
2.0
202+
2.0
203+
2.0
204+
1.0
205+
2.0
206+
```
207+
208+
One can easily check the correctness
209+
```julia
210+
julia> wr1 = solve(IndependentSet(g; weights=collect(source_weights)), SingleConfigMax())[]
211+
(2.2, ConfigSampler{10, 1, 1}(0100100110))ₜ
212+
213+
julia> wr2 = solve(IndependentSet(SimpleGraph(w_res.grid_graph); weights=mapped_weights), SingleConfigMax())[].c.data
214+
(178.2, ConfigSampler{218, 1, 4}(10001110100000111000110101000100010110010010110010010001010101100010011001010000101000100010101010010100001001101100000110010001010101010001100000110110010010111011000001111000010110101011010010101010101010101010100101))ₜ
215+
216+
julia> wr2.n - w_res.mis_overhead
217+
2.1999999999999886
218+
219+
julia> map_configs_back(w_res, [wr2])
220+
1-element Vector{Vector{Int64}}:
221+
[0, 1, 0, 0, 1, 0, 0, 1, 1, 0]
180222
```
223+
224+
Yep! We get exactly the same ground state.

examples/petersen.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ G, tape = apply_gadgets!(copy(ug))
1515
locs = coordinates(G)
1616

1717
using GraphTensorNetworks
18-
s1 = solve(Independence(g), "size max")
19-
s2 = solve(Independence(SimpleGraph(G)), "size max")
18+
s1 = solve(IndependentSet(g), SizeMax())
19+
s2 = solve(IndependentSet(SimpleGraph(G)), SizeMax())
2020
mis_overhead0 = 2 * nv(g) * (nv(g)-1) + nv(g)
2121
mis_overhead1 = sum(x->mis_overhead(x[1]), tape)
2222
s1[].n == s2[].n - mis_overhead0 - mis_overhead1

project/createmap.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ using UnitDiskMapping, GraphTensorNetworks, Graphs
22

33
function mapped_entry_to_compact(s::Pattern)
44
locs, g, pins = mapped_graph(s)
5-
a = solve(Independence(g; openvertices=pins), "size max")
5+
a = solve(IndependentSet(g; openvertices=pins), SizeMax())
66
b = mis_compactify!(copy(a))
77
n = length(a)
88
d = Dict{Int,Int}() # the mapping from bad to good
@@ -27,7 +27,7 @@ end
2727
# from mapped graph bounary configuration to compact bounary configuration
2828
function source_entry_to_configs(s::Pattern)
2929
locs, g, pins = source_graph(s)
30-
a = solve(Independence(g, openvertices=pins), "configs max")
30+
a = solve(IndependentSet(g, openvertices=pins), ConfigsMax())
3131
d = Dict{Int,Vector{BitVector}}() # the mapping from bad to good
3232
for i=1:length(a)
3333
d[i-1] = [BitVector(s) for s in a[i].c.data]
@@ -38,8 +38,8 @@ end
3838
function compute_mis_overhead(s)
3939
locs1, g1, pins1 = source_graph(s)
4040
locs2, g2, pins2 = mapped_graph(s)
41-
m1 = mis_compactify!(solve(Independence(g1, openvertices=pins1), "size max"))
42-
m2 = mis_compactify!(solve(Independence(g2, openvertices=pins2), "size max"))
41+
m1 = mis_compactify!(solve(IndependentSet(g1, openvertices=pins1), SizeMax()))
42+
m2 = mis_compactify!(solve(IndependentSet(g2, openvertices=pins2), SizeMax()))
4343
@assert nv(g1) == length(locs1) && nv(g2) == length(locs2)
4444
sig, diff = UnitDiskMapping.is_diff_by_const(GraphTensorNetworks.content.(m1), GraphTensorNetworks.content.(m2))
4545
@assert sig

project/map_config_back.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ using GraphTensorNetworks, Graphs
44

55
function all_configurations(p::Pattern)
66
mlocs, mg, mpins = mapped_graph(p)
7-
gp = Independence(mg, openvertices=mpins)
8-
res = solve(gp, "configs max")
7+
gp = IndependentSet(mg, openvertices=mpins)
8+
res = solve(gp, ConfigsMax())
99
configs = []
1010
for element in res
1111
for bs in element.c.data

src/mapping.jl

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -254,30 +254,42 @@ function center_location(tc::CopyLine; padding::Int)
254254
end
255255
function copyline_locations(tc::CopyLine; padding::Int)
256256
s = 4
257+
nline = 0
257258
I, J = center_location(tc; padding=padding)
258259
locations = _weight_type(tc)[]
259260
# grow up
260-
for i=I+s*(tc.vstart-tc.hslot)+1:I # even number of nodes up
261-
push!(locations, _weight2(tc, i, J))
261+
start = I+s*(tc.vstart-tc.hslot)+1
262+
if tc.vstart < tc.hslot
263+
nline += 1
264+
end
265+
for i=I:-1:start # even number of nodes up
266+
push!(locations, _weighted(tc, i, J, 1+(i!=start))) # half weight on last node
262267
end
263268
# grow down
264-
for i=I:I+s*(tc.vstop-tc.hslot)-1 # even number of nodes down
269+
stop = I+s*(tc.vstop-tc.hslot)-1
270+
if tc.vstop > tc.hslot
271+
nline += 1
272+
end
273+
for i=I:stop # even number of nodes down
265274
if i == I
266-
push!(locations, _weight2(tc, i+1, J+1))
275+
push!(locations, _weighted(tc, i+1, J+1, 2))
267276
else
268-
push!(locations, _weight2(tc, i, J))
277+
push!(locations, _weighted(tc, i, J, 1+(i!=stop)))
269278
end
270279
end
271280
# grow right
272-
for j=J+2:J+s*(tc.hstop-tc.vslot)-1 # even number of nodes right
273-
push!(locations, _weight2(tc, I, j))
281+
stop = J+s*(tc.hstop-tc.vslot)-1
282+
if tc.hstop > tc.vslot
283+
nline += 1
274284
end
275-
push!(locations, _weight1(tc, I, J+1)) # center node
285+
for j=J+2:stop # even number of nodes right
286+
push!(locations, _weighted(tc, I, j, 1 + (j!=stop))) # half weight on last node
287+
end
288+
push!(locations, _weighted(tc, I, J+1, nline)) # center node
276289
return locations
277290
end
278291
_weight_type(::CopyLine{UnWeighted}) = SimpleNode{Int}
279-
_weight2(::CopyLine{UnWeighted}, i, j) = SimpleNode(i, j)
280-
_weight1(::CopyLine{UnWeighted}, i, j) = SimpleNode(i, j)
292+
_weighted(::CopyLine{UnWeighted}, i, j, w) = SimpleNode(i, j)
281293

282294
export ugrid
283295
function ugrid(mode, g::SimpleGraph, vertex_order::AbstractVector{Int}; padding=2, nrow=nv(g))
@@ -342,9 +354,20 @@ end
342354
export mis_overhead_copylines
343355
function mis_overhead_copylines(ug::UGrid{WC,W}) where {WC,W}
344356
sum(ug.lines) do line
345-
locs = copyline_locations(line; padding=ug.padding)
357+
mis_overhead_copyline(line)
358+
end
359+
end
360+
361+
function mis_overhead_copyline(line::CopyLine{W}) where {W}
362+
if W === Weighted
363+
s = 4
364+
return (line.hslot - line.vstart) * s +
365+
(line.vstop - line.hslot) * s +
366+
max((line.hstop - line.vslot) * s - 2, 0)
367+
else
368+
locs = copyline_locations(line; padding=2)
346369
@assert length(locs) % 2 == 1
347-
W === Weighted ? length(locs)-1 : length(locs) ÷ 2
370+
return length(locs) ÷ 2
348371
end
349372
end
350373

@@ -360,20 +383,23 @@ end
360383
"""
361384
map_graph([mode=Weighted(),] g::SimpleGraph; vertex_order=Branching(), ruleset=[...])
362385
363-
Map a graph to a unit disk grid graph that being "equivalent" to the original graph.
386+
Map a graph to a unit disk grid graph that being "equivalent" to the original graph, and return a `MappingResult` instance.
364387
Here "equivalent" means a maximum independent set in the grid graph can be mapped back to
365388
a maximum independent set of the original graph in polynomial time.
366389
390+
Positional Arguments
391+
-------------------------------------
392+
* `mode` is optional, it can be `Weighted()` (default) or `UnWeighted()`.
393+
* `g` is a graph instance, check the documentation of [`Graphs`](https://juliagraphs.org/Graphs.jl/dev/) for details.
367394
368-
* `mode` is optional, it can be `Weighted()` (default) or `UnWeighted`.
395+
Keyword Arguments
396+
-------------------------------------
369397
* `vertex_order` specifies the order finding algorithm for vertices.
370398
Different vertex orders have different path width, i.e. different depth of mapped grid graph.
371399
It can be a vector or one of the following inputs
372400
* `Greedy()` fast but not optimal.
373401
* `Branching()` slow but optimal.
374402
* `ruleset` specifies and extra set of optimization patterns (not the crossing patterns).
375-
376-
Returns a `MappingResult` instance.
377403
"""
378404
function map_graph(g::SimpleGraph; vertex_order=Branching(), ruleset=default_simplifier_ruleset(UnWeighted()))
379405
map_graph(UnWeighted(), g; ruleset=ruleset, vertex_order=vertex_order)
@@ -388,7 +414,23 @@ function map_graph(mode, g::SimpleGraph; vertex_order=Branching(), ruleset=defau
388414
return MappingResult(ug, vcat(tape, tape2) , mis_overhead0 + mis_overhead1 + mis_overhead2)
389415
end
390416

391-
map_configs_back(r::MappingResult{<:Cell}, configs::AbstractVector) = unapply_gadgets!(copy(r.grid_graph), r.mapping_history, copy.(configs))[2]
417+
"""
418+
map_configs_back(res::MappingResult, configs::AbstractVector)
419+
420+
Map MIS solutions for the mapped graph to a solution for the source graph.
421+
"""
422+
function map_configs_back(res::MappingResult, configs::AbstractVector)
423+
cs = map(configs) do cfg
424+
c = zeros(Int, size(res.grid_graph.content))
425+
for (i, loc) in enumerate(findall(!isempty, res.grid_graph.content))
426+
c[loc] = cfg[i]
427+
end
428+
c
429+
end
430+
return _map_configs_back(res, cs)
431+
end
432+
_map_configs_back(r::MappingResult{<:Cell}, configs::AbstractVector{<:AbstractMatrix}) = unapply_gadgets!(copy(r.grid_graph), r.mapping_history, copy.(configs))[2]
433+
392434
default_simplifier_ruleset(::UnWeighted) = vcat([rotated_and_reflected(rule) for rule in simplifier_ruleset]...)
393435
default_simplifier_ruleset(::Weighted) = weighted.(default_simplifier_ruleset(UnWeighted()))
394436

0 commit comments

Comments
 (0)