Skip to content

Commit dd62374

Browse files
committed
update docs
1 parent bfdbca9 commit dd62374

File tree

12 files changed

+263
-41
lines changed

12 files changed

+263
-41
lines changed

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
1818
Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
1919
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
2020
SIMDTypes = "94e857df-77ce-4151-89e5-788b33177be4"
21+
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
2122
TropicalNumbers = "b3a74e9c-7526-4576-a4eb-79c0d4c32334"
2223
Viznet = "52a3aca4-6234-47fd-b74a-806bdf78ede9"
2324

2425
[compat]
2526
CUDA = "3.5"
27+
Cairo = "1.0"
2628
Compose = "0.9"
2729
FFTW = "1.4"
2830
Graphs = "1.4"
@@ -35,7 +37,7 @@ Requires = "1"
3537
SIMDTypes = "0.1"
3638
TropicalNumbers = "0.4, 0.5"
3739
Viznet = "0.3"
38-
Cairo = "1.0"
40+
StatsBase = "0.33"
3941
julia = "1"
4042

4143
[extras]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ time/space complexity is (7.965784284662086, 4.0)
5858

5959
Here, the `problem` is a `Independence` instance, it contains the tensor network contraction tree for the target graph.
6060
Here, we choose the `TreeSA` optimizer to optimize the tensor network contraciton tree, it is a local search based algorithm, check [arXiv: 2108.05665](https://arxiv.org/abs/2108.05665). You will see some warnings, do not panic, this is because we set `sc_target` (target space complex) to 1 for agressive optimization of space complexity. Type `?TreeSA` in a Julia REPL for more information about the key word arguments.
61-
Similarly, one can select tensor network structures for solving other problems like `MaximalIndependence`, `MaxCut`, `Matching`, `Coloring{K}` and `set_packing`.
61+
Similarly, one can select tensor network structures for solving other problems like `MaximalIndependence`, `MaxCut`, `Matching`, `Coloring{K}`, `PaintShop` and `set_packing`.
6262

6363
#### 1. find MIS size, count MISs and count ISs
6464
```julia

docs/make.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Pkg
22
using GraphTensorNetworks
3-
using GraphTensorNetworks: TropicalNumbers, Polynomials, Mods
3+
using GraphTensorNetworks: TropicalNumbers, Polynomials, Mods, OMEinsum, OMEinsumContractionOrders
44
using Documenter
55
using DocThemeIndigo
66
using Literate
@@ -19,7 +19,7 @@ indigo = DocThemeIndigo.install(GraphTensorNetworks)
1919
DocMeta.setdocmeta!(GraphTensorNetworks, :DocTestSetup, :(using GraphTensorNetworks); recursive=true)
2020

2121
makedocs(;
22-
modules=[GraphTensorNetworks, TropicalNumbers, Polynomials, Mods],
22+
modules=[GraphTensorNetworks, TropicalNumbers, Polynomials, Mods, OMEinsum, OMEinsumContractionOrders],
2323
authors="Jinguo Liu",
2424
repo="https://github.com/Happy-Diode/GraphTensorNetworks.jl/blob/{commit}{path}#{line}",
2525
sitename="GraphTensorNetworks.jl",

docs/src/ref.md

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,86 @@
1-
```@meta
2-
DocTestSetup = quote
3-
import TropicalNumbers, Mods, Polynomials
4-
end
5-
```
61
# References
2+
## Graph problems
3+
```@docs
4+
solve
5+
Independence
6+
MaximalIndependence
7+
Matching
8+
Coloring
9+
MaxCut
10+
PaintShop
11+
```
712

8-
```@autodocs
9-
Modules = [GraphTensorNetworks]
13+
```@docs
14+
set_packing
1015
```
1116

17+
## Properties
1218
```@docs
13-
TropicalNumbers.Tropical
19+
SizeMax
20+
CountingAll
21+
CountingMax
22+
GraphPolynomial
23+
SingleConfigMax
24+
ConfigsAll
25+
ConfigsMax
1426
```
1527

28+
## Element Algebras
1629
```@docs
30+
TropicalNumbers.Tropical
1731
TropicalNumbers.CountingTropical
32+
Mods.Mod
33+
Polynomials.Polynomial
34+
TruncatedPoly
35+
Max2Poly
36+
ConfigEnumerator
37+
ConfigSampler
1838
```
1939

2040
```@docs
21-
Mods.Mod
41+
StaticBitVector
42+
StaticElementVector
43+
save_configs
44+
load_configs
45+
@bv_str
46+
onehotv
47+
is_commutative_semiring
2248
```
2349

50+
## Tensor Network
2451
```@docs
25-
Polynomials.Polynomial
52+
optimize_code
53+
timespace_complexity
54+
@ein_str
55+
GreedyMethod
56+
TreeSA
57+
SABipartite
58+
KaHyParBipartite
59+
MergeVectors
60+
MergeGreedy
61+
```
62+
63+
## Others
64+
#### Graph
65+
```@docs
66+
is_independent_set
67+
mis_compactify!
68+
show_graph
69+
70+
diagonal_coupled_graph
71+
square_lattice_graph
72+
unitdisk_graph
73+
```
74+
75+
One can also use `random_regular_graph` and `smallgraph` in [Graphs](https://github.com/JuliaGraphs/Graphs.jl) to build special graphs.
76+
77+
#### Lower level APIs
78+
```@docs
79+
best_solutions
80+
best2_solutions
81+
solutions
82+
all_solutions
83+
graph_polynomial
84+
max_size
85+
max_size_count
2686
```

examples/IndependentSet/main.jl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# # Independent set problem
22

3-
# ## Problem definition
3+
# ## Introduction
4+
using GraphTensorNetworks, Graphs
45

56
# Please check the docstring of [`Independence`](@ref) for the definition of independence problem.
6-
# In the following, we are going to defined an independent set problem for the Petersen graph.
7+
@doc Independence
78

8-
using GraphTensorNetworks, Graphs
9+
# In the following, we are going to defined an independent set problem for the Petersen graph.
910

1011
graph = Graphs.smallgraph(:petersen)
1112

@@ -18,13 +19,13 @@ show_graph(graph; locs=locations)
1819

1920
# Let us contruct the problem instance with optimized tensor network contraction order as bellow.
2021
problem = Independence(graph; optimizer=TreeSA(sc_weight=1.0, ntrials=10,
21-
βs=0.01:0.1:15.0, niters=20, rw_weight=0.2));
22+
βs=0.01:0.1:15.0, niters=20, rw_weight=0.2),
23+
simplifier=MergeGreedy());
2224

