Subquotients

A subquotient is a submodule of a quotient of a free module. In this section, the expression subquotient refers to a subquotient over a ring of type MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing. That is, given a ring $R$ of one of these types, a subquotient $M$ over $R$ is a module of type

\[M = (\text{im } a + \text{im } b)/\text{im } b,\]

where

\[a:R^s ⟶R^p \;\text{ and }\; b:R^t ⟶R^p\]

are two homomorphisms of free $R$-modules with the same codomain. We then refer to

  • the module $M$ as the subquotient defined by $a$ and $b$,
  • the codomain $R^p$ as the ambient free module of $M$,
  • the images of the canonical basis vectors of $R^s$ in $R^p$ as the ambient representatives of the generators of $M$, and
  • the images of the canonical basis vectors of $R^t$ in $R^p$ as the relations of $M$.

Alternatively, we speak of the subquotient of $\;\text{im } a\;$ by $\;\text{im } b\;$ or the subquotient defined by $A$ and $B$, where $A$ and $B$ are the matrices representing $a$ and $b$, respectively.

Finally, we refer to

  • the quotient of $R^p$ by the submodule generated by the relations of $M$ as the ambient module of $M$,

and regard $M$ as a submodule of that ambient module, embedded in the natural way.

Note

Recall from the section on free modules that by a free $R$-module we mean a free module of type $R^p$ , where we think of $R^p$ as a free module with a given basis, namely the basis of standard unit vectors. Accordingly, elements of free modules are represented by coordinate vectors, and homomorphisms between free modules by matrices. Here, by convention, vectors are row vectors, and matrices operate by multiplication on the right.

Note

Over a graded ring $R$, we work with graded free modules $R^s$, $R^p$, $R^t$ and graded homomorphisms $a$, $b$. As a consequence, every module involved in the construction of the subquotient defined by $a$ and $b$ carries an induced grading. In particular, the subquotient itself carries an induced grading.

Types

All OSCAR types for the finitely presented modules considered here belong to the abstract type ModuleFP{T}, where T is the element type of the underlying ring. Graded or not, the subquotients belong to the abstract subtype AbstractSubQuo{T} <: ModuleFP{T}, they are modeled as objects of the concrete type SubquoModule{T} <: AbstractSubQuo{T}.

Note

Canonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The SubquoModule type is designed so that it allows for the caching of such maps when executing functions. The tensor_product function discussed in this section provides an example.

Constructors

subquotientMethod
subquotient(a::FreeModuleHom, b::FreeModuleHom)

Given homomorphisms a and b between free modules such that codomain(a) === codomain(b), return $(\text{im } a + \text{im } b)/\text{im } b$.

subquotient(F::FreeMod{T}, A::MatElem{T}, B::MatElem{T}) where T

Given matrices A and B with rank F columns, return $(\text{im } a + \text{im } b)/\text{im } b$, where a and b are free module homomorphisms with codomain F represented by A and B.

subquotient(A::MatElem{T}, B::MatElem{T}) where T

Given matrices A and B with the same number of columns, create a free module F whose rank is that number, and return $(\text{im } a + \text{im } b)/\text{im } b$, where a and b are free module homomorphisms with codomain F represented by A and B.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);

julia> FR = free_module(R, 1)
Free module of rank 1 over R

julia> AR = R[x; y]
[x]
[y]

julia> BR = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> MR = SubquoModule(FR, AR, BR)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> P = ideal(R, [x, y, z]);

julia> U = complement_of_prime_ideal(P);

julia> RL, _ = localization(R, U);

julia> FRL = free_module(RL, 1)
Free module of rank 1 over Localization of R at complement of prime ideal (x, y, z)

julia> ARL = RL[x; y]
[x]
[y]

