# Operations on Modules

### Kernel

kernelMethod
kernel(a::ModuleFPHom)

Return the kernel of a as an object of type SubQuo.

Additionally, if K denotes this object, return the inclusion map K $\rightarrow$ domain(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, 3)
Free module of rank 3 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

julia> W = matrix(R, [y 0; x y; 0 z])
[y   0]
[x   y]
[0   z]

julia> a = hom(F, G, W);

julia> kernel(a)
(Submodule with 1 generator
1 -> x*z*e - y*z*e + y^2*e
represented as subquotient with no relations., Map with following data
Domain:
=======
Submodule with 1 generator
1 -> x*z*e - y*z*e + y^2*e
represented as subquotient with no relations.
Codomain:
=========
Free module of rank 3 over Multivariate Polynomial Ring in x, y, z over Rational Field)
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> F1 = 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(F1, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e
2 -> y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e

julia> N = M;

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

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

julia> K, iota = kernel(b)
(Subquotient of Submodule with 3 generators
1 -> (-x + y^2)*e
2 -> x*y*e
3 -> -x*y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e, Map with following data
Domain:
=======
Subquotient of Submodule with 3 generators
1 -> (-x + y^2)*e
2 -> x*y*e
3 -> -x*y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e
2 -> y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e)
source

### Image

imageMethod
image(a::ModuleFPHom)

Return the image of a as an object of type SubQuo.

Additionally, if I denotes this object, return the inclusion map I $\rightarrow$ codomain(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, 3)
Free module of rank 3 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

julia> W = matrix(R, [y 0; x y; 0 z])
[y   0]
[x   y]
[0   z]

julia> a = hom(F, G, W);

julia> I, iota = image(a)
(Submodule with 3 generators
1 -> y*e
2 -> x*e + y*e
3 -> z*e
represented as subquotient with no relations., Map with following data
Domain:
=======
Submodule with 3 generators
1 -> y*e
2 -> x*e + y*e
3 -> z*e
represented as subquotient with no relations.
Codomain:
=========
Free module of rank 2 over Multivariate Polynomial Ring in x, y, z over Rational Field)
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> F1 = 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(F1, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e
2 -> y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e

julia> N = M;

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

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

julia> image(b)
(Subquotient of Submodule with 2 generators
1 -> x*y^2*e
2 -> x*y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e, Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> x*y^2*e
2 -> x*y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e
2 -> y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e)
source

### Cokernel

cokernelMethod
cokernel(a::ModuleFPHom)

Return the cokernel of a as an object of type SubQuo.

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, 3)
Free module of rank 3 over Multivariate Polynomial Ring in x, y, z over Rational Field

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

julia> W = matrix(R, [y 0; x y; 0 z])
[y   0]
[x   y]
[0   z]

julia> a = hom(F, G, W);

julia> cokernel(a)
Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 3 generators
1 -> y*e
2 -> x*e + y*e
3 -> z*e
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> F1 = 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(F1, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e
2 -> y*e
by Submodule with 3 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e

julia> N = M;

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

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

julia> cokernel(b)
Subquotient of Submodule with 2 generators
1 -> x*e
2 -> y*e
by Submodule with 5 generators
1 -> x^2*e
2 -> y^3*e
3 -> z^4*e
4 -> x*y^2*e
5 -> x*y*e
source

## Direct Sums and Products

direct_sumMethod
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

• a vector containing the canonical injections $M_i\rightarrow\bigoplus_{i=1}^n M_i$ if task = :sum (default),
• a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\rightarrow M_i$ if task = :prod,
• two vectors containing the canonical injections and projections, respectively, if task = :both,
• none of the above maps if task = :none.
source
direct_productMethod
direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T

Given modules $M_1\dots M_n$, say, return the direct product $\prod_{i=1}^n M_i$.

• a vector containing the canonical projections $\prod_{i=1}^n M_i\rightarrow M_i$ if task = :prod (default),
• a vector containing the canonical injections $M_i\rightarrow\prod_{i=1}^n M_i$ if task = :sum,
• two vectors containing the canonical projections and injections, respectively, if task = :both,
• none of the above maps if task = :none.
source

## Presentations

presentationMethod
presentation(M::ModuleFP)

Return a free presentation of $M$.

Examples

julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);

julia> A = R[x; y];

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

julia> M = SubQuo(A, B);

julia> P = presentation(M);

julia> rank(P)
5

julia> rank(P)
2
source

## Syzygies and Free Resolutions

free_resolutionMethod
free_resolution(M::SubQuo; ordering::ModuleOrdering = default_ordering(M),
length::Int=0, algorithm::Symbol=:fres)

Return a free resolution of M.

If length != 0, the free resolution is only computed up to the length-th free module. algorithm can be set to :sres or :fres.

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> A = R[x; y]
[x]
[y]

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

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

julia> fr = free_resolution(M, length=1)

rank   | 6  2
-------|------
degree | 1  0

julia> is_complete(fr)
false

julia> fr
Free module of rank 0 over Multivariate Polynomial Ring in x, y, z over Rational Field

julia> fr

rank   | 0  2  6  6  2
-------|---------------
degree | 4  3  2  1  0

julia> is_complete(fr)
true

julia> fr = free_resolution(M, algorithm=:sres)

rank   | 0  2  6  6  2
-------|---------------
degree | 4  3  2  1  0
source

## Homology

homologyMethod
homology(C::ChainComplex{<:ModuleFP})

Return the homology of C.

Examples

julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F]);