2325

2426
# ## Solving properties
2527

26-
# ### The decision problem
27-
# ##### maximum independent set size ``\alpha(G)``
28+
# ### Maximum independent set size ``\alpha(G)``
2829
maximum_independent_set_size = solve(problem, SizeMax())
2930

3031
# ### Counting properties
@@ -34,12 +35,18 @@ count_all_independent_sets = solve(problem, CountingAll())
3435
# ##### counting independent sets with sizes ``\alpha(G)`` and ``\alpha(G)-1``
3536
count_max2_independent_sets = solve(problem, CountingMax(2))
3637

37-
# ##### computing the independence polynomial
38+
# ##### independence polynomial
3839
# For the definition of independence polynomial, please check the docstring of [`Independence`](@ref) or this [wiki page](https://mathworld.wolfram.com/IndependencePolynomial.html).
40+
# There are 3 methods to compute a graph polynomial, `:finitefield`, `:fft` and `:polynomial`.
41+
# These methods are introduced in the docstring of [`GraphPolynomial`](@ref).
3942
independence_polynomial = solve(problem, GraphPolynomial(; method=:finitefield))
4043

4144
# ### Configuration properties
4245
# ##### finding one maximum independent set (MIS)
46+
# There are two approaches to find one of the best solution.
47+
# The unbounded (default) version uses [`ConfigSampler`](@ref) to sample one of the best solutions directly.
48+
# The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients.
49+
# It requires caching intermediate states, but is often faster on CPU because it can use [`TropicalGEMM`](https://github.com/TensorBFS/TropicalGEMM.jl).
4350
max_config = solve(problem, SingleConfigMax(; bounded=false))[]
4451

4552
# The return value contains a bit string, and one should read this bit string from left to right.
@@ -49,7 +56,9 @@ show_graph(graph; locs=locations, colors=[iszero(max_config.c.data[i]) ? "white"
4956
for i=1:nv(graph)])
5057

5158
# ##### enumeration of all MISs
52-
all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]
59+
# There are two approaches to enumerate all best-K solutions.
60+
# The bounded (default) version is always prefered because it can significantly use the memory usage.
61+
all_max_configs = solve(problem, ConfigsMax(1; bounded=true))[]
5362

5463
using Compose
5564

src/GraphTensorNetworks.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export bestk_solutions
2323
export contractx, contractf, graph_polynomial, max_size, max_size_count
2424