julia> BRL = RL[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> MRL = SubquoModule(FRL, ARL, BRL)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> RQ, _ = quo(R, ideal(R, [2*x^2-y^3, 2*x^2-y^5]));

julia> FRQ = free_module(RQ, 1)
Free module of rank 1 over RQ

julia> ARQ = RQ[x; y]
[x]
[y]

julia> BRQ = RQ[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> MRQ = SubquoModule(FRQ, ARQ, BRQ)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> 2*x^2*e[1]
3 -> z^4*e[1]

julia> RQL, _ = localization(RQ, U);

julia> FRQL = free_module(RQL, 1)
Free module of rank 1 over Localization of RQ at complement of prime ideal

julia> ARQL = RQL[x; y]
[x]
[y]

julia> BRQL = RQL[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> MRQL = SubquoModule(FRQL, ARQL, BRQL)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> 0
2 -> 0
3 -> z^4*e[1]
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F1 = graded_free_module(Rg, [2,2,2]);

julia> F2 = graded_free_module(Rg, [2]);

julia> G = graded_free_module(Rg, [1,1]);

julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]]
3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
 y*e[1]
 (x + y)*e[1] + y*e[2]
 z*e[2]

julia> V2 = [z*G[2]+y*G[1]]
1-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
 y*e[1] + z*e[2]

julia> a1 = hom(F1, G, V1)
F1 -> G
e[1] -> y*e[1]
e[2] -> (x + y)*e[1] + y*e[2]
e[3] -> z*e[2]
Homogeneous module homomorphism

julia> a2 = hom(F2, G, V2)
F2 -> G
e[1] -> y*e[1] + z*e[2]
Homogeneous module homomorphism

julia> V = subquotient(a1,a2)
Graded subquotient of submodule of G generated by
1 -> y*e[1]
2 -> (x + y)*e[1] + y*e[2]
3 -> z*e[2]
by submodule of G generated by
1 -> y*e[1] + z*e[2]

julia> A1 = Rg[x y; 2*x^2 3*y^2]
[    x       y]
[2*x^2   3*y^2]

julia> A2 = Rg[x^3 x^2*y; (2*x^2+x*y)*x (2*y^3+y*x^2)]
[          x^3           x^2*y]
[2*x^3 + x^2*y   x^2*y + 2*y^3]

julia> B = Rg[4*x*y^3 (2*x+y)^4]
[4*x*y^3   16*x^4 + 32*x^3*y + 24*x^2*y^2 + 8*x*y^3 + y^4]

julia> F2 = graded_free_module(Rg,[0,0])
Graded free module Rg^2([0]) of rank 2 over Rg

julia> M1 = SubquoModule(F2, A1, B)
Graded subquotient of submodule of F2 generated by
1 -> x*e[1] + y*e[2]
2 -> 2*x^2*e[1] + 3*y^2*e[2]
by submodule of F2 generated by
1 -> 4*x*y^3*e[1] + (16*x^4 + 32*x^3*y + 24*x^2*y^2 + 8*x*y^3 + y^4)*e[2]
source

Data Associated to Subqotients

If M is a subquotient with ambient free R-module F, then

  • base_ring(M) refers to R,
  • ambient_free_module(M) to F,
  • gens(M) to the generators of M,
  • number_of_generators(M) / ngens(M) to the number of these generators,
  • M[i], gen(M, i) to the ith such generator,
  • ambient_representatives_generators(M) to the ambient representatives of the generators of M in F,
  • relations(M) to the relations of M, and
  • ambient_module(M) to the ambient module of M.
Examples
julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y]
[x]
[y]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> base_ring(M)
Multivariate polynomial ring in 3 variables x, y, z
  over rational field

julia> F === ambient_free_module(M)
true

julia> gens(M)
2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
 x*e[1]
 y*e[1]

julia> number_of_generators(M)
2

julia> gen(M, 2)
y*e[1]

julia> ambient_representatives_generators(M)
2-element Vector{FreeModElem{QQMPolyRingElem}}:
 x*e[1]
 y*e[1]

julia> relations(M)
3-element Vector{FreeModElem{QQMPolyRingElem}}:
 x^2*e[1]
 y^3*e[1]
 z^4*e[1]

