Skip to content

Commit 3bc7565

Browse files
authored
Reduced problems: SpinGlass to MaxCut (#50)
* update * new Laurent polynomial support * fix doc build * fix doc * fix spinglass * export Laurent polynomial * fix tests
1 parent 0ed9c86 commit 3bc7565

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+562
-222
lines changed

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "GenericTensorNetworks"
22
uuid = "3521c873-ad32-4bb4-b63d-f4f178f42b49"
33
authors = ["GiggleLiu <cacate0129@gmail.com> and contributors"]
4-
version = "1.1.0"
4+
version = "1.2.0"
55

66
[deps]
77
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The *solution space properties* include
1212
* The enumeration of solutions at certain sizes.
1313
* The direct sampling of solutions at certain sizes.
1414

15-
The solvable problems include [Independent set problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/IndependentSet/), [Maximal independent set problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/MaximalIS/), [Spin-glass problem (Cutting problem)](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/SpinGlass/), [Vertex matching problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Matching/), [Binary paint shop problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/PaintShop/), [Coloring problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Coloring/), [Dominating set problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/DominatingSet/), [Set packing problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/SetPacking/), [Satisfiability problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Satisfiability/) and [Set covering problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/SetCovering/).
15+
The solvable problems include [Independent set problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/IndependentSet/), [Maximal independent set problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/MaximalIS/), [Spin-glass problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/SpinGlass/), [Cutting problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/MaxCut/), [Vertex matching problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Matching/), [Binary paint shop problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/PaintShop/), [Coloring problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Coloring/), [Dominating set problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/DominatingSet/), [Set packing problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/SetPacking/), [Satisfiability problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Satisfiability/) and [Set covering problem](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/SetCovering/).
1616

1717
## Installation
1818
<p>

docs/make.jl

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ makedocs(;
4949
"Independent set problem" => "generated/IndependentSet.md",
5050
"Maximal independent set problem" => "generated/MaximalIS.md",
5151
"Spin glass problem" => "generated/SpinGlass.md",
52+
"Cutting problem" => "generated/MaxCut.md",
5253
"Vertex matching problem" => "generated/Matching.md",
5354
"Binary paint shop problem" => "generated/PaintShop.md",
5455
"Coloring problem" => "generated/Coloring.md",

docs/src/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The *solution space properties* include
1111
* The enumeration of solutions at certain sizes.
1212
* The direct sampling of solutions at certain sizes.
1313

14-
The solvable problems include [Independent set problem](@ref), [Maximal independent set problem](@ref), [Spin-glass problem (Cutting problem)](@ref), [Vertex matching problem](@ref), [Binary paint shop problem](@ref), [Coloring problem](@ref), [Dominating set problem](@ref), [Satisfiability problem](@ref), [Set packing problem](@ref) and [Set covering problem](@ref).
14+
The solvable problems include [Independent set problem](@ref), [Maximal independent set problem](@ref), [Spin-glass problem](@ref), [Cutting problem](@ref), [Vertex matching problem](@ref), [Binary paint shop problem](@ref), [Coloring problem](@ref), [Dominating set problem](@ref), [Satisfiability problem](@ref), [Set packing problem](@ref) and [Set covering problem](@ref).
1515

1616
## Background knowledge
1717

docs/src/performancetips.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ Slicing technique has been used for graphs with space complexity greater than ``
193193
While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size.
194194
Among these benchmarks, computational tasks with data types real numbers, complex numbers, or [`Tropical`](@ref) numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category.
195195
Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough.
196-
These data types do not include those defined in [`Polynomial`](@ref), [`ConfigEnumerator`](@ref), [`ExtendedTropical`](@ref) and [`SumProductTree`](@ref) or a data type containing them as a part.
196+
These data types do not include those defined in [`Polynomial`](https://juliamath.github.io/Polynomials.jl/stable/polynomials/polynomial/#Polynomial-2), [`ConfigEnumerator`](@ref), [`ExtendedTropical`](@ref) and [`SumProductTree`](@ref) or a data type containing them as a part.
197197
In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial,
198198
but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU.
199199
In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only ``\sim150`` on a device with 32GB main memory.

docs/src/ref.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Matching
99
Coloring
1010
DominatingSet
1111
SpinGlass
12+
MaxCut
1213
PaintShop
1314
Satisfiability
1415
SetCovering
@@ -28,6 +29,7 @@ labels
2829
terms
2930
flavors
3031
get_weights
32+
chweights
3133
nflavor
3234
fixedvertices
3335
```
@@ -93,7 +95,7 @@ SumProductTree
9395
ConfigSampler
9496
```
9597

96-
`GenericTensorNetworks` also exports the [`Polynomial`](https://juliamath.github.io/Polynomials.jl/stable/polynomials/polynomial/#Polynomial-2) type defined in package `Polynomials`.
98+
`GenericTensorNetworks` also exports the [`Polynomial`](https://juliamath.github.io/Polynomials.jl/stable/polynomials/polynomial/#Polynomial-2) and [`LaurentPolynomial`](https://juliamath.github.io/Polynomials.jl/stable/polynomials/polynomial/#Polynomials.LaurentPolynomial) types defined in package `Polynomials`.
9799

98100
```@docs
99101
StaticBitVector

examples/MaxCut.jl

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# # Cutting problem
2+
3+
# !!! note
4+
# It is highly recommended to read the [Independent set problem](@ref) chapter before reading this one.
5+
6+
# ## Problem definition
7+
# In graph theory, a [cut](https://en.wikipedia.org/wiki/Cut_(graph_theory)) is a partition of the vertices of a graph into two disjoint subsets.
8+
# It is closely related to the [Spin-glass problem](@ref) in physics.
9+
# Finding the maximum cut is NP-Hard, where a maximum cut is a cut whose size is at least the size of any other cut,
10+
# where the size of a cut is the number of edges (or the sum of weights on edges) crossing the cut.
11+
12+
using GenericTensorNetworks, Graphs
13+
14+
# In the following, we are going to defined an cutting problem for the Petersen graph.
15+
16+
graph = Graphs.smallgraph(:petersen)
17+
18+
# We can visualize this graph using the following function
19+
rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a
20+
21+
locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...]
22+
23+
show_graph(graph; locs=locations, format=:svg)
24+
25+
# ## Generic tensor network representation
26+
# We define the cutting problem as
27+
problem = MaxCut(graph);
28+
29+
# ### Theory (can skip)
30+
#
31+
# We associated a vertex ``v\in V`` with a boolean degree of freedom ``s_v\in\{0, 1\}``.
32+
# Then the maximum cutting problem can be encoded to tensor networks by mapping an edge ``(i,j)\in E`` to an edge matrix labelled by ``s_i`` and ``s_j``
33+
# ```math
34+
# B(x_i, x_j, w_{ij}) = \left(\begin{matrix}
35+
# 1 & x_{i}^{w_{ij}}\\
36+
# x_{j}^{w_{ij}} & 1
37+
# \end{matrix}\right),
38+
# ```
39+
# where ``w_{ij}`` is a real number associated with edge ``(i, j)`` as the edge weight.
40+
# If and only if the bipartition cuts on edge ``(i, j)``,
41+
# this tensor contributes a factor ``x_{i}^{w_{ij}}`` or ``x_{j}^{w_{ij}}``.
42+
# Similarly, one can assign weights to vertices, which corresponds to the onsite energy terms in the spin glass.
43+
# The vertex tensor is
44+
# ```math
45+
# W(x_i, w_i) = \left(\begin{matrix}
46+
# 1\\
47+
# x_{i}^{w_i}
48+
# \end{matrix}\right),
49+
# ```
50+
# where ``w_i`` is a real number associated with vertex ``i`` as the vertex weight.
51+
52+
# Its contraction time space complexity is ``2^{{\rm tw}(G)}``, where ``{\rm tw(G)}`` is the [tree-width](https://en.wikipedia.org/wiki/Treewidth) of ``G``.
53+
54+
# ## Solving properties
55+
# ### Maximum cut size ``\gamma(G)``
56+
max_cut_size = solve(problem, SizeMax())[]
57+
58+
# ### Counting properties
59+
# ##### graph polynomial
60+
# The graph polynomial defined for the cutting problem is
61+
# ```math
62+
# C(G, x) = \sum_{k=0}^{\gamma(G)} c_k x^k,
63+
# ```
64+
# where ``\gamma(G)`` is the maximum cut size,
65+
# ``c_k/2`` is the number of cuts of size ``k`` in graph ``G=(V,E)``.
66+
# Since the variable ``x`` is defined on edges,
67+
# the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.
68+
max_config = solve(problem, GraphPolynomial())[]
69+
70+
# ### Configuration properties
71+
# ##### finding one max cut solution
72+
max_vertex_config = solve(problem, SingleConfigMax())[].c.data
73+
74+
max_cut_size_verify = cut_size(graph, max_vertex_config)
75+
76+
# You should see a consistent result as above `max_cut_size`.
77+
78+
show_graph(graph; locs=locations, vertex_colors=[
79+
iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
80+
81+
# where red vertices and white vertices are separated by the cut.

examples/SpinGlass.jl

+27-37
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
# # Spin-glass problem (Cutting problem)
1+
# # Spin-glass problem
22

33
# !!! note
44
# It is highly recommended to read the [Independent set problem](@ref) chapter before reading this one.
55

66
# ## Problem definition
77
# Let ``G=(V, E)`` be a graph, the [spin-glass](https://en.wikipedia.org/wiki/Spin_glass) problem in physics is characterized by the following energy function
88
# ```math
9-
# H = - \sum_{ij \in E} J_{ij} s_i s_j + \sum_{i \in V} h_i s_i,
9+
# H = -\sum_{ij \in E} J_{ij} s_i s_j + \sum_{i \in V} h_i s_i,
1010
# ```
11-
# where ``h_i`` is an onsite energy term associated with spin ``s_i \in \{0, 1\}``, and ``J_{ij}`` is the coupling strength between spins ``s_i`` and ``s_j``.
12-
#
13-
# The spin glass problem very close related to the cutting problem in graph theory.
14-
# A [cut](https://en.wikipedia.org/wiki/Cut_(graph_theory)) is a partition of the vertices of a graph into two disjoint subsets.
15-
# Finding the maximum cut (the spin glass maximum energy) is NP-Hard, where a maximum cut is a cut whose size is at least the size of any other cut,
16-
# where the size of a cut is the number of edges (or the sum of weights on edges) crossing the cut.
11+
# where ``h_i`` is an onsite energy term associated with spin ``s_i \in \{-1, 1\}``, and ``J_{ij}`` is the coupling strength between spins ``s_i`` and ``s_j``.
12+
# In the program, we use boolean variable ``n_i = \frac{1-s_i}{2}`` to represent a spin configuration.
1713

1814
using GenericTensorNetworks, Graphs
1915

@@ -29,52 +25,46 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]..
2925
show_graph(graph; locs=locations, format=:svg)
3026

3127
# ## Generic tensor network representation
32-
# We define the spin glass problem as
33-
problem = SpinGlass(graph);
28+
# We define an anti-ferromagnetic spin glass problem as
29+
problem = SpinGlass(graph; J=fill(-1, ne(graph)));
3430

3531
# ### Theory (can skip)
36-
#
37-
# For a vertex ``v\in V``, we define a boolean degree of freedom ``s_v\in\{0, 1\}``.
38-
# Then the spin glass problem can be encoded to tensor networks by mapping an edge ``(i,j)\in E`` to an edge matrix labelled by ``s_is_j``
32+
# The spin glass problem is reduced to the [Cutting problem](@ref) for solving.
33+
# Let ``G=(V,E)`` be a graph, the cutting problem can also be described by the following energy model
3934
# ```math
40-
# B(x_{\langle i, j\rangle}) = \left(\begin{matrix}
41-
# 1 & x_{\langle i, j\rangle}^{w_{\langle i,j \rangle}}\\
42-
# x_{\langle i, j\rangle}^{w_{\langle i,j \rangle}} & 1
43-
# \end{matrix}\right),
35+
# H^c = \sum_{ij \in E} C_{ij} ((1 - n_i) n_j + (1 - n_j) n_i) + \sum_{i \in V} w_i n_i,
4436
# ```
45-
# If and only if the spin configuration is anti-parallel on edge ``(i, j)``,
46-
# this tensor contributes a factor ``x_{\langle i, j\rangle}^{w_{\langle i,j \rangle}}``,
47-
# where ``w_{\langle i,j\rangle}`` is the weight of this edge.
48-
# Similar to other problems, we can define a polynomial about edges variables by setting ``x_{\langle i, j\rangle} = x``,
49-
# where its k-th coefficient is two times the number of configurations with energy (cut size) k.
50-
51-
# Its contraction time space complexity is ``2^{{\rm tw}(G)}``, where ``{\rm tw(G)}`` is the [tree-width](https://en.wikipedia.org/wiki/Treewidth) of ``G``.
37+
# where ``n_i`` is the same as the partition index in the cutting problem,
38+
# ``C_{ij} = 2J_{ij}`` are edge weights and ``w_i = -2h_i`` are vertex weights.
39+
# The total energy is shifted by ``-\sum_{ij\in E}J_{ij} + \sum_{i \in V} h_i``.
5240

5341
# ## Solving properties
54-
# ### Maximum energy ``E^*(G)``
42+
# ### Minimum and maximum energies
43+
# Its ground state energy is -9.
44+
Emin = solve(problem, SizeMin())[]
45+
# While the state correspond to the highest energy has the ferromagnetic order.
5546
Emax = solve(problem, SizeMax())[]
5647

5748
# ### Counting properties
5849
# ##### graph polynomial
59-
# The graph polynomial defined for the spin glass problem is
50+
# The graph polynomial defined for the spin glass problem is a Laurent polynomial
6051
# ```math
61-
# C(G, x) = \sum_{k=0}^{E^*(G)} c_k x^k,
52+
# Z(G, J, h, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,
6253
# ```
63-
# where ``\alpha(G)`` is the maximum independent set size,
64-
# ``c_k/2`` is the number of anti-parallel edges (cuts) of size ``k`` in graph ``G=(V,E)``.
65-
# Since the variable ``x`` is defined on edges,
66-
# the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.
67-
max_config = solve(problem, GraphPolynomial())[]
54+
# where ``E_{\rm min}`` and ``E_{\rm max}`` are minimum and maximum energies,
55+
# ``c_k`` is the number of spin configurations with energy ``k``.
56+
# Let ``x = e^\beta``, it corresponds to the partition function of a spin glass at temperature ``\beta^{-1}``.
57+
partition_function = solve(problem, GraphPolynomial())[]
6858

6959
# ### Configuration properties
70-
# ##### finding one solution with highest energy
71-
max_vertex_config = solve(problem, SingleConfigMax())[].c.data
60+
# ##### finding a ground state
61+
ground_state = solve(problem, SingleConfigMin())[].c.data
7262

73-
Emax_verify = spinglass_energy(graph, max_vertex_config)
63+
Emin_verify = spinglass_energy(graph, ground_state)
7464

75-
# You should see a consistent result as above `Emax`.
65+
# You should see a consistent result as above `Emin`.
7666

7767
show_graph(graph; locs=locations, vertex_colors=[
78-
iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
68+
iszero(ground_state[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
7969

8070
# where a red vertice and a white vertice correspond to a spin having value 1 and 0 respectively.

src/GenericTensorNetworks.jl

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
module GenericTensorNetworks
22

3-
using OMEinsumContractionOrders: SlicedEinsum
3+
using OMEinsumContractionOrders
44
using Core: Argument
55
using TropicalNumbers
66
using OMEinsum
7-
using OMEinsum: timespace_complexity, getixsv
7+
using OMEinsum: timespace_complexity, getixsv, NestedEinsum, getixs, getiy, DynamicEinCode
88
using Graphs, Random
99
using DelimitedFiles, Serialization, Printf
1010
using LuxorGraphPlot
11+
import Polynomials
12+
using Polynomials: Polynomial, LaurentPolynomial, printpoly, fit
13+
using FFTW
14+
using Mods, Primes
15+
using Base.Cartesian
16+
import AbstractTrees: children, printnode, print_tree
17+
import StatsBase
1118

1219
# OMEinsum
1320
export timespace_complexity, timespacereadwrite_complexity, @ein_str, getixsv, getiyv
@@ -19,7 +26,7 @@ export estimate_memory
1926
# Algebras
2027
export StaticBitVector, StaticElementVector, @bv_str
2128
export is_commutative_semiring
22-
export Max2Poly, TruncatedPoly, Polynomial, Tropical, CountingTropical, StaticElementVector, Mod
29+
export Max2Poly, TruncatedPoly, Polynomial, LaurentPolynomial, Tropical, CountingTropical, StaticElementVector, Mod
2330
export ConfigEnumerator, onehotv, ConfigSampler, SumProductTree
2431
export CountingTropicalF64, CountingTropicalF32, TropicalF64, TropicalF32, ExtendedTropical
2532
export generate_samples, OnehotVec
@@ -30,11 +37,12 @@ export square_lattice_graph, unit_disk_graph, random_diagonal_coupled_graph, ran
3037
export line_graph
3138

3239
# Tensor Networks (Graph problems)
33-
export GraphProblem, optimize_code, NoWeight
34-
export flavors, labels, terms, nflavor, get_weights, fixedvertices
40+
export GraphProblem, optimize_code, NoWeight, ZeroWeight
41+
export flavors, labels, terms, nflavor, get_weights, fixedvertices, chweights
3542
export IndependentSet, mis_compactify!, is_independent_set
3643
export MaximalIS, is_maximal_independent_set
37-
export cut_size, spinglass_energy, SpinGlass
44+
export cut_size, MaxCut
45+
export spinglass_energy, SpinGlass
3846
export PaintShop, paintshop_from_pairs, num_paint_shop_color_switch, paint_shop_coloring_from_config
3947
export Coloring, is_vertex_coloring
4048
export Satisfiability, CNF, CNFClause, BoolVar, satisfiable, @bools, , ¬,
@@ -69,8 +77,6 @@ include("deprecate.jl")
6977
include("multiprocessing.jl")
7078
include("visualize.jl")
7179

72-
Base.@deprecate MaxCut(g::SimpleGraph; weights=NoWeight(), openvertices=(), fixedvertices=Dict{Int,Int}(), optimizer=GreedyMethod(), simplifier=nothing) SpinGlass(g; edge_weights=weights, openvertices, fixedvertices, optimizer, simplifier)
73-
7480
using Requires
7581
function __init__()
7682
@require CUDA="052768ef-5323-5732-b1bb-66c8b64840ba" include("cuda.jl")

0 commit comments

Comments
 (0)