Subquotient Modules

A subquotient module is a submodule of a quotient of a free module. In what follows, we simply use the expression subquotient to refer to a subquotient module over a multivariate polynomial ring. More concretely, given a multivariate polynomial ring $R$, 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.

Types

All OSCAR types for finitely presented modules over multivariate polynomial rings belong to the abstract type ModuleFP{T}, where T is the element type of the polynomial ring. For subquotients, OSCAR provides the abstract subtype AbstractSubQuo{T} <: ModuleFP{T} and its concrete descendant SubQuo{T}.

Note

Canonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The SubQuo 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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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]
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,
  • 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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 x, y, z over Rational Field

julia> F === ambient_free_module(M)
true

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

julia> ngens(M)
2

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

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

julia> relations(M)
3-element Vector{FreeModElem{fmpq_mpoly}}:
 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]

Elements of Subqotients

All OSCAR types for elements of finitely presented modules over multivariate polynomial rings 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 SubQuoElem{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::SubQuo{T})(c::SRow{T}) where T
(M::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 multivariate polynomial ring $R$ with element type T,

  • parent(m) refers to M,
  • coefficients(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::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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> coefficients(m)
Sparse row with positions [1, 2] and values fmpq_mpoly[z, 1]

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

julia> typeof(m)
SubQuoElem{fmpq_mpoly}

julia> typeof(fm)
FreeModElem{fmpq_mpoly}

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

julia> F = ambient_free_module(M)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> typeof(f)
FreeModElem{fmpq_mpoly}

julia> typeof(M(f))
SubQuoElem{fmpq_mpoly}

The zero element of a subquotient is obtained as follows:

zeroMethod
zero(M::SubQuo)

Return the zero element of M.

source

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

iszeroMethod
iszero(m::SubQuoElem)

Return true if m is zero, false otherwise.

Examples

julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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> iszero(M[1])
false

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

Tests on Subqotients

==Method
==(M::SubQuo{T}, N::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 = SubQuo(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
source
issubsetMethod
issubset(M::SubQuo{T}, N::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 = SubQuo(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> issubset(M, N)
true
source
iszeroMethod
iszero(M::SubQuo)

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

Examples

julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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 = SubQuo(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> iszero(M)
false
source

Basic Operations on Subquotients

+Method
+(M::SubQuo{T},N::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 = SubQuo(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]
source
sumMethod
sum(M::SubQuo{T},N::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 = SubQuo(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]
source
intersectMethod
intersect(M::SubQuo{T}, N::SubQuo{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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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 = SubQuo(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])
source

Submodules and Quotients

subMethod
sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of elements of M, return the submodule of M generated by these elements.

Put more precisely, return this submodule as an object of type SubQuo.

Additionally, if N denotes this object,

  • return the inclusion map N $\to$ M if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ M if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

source
quoMethod
quo(M::SubQuo{T}, V::Vector{<:SubQuoElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of elements of M, return the quotient of M by the submodule of M which is generated by these elements.

Put more precisely, return the quotient as an object of type SubQuo.

Additionally, if N denotes this object,

  • return the projection map M $\to$ N if task = :with_morphism (default),
  • return and cache the projection map M $\to$ N if task = :cache_morphism,
  • do none of the above if task = :none or task = :module.

If task = :only_morphism, return only the projection map.

source

Homomorphisms From Subqotients

All OSCAR types for homomorphisms of finitely presented modules over multivariate polynomial rings 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::SubQuo{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::SubQuo{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.

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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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{SubQuoElem{fmpq_mpoly}}:
 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 = matrix(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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

julia> A = R[x; y];

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

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

julia> N = M;

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

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

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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

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

julia> M = SubQuo(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]
source

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