julia> ambient_module(M)
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

In the graded case, we also have:

grading_groupMethod
grading_group(M::SubquoModule)

Return the grading group of base_ring(M).

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F1 = graded_free_module(Rg, [2,2,2]);

julia> F2 = graded_free_module(Rg, [2]);

julia> G = graded_free_module(Rg, [1,1]);

julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];

julia> V2 = [z*G[2]+y*G[1]];

julia> a1 = hom(F1, G, V1);

julia> a2 = hom(F2, G, V2);

julia> M = subquotient(a1,a2);

julia> grading_group(M)
Z
source
degrees_of_generatorsMethod
degrees_of_generators(M::SubquoModule; check::Bool=true)

Return the degrees of the generators of M.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F1 = graded_free_module(Rg, [2,2,2]);

julia> F2 = graded_free_module(Rg, [2]);

julia> G = graded_free_module(Rg, [1,1]);

julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];

julia> V2 = [z*G[2]+y*G[1]];

julia> a1 = hom(F1, G, V1);

julia> a2 = hom(F2, G, V2);

julia> M = subquotient(a1,a2);

julia> degrees_of_generators(M)
3-element Vector{FinGenAbGroupElem}:
 [2]
 [2]
 [2]

julia> gens(M)
3-element Vector{SubquoModuleElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
 y*e[1]
 (x + y)*e[1] + y*e[2]
 z*e[2]
source

Elements of Subqotients

All OSCAR types for elements of finitely presented modules considered here belong to the abstract type ModuleElemFP{T}, where T is the element type of the polynomial ring. For elements of subquotients, there are the abstract subtype AbstractSubQuoElem{T} <: ModuleFPElem{T} and its concrete descendant SubquoModuleElem{T} which implements an element $m$ of a subquotient $M$ over a ring $R$ as a sparse row, that is, as an object of type SRow{T}. This object specifies the coefficients of an $R$-linear combination of the generators of $M$ giving $m$. To create an element, enter the coefficients as a sparse row or a vector:

(M::SubquoModule{T})(c::SRow{T}) where T
(M::SubquoModule{T})(c::Vector{T}) where T

Alternatively, directly write the element as an $R$-linear combination of generators of $M$.

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y]
[x]
[y]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> m = M(sparse_row(R, [(1,z),(2,one(R))]))
(x*z + y)*e[1]

julia> n = M([z, one(R)])
(x*z + y)*e[1]

julia> o = z*M[1] + M[2]
(x*z + y)*e[1]

julia> m == n == o
true

Given an element m of a subquotient M over a ring $R$ with element type T,

  • parent(m) refers to M,
  • coordinates(m) to an object of type SRow{T} specifying the coefficients of an $R$-linear combination of the generators of $M$ which gives $m$, and
  • ambient_representative(m) to an element of the ambient free module of M which represents m.

Given an element f of the ambient free module of a subquotient M such that f represents an element of M, the function below creates the represented element:

(M::SubquoModule{T})(f::FreeModElem{T}; check::Bool = true) where T

By default (check = true), it is tested whether f indeed represents an element of M. If this is already clear, it may be convenient to omit the test (check = false).

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y]
[x]
[y]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> m = z*M[1] + M[2]
(x*z + y)*e[1]

julia> parent(m)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> coordinates(m)
Sparse row with positions [1, 2] and values QQMPolyRingElem[z, 1]

julia> fm = ambient_representative(m)
(x*z + y)*e[1]

julia> typeof(m)
SubquoModuleElem{QQMPolyRingElem}

julia> typeof(fm)
FreeModElem{QQMPolyRingElem}

julia> parent(fm) === ambient_free_module(M)
true

julia> F = ambient_free_module(M)
Free module of rank 1 over R

julia> f = x*F[1]
x*e[1]

julia> M(f)
x*e[1]