2525
# Graphs
26-
export random_regular_graph, diagonal_coupled_graph, isindependentset
26+
export random_regular_graph, diagonal_coupled_graph, is_independent_set
2727
export square_lattice_graph, unitdisk_graph
2828

2929
# Tensor Networks (Graph problems)
@@ -33,7 +33,6 @@ export Independence, MaximalIndependence, Matching, Coloring, optimize_code, set
3333
export solve, SizeMax, CountingAll, CountingMax, GraphPolynomial, SingleConfigMax, ConfigsAll, ConfigsMax
3434

3535
# Utilities
36-
export is_independent_set
3736
export mis_compactify!
3837
export save_configs, load_configs
3938

src/arithematics.jl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@ Base.abs(x::Mod) = x
88
Base.isless(x::Mod{N}, y::Mod{N}) where N = mod(x.val, N) < mod(y.val, N)
99

1010

11-
# this function is used for testing
11+
"""
12+
is_commutative_semiring(a::T, b::T, c::T) where T
13+
14+
Check if elements `a`, `b` and `c` satisfied the commutative semiring requirements.
15+
```math
16+
\\begin{align*}
17+
(a \\oplus b) \\oplus c = a \\oplus (b \\oplus c) & \\hspace{5em}\\triangleright\\text{commutative monoid \$\\oplus\$ with identity \$\\mathbb{0}\$}\\\\
18+
a \\oplus \\mathbb{0} = \\mathbb{0} \\oplus a = a &\\\\
19+
a \\oplus b = b \\oplus a &\\\\
20+
&\\\\
21+
(a \\odot b) \\odot c = a \\odot (b \\odot c) & \\hspace{5em}\\triangleright \\text{commutative monoid \$\\odot\$ with identity \$\\mathbb{1}\$}\\\\
22+
a \\odot \\mathbb{1} = \\mathbb{1} \\odot a = a &\\\\
23+
a \\odot b = b \\odot a &\\\\
24+
&\\\\
25+
a \\odot (b\\oplus c) = a\\odot b \\oplus a\\odot c & \\hspace{5em}\\triangleright \\text{left and right distributive}\\\\
26+
(a\\oplus b) \\odot c = a\\odot c \\oplus b\\odot c &\\\\
27+
&\\\\
28+
a \\odot \\mathbb{0} = \\mathbb{0} \\odot a = \\mathbb{0}
29+
\\end{align*}
30+
```
31+
"""
1232
function is_commutative_semiring(a::T, b::T, c::T) where T
1333
# +
1434
if (a + b) + c != a + (b + c)
@@ -70,6 +90,10 @@ struct TruncatedPoly{K,T,TO} <: Number
7090
coeffs::NTuple{K,T}
7191
maxorder::TO
7292
end
93+
94+
"""
95+
Max2Poly{T,TO} = TruncatedPoly{2,T,TO}
96+
"""
7397
const Max2Poly{T,TO} = TruncatedPoly{2,T,TO}
7498
Max2Poly(a, b, maxorder) = TruncatedPoly((a, b), maxorder)
7599
Max2Poly{T,TO}(a, b, maxorder) where {T,TO} = TruncatedPoly{2,T,TO}((a, b), maxorder)

