Finitely generated modules
Singular.jl allows the creation of submodules of a free module over a Singular polynomial ring, given by a finite generating set. These are internally stored as a list of elements of a free module over a polynomial ring $R$. This list of generators can also have the property of being a Groebner basis.
The default finitely generated module type in Singular.jl is the Singular smodule
type.
Module objects have a parent object which represents the class of $R$-modules they belong to, the data for which is given by the polynomial ring $R$ over which the modules are defined.
The types of modules and associated parent objects are given in the following table according to the library provding them.
Library | Element type | Parent type |
---|---|---|
Singular | smodule{T} | Singular.ModuleClass{T} |
These types are parameterised by the type of elements in the polynomial ring $R$.
All module types belong directly to the abstract type Module{T}
and all the module class parent object types belong to the abstract type Set
.
Module functionality
Singular.jl modules implement standard operations one would expect on modules. 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 modules that is not included in this list of basic operations.
Constructors
Given a Singular polynomial ring $R$, the following constructors are available for creating modules.
Module{T <: Nemo.RingElem}(R::PolyRing{T}, vecs::svector{spoly{T}}...)
Construct the module over the polynomial ring $R$ whose generators are given by the given parameter list of vectors (of length $n$), each component of which is a polynomial. These vectors represent elements of the free module $R^n$.
Note that Module
must be prepended with the package name Singular
to disambiguate from Base.Module
.
Examples
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
v1 = vector(R, x + 1, x*y + 1, y)
v2 = vector(R, x^2 + 1, 2x + 3y, x)
M = Singular.Module(R, v1, v2)
Basic manipulation
Singular.ngens
— Method.ngens(I::smodule)
Return the number of generators in the current representation of the module (as a list of vectors).
Base.LinAlg.rank
— Method.rank(I::smodule)
Return the rank $n$ of the ambient space $R^n$ of which this module is a submodule.
Singular.jl overloads the setindex!
and getindex
functions so that one can access the generators of a module using array notation. Each entry is a vector in $R^n$.
M[n::Int]
Base.iszero
— Method.iszero(p::smodule)
Return
true
if this is algebraically the zero module.
Examples
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
v1 = vector(R, x + 1, x*y + 1, y)
v2 = vector(R, x^2 + 1, 2x + 3y, x)
M = Singular.Module(R, v1, v2)
iszero(M) == false
M[1] == v1
n = rank(M)
d = ngens(M)
Standard basis
Base.std
— Method.std(I::smodule; complete_reduction::Bool=false)
Compute the Groebner basis of the module $I$. If
complete_reduction
is set totrue
, the result is unique, up to permutation of the generators and multiplication by constants. If not, only the leading terms are unique (up to permutation of the generators and multiplication by constants, of course). Presently the polynomial ring used must be over a field or over the Singular integers.
Examples
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
v1 = vector(R, x + 1, x*y + 1, y)
v2 = vector(R, x^2 + 1, 2x + 3y, x)
v3 = x*v1 + y*v2 + vector(R, x, y + 1, y^2)
M = Singular.Module(R, v1, v2, v3)
G = std(M; complete_reduction=true)
Syzygies
Singular.syz
— Method.syz(M::smodule)
Compute the module of syzygies of the given module. This will be given as a set of generators in an ambient space $R^n$, where $n$ is the number of generators in $M$.
Examples
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
v1 = vector(R, (x + 1)*y, (x*y + 1)*y, y)
v2 = vector(R, (x + 1)*x, (x*y + 1)*x, x)
M = Singular.Module(R, v1, v2)
Z = syz(M)
Free resolutions
Singular.sres
— Method.sres{T <: Nemo.RingElem}(I::smodule{T}, max_length::Int)
Compute a free resolution of the given module $I$ of length up to the given maximum length. If
max_length
is set to zero, a full length free resolution is computed. Each element of the resolution is itself a module.
Examples
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
v1 = vector(R, x + 1, x*y + 1, y)
v2 = vector(R, x^2 + 1, 2x + 3y, x)
M = std(Singular.Module(R, v1, v2))
F = sres(M, 0)
M1 = Singular.Matrix(M)
M2 = Singular.Matrix(F[2])
# test we have a complex
iszero(M1*M2)