From bb741107d2fc8fef7a94625b6b15b98c1e4ed061 Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Sat, 15 Feb 2025 16:36:18 -0600 Subject: [PATCH 1/5] [documentation] Add tutorials --- docs/Project.toml | 1 + docs/make.jl | 5 +- docs/src/smc.mtx | 817 ++++++++++++++++++++++++++++++++++++++++++ docs/src/tutorials.md | 237 ++++++++++++ docs/src/vis.md | 2 +- 5 files changed, 1060 insertions(+), 2 deletions(-) create mode 100644 docs/src/smc.mtx create mode 100644 docs/src/tutorials.md diff --git a/docs/Project.toml b/docs/Project.toml index fc5d3c54..8b2256c8 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -4,5 +4,6 @@ ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" +MatrixMarket = "4d4711f2-db25-561a-b6b3-d35e7d4047d3" SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" diff --git a/docs/make.jl b/docs/make.jl index 405e8082..5712310f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,7 +12,10 @@ makedocs(; sitename="SparseMatrixColorings.jl", format=Documenter.HTML(), pages=[ - "Home" => "index.md", "api.md", "Developer Documentation" => ["dev.md", "vis.md"] + "Home" => "index.md", + "api.md", + "Tutorials" => "tutorials.md", + "Developer Documentation" => ["dev.md", "vis.md"], ], plugins=[links], ) diff --git a/docs/src/smc.mtx b/docs/src/smc.mtx new file mode 100644 index 00000000..e7fb3d8d --- /dev/null +++ b/docs/src/smc.mtx @@ -0,0 +1,817 @@ +%%MatrixMarket matrix coordinate integer symmetric +100 100 815 +1 1 1 +2 1 1 +3 1 1 +11 1 1 +12 1 1 +13 1 1 +21 1 1 +22 1 1 +23 1 1 +2 2 1 +3 2 1 +4 2 1 +11 2 1 +12 2 1 +13 2 1 +14 2 1 +22 2 1 +23 2 1 +24 2 1 +3 3 1 +4 3 1 +5 3 1 +12 3 1 +13 3 1 +14 3 1 +15 3 1 +23 3 1 +24 3 1 +25 3 1 +4 4 1 +5 4 1 +6 4 1 +13 4 1 +14 4 1 +15 4 1 +16 4 1 +24 4 1 +25 4 1 +26 4 1 +5 5 1 +6 5 1 +7 5 1 +14 5 1 +15 5 1 +16 5 1 +17 5 1 +25 5 1 +26 5 1 +6 6 1 +7 6 1 +8 6 1 +15 6 1 +16 6 1 +17 6 1 +26 6 1 +7 7 1 +8 7 1 +9 7 1 +15 7 1 +16 7 1 +17 7 1 +18 7 1 +26 7 1 +27 7 1 +8 8 1 +9 8 1 +10 8 1 +16 8 1 +17 8 1 +18 8 1 +19 8 1 +26 8 1 +27 8 1 +28 8 1 +9 9 1 +10 9 1 +17 9 1 +18 9 1 +19 9 1 +20 9 1 +27 9 1 +28 9 1 +29 9 1 +10 10 1 +18 10 1 +19 10 1 +20 10 1 +28 10 1 +29 10 1 +30 10 1 +11 11 1 +12 11 1 +13 11 1 +21 11 1 +22 11 1 +23 11 1 +31 11 1 +32 11 1 +33 11 1 +12 12 1 +13 12 1 +14 12 1 +21 12 1 +22 12 1 +23 12 1 +24 12 1 +32 12 1 +33 12 1 +34 12 1 +13 13 1 +14 13 1 +15 13 1 +22 13 1 +23 13 1 +24 13 1 +25 13 1 +33 13 1 +34 13 1 +35 13 1 +14 14 1 +15 14 1 +16 14 1 +23 14 1 +24 14 1 +25 14 1 +26 14 1 +34 14 1 +35 14 1 +36 14 1 +15 15 1 +16 15 1 +17 15 1 +24 15 1 +25 15 1 +26 15 1 +27 15 1 +35 15 1 +36 15 1 +16 16 1 +17 16 1 +18 16 1 +25 16 1 +26 16 1 +27 16 1 +36 16 1 +17 17 1 +18 17 1 +19 17 1 +25 17 1 +26 17 1 +27 17 1 +28 17 1 +36 17 1 +37 17 1 +18 18 1 +19 18 1 +20 18 1 +26 18 1 +27 18 1 +28 18 1 +29 18 1 +36 18 1 +37 18 1 +38 18 1 +19 19 1 +20 19 1 +27 19 1 +28 19 1 +29 19 1 +30 19 1 +37 19 1 +38 19 1 +39 19 1 +20 20 1 +28 20 1 +29 20 1 +30 20 1 +38 20 1 +39 20 1 +40 20 1 +21 21 1 +22 21 1 +23 21 1 +31 21 1 +32 21 1 +33 21 1 +41 21 1 +42 21 1 +43 21 1 +22 22 1 +23 22 1 +24 22 1 +31 22 1 +32 22 1 +33 22 1 +34 22 1 +42 22 1 +43 22 1 +44 22 1 +23 23 1 +24 23 1 +25 23 1 +32 23 1 +33 23 1 +34 23 1 +35 23 1 +43 23 1 +44 23 1 +45 23 1 +24 24 1 +25 24 1 +26 24 1 +33 24 1 +34 24 1 +35 24 1 +36 24 1 +44 24 1 +45 24 1 +46 24 1 +25 25 1 +26 25 1 +27 25 1 +34 25 1 +35 25 1 +36 25 1 +37 25 1 +45 25 1 +46 25 1 +26 26 1 +27 26 1 +28 26 1 +35 26 1 +36 26 1 +37 26 1 +46 26 1 +27 27 1 +28 27 1 +29 27 1 +35 27 1 +36 27 1 +37 27 1 +38 27 1 +46 27 1 +47 27 1 +28 28 1 +29 28 1 +30 28 1 +36 28 1 +37 28 1 +38 28 1 +39 28 1 +46 28 1 +47 28 1 +48 28 1 +29 29 1 +30 29 1 +37 29 1 +38 29 1 +39 29 1 +40 29 1 +47 29 1 +48 29 1 +49 29 1 +30 30 1 +38 30 1 +39 30 1 +40 30 1 +48 30 1 +49 30 1 +50 30 1 +31 31 1 +32 31 1 +33 31 1 +41 31 1 +42 31 1 +43 31 1 +51 31 1 +52 31 1 +32 32 1 +33 32 1 +34 32 1 +41 32 1 +42 32 1 +43 32 1 +44 32 1 +51 32 1 +52 32 1 +53 32 1 +33 33 1 +34 33 1 +35 33 1 +42 33 1 +43 33 1 +44 33 1 +45 33 1 +52 33 1 +53 33 1 +54 33 1 +34 34 1 +35 34 1 +36 34 1 +43 34 1 +44 34 1 +45 34 1 +46 34 1 +53 34 1 +54 34 1 +55 34 1 +35 35 1 +36 35 1 +37 35 1 +44 35 1 +45 35 1 +46 35 1 +47 35 1 +54 35 1 +55 35 1 +56 35 1 +57 35 1 +36 36 1 +37 36 1 +38 36 1 +45 36 1 +46 36 1 +47 36 1 +55 36 1 +56 36 1 +57 36 1 +37 37 1 +38 37 1 +39 37 1 +45 37 1 +46 37 1 +47 37 1 +48 37 1 +55 37 1 +56 37 1 +57 37 1 +58 37 1 +38 38 1 +39 38 1 +40 38 1 +46 38 1 +47 38 1 +48 38 1 +49 38 1 +57 38 1 +58 38 1 +59 38 1 +39 39 1 +40 39 1 +47 39 1 +48 39 1 +49 39 1 +50 39 1 +58 39 1 +59 39 1 +60 39 1 +40 40 1 +48 40 1 +49 40 1 +50 40 1 +59 40 1 +60 40 1 +41 41 1 +42 41 1 +43 41 1 +51 41 1 +52 41 1 +61 41 1 +42 42 1 +43 42 1 +44 42 1 +51 42 1 +52 42 1 +53 42 1 +61 42 1 +62 42 1 +43 43 1 +44 43 1 +45 43 1 +51 43 1 +52 43 1 +53 43 1 +54 43 1 +61 43 1 +62 43 1 +63 43 1 +44 44 1 +45 44 1 +46 44 1 +52 44 1 +53 44 1 +54 44 1 +55 44 1 +62 44 1 +63 44 1 +64 44 1 +45 45 1 +46 45 1 +47 45 1 +53 45 1 +54 45 1 +55 45 1 +56 45 1 +57 45 1 +63 45 1 +64 45 1 +65 45 1 +46 46 1 +47 46 1 +48 46 1 +54 46 1 +55 46 1 +56 46 1 +57 46 1 +58 46 1 +64 46 1 +65 46 1 +66 46 1 +67 46 1 +68 46 1 +47 47 1 +48 47 1 +49 47 1 +55 47 1 +56 47 1 +57 47 1 +58 47 1 +59 47 1 +67 47 1 +68 47 1 +69 47 1 +48 48 1 +49 48 1 +50 48 1 +57 48 1 +58 48 1 +59 48 1 +60 48 1 +68 48 1 +69 48 1 +70 48 1 +49 49 1 +50 49 1 +58 49 1 +59 49 1 +60 49 1 +69 49 1 +70 49 1 +50 50 1 +59 50 1 +60 50 1 +70 50 1 +51 51 1 +52 51 1 +53 51 1 +61 51 1 +62 51 1 +71 51 1 +52 52 1 +53 52 1 +54 52 1 +61 52 1 +62 52 1 +63 52 1 +71 52 1 +72 52 1 +53 53 1 +54 53 1 +55 53 1 +61 53 1 +62 53 1 +63 53 1 +64 53 1 +71 53 1 +72 53 1 +73 53 1 +54 54 1 +55 54 1 +56 54 1 +62 54 1 +63 54 1 +64 54 1 +65 54 1 +72 54 1 +73 54 1 +74 54 1 +55 55 1 +56 55 1 +57 55 1 +63 55 1 +64 55 1 +65 55 1 +66 55 1 +67 55 1 +73 55 1 +74 55 1 +75 55 1 +56 56 1 +57 56 1 +58 56 1 +64 56 1 +65 56 1 +66 56 1 +67 56 1 +68 56 1 +74 56 1 +75 56 1 +76 56 1 +77 56 1 +78 56 1 +57 57 1 +58 57 1 +59 57 1 +65 57 1 +66 57 1 +67 57 1 +68 57 1 +69 57 1 +77 57 1 +78 57 1 +79 57 1 +58 58 1 +59 58 1 +60 58 1 +67 58 1 +68 58 1 +69 58 1 +70 58 1 +78 58 1 +79 58 1 +80 58 1 +59 59 1 +60 59 1 +68 59 1 +69 59 1 +70 59 1 +79 59 1 +80 59 1 +60 60 1 +69 60 1 +70 60 1 +80 60 1 +61 61 1 +62 61 1 +63 61 1 +71 61 1 +72 61 1 +81 61 1 +62 62 1 +63 62 1 +64 62 1 +71 62 1 +72 62 1 +73 62 1 +81 62 1 +82 62 1 +63 63 1 +64 63 1 +65 63 1 +71 63 1 +72 63 1 +73 63 1 +74 63 1 +81 63 1 +82 63 1 +83 63 1 +64 64 1 +65 64 1 +66 64 1 +72 64 1 +73 64 1 +74 64 1 +75 64 1 +82 64 1 +83 64 1 +84 64 1 +65 65 1 +66 65 1 +67 65 1 +73 65 1 +74 65 1 +75 65 1 +76 65 1 +77 65 1 +83 65 1 +84 65 1 +85 65 1 +66 66 1 +67 66 1 +68 66 1 +74 66 1 +75 66 1 +76 66 1 +77 66 1 +78 66 1 +84 66 1 +85 66 1 +86 66 1 +87 66 1 +88 66 1 +67 67 1 +68 67 1 +69 67 1 +75 67 1 +76 67 1 +77 67 1 +78 67 1 +79 67 1 +87 67 1 +88 67 1 +89 67 1 +68 68 1 +69 68 1 +70 68 1 +77 68 1 +78 68 1 +79 68 1 +80 68 1 +88 68 1 +89 68 1 +90 68 1 +69 69 1 +70 69 1 +78 69 1 +79 69 1 +80 69 1 +89 69 1 +90 69 1 +70 70 1 +79 70 1 +80 70 1 +90 70 1 +71 71 1 +72 71 1 +73 71 1 +81 71 1 +82 71 1 +91 71 1 +72 72 1 +73 72 1 +74 72 1 +81 72 1 +82 72 1 +83 72 1 +91 72 1 +92 72 1 +73 73 1 +74 73 1 +75 73 1 +81 73 1 +82 73 1 +83 73 1 +84 73 1 +91 73 1 +92 73 1 +93 73 1 +74 74 1 +75 74 1 +76 74 1 +82 74 1 +83 74 1 +84 74 1 +85 74 1 +92 74 1 +93 74 1 +94 74 1 +75 75 1 +76 75 1 +77 75 1 +83 75 1 +84 75 1 +85 75 1 +86 75 1 +87 75 1 +93 75 1 +94 75 1 +95 75 1 +76 76 1 +77 76 1 +78 76 1 +84 76 1 +85 76 1 +86 76 1 +87 76 1 +88 76 1 +94 76 1 +95 76 1 +96 76 1 +97 76 1 +98 76 1 +77 77 1 +78 77 1 +79 77 1 +85 77 1 +86 77 1 +87 77 1 +88 77 1 +89 77 1 +97 77 1 +98 77 1 +99 77 1 +78 78 1 +79 78 1 +80 78 1 +87 78 1 +88 78 1 +89 78 1 +90 78 1 +98 78 1 +99 78 1 +100 78 1 +79 79 1 +80 79 1 +88 79 1 +89 79 1 +90 79 1 +99 79 1 +100 79 1 +80 80 1 +89 80 1 +90 80 1 +100 80 1 +81 81 1 +82 81 1 +83 81 1 +91 81 1 +92 81 1 +82 82 1 +83 82 1 +84 82 1 +91 82 1 +92 82 1 +93 82 1 +83 83 1 +84 83 1 +85 83 1 +91 83 1 +92 83 1 +93 83 1 +94 83 1 +84 84 1 +85 84 1 +86 84 1 +92 84 1 +93 84 1 +94 84 1 +95 84 1 +85 85 1 +86 85 1 +87 85 1 +93 85 1 +94 85 1 +95 85 1 +96 85 1 +97 85 1 +86 86 1 +87 86 1 +88 86 1 +94 86 1 +95 86 1 +96 86 1 +97 86 1 +98 86 1 +87 87 1 +88 87 1 +89 87 1 +95 87 1 +96 87 1 +97 87 1 +98 87 1 +99 87 1 +88 88 1 +89 88 1 +90 88 1 +97 88 1 +98 88 1 +99 88 1 +100 88 1 +89 89 1 +90 89 1 +98 89 1 +99 89 1 +100 89 1 +90 90 1 +99 90 1 +100 90 1 +91 91 1 +92 91 1 +93 91 1 +92 92 1 +93 92 1 +94 92 1 +93 93 1 +94 93 1 +95 93 1 +94 94 1 +95 94 1 +96 94 1 +95 95 1 +96 95 1 +97 95 1 +96 96 1 +97 96 1 +98 96 1 +97 97 1 +98 97 1 +99 97 1 +98 98 1 +99 98 1 +100 98 1 +99 99 1 +100 99 1 +100 100 1 diff --git a/docs/src/tutorials.md b/docs/src/tutorials.md new file mode 100644 index 00000000..98ea32d0 --- /dev/null +++ b/docs/src/tutorials.md @@ -0,0 +1,237 @@ +# Tutorials + +## Introduction to SparseMatrixColorings.jl + +The three main functions to perform a coloring with `SparseMatrixColorings.jl` are [`coloring`](@ref coloring), [`ColoringProblem`](@ref ColoringProblem) and [`GreedyColoringAlgorithm`](@ref GreedyColoringAlgorithm). + +```@example tutorial; continued = true +using SparseMatrixColorings, SparseArrays + +S = sparse([ + 0 0 1 1 0 1 + 1 0 0 0 1 0 + 0 1 0 0 1 0 + 0 1 1 0 0 0 +]) + +problem = ColoringProblem() +algo = GreedyColoringAlgorithm() +result = coloring(S, problem, algo) +``` + +Based on the result of `coloring`, you can easily recover a vector of integer colors with [`row_colors`](@ref row_colors), [`column_colors`](@ref column_colors), as well as the groups of colors with [`row_groups`](@ref row_groups) and [`column_groups`](@ref column_groups). + +```@example tutorial +column_colors(result) +``` + +```@example tutorial +column_groups(result) +``` + +The number of colors can be determined with [`ncolors`](@ref ncolors). +```@example tutorial +ncolors(result) +``` + +The functions [`compress`](@ref compress) and [`decompress`](@ref decompress) efficiently store and retrieve compressed representations of colorings for sparse matrices. + +```@example tutorial +M = sparse([ + 0 0 4 6 0 9 + 1 0 0 0 7 0 + 0 2 0 0 8 0 + 0 3 5 0 0 0 +]) + +B = compress(M, result) +``` + +```@example tutorial +C = decompress(B, result) +``` + +The functions [`decompress!`](@ref decompress!) and [`decompress_single_color!`](@ref decompress_single_color!) are in-place variants of [`decompress`](@ref decompress). + +```@example tutorial +D = [10 14 18 + 11 15 0 + 12 16 0 + 13 17 0] + +decompress!(C, D, result) +``` +```@example tutorial +C .= 0 +decompress_single_color!(C, D[:, 2], 2, result) +``` + +We now illustrate the six variants of colorings available in `SparseMatrixColorings.jl` on the following matrix with a symmetric sparsity pattern. + +```@example tutorial +using SparseMatrixColorings: show_colors # hide +using Images # hide +using MatrixMarket +S = MatrixMarket.mmread("smc.mtx") +``` + +## Column coloring of Jacobians + +```@example tutorial; continued = true +problem = ColoringProblem(; structure=:nonsymmetric, + partition=:column) + +order = NaturalOrder() + +algo = GreedyColoringAlgorithm(order; + decompression=:direct) + +result = coloring(S, problem, algo) +``` +```@example tutorial +ccolors = column_colors(result) +cgroups = column_groups(result) +num_colors = ncolors(result) +``` + +```@example tutorial +A_img, B_img = show_colors(result, scale=5, pad=2) # hide +A_img # hide +``` + +## Row coloring of Jacobians + +```@example tutorial; continued = true +problem = ColoringProblem(; structure=:nonsymmetric, + partition=:row) + +order = LargestFirst() + +algo = GreedyColoringAlgorithm(order; + decompression=:direct) + +result = coloring(S, problem, algo) +``` + +```@example tutorial +rcolors = row_colors(result) +rgroups = row_groups(result) +num_colors = ncolors(result) +``` + +```@example tutorial +A_img, B_img = show_colors(result, scale=5, pad=2) # hide +A_img # hide +``` + +## Star bicoloring of Jacobians + +```@example tutorial; continued = true +using SparseMatrixColorings, MatrixMarket + +S = MatrixMarket.mmread("smc.mtx") + +problem = ColoringProblem(; structure=:nonsymmetric, + partition=:bidirectional) + +order = RandomOrder() + +algo = GreedyColoringAlgorithm(order; + decompression=:direct, + postprocessing=true) + +result = coloring(S, problem, algo) +``` + +```@example tutorial +rcolors = row_colors(result) +rgroups = row_groups(result) +ccolors = column_colors(result) +cgroups = column_groups(result) +num_colors = ncolors(result) +``` + +```@example tutorial +A_img, Br_img, Bc_img = show_colors(result, scale=5, pad=2) # hide +A_img # hide +``` + +## Acyclic bicoloring of Jacobians + +```@example tutorial; continued = true +problem = ColoringProblem(; structure=:nonsymmetric, + partition=:bidirectional) + +order = RandomOrder() + +algo = GreedyColoringAlgorithm(order; + decompression=:substitution, + postprocessing=true) + +result = coloring(S, problem, algo) +``` + +```@example tutorial +rcolors = row_colors(result) +rgroups = row_groups(result) +ccolors = column_colors(result) +cgroups = column_groups(result) +num_colors = ncolors(result) +``` + +```@example tutorial +A_img, Br_img, Bc_img = show_colors(result, scale=5, pad=2) # hide +A_img # hide +``` + +## Star coloring of Hessians + +```@example tutorial; continued = true +problem = ColoringProblem(; structure=:symmetric, + partition=:column) + +order = NaturalOrder() + +algo = GreedyColoringAlgorithm(order; + decompression=:direct, + postprocessing=false) + +result = coloring(S, problem, algo) +``` + +```@example tutorial +ccolors = column_colors(result) +cgroups = column_groups(result) +num_colors = ncolors(result) +``` + +```@example tutorial +A_img, B_img = show_colors(result, scale=5, pad=2) # hide +A_img # hide +``` + +## Acyclic coloring of Hessians + +```@example tutorial; continued = true +problem = ColoringProblem(; structure=:symmetric, + partition=:column) + +order = NaturalOrder() + +algo = GreedyColoringAlgorithm(order; + decompression=:substitution, + postprocessing=false) + +result = coloring(S, problem, algo) +``` + +```@example tutorial +ccolors = column_colors(result) +cgroups = column_groups(result) +num_colors = ncolors(result) +``` + +```@example tutorial +A_img, B_img = show_colors(result, scale=5, pad=2) # hide +A_img # hide +``` diff --git a/docs/src/vis.md b/docs/src/vis.md index 72c76f22..7dec846d 100644 --- a/docs/src/vis.md +++ b/docs/src/vis.md @@ -60,7 +60,7 @@ Finally, a background color can be passed via the `background` keyword argument. We demonstrate this on a bidirectional coloring. -```@example img +```@example img; continue = true S = sparse([ 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 From ccfc0d980312701bee64d7eb832658adf5795f9e Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Sat, 15 Feb 2025 16:47:01 -0600 Subject: [PATCH 2/5] Use the option push_preview=true --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 5712310f..b7c36c3a 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -20,4 +20,4 @@ makedocs(; plugins=[links], ) -deploydocs(; repo="github.com/gdalle/SparseMatrixColorings.jl", devbranch="main") +deploydocs(; repo="github.com/gdalle/SparseMatrixColorings.jl", push_preview=true, devbranch="main") From 56ed48dd77bad5b30680540086506df98b94155a Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Sat, 15 Feb 2025 16:55:55 -0600 Subject: [PATCH 3/5] Use JuliaFormatter on docs/make.jl --- docs/make.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index b7c36c3a..56360c89 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -20,4 +20,6 @@ makedocs(; plugins=[links], ) -deploydocs(; repo="github.com/gdalle/SparseMatrixColorings.jl", push_preview=true, devbranch="main") +deploydocs(; + repo="github.com/gdalle/SparseMatrixColorings.jl", push_preview=true, devbranch="main" +) From c307ca74cc5d9cc15e6700ae32164c70d48221ed Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Sat, 15 Feb 2025 18:30:49 -0600 Subject: [PATCH 4/5] Update tutorials.md --- docs/src/tutorials.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/src/tutorials.md b/docs/src/tutorials.md index 98ea32d0..f441d61b 100644 --- a/docs/src/tutorials.md +++ b/docs/src/tutorials.md @@ -75,7 +75,7 @@ using MatrixMarket S = MatrixMarket.mmread("smc.mtx") ``` -## Column coloring of Jacobians +## Column coloring ```@example tutorial; continued = true problem = ColoringProblem(; structure=:nonsymmetric, @@ -99,7 +99,7 @@ A_img, B_img = show_colors(result, scale=5, pad=2) # hide A_img # hide ``` -## Row coloring of Jacobians +## Row coloring ```@example tutorial; continued = true problem = ColoringProblem(; structure=:nonsymmetric, @@ -124,7 +124,7 @@ A_img, B_img = show_colors(result, scale=5, pad=2) # hide A_img # hide ``` -## Star bicoloring of Jacobians +## Star bicoloring ```@example tutorial; continued = true using SparseMatrixColorings, MatrixMarket @@ -156,7 +156,7 @@ A_img, Br_img, Bc_img = show_colors(result, scale=5, pad=2) # hide A_img # hide ``` -## Acyclic bicoloring of Jacobians +## Acyclic bicoloring ```@example tutorial; continued = true problem = ColoringProblem(; structure=:nonsymmetric, @@ -184,7 +184,7 @@ A_img, Br_img, Bc_img = show_colors(result, scale=5, pad=2) # hide A_img # hide ``` -## Star coloring of Hessians +## Symmetric star coloring ```@example tutorial; continued = true problem = ColoringProblem(; structure=:symmetric, @@ -210,7 +210,7 @@ A_img, B_img = show_colors(result, scale=5, pad=2) # hide A_img # hide ``` -## Acyclic coloring of Hessians +## Symmetric acyclic coloring ```@example tutorial; continued = true problem = ColoringProblem(; structure=:symmetric, From 1cb0751a496fb7b606d2e74fadc2583c0f799d41 Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Mon, 26 May 2025 14:14:50 +0200 Subject: [PATCH 5/5] Refresh tutorial, add citations --- CITATION.cff | 20 ++ README.md | 22 +- docs/Project.toml | 1 - docs/make.jl | 2 +- docs/src/smc.mtx | 817 ------------------------------------------ docs/src/tutorial.md | 323 +++++++++++++++++ docs/src/tutorials.md | 237 ------------ src/decompression.jl | 9 + 8 files changed, 373 insertions(+), 1058 deletions(-) delete mode 100644 docs/src/smc.mtx create mode 100644 docs/src/tutorial.md delete mode 100644 docs/src/tutorials.md diff --git a/CITATION.cff b/CITATION.cff index 18ff414f..c2c0a8fb 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -28,3 +28,23 @@ keywords: - automatic differentiation - julia programming language license: MIT +preferred-citation: + authors: + - given-names: Alexis + family-names: Montoison + orcid: 'https://orcid.org/0000-0002-3403-5450' + - given-names: Guillaume + family-names: Dalle + orcid: 'https://orcid.org/0000-0003-4866-1687' + - given-names: Assefaw + family-names: Gebremedhin + orcid: 'https://orcid.org/0000-0001-5383-8032' + title: "Revisiting Sparse Matrix Coloring and Bicoloring" + year: 2025 + type: article + url: 'https://arxiv.org/abs/2505.07308' + identifiers: + - type: doi + value: 10.48550/arXiv.2505.07308 + description: Arxiv + abstract: "Sparse matrix coloring and bicoloring are fundamental building blocks of sparse automatic differentiation. Bicoloring is particularly advantageous for rectangular Jacobian matrices with at least one dense row and column. Indeed, in such cases, unidirectional row or column coloring demands a number of colors equal to the number of rows or columns. We introduce a new strategy for bicoloring that encompasses both direct and substitution-based decompression approaches. Our method reformulates the two variants of bicoloring as star and acyclic colorings of an augmented symmetric matrix. We extend the concept of neutral colors, previously exclusive to bicoloring, to symmetric colorings, and we propose a post-processing routine that neutralizes colors to further reduce the overall color count. We also present the Julia package SparseMatrixColorings, which includes these new bicoloring algorithms alongside all standard coloring methods for sparse derivative matrix computation. Compared to ColPack, the Julia package also offers enhanced implementations for star and acyclic coloring, vertex ordering, as well as decompression." diff --git a/README.md b/README.md index 40b3a2d6..66b10dd3 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![Dev Documentation](https://img.shields.io/badge/docs-dev-blue.svg)](https://gdalle.github.io/SparseMatrixColorings.jl/dev/) [![Coverage](https://codecov.io/gh/gdalle/SparseMatrixColorings.jl/branch/main/graph/badge.svg)](https://app.codecov.io/gh/gdalle/SparseMatrixColorings.jl) [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/JuliaDiff/BlueStyle) +[![arXiv](https://img.shields.io/badge/arXiv-2505.07308-b31b1b.svg)](https://arxiv.org/abs/2505.07308) [![DOI](https://zenodo.org/badge/801999408.svg)](https://zenodo.org/doi/10.5281/zenodo.11314275) Coloring algorithms for sparse Jacobian and Hessian matrices. @@ -19,7 +20,11 @@ pkg> add SparseMatrixColorings ## Background -The algorithms implemented in this package are taken from the following articles: +The algorithms implemented in this package are described in the following preprint: + +- [_Revisiting Sparse Matrix Coloring and Bicoloring_](https://arxiv.org/abs/2505.07308), Montoison et al. (2025) + +and inspired by previous works: - [_What Color Is Your Jacobian? Graph Coloring for Computing Derivatives_](https://epubs.siam.org/doi/10.1137/S0036144504444711), Gebremedhin et al. (2005) - [_New Acyclic and Star Coloring Algorithms with Application to Computing Hessians_](https://epubs.siam.org/doi/abs/10.1137/050639879), Gebremedhin et al. (2007) @@ -35,5 +40,18 @@ Some parts of the articles (like definitions) are thus copied verbatim in the do ## Citing -Please cite this software using the provided `CITATION.cff` file. +Please cite this software using the provided `CITATION.cff` file or the `.bib` entry below: + +```bibtex +@unpublished{montoison2025revisitingsparsematrixcoloring, + title={Revisiting Sparse Matrix Coloring and Bicoloring}, + author={Alexis Montoison and Guillaume Dalle and Assefaw Gebremedhin}, + year={2025}, + eprint={2505.07308}, + archivePrefix={arXiv}, + primaryClass={math.NA}, + url={https://arxiv.org/abs/2505.07308}, +} +``` + The link resolves to the latest version on Zenodo. diff --git a/docs/Project.toml b/docs/Project.toml index b6a6ee26..61f164de 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -4,7 +4,6 @@ ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" -MatrixMarket = "4d4711f2-db25-561a-b6b3-d35e7d4047d3" SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" diff --git a/docs/make.jl b/docs/make.jl index 56360c89..78fba268 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -13,8 +13,8 @@ makedocs(; format=Documenter.HTML(), pages=[ "Home" => "index.md", + "tutorial.md", "api.md", - "Tutorials" => "tutorials.md", "Developer Documentation" => ["dev.md", "vis.md"], ], plugins=[links], diff --git a/docs/src/smc.mtx b/docs/src/smc.mtx deleted file mode 100644 index e7fb3d8d..00000000 --- a/docs/src/smc.mtx +++ /dev/null @@ -1,817 +0,0 @@ -%%MatrixMarket matrix coordinate integer symmetric -100 100 815 -1 1 1 -2 1 1 -3 1 1 -11 1 1 -12 1 1 -13 1 1 -21 1 1 -22 1 1 -23 1 1 -2 2 1 -3 2 1 -4 2 1 -11 2 1 -12 2 1 -13 2 1 -14 2 1 -22 2 1 -23 2 1 -24 2 1 -3 3 1 -4 3 1 -5 3 1 -12 3 1 -13 3 1 -14 3 1 -15 3 1 -23 3 1 -24 3 1 -25 3 1 -4 4 1 -5 4 1 -6 4 1 -13 4 1 -14 4 1 -15 4 1 -16 4 1 -24 4 1 -25 4 1 -26 4 1 -5 5 1 -6 5 1 -7 5 1 -14 5 1 -15 5 1 -16 5 1 -17 5 1 -25 5 1 -26 5 1 -6 6 1 -7 6 1 -8 6 1 -15 6 1 -16 6 1 -17 6 1 -26 6 1 -7 7 1 -8 7 1 -9 7 1 -15 7 1 -16 7 1 -17 7 1 -18 7 1 -26 7 1 -27 7 1 -8 8 1 -9 8 1 -10 8 1 -16 8 1 -17 8 1 -18 8 1 -19 8 1 -26 8 1 -27 8 1 -28 8 1 -9 9 1 -10 9 1 -17 9 1 -18 9 1 -19 9 1 -20 9 1 -27 9 1 -28 9 1 -29 9 1 -10 10 1 -18 10 1 -19 10 1 -20 10 1 -28 10 1 -29 10 1 -30 10 1 -11 11 1 -12 11 1 -13 11 1 -21 11 1 -22 11 1 -23 11 1 -31 11 1 -32 11 1 -33 11 1 -12 12 1 -13 12 1 -14 12 1 -21 12 1 -22 12 1 -23 12 1 -24 12 1 -32 12 1 -33 12 1 -34 12 1 -13 13 1 -14 13 1 -15 13 1 -22 13 1 -23 13 1 -24 13 1 -25 13 1 -33 13 1 -34 13 1 -35 13 1 -14 14 1 -15 14 1 -16 14 1 -23 14 1 -24 14 1 -25 14 1 -26 14 1 -34 14 1 -35 14 1 -36 14 1 -15 15 1 -16 15 1 -17 15 1 -24 15 1 -25 15 1 -26 15 1 -27 15 1 -35 15 1 -36 15 1 -16 16 1 -17 16 1 -18 16 1 -25 16 1 -26 16 1 -27 16 1 -36 16 1 -17 17 1 -18 17 1 -19 17 1 -25 17 1 -26 17 1 -27 17 1 -28 17 1 -36 17 1 -37 17 1 -18 18 1 -19 18 1 -20 18 1 -26 18 1 -27 18 1 -28 18 1 -29 18 1 -36 18 1 -37 18 1 -38 18 1 -19 19 1 -20 19 1 -27 19 1 -28 19 1 -29 19 1 -30 19 1 -37 19 1 -38 19 1 -39 19 1 -20 20 1 -28 20 1 -29 20 1 -30 20 1 -38 20 1 -39 20 1 -40 20 1 -21 21 1 -22 21 1 -23 21 1 -31 21 1 -32 21 1 -33 21 1 -41 21 1 -42 21 1 -43 21 1 -22 22 1 -23 22 1 -24 22 1 -31 22 1 -32 22 1 -33 22 1 -34 22 1 -42 22 1 -43 22 1 -44 22 1 -23 23 1 -24 23 1 -25 23 1 -32 23 1 -33 23 1 -34 23 1 -35 23 1 -43 23 1 -44 23 1 -45 23 1 -24 24 1 -25 24 1 -26 24 1 -33 24 1 -34 24 1 -35 24 1 -36 24 1 -44 24 1 -45 24 1 -46 24 1 -25 25 1 -26 25 1 -27 25 1 -34 25 1 -35 25 1 -36 25 1 -37 25 1 -45 25 1 -46 25 1 -26 26 1 -27 26 1 -28 26 1 -35 26 1 -36 26 1 -37 26 1 -46 26 1 -27 27 1 -28 27 1 -29 27 1 -35 27 1 -36 27 1 -37 27 1 -38 27 1 -46 27 1 -47 27 1 -28 28 1 -29 28 1 -30 28 1 -36 28 1 -37 28 1 -38 28 1 -39 28 1 -46 28 1 -47 28 1 -48 28 1 -29 29 1 -30 29 1 -37 29 1 -38 29 1 -39 29 1 -40 29 1 -47 29 1 -48 29 1 -49 29 1 -30 30 1 -38 30 1 -39 30 1 -40 30 1 -48 30 1 -49 30 1 -50 30 1 -31 31 1 -32 31 1 -33 31 1 -41 31 1 -42 31 1 -43 31 1 -51 31 1 -52 31 1 -32 32 1 -33 32 1 -34 32 1 -41 32 1 -42 32 1 -43 32 1 -44 32 1 -51 32 1 -52 32 1 -53 32 1 -33 33 1 -34 33 1 -35 33 1 -42 33 1 -43 33 1 -44 33 1 -45 33 1 -52 33 1 -53 33 1 -54 33 1 -34 34 1 -35 34 1 -36 34 1 -43 34 1 -44 34 1 -45 34 1 -46 34 1 -53 34 1 -54 34 1 -55 34 1 -35 35 1 -36 35 1 -37 35 1 -44 35 1 -45 35 1 -46 35 1 -47 35 1 -54 35 1 -55 35 1 -56 35 1 -57 35 1 -36 36 1 -37 36 1 -38 36 1 -45 36 1 -46 36 1 -47 36 1 -55 36 1 -56 36 1 -57 36 1 -37 37 1 -38 37 1 -39 37 1 -45 37 1 -46 37 1 -47 37 1 -48 37 1 -55 37 1 -56 37 1 -57 37 1 -58 37 1 -38 38 1 -39 38 1 -40 38 1 -46 38 1 -47 38 1 -48 38 1 -49 38 1 -57 38 1 -58 38 1 -59 38 1 -39 39 1 -40 39 1 -47 39 1 -48 39 1 -49 39 1 -50 39 1 -58 39 1 -59 39 1 -60 39 1 -40 40 1 -48 40 1 -49 40 1 -50 40 1 -59 40 1 -60 40 1 -41 41 1 -42 41 1 -43 41 1 -51 41 1 -52 41 1 -61 41 1 -42 42 1 -43 42 1 -44 42 1 -51 42 1 -52 42 1 -53 42 1 -61 42 1 -62 42 1 -43 43 1 -44 43 1 -45 43 1 -51 43 1 -52 43 1 -53 43 1 -54 43 1 -61 43 1 -62 43 1 -63 43 1 -44 44 1 -45 44 1 -46 44 1 -52 44 1 -53 44 1 -54 44 1 -55 44 1 -62 44 1 -63 44 1 -64 44 1 -45 45 1 -46 45 1 -47 45 1 -53 45 1 -54 45 1 -55 45 1 -56 45 1 -57 45 1 -63 45 1 -64 45 1 -65 45 1 -46 46 1 -47 46 1 -48 46 1 -54 46 1 -55 46 1 -56 46 1 -57 46 1 -58 46 1 -64 46 1 -65 46 1 -66 46 1 -67 46 1 -68 46 1 -47 47 1 -48 47 1 -49 47 1 -55 47 1 -56 47 1 -57 47 1 -58 47 1 -59 47 1 -67 47 1 -68 47 1 -69 47 1 -48 48 1 -49 48 1 -50 48 1 -57 48 1 -58 48 1 -59 48 1 -60 48 1 -68 48 1 -69 48 1 -70 48 1 -49 49 1 -50 49 1 -58 49 1 -59 49 1 -60 49 1 -69 49 1 -70 49 1 -50 50 1 -59 50 1 -60 50 1 -70 50 1 -51 51 1 -52 51 1 -53 51 1 -61 51 1 -62 51 1 -71 51 1 -52 52 1 -53 52 1 -54 52 1 -61 52 1 -62 52 1 -63 52 1 -71 52 1 -72 52 1 -53 53 1 -54 53 1 -55 53 1 -61 53 1 -62 53 1 -63 53 1 -64 53 1 -71 53 1 -72 53 1 -73 53 1 -54 54 1 -55 54 1 -56 54 1 -62 54 1 -63 54 1 -64 54 1 -65 54 1 -72 54 1 -73 54 1 -74 54 1 -55 55 1 -56 55 1 -57 55 1 -63 55 1 -64 55 1 -65 55 1 -66 55 1 -67 55 1 -73 55 1 -74 55 1 -75 55 1 -56 56 1 -57 56 1 -58 56 1 -64 56 1 -65 56 1 -66 56 1 -67 56 1 -68 56 1 -74 56 1 -75 56 1 -76 56 1 -77 56 1 -78 56 1 -57 57 1 -58 57 1 -59 57 1 -65 57 1 -66 57 1 -67 57 1 -68 57 1 -69 57 1 -77 57 1 -78 57 1 -79 57 1 -58 58 1 -59 58 1 -60 58 1 -67 58 1 -68 58 1 -69 58 1 -70 58 1 -78 58 1 -79 58 1 -80 58 1 -59 59 1 -60 59 1 -68 59 1 -69 59 1 -70 59 1 -79 59 1 -80 59 1 -60 60 1 -69 60 1 -70 60 1 -80 60 1 -61 61 1 -62 61 1 -63 61 1 -71 61 1 -72 61 1 -81 61 1 -62 62 1 -63 62 1 -64 62 1 -71 62 1 -72 62 1 -73 62 1 -81 62 1 -82 62 1 -63 63 1 -64 63 1 -65 63 1 -71 63 1 -72 63 1 -73 63 1 -74 63 1 -81 63 1 -82 63 1 -83 63 1 -64 64 1 -65 64 1 -66 64 1 -72 64 1 -73 64 1 -74 64 1 -75 64 1 -82 64 1 -83 64 1 -84 64 1 -65 65 1 -66 65 1 -67 65 1 -73 65 1 -74 65 1 -75 65 1 -76 65 1 -77 65 1 -83 65 1 -84 65 1 -85 65 1 -66 66 1 -67 66 1 -68 66 1 -74 66 1 -75 66 1 -76 66 1 -77 66 1 -78 66 1 -84 66 1 -85 66 1 -86 66 1 -87 66 1 -88 66 1 -67 67 1 -68 67 1 -69 67 1 -75 67 1 -76 67 1 -77 67 1 -78 67 1 -79 67 1 -87 67 1 -88 67 1 -89 67 1 -68 68 1 -69 68 1 -70 68 1 -77 68 1 -78 68 1 -79 68 1 -80 68 1 -88 68 1 -89 68 1 -90 68 1 -69 69 1 -70 69 1 -78 69 1 -79 69 1 -80 69 1 -89 69 1 -90 69 1 -70 70 1 -79 70 1 -80 70 1 -90 70 1 -71 71 1 -72 71 1 -73 71 1 -81 71 1 -82 71 1 -91 71 1 -72 72 1 -73 72 1 -74 72 1 -81 72 1 -82 72 1 -83 72 1 -91 72 1 -92 72 1 -73 73 1 -74 73 1 -75 73 1 -81 73 1 -82 73 1 -83 73 1 -84 73 1 -91 73 1 -92 73 1 -93 73 1 -74 74 1 -75 74 1 -76 74 1 -82 74 1 -83 74 1 -84 74 1 -85 74 1 -92 74 1 -93 74 1 -94 74 1 -75 75 1 -76 75 1 -77 75 1 -83 75 1 -84 75 1 -85 75 1 -86 75 1 -87 75 1 -93 75 1 -94 75 1 -95 75 1 -76 76 1 -77 76 1 -78 76 1 -84 76 1 -85 76 1 -86 76 1 -87 76 1 -88 76 1 -94 76 1 -95 76 1 -96 76 1 -97 76 1 -98 76 1 -77 77 1 -78 77 1 -79 77 1 -85 77 1 -86 77 1 -87 77 1 -88 77 1 -89 77 1 -97 77 1 -98 77 1 -99 77 1 -78 78 1 -79 78 1 -80 78 1 -87 78 1 -88 78 1 -89 78 1 -90 78 1 -98 78 1 -99 78 1 -100 78 1 -79 79 1 -80 79 1 -88 79 1 -89 79 1 -90 79 1 -99 79 1 -100 79 1 -80 80 1 -89 80 1 -90 80 1 -100 80 1 -81 81 1 -82 81 1 -83 81 1 -91 81 1 -92 81 1 -82 82 1 -83 82 1 -84 82 1 -91 82 1 -92 82 1 -93 82 1 -83 83 1 -84 83 1 -85 83 1 -91 83 1 -92 83 1 -93 83 1 -94 83 1 -84 84 1 -85 84 1 -86 84 1 -92 84 1 -93 84 1 -94 84 1 -95 84 1 -85 85 1 -86 85 1 -87 85 1 -93 85 1 -94 85 1 -95 85 1 -96 85 1 -97 85 1 -86 86 1 -87 86 1 -88 86 1 -94 86 1 -95 86 1 -96 86 1 -97 86 1 -98 86 1 -87 87 1 -88 87 1 -89 87 1 -95 87 1 -96 87 1 -97 87 1 -98 87 1 -99 87 1 -88 88 1 -89 88 1 -90 88 1 -97 88 1 -98 88 1 -99 88 1 -100 88 1 -89 89 1 -90 89 1 -98 89 1 -99 89 1 -100 89 1 -90 90 1 -99 90 1 -100 90 1 -91 91 1 -92 91 1 -93 91 1 -92 92 1 -93 92 1 -94 92 1 -93 93 1 -94 93 1 -95 93 1 -94 94 1 -95 94 1 -96 94 1 -95 95 1 -96 95 1 -97 95 1 -96 96 1 -97 96 1 -98 96 1 -97 97 1 -98 97 1 -99 97 1 -98 98 1 -99 98 1 -100 98 1 -99 99 1 -100 99 1 -100 100 1 diff --git a/docs/src/tutorial.md b/docs/src/tutorial.md new file mode 100644 index 00000000..fec54f13 --- /dev/null +++ b/docs/src/tutorial.md @@ -0,0 +1,323 @@ +# Tutorial + +Here we give a brief introduction to the contents of the package, see the [API reference](@ref) for more details. + +```@example tutorial +using SparseMatrixColorings +using LinearAlgebra +using SparseArrays +using StableRNGs +using SparseMatrixColorings: show_colors # hide +using Images # hide + +scale=15 # hide +pad=3 # hide +border=2 # hide +nothing # hide +``` + +## Coloring problems and algorithms + +SparseMatrixColorings.jl is based on the combination of a coloring problem and a coloring algorithm, which will be passed to the [`coloring`](@ref) function. + +The problem defines what you want to solve. It is always a [`ColoringProblem`](@ref), and you can select options such as + +- the structure of the matrix (`:nonsymmetric` or `:symmetric`) +- the type of partition you want (`:column`, `:row` or `:bidirectional`). + +```@example tutorial +problem = ColoringProblem() +``` + +The algorithm defines how you want to solve it. It can be either a [`GreedyColoringAlgorithm`](@ref) or a [`ConstantColoringAlgorithm`](@ref). For `GreedyColoringAlgorithm`, you can select options such as + +- the order in which vertices are processed (a subtype of [`AbstractOrder`](@ref SparseMatrixColorings.AbstractOrder)) +- the type of decompression you want (`:direct` or `:substitution`) + +```@example tutorial +algo = GreedyColoringAlgorithm() +``` + +## Coloring results + +The [`coloring`](@ref) function takes a matrix, a problem and an algorithm, to return a result subtyping [`AbstractColoringResult`](@ref). + +```@example tutorial +S = sparse([ + 0 0 1 1 0 1 + 1 0 0 0 1 0 + 0 1 0 0 1 0 + 0 1 1 0 0 0 +]) + +result = coloring(S, problem, algo) +``` + +The detailed type and fields of that result are _not part of the public API_. +To access its contents, you can use the following getters: + +- [`sparsity_pattern`](@ref) for the matrix initially provided to `coloring` +- [`ncolors`](@ref) for the total number of distinct colors +- [`row_colors`](@ref), [`column_colors`](@ref) for vectors of integer colors (depending on the partition) +- [`row_groups`](@ref), [`column_groups`](@ref) for vector of row or column indices grouped by color (depending on the partition) + +Here, we have a column coloring, so we can try the following: + +```@example tutorial +column_colors(result) +``` + +```@example tutorial +column_groups(result) +``` + +```@example tutorial +ncolors(result) +``` + +## Compression and decompression + +The functions [`compress`](@ref) and [`decompress`](@ref) efficiently store and retrieve compressed representations of sparse matrices, using the coloring result as a starting point. + +Compression sums all columns or rows with the same color: + +```@example tutorial +M = sparse([ + 0 0 4 6 0 9 + 1 0 0 0 7 0 + 0 2 0 0 8 0 + 0 3 5 0 0 0 +]) + +B = compress(M, result) +``` + +Decompression recovers the original matrix from its compressed version: + +```@example tutorial +C = decompress(B, result) +``` + +The functions [`decompress!`](@ref) and [`decompress_single_color!`](@ref) are in-place variants of [`decompress`](@ref). + +```@example tutorial +D = [ + 10 14 18 + 11 15 0 + 12 16 0 + 13 17 0 +] + +decompress!(C, D, result) +``` + +```@example tutorial +nonzeros(C) .= -1 +decompress_single_color!(C, D[:, 2], 2, result) +``` + +## Unidirectional variants + +We now illustrate the variants of colorings available, on the following matrix: + +```@example tutorial +S = sparse(Symmetric(sprand(StableRNG(0), Bool, 10, 10, 0.4))) +``` + +We start with unidirectional colorings, where only rows or columns are colored and the matrix is not assumed to be symmetric. + +### Column coloring + +```@example tutorial +problem = ColoringProblem(; structure=:nonsymmetric, partition=:column) +algo = GreedyColoringAlgorithm(; decompression=:direct) +result = coloring(S, problem, algo) +nothing # hide +``` + +```@example tutorial +ncolors(result), column_colors(result) +``` + +Here is the colored matrix + +```@example tutorial +A_img, B_img = show_colors(result; scale, pad, border) # hide +A_img # hide +``` + +and its columnwise compression + +```@example tutorial +B_img # hide +``` + +### Row coloring + +```@example tutorial +problem = ColoringProblem(; structure=:nonsymmetric, partition=:row) +algo = GreedyColoringAlgorithm(; decompression=:direct) +result = coloring(S, problem, algo) +nothing # hide +``` + +```@example tutorial +ncolors(result), row_colors(result) +``` + +Here is the colored matrix + +```@example tutorial +A_img, B_img = show_colors(result; scale, pad, border) # hide +A_img # hide +``` + +and its rowwise compression + +```@example tutorial +B_img # hide +``` + +## Symmetric variants + +We continue with unidirectional symmetric colorings, where coloring rows is equivalent to coloring columns. +Symmetry is leveraged to possibly reduce the number of necessary colors. + +### Star coloring + +Star coloring is the algorithm used for symmetric matrices with direct decompression. + +```@example tutorial +problem = ColoringProblem(; structure=:symmetric, partition=:column) +algo = GreedyColoringAlgorithm(; decompression=:direct) +result = coloring(S, problem, algo) +nothing # hide +``` + +```@example tutorial +ncolors(result), column_colors(result) +``` + +Here is the colored matrix + +```@example tutorial +A_img, B_img = show_colors(result; scale, pad, border) # hide +A_img # hide +``` + +and its columnwise compression + +```@example tutorial +B_img # hide +``` + +### Acyclic coloring + +Acyclic coloring is the algorithm used for symmetric matrices with decompression by substitution. + +```@example tutorial +problem = ColoringProblem(; structure=:symmetric, partition=:column) +algo = GreedyColoringAlgorithm(; decompression=:substitution) +result = coloring(S, problem, algo) +nothing # hide +``` + +```@example tutorial +ncolors(result), column_colors(result) +``` + +Here is the colored matrix + +```@example tutorial +A_img, B_img = show_colors(result; scale, pad, border) # hide +A_img # hide +``` + +and its columnwise compression + +```@example tutorial +B_img # hide +``` + +## Bidirectional variants + +We finish with bidirectional colorings, where both rows and columns are colored and the matrix is not assumed to be symmetric. + +Bicoloring is most relevant for matrices with dense rows and columns, which is why we consider the following test case: + +```@example tutorial +S_bi = copy(S) +S_bi[:, 1] .= true +S_bi[1, :] .= true +S_bi +``` + +With our implementations, bidirectional coloring works better using a [`RandomOrder`](@ref). + +### Star bicoloring + +```@example tutorial +problem = ColoringProblem(; structure=:nonsymmetric, partition=:bidirectional) +algo = GreedyColoringAlgorithm(RandomOrder(StableRNG(0), 0); decompression=:direct) +result = coloring(S_bi, problem, algo) +nothing # hide +``` + +```@example tutorial +ncolors(result), column_colors(result) +``` + +Here is the colored matrix + +```@example tutorial +Arc_img, _, _, Br_img, Bc_img = show_colors(result; scale, pad, border) # hide +Arc_img # hide +``` + +its columnwise compression + +```@example tutorial +Bc_img # hide +``` + +and rowwise compression + +```@example tutorial +Br_img # hide +``` + +Both are necessary to reconstruct the original. + +#### Acyclic bicoloring + +```@example tutorial +problem = ColoringProblem(; structure=:nonsymmetric, partition=:bidirectional) +algo = GreedyColoringAlgorithm(RandomOrder(StableRNG(0), 0); decompression=:substitution) +result = coloring(S_bi, problem, algo) +nothing # hide +``` + +```@example tutorial +ncolors(result), column_colors(result) +``` + +Here is the colored matrix + +```@example tutorial +Arc_img, _, _, Br_img, Bc_img = show_colors(result; scale=20, pad, border) # hide +Arc_img # hide +``` + +its columnwise compression + +```@example tutorial +Bc_img # hide +``` + +and rowwise compression + +```@example tutorial +Br_img # hide +``` + +Both are necessary to reconstruct the original. diff --git a/docs/src/tutorials.md b/docs/src/tutorials.md deleted file mode 100644 index f441d61b..00000000 --- a/docs/src/tutorials.md +++ /dev/null @@ -1,237 +0,0 @@ -# Tutorials - -## Introduction to SparseMatrixColorings.jl - -The three main functions to perform a coloring with `SparseMatrixColorings.jl` are [`coloring`](@ref coloring), [`ColoringProblem`](@ref ColoringProblem) and [`GreedyColoringAlgorithm`](@ref GreedyColoringAlgorithm). - -```@example tutorial; continued = true -using SparseMatrixColorings, SparseArrays - -S = sparse([ - 0 0 1 1 0 1 - 1 0 0 0 1 0 - 0 1 0 0 1 0 - 0 1 1 0 0 0 -]) - -problem = ColoringProblem() -algo = GreedyColoringAlgorithm() -result = coloring(S, problem, algo) -``` - -Based on the result of `coloring`, you can easily recover a vector of integer colors with [`row_colors`](@ref row_colors), [`column_colors`](@ref column_colors), as well as the groups of colors with [`row_groups`](@ref row_groups) and [`column_groups`](@ref column_groups). - -```@example tutorial -column_colors(result) -``` - -```@example tutorial -column_groups(result) -``` - -The number of colors can be determined with [`ncolors`](@ref ncolors). -```@example tutorial -ncolors(result) -``` - -The functions [`compress`](@ref compress) and [`decompress`](@ref decompress) efficiently store and retrieve compressed representations of colorings for sparse matrices. - -```@example tutorial -M = sparse([ - 0 0 4 6 0 9 - 1 0 0 0 7 0 - 0 2 0 0 8 0 - 0 3 5 0 0 0 -]) - -B = compress(M, result) -``` - -```@example tutorial -C = decompress(B, result) -``` - -The functions [`decompress!`](@ref decompress!) and [`decompress_single_color!`](@ref decompress_single_color!) are in-place variants of [`decompress`](@ref decompress). - -```@example tutorial -D = [10 14 18 - 11 15 0 - 12 16 0 - 13 17 0] - -decompress!(C, D, result) -``` -```@example tutorial -C .= 0 -decompress_single_color!(C, D[:, 2], 2, result) -``` - -We now illustrate the six variants of colorings available in `SparseMatrixColorings.jl` on the following matrix with a symmetric sparsity pattern. - -```@example tutorial -using SparseMatrixColorings: show_colors # hide -using Images # hide -using MatrixMarket -S = MatrixMarket.mmread("smc.mtx") -``` - -## Column coloring - -```@example tutorial; continued = true -problem = ColoringProblem(; structure=:nonsymmetric, - partition=:column) - -order = NaturalOrder() - -algo = GreedyColoringAlgorithm(order; - decompression=:direct) - -result = coloring(S, problem, algo) -``` -```@example tutorial -ccolors = column_colors(result) -cgroups = column_groups(result) -num_colors = ncolors(result) -``` - -```@example tutorial -A_img, B_img = show_colors(result, scale=5, pad=2) # hide -A_img # hide -``` - -## Row coloring - -```@example tutorial; continued = true -problem = ColoringProblem(; structure=:nonsymmetric, - partition=:row) - -order = LargestFirst() - -algo = GreedyColoringAlgorithm(order; - decompression=:direct) - -result = coloring(S, problem, algo) -``` - -```@example tutorial -rcolors = row_colors(result) -rgroups = row_groups(result) -num_colors = ncolors(result) -``` - -```@example tutorial -A_img, B_img = show_colors(result, scale=5, pad=2) # hide -A_img # hide -``` - -## Star bicoloring - -```@example tutorial; continued = true -using SparseMatrixColorings, MatrixMarket - -S = MatrixMarket.mmread("smc.mtx") - -problem = ColoringProblem(; structure=:nonsymmetric, - partition=:bidirectional) - -order = RandomOrder() - -algo = GreedyColoringAlgorithm(order; - decompression=:direct, - postprocessing=true) - -result = coloring(S, problem, algo) -``` - -```@example tutorial -rcolors = row_colors(result) -rgroups = row_groups(result) -ccolors = column_colors(result) -cgroups = column_groups(result) -num_colors = ncolors(result) -``` - -```@example tutorial -A_img, Br_img, Bc_img = show_colors(result, scale=5, pad=2) # hide -A_img # hide -``` - -## Acyclic bicoloring - -```@example tutorial; continued = true -problem = ColoringProblem(; structure=:nonsymmetric, - partition=:bidirectional) - -order = RandomOrder() - -algo = GreedyColoringAlgorithm(order; - decompression=:substitution, - postprocessing=true) - -result = coloring(S, problem, algo) -``` - -```@example tutorial -rcolors = row_colors(result) -rgroups = row_groups(result) -ccolors = column_colors(result) -cgroups = column_groups(result) -num_colors = ncolors(result) -``` - -```@example tutorial -A_img, Br_img, Bc_img = show_colors(result, scale=5, pad=2) # hide -A_img # hide -``` - -## Symmetric star coloring - -```@example tutorial; continued = true -problem = ColoringProblem(; structure=:symmetric, - partition=:column) - -order = NaturalOrder() - -algo = GreedyColoringAlgorithm(order; - decompression=:direct, - postprocessing=false) - -result = coloring(S, problem, algo) -``` - -```@example tutorial -ccolors = column_colors(result) -cgroups = column_groups(result) -num_colors = ncolors(result) -``` - -```@example tutorial -A_img, B_img = show_colors(result, scale=5, pad=2) # hide -A_img # hide -``` - -## Symmetric acyclic coloring - -```@example tutorial; continued = true -problem = ColoringProblem(; structure=:symmetric, - partition=:column) - -order = NaturalOrder() - -algo = GreedyColoringAlgorithm(order; - decompression=:substitution, - postprocessing=false) - -result = coloring(S, problem, algo) -``` - -```@example tutorial -ccolors = column_colors(result) -cgroups = column_groups(result) -num_colors = ncolors(result) -``` - -```@example tutorial -A_img, B_img = show_colors(result, scale=5, pad=2) # hide -A_img # hide -``` diff --git a/src/decompression.jl b/src/decompression.jl index 97aa0900..bc04394c 100644 --- a/src/decompression.jl +++ b/src/decompression.jl @@ -116,6 +116,9 @@ The in-place alternative is [`decompress!`](@ref). Compression means summing either the columns or the rows of `A` which share the same color. It is done by calling [`compress`](@ref). +!!! warning + For some coloring variants, the `result` object is mutated during decompression. + # Example ```jldoctest @@ -196,6 +199,9 @@ It is done by calling [`compress`](@ref). For `:symmetric` coloring results (and for those only), an optional positional argument `uplo in (:U, :L, :F)` can be passed to specify which part of the matrix `A` should be updated: the Upper triangle, the Lower triangle, or the Full matrix. When `A isa SparseMatrixCSC`, using the `uplo` argument requires a target matrix which only stores the relevant triangle(s). +!!! warning + For some coloring variants, the `result` object is mutated during decompression. + # Example ```jldoctest @@ -261,6 +267,9 @@ Decompress the vector `b` corresponding to color `c` in-place into `A`, given a For `:symmetric` coloring results (and for those only), an optional positional argument `uplo in (:U, :L, :F)` can be passed to specify which part of the matrix `A` should be updated: the Upper triangle, the Lower triangle, or the Full matrix. When `A isa SparseMatrixCSC`, using the `uplo` argument requires a target matrix which only stores the relevant triangle(s). +!!! warning + For some coloring variants, the `result` object is mutated during decompression. + # Example ```jldoctest