Resolutions

Functions for creating free resolutions of modules and ideals in Singular.jl return a special Singular object of type sresolution{T}. The support in Singular.jl for this type primarily exists to allow interaction with such resolutions. Free resolutions can have the property of being minimal, which is specified by the minimal field of the sresolution{T} type.

Resolution objects have a parent object which represents the set of resolutions they belong to, the data for which is given by the polynomial ring $R$ over which the modules in the resolution are defined.

The types of resolutions and associated parent objects are given in the following table according to the library providing them.

LibraryElement typeParent type
Singularsresolution{T}Singular.ResolutionSet{T}

These types are parameterised by the type of elements in the polynomial ring $R$ over which the modules belonging to the resolution are defined.

All resolution types belong directly to the abstract type SetElem and all the resolution set parent object types belong to the abstract type Set.

Resolution functionality

Singular.jl resolutions implement standard operations one would expect on all AbstractAlgebra compatible objects. These include:

  • Operations common to all AbstractAlgebra objects, such as parent, base_ring, elem_type, parent_type, parent, deepcopy, etc.

Below, we describe all of the functionality for Singular.jl resolutions that is not included in this list of basic operations.

Constructors

There are currently two ways to create resolutions in Singular.jl: They can either be created by taking the free resolution of an ideal or module over a polynomial ring, as described in the relevant sections of the documentation, or they can be created by the following constructor:

Singular.ResolutionMethod
Resolution(C::Vector{smodule{T}}) where T <: AbstractAlgebra.RingElem

Create a new resolution whose maps are given by the elements of an array C of modules. Note that it is not checked that the maps are actually composable and that their pairwise composition is the zero map, that is, that the created resolution is a complex.

source

Example

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular Polynomial Ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])

julia> M1 = Singular.Module(R, vector(R, x), vector(R, y))
Singular Module over Singular Polynomial Ring (QQ),(x,y),(dp(2),C), with Generators:
x*gen(1)
y*gen(1)

julia> M2 = Singular.Module(R, vector(R, y, -x))
Singular Module over Singular Polynomial Ring (QQ),(x,y),(dp(2),C), with Generators:
-x*gen(2)+y*gen(1)

julia> F = Resolution([M1, M2]);

julia> F[1]
Singular Module over Singular Polynomial Ring (QQ),(x,y),(dp(2),C), with Generators:
x*gen(1)
y*gen(1)

julia> F[2]
Singular Module over Singular Polynomial Ring (QQ),(x,y),(dp(2),C), with Generators:
-x*gen(2)+y*gen(1)

Alternatively, resolutions can be refined to minimal resolutions, as described below.

Other than this, there are currently no additional ways to create resolutions in Singular.jl.

Basic manipulation

Base.lengthMethod
length(r::sresolution)

Return the length of the resolution. This is what is mathematically meant by the length of a resolution. Over a field, this should be at most the number of variables in the polynomial ring.

source

Singular.jl overloads the getindex function so that one can access the modules in a resolution $F$.

F[n::Int]

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
(Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C), spoly{n_Q}[w, x, y, z])

julia> I = Ideal(R, w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z)
Singular ideal over Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C) with generators (w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z)

julia> F = fres(std(I), 0)
Singular resolution: R^1 <- R^5 <- R^6 <- R^2

julia> n = length(F)
3

julia> M1 = F[1]
Singular ideal over Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C) with generators (y^2 - w*z, x*y - z^2, x^2 - w*y, w*x - y*z, w^2 - x*z)

Betti numbers

Singular.bettiMethod
betti(r::sresolution)

Return the Betti numbers, i.e. the ranks of the free modules in the given free resolution. These are returned as a Julia array of Ints. Note that the output of this command is useful only in the graded case.

source

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
(Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C), spoly{n_Q}[w, x, y, z])

julia> I = Ideal(R, w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z)
Singular ideal over Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C) with generators (w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z)

julia> F = fres(std(I), 3)
Singular resolution: R^1 <- R^5 <- R^6 <- R^2

julia> M = minres(F)
Singular resolution: R^1 <- R^5 <- R^5 <- R^1

julia> B = betti(M)
3×4 Matrix{Int32}:
 1  0  0  0
 0  5  5  0
 0  0  0  1

Minimal resolutions

Singular.minresMethod
minres{T <: Nemo.FieldElem}(r::sresolution{spoly{T}})

Return a minimal free resolution, given any free resolution. In the graded case, there exists a uniquely determined minimal resolution. If the supplied resolution is already minimal, it may be returned without making a copy.

source

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
(Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C), spoly{n_Q}[w, x, y, z])

julia> I = Ideal(R, w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z)
Singular ideal over Singular polynomial ring (QQ),(w,x,y,z),(dp(4),C) with generators (w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z)

julia> F = fres(std(I), 3)
Singular resolution: R^1 <- R^5 <- R^6 <- R^2

julia> M = minres(F)
Singular resolution: R^1 <- R^5 <- R^5 <- R^1