julia> typeof(f)
FreeModElem{QQMPolyRingElem}

julia> typeof(M(f))
SubquoModuleElem{QQMPolyRingElem}

The zero element of a subquotient is obtained as follows:

zeroMethod
zero(M::SubquoModule)

Return the zero element of M.

source

Whether a given element of a subquotient is zero can be tested as follows:

is_zeroMethod
is_zero(m::SubquoModuleElem)

Return true if m is zero, false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y]
[x]
[y]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> is_zero(M[1])
false

julia> is_zero(x*M[1])
true
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1)
Graded free module Rg^1([0]) of rank 1 over Rg

julia> A = Rg[x; y]
[x]
[y]

julia> B = Rg[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> is_zero(M[1])
false

julia> is_zero(x*M[1])
true
source

In the graded case, we additionally have:

is_homogeneousMethod
is_homogeneous(m::SubquoModuleElem)

Return true if m is homogeneous, false otherwise.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F1 = graded_free_module(Rg, [2,2,2]);

julia> F2 = graded_free_module(Rg, [2]);

julia> G = graded_free_module(Rg, [1,1]);

julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];

julia> V2 = [z*G[2]+y*G[1]];

julia> a1 = hom(F1, G, V1);

julia> a2 = hom(F2, G, V2);

julia> M = subquotient(a1,a2);

julia> m1 = x*M[1]+y*M[2]+z*M[3]
(2*x*y + y^2)*e[1] + (y^2 + z^2)*e[2]

julia> is_homogeneous(m1)
true

julia> is_homogeneous(zero(M))
true

julia> m2 = M[1]+x*M[2]
(x^2 + x*y + y)*e[1] + x*y*e[2]

julia> is_homogeneous(m2)
false

julia> m3 = x*M[1]+M[2]+x*M[3]
(x*y + x + y)*e[1] + (x*z + y)*e[2]

julia> is_homogeneous(m3)
true

julia> simplify(m3)
x*e[1] + (y - z)*e[2]
source
degreeMethod
degree(m::SubquoModuleElem; check::Bool=true)

Given a homogeneous element m of a graded subquotient, return the degree of m.

degree(::Type{Vector{Int}}, m::SubquoModuleElem)

Given a homogeneous element m of a $\mathbb Z^m$-graded subquotient, return the degree of m, converted to a vector of integer numbers.

degree(::Type{Int}, m::SubquoModuleElem)

Given a homogeneous element m of a $\mathbb Z$-graded subquotient, return the degree of m, converted to an integer number.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F1 = graded_free_module(Rg, [2,2,2]);

julia> F2 = graded_free_module(Rg, [2]);

julia> G = graded_free_module(Rg, [1,1]);

julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];

julia> V2 = [z*G[2]+y*G[1]];

julia> a1 = hom(F1, G, V1);

julia> a2 = hom(F2, G, V2);

julia> M = subquotient(a1,a2);

julia> m = x*y*z*M[1]
x*y^2*z*e[1]

julia> degree(m)
[5]

julia> degree(Int, m)
5

julia> m3 = x*M[1]+M[2]+x*M[3]
(x*y + x + y)*e[1] + (x*z + y)*e[2]

julia> degree(m3)
[2]
source

Tests on Subqotients

The functions is_graded, is_standard_graded, is_z_graded, and is_zm_graded carry over analogously to subquotients. They return true if the respective property is satisfied, and false otherwise. In addition, we have:

==Method
==(M::SubquoModule{T}, N::SubquoModule{T}) where {T}

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return true if M equals N, where M and N are regarded as submodules of the common ambient module.

Here, ambient_module(M) == ambient_module(N) if

  • ambient_free_module(M) === ambient_free_module(N), and
  • the submodules of the common ambient free module generated by the relations of M and N, respectively, are equal.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> AM = R[x;]
[x]

julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = R[x; y]
[x]
[y]

julia> BN = R[x^2+y^4; y^3; z^4]
[x^2 + y^4]
[      y^3]
[      z^4]

julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> (x^2 + y^4)*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> M == N
false
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 2);

julia> O1 = [x*F[1]+y*F[2],y*F[2]];

julia> O1a = [x*F[1],y*F[2]];

julia> O2 = [x^2*F[1]+y^2*F[2],y^2*F[2]];

julia> M1 = SubquoModule(F, O1, O2)
Graded subquotient of submodule of F generated by
1 -> x*e[1] + y*e[2]
2 -> y*e[2]
by submodule of F generated by
1 -> x^2*e[1] + y^2*e[2]
2 -> y^2*e[2]

julia> M2 = SubquoModule(F, O1a, O2)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[2]
by submodule of F generated by
1 -> x^2*e[1] + y^2*e[2]
2 -> y^2*e[2]

julia> M1 == M2
true
source
is_subsetMethod
is_subset(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return true if M is contained in N, where M and N are regarded as submodules of the common ambient module.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> AM = R[x;]
[x]

julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = R[x; y]
[x]
[y]

julia> BN = R[x^2+y^4; y^3; z^4]
[x^2 + y^4]
[      y^3]
[      z^4]

julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> (x^2 + y^4)*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> is_subset(M, N)
true
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 2);

julia> O1 = [x*F[1]+y*F[2],y*F[2]];

julia> O1a = [x*F[1],y*F[2]];

julia> O2 = [x^2*F[1]+y^2*F[2],y^2*F[2]];

julia> M1 = SubquoModule(F, O1, O2)
Graded subquotient of submodule of F generated by
1 -> x*e[1] + y*e[2]
2 -> y*e[2]
by submodule of F generated by
1 -> x^2*e[1] + y^2*e[2]
2 -> y^2*e[2]

julia> M2 = SubquoModule(F, O1a, O2)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[2]
by submodule of F generated by
1 -> x^2*e[1] + y^2*e[2]
2 -> y^2*e[2]

julia> is_subset(M1,M2)
true

julia> is_subset(M2,M1)
true

julia> M1 == M2
true
source
is_zeroMethod
is_zero(M::SubquoModule)

Return true if M is the zero module, false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x^2+y^2;]
[x^2 + y^2]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 1 generator
1 -> (x^2 + y^2)*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> is_zero(M)
false
source

Basic Operations on Subquotients

+Method
+(M::SubquoModule{T},N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the sum of M and N regarded as submodules of the common ambient module.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> AM = R[x;]
[x]

julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = R[y;]
[y]

julia> BN = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> O = M + N
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> AM = Rg[x;];

julia> BM = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, AM, BM)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = Rg[y;];

julia> BN = Rg[x^2; y^3; z^4];

julia> N = SubquoModule(F, AN, BN)
Graded subquotient of submodule of F generated by
1 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> M + N
Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
source
sumMethod
sum(M::SubquoModule{T},N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the sum of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\to$ M + N and N $\to$ M + N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> AM = R[x;]
[x]

julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = R[y;]
[y]

julia> BN = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> O = sum(M, N);

julia> O[1]
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> O[2]
Map with following data
Domain:
=======
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> O[3]
Map with following data
Domain:
=======
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> AM = Rg[x;];

julia> BM = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, AM, BM)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = Rg[y;];

julia> BN = Rg[x^2; y^3; z^4];

julia> N = SubquoModule(F, AN, BN)
Graded subquotient of submodule of F generated by
1 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> sum(M, N)
(Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1], M -> Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
x*e[1] -> x*e[1]
Homogeneous module homomorphism, N -> Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
y*e[1] -> y*e[1]
Homogeneous module homomorphism)
source
intersectMethod
intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\cap$ N $\to$ M and M $\cap$ N $\to$ N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> AM = R[x;]
[x]

julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = R[y;]
[y]

julia> BN = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> intersect(M, N)
(Subquotient of Submodule with 2 generators
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1], Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1], Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1])
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> AM = Rg[x;];