src/bitvector.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,22 @@ Base.:(&)(x::StaticElementVector{N,S,C}, y::StaticElementVector{N,S,C}) where {N
5454
# difference of two element sets
5555
Base.:()(x::StaticElementVector{N,S,C}, y::StaticElementVector{N,S,C}) where {N,S,C} = StaticElementVector{N,S,C}(x.data .⊻ y.data)
5656

57+
"""
58+
onehotv(::Type{<:StaticElementVector}, i, v)
59+
onehotv(::Type{<:StaticBitVector, i)
60+
61+
Returns a static element vector, with the value at location `i` being `v` (1 if not specified).
62+
"""
5763
function onehotv(::Type{StaticElementVector{N,S,C}}, i, v) where {N,S,C}
5864
x = zeros(Int,N)
5965
x[i] = v
6066
return convert(StaticElementVector{N,S,C}, x)
6167
end
6268

6369
##### BitVectors
70+
"""
71+
StaticBitVector{N,C} = StaticElementVector{N,1,C}
72+
"""
6473
const StaticBitVector{N,C} = StaticElementVector{N,1,C}
6574
@inline function Base.getindex(x::StaticBitVector{N,C}, i::Integer) where {N,C}
6675
@boundscheck (i <= N || throw(BoundsError(x, i))) # NOTE: still checks bounds in global scope, why?
@@ -86,6 +95,7 @@ staticfalses(::Type{StaticBitVector{N,C}}) where {N,C} = zero(StaticBitVector{N,
8695
@generated function statictrues(::Type{StaticBitVector{N,C}}) where {N,C}
8796
Expr(:call, :(StaticBitVector{$N,$C}), Expr(:tuple, fill(typemax(UInt64), C)...))
8897
end
98+
8999
onehotv(::Type{StaticBitVector{N,C}}, i, v) where {N,C} = v > 0 ? onehotv(StaticBitVector{N,C}, i) : zero(StaticBitVector{N,C})
90100
function onehotv(::Type{StaticBitVector{N,C}}, i) where {N,C}
91101
x = falses(N)

src/graphs.jl

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1-
using Graphs, OMEinsumContractionOrders
1+
using Graphs, OMEinsumContractionOrders, StatsBase
22

3-
isindependentset(g, v) = !any(e->v[e.src] == 1 && v[e.dst] == 1, edges(g))
3+
"""
4+
is_independent_set(g::SimpleGraph, vertices)
45
6+
Return true if `vertices` is an independent set of graph `g`.
7+
"""
8+
is_independent_set(g::SimpleGraph, v) = !any(e->v[e.src] == 1 && v[e.dst] == 1, edges(g))
9+
10+
"""
11+
square_lattice_graph(mask::AbstractMatrix{Bool})
12+
13+
Create a masked square lattice graph.
14+
"""
515
function square_lattice_graph(mask::AbstractMatrix{Bool})
616
locs = [(i, j) for i=1:size(mask, 1), j=1:size(mask, 2) if mask[i,j]]
717
unitdisk_graph(locs, 1.1)
818
end
919

20+
"""
21+
random_diagonal_coupled_graph(m::Int, n::Int, ρ::Real)
22+
23+
Create a random masked diagonal coupled square lattice graph, with number of vertices fixed to ``\\lfloor mn\\rho \\rceil``.
24+
"""
1025
function random_diagonal_coupled_graph(m::Int, n::Int, ρ::Real)
11-
diagonal_coupled_graph(rand(m, n) .< ρ)
26+
@assert ρ >=0 && ρ <= 1
27+
diagonal_coupled_graph(generate_mask(m, n, round(Int,m*n*ρ)))
1228
end
29+
function generate_mask(Nx::Int, Ny::Int, natoms::Int)
30+
mask = zeros(Bool, Nx, Ny)
31+
mask[sample(1:Nx*Ny, natoms; replace=false)] .= true
32+
return mask
33+
end
34+
35+
"""
36+
diagonal_coupled_graph(mask::AbstractMatrix{Bool})
1337
38+
Create a masked diagonal coupled square lattice graph from a specified `mask`.
39+
"""
1440
function diagonal_coupled_graph(mask::AbstractMatrix{Bool})
1541
locs = [(i, j) for i=1:size(mask, 1), j=1:size(mask, 2) if mask[i,j]]
1642
unitdisk_graph(locs, 1.5)
1743
end
1844

45+
"""
46+
unitdisk_graph(locs::AbstractVector, unit::Real)
47+
48+
Create a unit disk graph with locations specified by `locs` and unit distance `unit`.
49+
"""
1950
function unitdisk_graph(locs::AbstractVector, unit::Real)
2051
n = length(locs)
2152
g = SimpleGraph(n)

src/interfaces.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,20 @@ function solve(gp::GraphProblem, property::AbstractProperty; T=Float64, usecuda=
180180
end
181181
_has_weight(gp::GraphProblem) = hasfield(typeof(gp), :weights) && gp.weights isa Vector # ugly but makes life easier
182182

183+
"""
184+
max_size(problem; usecuda=false)
185+
186+
Returns the maximum size of the graph problem.
187+
A shorthand of `solve(problem, SizeMax(); usecuda=false)`.
188+
"""
189+
function max_size end
190+
"""
191+
max_size_count(problem; usecuda=false)
192+
193+
Returns the maximum size and the counting of the graph problem.
194+
It is a shorthand of `solve(problem, CountingMax(); usecuda=false)`.
195+
"""
196+
function max_size_count end
183197
for TP in [:MaximalIndependence, :Independence, :Matching, :MaxCut, :PaintShop]
184198
@eval max_size(m::$TP; usecuda=false) = Int(sum(solve(m, SizeMax(); usecuda=usecuda)).n) # floating point number is faster (BLAS)
185199
@eval max_size_count(m::$TP; usecuda=false) = (r = sum(solve(m, CountingMax(); usecuda=usecuda)); (Int(r.n), Int(r.c)))

0 commit comments

Comments
 (0)