/alga

Algebraic graphs

Primary LanguageHaskellMIT LicenseMIT

Algebraic graphs

Linux & OS X status Windows status

A library for algebraic construction and manipulation of graphs in Haskell. See this paper for the motivation behind the library, the underlying theory and implementation details.

The following series of blog posts also describe the ideas behind the library:

You can find more code in this old experimental repo: https://github.com/snowleopard/graph-algebra.

Performance

Some quick benchmarks with Criterion, I'll keep adding more graph instances, with some high-performance options too.

2D mesh

2D meshes are constructed as path [1..n] `box` path [1..n].

Benchmark |V| |E| Runtime
Compute the size of VertexSet 1 0 318 ns
100 180 154 μs
10 000 19 800 31.8 ms
1 000 000 1 998 000 7.33 s
Compute the size of Relation 1 0 250 ns
100 180 152 μs
10 000 19 800 35.7 ms
1 000 000 1 998 000 8.79 s
Compute the number of edges in AdjacencyMap 1 0 334 ns
100 180 223 μs
10 000 19 800 49.5 ms
1 000 000 1 998 000 10.5 s
Compute the size of Int.VertexSet 1 0 315 ns
100 180 52 μs
10 000 19 800 7.4 ms
1 000 000 1 998 000 1.54 s
Compute the number of edges in Int.AdjacencyMap 1 0 303 ns
100 180 98.9 μs
10 000 19 800 18 ms
1 000 000 1 998 000 4.24 s

Clique

A clique is simply clique [1..n]. We can handle cliques with billions of edges thanks to the simple connectivity structure exploited by AdjacencyMap. The VertexSet instance ignores edges altogether and eats cliques for breakfast.

Benchmark |V| |E| Runtime
Compute the size of Int.VertexSet 1 1 43.2 ns
10 45 375 ns
100 4 950 3.67 μs
1 000 499 500 55.3 μs
10 000 49 995 000 2.08 ms
44 722 1 000 006 281 13.8 ms
Compute the size of Relation 1 1 38.9 ns
10 45 7.74 μs
100 4 950 969 μs
1 000 499 500 93.8 ms
10 000 49 995 000 11.2 s
Compute the number of edges in Int.AdjacencyMap 1 1 45.4 ns
10 45 1.72 μs
100 4 950 49.3 μs
1 000 499 500 3.68 ms
10 000 49 995 000 376 ms
44 722 1 000 006 281 10.2 s

De Bruijn graphs

De Bruijn graphs are constructed as deBruijn n "0123456789" and as gmap fastRead $ deBruijn n "0123456789" for Int instances, where fastRead = foldr (\c r -> r + ord c - ord '0') 0. Note that gmap fastRead takes roughly 5% of Int.AdjacencyMap runtime and 15% of Int.VertexMap runtime.

Benchmark |V| |E| Runtime
Compute the size of VertexSet 10 100 4.86 μs
100 1 000 104 μs
1 000 10 000 2.09 ms
10 000 100 000 34.8 ms
100 000 1 000 000 430 ms
1 000 000 10 000 000 6.35 s
Compute the size of Relation 10 100 7.13 μs
100 1 000 282 μs
1 000 10 000 6.05 ms
10 000 100 000 83.1 ms
100 000 1 000 000 960 ms
1 000 000 10 000 000 11.4 s
Compute the number of edges in AdjacencyMap 10 100 7.83 μs
100 1 000 159 μs
1 000 10 000 3.04 ms
10 000 100 000 47.5 ms
100 000 1 000 000 644 ms
1 000 000 10 000 000 8.13 s
Compute the size of Int.VertexSet 10 100 5.13 μs
100 1 000 61.8 μs
1 000 10 000 882 μs
10 000 100 000 8.93 ms
100 000 1 000 000 105 ms
1 000 000 10 000 000 1.10 s
Compute the number of edges in Int.AdjacencyMap 10 100 8.59 μs
100 1 000 175 μs
1 000 10 000 2.76 ms
10 000 100 000 30.4 ms
100 000 1 000 000 368 ms
1 000 000 10 000 000 3.77 s