julia> B, _ = quo(F, [x^3*F]);

julia> a = hom(A, B, [x^2*B]);

julia> b = hom(B, B, [x^2*B]);

julia> C = ChainComplex(ModuleFP, [a, b]);

julia> H = homology(C)
3-element Vector{SubQuo{fmpq_mpoly}}:
Subquotient of Submodule with 1 generator
1 -> x*e
by Submodule with 1 generator
1 -> x^4*e
Subquotient of Submodule with 1 generator
1 -> x*e
by Submodule with 2 generators
1 -> x^3*e
2 -> x^2*e
Subquotient of Submodule with 1 generator
1 -> e
by Submodule with 2 generators
1 -> x^3*e
2 -> x^2*e
source
homologyMethod
homology(C::ChainComplex{<:ModuleFP}, i::Int)

Return the i-th homology module of C.

Examples

julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F]);

julia> B, _ = quo(F, [x^3*F]);

julia> a = hom(A, B, [x^2*B]);

julia> b = hom(B, B, [x^2*B]);

julia> C = ChainComplex(ModuleFP, [a, b]);

julia> H = homology(C, 1)
Subquotient of Submodule with 1 generator
1 -> x*e
by Submodule with 2 generators
1 -> x^3*e
2 -> x^2*e
source

## Hom and Ext

homFunction
hom(M::ModuleFP, N::ModuleFP)

Return the module Hom(M,N) as an object of type SubQuo.

Additionally, if H is that object, return the map which sends an element of H to the corresponding homomorphism M $\to$N.

Examples

julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);

julia> F = FreeMod(R, 2);

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

julia> M = quo(F, V)
Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e

julia> H = hom(M, M)
hom of (Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e, Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e)

julia> gens(H)
2-element Vector{SubQuoElem{fmpq_mpoly}}:
(e -> e)
(e -> e)

julia> relations(H)
4-element Vector{FreeModElem{fmpq_mpoly}}:
x*(e -> e)
y^2*(e -> e)
x*(e -> e)
y^2*(e -> e)
source
element_to_homomorphismMethod
element_to_homomorphism(f::ModuleFPElem)

If f is an element of a module created via hom(M,N), for some modules M and N, return the homomorphism M $\to$ N corresponding to f.

Examples

julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);

julia> F = FreeMod(R, 2);

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

julia> M = quo(F, V)
Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e

julia> H = hom(M, M);

julia> gens(H)
2-element Vector{SubQuoElem{fmpq_mpoly}}:
(e -> e)
(e -> e)

julia> relations(H)
4-element Vector{FreeModElem{fmpq_mpoly}}:
x*(e -> e)
y^2*(e -> e)
x*(e -> e)
y^2*(e -> e)

julia> a = element_to_homomorphism(H+y*H)
Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e

julia> matrix(a)
[1   0]
[0   y]
source
homomorphism_to_elementMethod
homomorphism_to_element(H::ModuleFP, a::ModuleFPHom)