julia> BM = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, AM, BM)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> AN = Rg[y;];

julia> BN = Rg[x^2; y^3; z^4];

julia> N = SubquoModule(F, AN, BN)
Graded subquotient of submodule of F generated by
1 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> intersect(M, N)
(Graded subquotient of submodule of F generated by
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1], Graded subquotient of submodule of F generated by
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1] -> M
-x*y*e[1] -> -x*y*e[1]
x*z^4*e[1] -> x*z^4*e[1]
Homogeneous module homomorphism, Graded subquotient of submodule of F generated by
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1] -> N
-x*y*e[1] -> x*y*e[1]
x*z^4*e[1] -> 0
Homogeneous module homomorphism)
source

Submodules and Quotients

subMethod
sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);

julia> F = free_module(R, 1);

julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];

julia> N, incl = sub(F, V);

julia> N
Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
represented as subquotient with no relations.

julia> incl
Map with following data
Domain:
=======
Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
represented as subquotient with no relations.
Codomain:
=========
Free module of rank 1 over R
source
quoMethod
quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T

Given a vector V of (homogeneous) elements of M, return a pair (N, pr) consisting of the quotient N = M/⟨V⟩ and the projection map pr : M → N.

If one is only interested in the actual object M, but not the map, use quo_object instead.

If cache_morphism is set to true, the projection is cached and available to transport and friends.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);

julia> F = free_module(R, 1);

julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];

julia> N, proj = quo(F, V);

julia> N
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> proj
Map with following data
Domain:
=======
Free module of rank 1 over R
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
source

Homomorphisms From Subqotients

All OSCAR types for homomorphisms of finitely presented modules considered here belong to the abstract type ModuleFPHom{T1, T2}, where T1 and T2 are the types of domain and codomain respectively. For homomorphisms from subquotients, OSCAR provides the concrete type SubQuoHom{T1, T2} <: ModuleFPHom{T1, T2} as well as the following constructors:

homMethod
hom(M::SubquoModule{T}, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T

Given a vector V of ngens(M) elements of N, return the homomorphism M $\to$ N which sends the i-th generator M[i] of M to the i-th entry of V.

hom(M::SubquoModule{T}, N::ModuleFP{T},  A::MatElem{T})) where T

Given a matrix A with ngens(M) rows and ngens(N) columns, return the homomorphism M $\to$ N which sends the i-th generator M[i] of M to the linear combination $\sum_j A[i,j]*N[j]$ of the generators N[j] of N.

Note

The module N may be of type FreeMod or SubquoMod. If both modules M and N are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.

Warning

The functions do not check whether the resulting homomorphism is well-defined, that is, whether it sends the relations of M into the relations of N.

If you are uncertain with regard to well-definedness, use the function below. Note, however, that the check performed by the function requires a Gröbner basis computation. This may take some time.

is_welldefined(a::ModuleFPHom)

Return true if a is well-defined, and false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y]
[x]
[y]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> N = M;

julia> V = [y^2*N[1], x*N[2]]
2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
 x*y^2*e[1]
 x*y*e[1]

julia> a = hom(M, N, V)
Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> is_welldefined(a)
true

julia> W = R[y^2 0; 0 x]
[y^2   0]
[  0   x]

julia> b = hom(M, N, W);

julia> a == b
true
julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y];

julia> B = R[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B);

julia> N = M;

julia> W = [y*N[1], x*N[2]]
2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
 x*y*e[1]
 x*y*e[1]

julia> c = hom(M, N, W);

julia> is_welldefined(c)
false
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> N = M;

julia> V = [y^2*N[1], x^2*N[2]];

julia> a = hom(M, N, V)
M -> M
x*e[1] -> x*y^2*e[1]
y*e[1] -> x^2*y*e[1]
Graded module homomorphism of degree [2]

julia> is_welldefined(a)
true

julia> W = Rg[y^2 0; 0 x^2]
[y^2     0]
[  0   x^2]

