From d6b2392fb477f997cb4b6fcbd4f0913579c9161e Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Fri, 24 May 2024 19:20:55 +0200 Subject: [PATCH 1/4] Adjusting docu following PR #3700 --- docs/oscar_references.bib | 14 +++ .../CommutativeAlgebra/homological_algebra.md | 2 +- docs/src/CommutativeAlgebra/intro.md | 4 +- .../UngradedModules/FreeResolutions.jl | 95 ++++++++++++++++++- 4 files changed, 109 insertions(+), 6 deletions(-) diff --git a/docs/oscar_references.bib b/docs/oscar_references.bib index 9f41157264b..5eb4ae50eea 100644 --- a/docs/oscar_references.bib +++ b/docs/oscar_references.bib @@ -761,6 +761,20 @@ @Article{EM19 doi = {10.1112/jlms.12232} } +@Article{EMSS16, + author = {Er{\"o}cal, Bur{\c{c}}in and Motsak, Oleksandr and Schreyer, Frank-Olaf and Steenpa{\ss}, Andreas}, + title = {Refined algorithms to compute syzygies}, + zbl = {1405.14138}, + journal = {J. Symb. Comput.}, + fjournal = {Journal of Symbolic Computation}, + volume = {74}, + pages = {308--327}, + year = {2016}, + doi = {10.1016/j.jsc.2015.07.004}, + language = {English}, + zbmath = {6517845} +} + @Article{ES96, author = {Eisenbud, David and Sturmfels, Bernd}, title = {Binomial ideals}, diff --git a/docs/src/CommutativeAlgebra/homological_algebra.md b/docs/src/CommutativeAlgebra/homological_algebra.md index fc25f5605bb..c72abda1140 100644 --- a/docs/src/CommutativeAlgebra/homological_algebra.md +++ b/docs/src/CommutativeAlgebra/homological_algebra.md @@ -24,7 +24,7 @@ presentation(M::ModuleFP) present_as_cokernel(M::SubquoModule, task::Symbol = :none) ``` -## Syzygies and Free Resolutions +## Free Resolutions ```@docs free_resolution(M::SubquoModule{<:MPolyRingElem}; diff --git a/docs/src/CommutativeAlgebra/intro.md b/docs/src/CommutativeAlgebra/intro.md index 4927dd41dcc..f4d2f169ba3 100644 --- a/docs/src/CommutativeAlgebra/intro.md +++ b/docs/src/CommutativeAlgebra/intro.md @@ -27,8 +27,8 @@ a *Gröbner basis*. We refer to the corresponding [section](@ref gb_fields) in t !!! note In Oscar, it is possible to equip multivariate polynomial rings with gradings by finitely presented groups. - Most functions discussed in this chapter apply to both ungraded and graded polynomial rings. However, - for simplicity of the presentation, in this documentation, the functions are often only illustrated by examples with + Most functions related to multivariate polynomial rings discussed in this chapter apply to both the ungraded and graded case. + However, for simplicity of the presentation, in this documentation, the functions are often only illustrated by examples with focus on the former case, but work similarly for homogeneous ideals and graded modules in the latter case. !!! note diff --git a/src/Modules/UngradedModules/FreeResolutions.jl b/src/Modules/UngradedModules/FreeResolutions.jl index b7312236e7b..e53acbc7cd7 100644 --- a/src/Modules/UngradedModules/FreeResolutions.jl +++ b/src/Modules/UngradedModules/FreeResolutions.jl @@ -247,8 +247,26 @@ end Return a free resolution of `M`. If `length != 0`, the free resolution is only computed up to the `length`-th free module. -At the moment, options for `algorithm` are `:fres`, `:mres` and `:nres`. With `:mres` or `:nres`, -minimal free resolutions are returned. +Current options for `algorithm` are `:fres`, `:nres`, and `:mres`. + +!!! note + In the next note, we explain what the different options stand for. In doing so, we will not distinguish + between a homomorphism of free modules over `base_ring(M)` and the corresponding polynomial matrix. + Also, we somewhat abuse our notation by saying that a polynomial matrix is minimal if all its constant + entries are zero. We say that a (free) presentation is minimal if its presentation matrix is minimal. We say that + a free resolution is minimal, if all its syzygy matrices are minimal. Note that in the graded case, this gives + the usual notion of minimality. In this case, minimal free resolutions are unique up to isomorphism. + +!!! note + The function `free_resolution` first computes a presentation of `M`, thus obtaining a + presentation matrix (a first syzygy matrix) of `M`. It then proceeds by successively computing + higher syzygy modules, thus obtaining higher syzygy matrices. With `:fres`, the successive computation + of syzygies follows an enhanced version of Schreyer's algorithm [EMSS16](@cite). Typically, the + resulting resolution is far from being minimal. With `:nres` and `:mres`, a variant of the + standard algorithm to compute higher syzygy modules is used. Here, the algorithm is implemented + so that it returns higher syzygy matrices which are minimal. The difference between `:nres` and `:mres` + is that with `:mres`, already the presentation computed at the beginning is minimal. In particular, in the + graded case, using `:mres` yields a free resolution which is minimal in the usual sense. # Examples ```jldoctest @@ -293,11 +311,82 @@ R^2 <---- R^6 <---- R^6 <---- R^2 <---- 0 julia> is_complete(fr) true +``` + +``` +julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]); + +julia> Z = R(0) +0 -julia> fr = free_resolution(M, algorithm=:fres) +julia> O = R(1) +1 + +julia> B = [Z Z Z Z Z O; w^2-x*z w*x-y*z x^2-w*y x*y-z^2 y^2-w*z Z]; + +julia> A = transpose(matrix(B)); + +julia> M = graded_cokernel(A) +Graded subquotient of submodule of R^2 generated by +1 -> e[1] +2 -> e[2] +by submodule of R^2 generated by +1 -> (w^2 - x*z)*e[2] +2 -> (w*x - y*z)*e[2] +3 -> (-w*y + x^2)*e[2] +4 -> (x*y - z^2)*e[2] +5 -> (-w*z + y^2)*e[2] +6 -> e[1] + +julia> FM1 = free_resolution(M) Free resolution of M R^2 <---- R^6 <---- R^6 <---- R^2 <---- 0 0 1 2 3 4 + +julia> FM1[1] +Graded free module R^1([0]) + R^5([-2]) of rank 6 over R + +julia> betti_table(FM1) + 0 1 2 3 +----------------- +-1 : - 1 - - +0 : 2 - - - +1 : - 5 5 1 +2 : - - 1 1 +----------------- +total: 2 6 6 2 + + +julia> FM2 = free_resolution(M, algorithm = :nres) +Free resolution of M +R^2 <---- R^6 <---- R^5 <---- R^1 <---- 0 +0 1 2 3 4 + +julia> betti_table(FM2) + 0 1 2 3 +----------------- +-1 : - 1 - - +0 : 2 - - - +1 : - 5 5 - +2 : - - - 1 +----------------- +total: 2 6 5 1 + + +julia> FM3 = free_resolution(M, algorithm = :mres) +Free resolution of M +R^1 <---- R^5 <---- R^5 <---- R^1 <---- 0 +0 1 2 3 4 + +julia> betti_table(FM3) + 0 1 2 3 +----------------- +0 : 1 - - - +1 : - 5 5 - +2 : - - - 1 +----------------- +total: 1 5 5 1 + ``` **Note:** Over rings other than polynomial rings, the method will default to a lazy, From 429e713490f1f9f71a0c03e90437fb616ad245a3 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Mon, 27 May 2024 14:15:12 +0200 Subject: [PATCH 2/4] More illustrative example --- .../UngradedModules/FreeResolutions.jl | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/src/Modules/UngradedModules/FreeResolutions.jl b/src/Modules/UngradedModules/FreeResolutions.jl index e53acbc7cd7..625b03f7124 100644 --- a/src/Modules/UngradedModules/FreeResolutions.jl +++ b/src/Modules/UngradedModules/FreeResolutions.jl @@ -250,11 +250,11 @@ If `length != 0`, the free resolution is only computed up to the `length`-th fre Current options for `algorithm` are `:fres`, `:nres`, and `:mres`. !!! note - In the next note, we explain what the different options stand for. In doing so, we will not distinguish + In the note below, we explain what the different options stand for. In doing so, we do not distinguish between a homomorphism of free modules over `base_ring(M)` and the corresponding polynomial matrix. - Also, we somewhat abuse our notation by saying that a polynomial matrix is minimal if all its constant + Also, abusing our notation, we say that a polynomial matrix is minimal if all its constant entries are zero. We say that a (free) presentation is minimal if its presentation matrix is minimal. We say that - a free resolution is minimal, if all its syzygy matrices are minimal. Note that in the graded case, this gives + a free resolution is minimal if all its syzygy matrices are minimal. Note that in the graded case, this gives the usual notion of minimality. In this case, minimal free resolutions are unique up to isomorphism. !!! note @@ -322,7 +322,7 @@ julia> Z = R(0) julia> O = R(1) 1 -julia> B = [Z Z Z Z Z O; w^2-x*z w*x-y*z x^2-w*y x*y-z^2 y^2-w*z Z]; +julia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z]; julia> A = transpose(matrix(B)); @@ -331,35 +331,39 @@ Graded subquotient of submodule of R^2 generated by 1 -> e[1] 2 -> e[2] by submodule of R^2 generated by -1 -> (w^2 - x*z)*e[2] -2 -> (w*x - y*z)*e[2] -3 -> (-w*y + x^2)*e[2] -4 -> (x*y - z^2)*e[2] -5 -> (-w*z + y^2)*e[2] -6 -> e[1] +1 -> w*y*e[2] +2 -> (w*z - x*y)*e[2] +3 -> (x*z - y^2)*e[2] +4 -> e[1] julia> FM1 = free_resolution(M) Free resolution of M -R^2 <---- R^6 <---- R^6 <---- R^2 <---- 0 +R^2 <---- R^7 <---- R^8 <---- R^3 <---- 0 0 1 2 3 4 -julia> FM1[1] -Graded free module R^1([0]) + R^5([-2]) of rank 6 over R - julia> betti_table(FM1) 0 1 2 3 ----------------- -1 : - 1 - - 0 : 2 - - - -1 : - 5 5 1 -2 : - - 1 1 +1 : - 3 3 1 +2 : - 3 5 2 ----------------- -total: 2 6 6 2 +total: 2 7 8 3 + +julia> matrix(map(FM1, 1)) +[1 0] +[0 -x*z + y^2] +[0 -w*z + x*y] +[0 w*y] +[0 x^2*z] +[0 w*x*z] +[0 w^2*z] julia> FM2 = free_resolution(M, algorithm = :nres) Free resolution of M -R^2 <---- R^6 <---- R^5 <---- R^1 <---- 0 +R^2 <---- R^4 <---- R^4 <---- R^2 <---- 0 0 1 2 3 4 julia> betti_table(FM2) @@ -367,25 +371,37 @@ julia> betti_table(FM2) ----------------- -1 : - 1 - - 0 : 2 - - - -1 : - 5 5 - -2 : - - - 1 +1 : - 3 - - +2 : - - 4 2 ----------------- -total: 2 6 5 1 +total: 2 4 4 2 +julia> matrix(map(FM2, 1)) +[1 0] +[0 -x*z + y^2] +[0 -w*z + x*y] +[0 w*y] + julia> FM3 = free_resolution(M, algorithm = :mres) Free resolution of M -R^1 <---- R^5 <---- R^5 <---- R^1 <---- 0 +R^1 <---- R^3 <---- R^4 <---- R^2 <---- 0 0 1 2 3 4 julia> betti_table(FM3) 0 1 2 3 ----------------- 0 : 1 - - - -1 : - 5 5 - -2 : - - - 1 +1 : - 3 - - +2 : - - 4 2 ----------------- -total: 1 5 5 1 +total: 1 3 4 2 + + +julia> matrix(map(FM3, 1)) +[-x*z + y^2] +[-w*z + x*y] +[ w*y] ``` From b67d3e4e0637c4c8b20d225d5debfb963b67575f Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Tue, 28 May 2024 15:59:24 +0200 Subject: [PATCH 3/4] Documenting more methods and improving text --- .../CommutativeAlgebra/homological_algebra.md | 7 ++ .../UngradedModules/FreeResolutions.jl | 28 ++--- src/Modules/UngradedModules/Presentation.jl | 113 ++++++++++++------ 3 files changed, 96 insertions(+), 52 deletions(-) diff --git a/docs/src/CommutativeAlgebra/homological_algebra.md b/docs/src/CommutativeAlgebra/homological_algebra.md index c72abda1140..fdcd5f93aac 100644 --- a/docs/src/CommutativeAlgebra/homological_algebra.md +++ b/docs/src/CommutativeAlgebra/homological_algebra.md @@ -12,6 +12,13 @@ for module homomorphisms and basic functions for handling chain and cochain comp discussed in the module section. Building on these functions, we here introduce further OSCAR functionality supporting computations in homological algebra. + +## Pruning Modules + +```@docs +prune_with_map(M::ModuleFP) +``` + ## Presentations ```@docs diff --git a/src/Modules/UngradedModules/FreeResolutions.jl b/src/Modules/UngradedModules/FreeResolutions.jl index 625b03f7124..81e32c5e6c8 100644 --- a/src/Modules/UngradedModules/FreeResolutions.jl +++ b/src/Modules/UngradedModules/FreeResolutions.jl @@ -241,7 +241,7 @@ end @doc raw""" free_resolution(M::SubquoModule{<:MPolyRingElem}; ordering::ModuleOrdering = default_ordering(M), - length::Int=0, algorithm::Symbol=:fres + length::Int = 0, algorithm::Symbol = :fres ) Return a free resolution of `M`. @@ -250,23 +250,19 @@ If `length != 0`, the free resolution is only computed up to the `length`-th fre Current options for `algorithm` are `:fres`, `:nres`, and `:mres`. !!! note - In the note below, we explain what the different options stand for. In doing so, we do not distinguish - between a homomorphism of free modules over `base_ring(M)` and the corresponding polynomial matrix. - Also, abusing our notation, we say that a polynomial matrix is minimal if all its constant - entries are zero. We say that a (free) presentation is minimal if its presentation matrix is minimal. We say that - a free resolution is minimal if all its syzygy matrices are minimal. Note that in the graded case, this gives - the usual notion of minimality. In this case, minimal free resolutions are unique up to isomorphism. + The function first computes a presentation of `M`. It then successively computes + higher syzygy modules. !!! note - The function `free_resolution` first computes a presentation of `M`, thus obtaining a - presentation matrix (a first syzygy matrix) of `M`. It then proceeds by successively computing - higher syzygy modules, thus obtaining higher syzygy matrices. With `:fres`, the successive computation - of syzygies follows an enhanced version of Schreyer's algorithm [EMSS16](@cite). Typically, the - resulting resolution is far from being minimal. With `:nres` and `:mres`, a variant of the - standard algorithm to compute higher syzygy modules is used. Here, the algorithm is implemented - so that it returns higher syzygy matrices which are minimal. The difference between `:nres` and `:mres` - is that with `:mres`, already the presentation computed at the beginning is minimal. In particular, in the - graded case, using `:mres` yields a free resolution which is minimal in the usual sense. + - If `algorithm == mres`, and `M` is positively graded, a minimal free resolution is returned. + - If `algorithm == nres`, and `M` is positively graded, the function proceeds as above except + that it starts by computing a presentation which is not neccessarily minimal. + In both cases, if `M` is not (positively) graded, the function still aims at returning an ''improved'' resolution. + +!!! note + If `algorithm == fres`, the function relies on an enhanced version of Schreyer's algorithm + [EMSS16](@cite). Typically, this is more efficient than the approaches above, but the + resulting resolution is far from being minimal. # Examples ```jldoctest diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index 24ba8ce886d..8b5e83af93c 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -1,10 +1,13 @@ #################### @doc raw""" - presentation(M::SubquoModule; minimal=false) + presentation(M::SubquoModule; minimal = false) -Return a free presentation of `M`. If `minimal` is set to `true`, the returned -presentation is minimal. +Return a (free) presentation of `M`. + +!!! note + If `minimal` is `true`, and `M` is positively graded, a minimal presentation is returned. + If `minimal` is `true`, and `M` is not (positively) graded, the function still aims at returning an ''improved'' presentation. """ function presentation(SQ::SubquoModule; minimal=false) @@ -191,9 +194,9 @@ end @doc raw""" presentation(F::FreeMod) -Return a free presentation of `F`. +Return a (free) presentation of `F`. """ -function presentation(F::FreeMod) +function presentation(F::FreeMod; minimal = false) if is_graded(F) Z = graded_free_module(F.R, 0) else @@ -206,22 +209,48 @@ function presentation(F::FreeMod) end @doc raw""" - presentation(M::ModuleFP) + presentation(M::ModuleFP; minimal = false) + +Return a (free) presentation of `M`. -Return a free presentation of `M`. +!!! note + If `minimal` is `true`, and `M` is positively graded, a minimal presentation is returned. + If `minimal` is `true`, and `M` is not (positively) graded, the function still aims at returning an ''improved'' presentation. # Examples ```jldoctest -julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]); +julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]); -julia> A = R[x; y]; +julia> Z = R(0) +0 -julia> B = R[x^2; y^3; z^4]; +julia> O = R(1) +1 -julia> M = SubquoModule(A, B); +julia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z]; + +julia> A = transpose(matrix(B)) +[0 w*y] +[0 w*z - x*y] +[0 x*z - y^2] +[1 0] + +julia> M = graded_cokernel(A) +Graded subquotient of submodule of R^2 generated by +1 -> e[1] +2 -> e[2] +by submodule of R^2 generated by +1 -> w*y*e[2] +2 -> (w*z - x*y)*e[2] +3 -> (x*z - y^2)*e[2] +4 -> e[1] + +julia> PM1 = presentation(M) +0 <---- M <---- R^2 <---- R^4 + +julia> PM2 = presentation(M, minimal = true) +0 <---- M <---- R^1 <---- R^3 -julia> P = presentation(M) -0 <---- M <---- R^2 <---- R^5 ``` ```jldoctest @@ -313,7 +342,7 @@ e[5] -> z^4*e[2] Homogeneous module homomorphism ``` """ -function presentation(M::ModuleFP) +function presentation(M::ModuleFP; minimal=false) error("presentation is not implemented for the given types.") end @@ -477,36 +506,48 @@ end @doc raw""" prune_with_map(M::ModuleFP) -Returns another module `N` and an isomorphism from `N` to `M` such +If `M` is positively graded, return a module `N` and an isomorphism from `N` to `M` such that `N` is generated by a minimal number of elements. +If `M` is not (positively) graded, the function still aims at reducing the number of generators. + # Examples ```jldoctest -julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]); +julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]); -julia> M = SubquoModule(identity_matrix(R, 2), R[1 x+y]) -Subquotient of Submodule with 2 generators +julia> Z = R(0) +0 + +julia> O = R(1) +1 + +julia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z]; + +julia> A = transpose(matrix(B)) +[0 w*y] +[0 w*z - x*y] +[0 x*z - y^2] +[1 0] + +julia> M = graded_cokernel(A) +Graded subquotient of submodule of R^2 generated by 1 -> e[1] 2 -> e[2] -by Submodule with 1 generator -1 -> e[1] + (x + y)*e[2] +by submodule of R^2 generated by +1 -> w*y*e[2] +2 -> (w*z - x*y)*e[2] +3 -> (x*z - y^2)*e[2] +4 -> e[1] -julia> N, phi = prune_with_map(M) -(Submodule with 1 generator -1 -> e[1] -represented as subquotient with no relations., Map with following data -Domain: -======= -Submodule with 1 generator -1 -> e[1] -represented as subquotient with no relations. -Codomain: -========= -Subquotient of Submodule with 2 generators +julia> N, phi = prune_with_map(M); + +julia> N +Graded subquotient of submodule of R^1 generated by 1 -> e[1] -2 -> e[2] -by Submodule with 1 generator -1 -> e[1] + (x + y)*e[2]) +by submodule of R^1 generated by +1 -> (-x*z + y^2)*e[1] +2 -> (-w*z + x*y)*e[1] +3 -> w*y*e[1] julia> phi(first(gens(N))) e[2] @@ -566,7 +607,7 @@ end function _presentation_minimal(SQ::ModuleFP{T}; minimal_kernel::Bool=true) where {T<:MPolyRingElem{<:FieldElem}} R = base_ring(SQ) - + # Prepare to set some names br_name = AbstractAlgebra.get_name(R) if br_name === nothing From 52d9cb2de6c09bd881384568da1495d6adf8be52 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Tue, 28 May 2024 16:15:05 +0200 Subject: [PATCH 4/4] remove white space --- src/Modules/UngradedModules/Presentation.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index 8b5e83af93c..f651509f872 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -606,8 +606,9 @@ end function _presentation_minimal(SQ::ModuleFP{T}; minimal_kernel::Bool=true) where {T<:MPolyRingElem{<:FieldElem}} + R = base_ring(SQ) - + # Prepare to set some names br_name = AbstractAlgebra.get_name(R) if br_name === nothing