If the module H is created via hom(M,N), for some modules M and N, and a: M $\to$ N is a homomorphism, then return the element of H corresponding to a.

Examples

julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);

julia> F = FreeMod(R, 2);

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

julia> M = quo(F, V)
Subquotient of Submodule with 2 generators
1 -> e
2 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y^2*e

julia> H = hom(M, M);

julia> gens(H)
2-element Vector{SubQuoElem{fmpq_mpoly}}:
(e -> e)
(e -> e)

julia> relations(H)
4-element Vector{FreeModElem{fmpq_mpoly}}:
x*(e -> e)
y^2*(e -> e)
x*(e -> e)
y^2*(e -> e)

julia> W =  [M, y*M];

julia> a = hom(M, M, W);

julia> iswelldefined(a)
true

julia> matrix(a)
[1   0]
[0   y]

julia> m = homomorphism_to_element(H, a)
(e -> e) + y*(e -> e)
source
extMethod
ext(M::ModuleFP, N::ModuleFP, i::Int)

Return $\text{Ext}^i(M,N)$.

Examples

julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);

julia> F = FreeMod(R, 1);

julia> V = [x*F, y*F];

julia> M = quo(F, V)
Subquotient of Submodule with 1 generator
1 -> e
by Submodule with 2 generators
1 -> x*e
2 -> y*e

julia> ext(M, M, 0)
Subquotient of Submodule with 1 generator
1 -> (e -> e)
by Submodule with 2 generators
1 -> x*(e -> e)
2 -> y*(e -> e)

julia> ext(M, M, 1)
Subquotient of Submodule with 2 generators
1 -> (e -> e)
2 -> (e -> e)
by Submodule with 4 generators
1 -> x*(e -> e)
2 -> y*(e -> e)
3 -> x*(e -> e)
4 -> y*(e -> e)

julia> ext(M, M, 2)
Subquotient of Submodule with 1 generator
1 -> (e -> e)
by Submodule with 3 generators
1 -> x*(e -> e)
2 -> y*(e -> e)
3 -> -y*(e -> e)

julia> ext(M, M, 3)
Submodule with 0 generators
represented as subquotient with no relations.
source

## Tensorproduct and Tor

tensor_productMethod
tensor_product(M::ModuleFP...; task::Symbol = :none)

Given a collection of modules, say, $M_1, \dots, M_n$ over a ring $R$, return $M_1\otimes_R \cdots \otimes_R M_n$.

If task = :map, additionally return the map which sends a tuple $(m_1,\dots, m_n)$ of elements $m_i\in M_i$ to the pure tensor $m_1\otimes\dots\otimes m_n$.

Examples

julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);

julia> F = free_module(R, 1);

julia> A = R[x; y];

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

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

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

julia> T, t = tensor_product(M, M; task = :map);

julia> gens(T)
4-element Vector{SubQuoElem{fmpq_mpoly}}:
x^2*e \otimes e
x*y*e \otimes e
x*y*e \otimes e
y^2*e \otimes e

julia> domain(t)
parent of tuples of type Tuple{SubQuoElem{fmpq_mpoly}, SubQuoElem{fmpq_mpoly}}

julia> t((M, M))
x*y*e \otimes e
source
torMethod
tor(M::ModuleFP, N::ModuleFP, i::Int)

Return $\text{Tor}_i(M,N)$.

Examples

julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);

julia> A = R[x; y];

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

julia> M = SubQuo(A, B);

julia> F = free_module(R, 1);

julia> Q, _ = quo(F, [x*F]);

julia> T0 = tor(Q, M, 0)
Subquotient of Submodule with 2 generators
1 -> x*e \otimes e
2 -> y*e \otimes e
by Submodule with 4 generators
1 -> x^2*e \otimes e
2 -> y^3*e \otimes e
3 -> z^4*e \otimes e
4 -> x*y*e \otimes e

julia> T1 = tor(Q, M, 1)
Subquotient of Submodule with 1 generator
1 -> -x*e \otimes e
by Submodule with 3 generators
1 -> x^2*e \otimes e
2 -> y^3*e \otimes e
3 -> z^4*e \otimes e

julia> T2 =  tor(Q, M, 2)
Submodule with 0 generators
represented as subquotient with no relations.
source