julia> b = hom(M, N, W)
M -> M
x*e[1] -> x*y^2*e[1]
y*e[1] -> x^2*y*e[1]
Graded module homomorphism of degree [2]

julia> a == b
true

julia> W = [y*N[1], x*N[2]]
2-element Vector{SubquoModuleElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
 x*y*e[1]
 x*y*e[1]

julia> c = hom(M, N, W)
M -> M
x*e[1] -> x*y*e[1]
y*e[1] -> x*y*e[1]
Graded module homomorphism of degree [1]

julia> is_welldefined(c)
false
source

Given a homomorphism of type SubQuoHom, a matrix A representing it is recovered by the following function:

matrixMethod
matrix(a::SubQuoHom)

Given a homomorphism a of type SubQuoHom with domain M and codomain N, return a matrix A with ngens(M) rows and ngens(N) columns such that a == hom(M, N, A).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over R

julia> A = R[x; y]
[x]
[y]

julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]

julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> N = M;

julia> V = [y^2*N[1], x*N[2]];

julia> a = hom(M, N, V);

julia> A = matrix(a)
[y^2   0]
[  0   x]

julia> a(M[1])
x*y^2*e[1]
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B)
Graded subquotient of submodule of F generated by
1 -> x*e[1]
2 -> y*e[1]
by submodule of F generated by
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]

julia> N = M;

julia> V = [y^2*N[1], x^2*N[2]];

julia> a = hom(M, N, V)
M -> M
x*e[1] -> x*y^2*e[1]
y*e[1] -> x^2*y*e[1]
Graded module homomorphism of degree [2]

julia> matrix(a)
[y^2     0]
[  0   x^2]
source

The domain and codomain of a homomorphism a of type SubQuoHom can be recovered by entering domain(a) and codomain(a), respectively.

The functions below test whether a homomorphism of type SubQuoHom is graded and homogeneous, respectively.

is_gradedMethod
is_graded(a::ModuleFPHom)

Return true if a is graded, false otherwise.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(R, 3)
Graded free module R^3([0]) of rank 3 over R

julia> G = graded_free_module(R, 2)
Graded free module R^2([0]) of rank 2 over R

julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]
3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
 y*e[1]
 x*e[1] + y*e[2]
 z*e[2]

julia> a = hom(F, G, V)
F -> G
e[1] -> y*e[1]
e[2] -> x*e[1] + y*e[2]
e[3] -> z*e[2]
Graded module homomorphism of degree [1]

julia> is_graded(a)
true
source
is_homogeneousMethod
is_homogeneous(a::SubQuoHom)

Return true if a is homogeneous, false otherwise

Here, if G is the grading group of a, a is homogeneous if a is graded of degree zero(G).

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B);

julia> N = M;

julia> V = [y^2*N[1], x^2*N[2]];

julia> a = hom(M, N, V)
M -> M
x*e[1] -> x*y^2*e[1]
y*e[1] -> x^2*y*e[1]
Graded module homomorphism of degree [2]

julia> is_homogeneous(a)
false
source

In the graded case, we additionally have:

degreeMethod
degree(a::SubQuoHom; check::Bool=true)

If a is graded, return the degree of a.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B);

julia> N = M;

julia> V = [y^2*N[1], x^2*N[2]];

julia> a = hom(M, N, V)
M -> M
x*e[1] -> x*y^2*e[1]
y*e[1] -> x^2*y*e[1]
Graded module homomorphism of degree [2]

julia> degree(a)
[2]
source
grading_groupMethod
grading_group(a::SubQuoHom)

If a is graded, return the grading group of a.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B);

julia> N = M;

julia> V = [y^2*N[1], x^2*N[2]];

julia> a = hom(M, N, V)
M -> M
x*e[1] -> x*y^2*e[1]
y*e[1] -> x^2*y*e[1]
Graded module homomorphism of degree [2]

julia> grading_group(a)
Z
source