In this tutorial, we describe how to work with modules in
Macaulay2.
A. Making modules from matrices
First, let’s define a ring.
i1 : R = QQ[a..f];
|
i2 : m = matrix{{a,b,d,e},{b,c,e,f}}
o2 = | a b d e |
| b c e f |
2 4
o2 : Matrix R <--- R
|
Use standard notation for cokernels, images and kernels (coker, cokernel, image, ker, kernel).
i3 : M = coker m
o3 = cokernel | a b d e |
| b c e f |
2
o3 : R-module, quotient of R
|
i4 : N = image m
o4 = image | a b d e |
| b c e f |
2
o4 : R-module, submodule of R
|
i5 : K = kernel m
o5 = image {1} | 0 e2-df cd-be ce-bf |
{1} | e2-df 0 -bd+ae -be+af |
{1} | -ce+bf -be+af b2-ac 0 |
{1} | cd-be bd-ae 0 b2-ac |
4
o5 : R-module, submodule of R
|
Given a module, one can find its presentation matrix.
i6 : presentation M -- this is just the original matrix
o6 = | a b d e |
| b c e f |
2 4
o6 : Matrix R <--- R
|
i7 : presentation N -- this one requires computation
o7 = {1} | 0 e2-df cd-be ce-bf |
{1} | e2-df 0 -bd+ae -be+af |
{1} | -ce+bf -be+af b2-ac 0 |
{1} | cd-be bd-ae 0 b2-ac |
4 4
o7 : Matrix R <--- R
|
B. Submodules and quotients
To define a submodule
IN of a module
N, where
I is an ideal, use
i8 : ideal(a,b)*N
o8 = image | a2 ab ad ae ab b2 bd be |
| ab ac ae af b2 bc be bf |
2
o8 : R-module, submodule of R
|
i9 : a*N + b*N
o9 = image | a2 ab ad ae ab b2 bd be |
| ab ac ae af b2 bc be bf |
2
o9 : R-module, submodule of R
|
In order to define a submodule of N generated by some elements of N, one way is the following.
i10 : N0 = image (a**N_{1}|N_{2}-N_{3})
o10 = image | ab d-e |
| ac e-f |
2
o10 : R-module, submodule of R
|
To understand what
Macaulay2 is doing here, let’s break this down. N
i defines a matrix R
1 --> N, which maps 1 to the i th generator of N. (See Section XX below for more information about module homomorphisms).
i11 : N_{1}
o11 = {1} | 0 |
{1} | 1 |
{1} | 0 |
{1} | 0 |
o11 : Matrix
|
One could use a*N
1, but it turns out that a ** N
1 works better:
i12 : a ** N_{1}
o12 = {1} | 0 |
{1} | a |
{1} | 0 |
{1} | 0 |
o12 : Matrix
|
Next, remember that the vertical bar concatenates matrices.
i13 : a ** N_{1} | N_{2}-N_{3}
o13 = {1} | 0 0 |
{1} | a 0 |
{1} | 0 1 |
{1} | 0 -1 |
o13 : Matrix
|
Now take the image of this matrix
i14 : N0 = image(a ** N_{1} | N_{2}-N_{3})
o14 = image | ab d-e |
| ac e-f |
2
o14 : R-module, submodule of R
|
The main advantage for using ** rather than * is that ** preservers homogeneity if possible.
i15 : isHomogeneous N0
o15 = true
|
Quotients are defined using standard mathematical notation.
i16 : Nbar = N/N0
o16 = subquotient (| a b d e |, | ab d-e |)
| b c e f | | ac e-f |
2
o16 : R-module, subquotient of R
|
Notice that this returns a subquotient module. We treat these later. Ideals and modules are treated differently in
Macaulay2 (and in commutative algebra in general). For example, asking for the dimension of an ideal I in a ring R gives the dimension of the quotient R/I, but the dimension of the module I gives a potentially very different answer. Use ideal and module to move between the two.
i17 : I = ideal(a^2, a*b, c^2)
2 2
o17 = ideal (a , a*b, c )
o17 : Ideal of R
|
i18 : J = module I
o18 = image | a2 ab c2 |
1
o18 : R-module, submodule of R
|
i19 : I == ideal J
o19 = true
|
i20 : codim I
o20 = 2
|
i21 : codim J
o21 = 0
|
C. Syzygies and free resolutions
Create a free resolution of an ideal (or module) using res.
i22 : C = res I
1 3 3 1
o22 = R <-- R <-- R <-- R <-- 0
0 1 2 3 4
o22 : ChainComplex
|
View the differential
i23 : C.dd
1 3
o23 = 0 : R <---------------- R : 1
| a2 ab c2 |
3 3
1 : R <---------------------- R : 2
{2} | -b -c2 0 |
{2} | a 0 -c2 |
{2} | 0 a2 ab |
3 1
2 : R <-------------- R : 3
{3} | c2 |
{4} | -b |
{4} | a |
1
3 : R <----- 0 : 4
0
o23 : ChainComplexMap
|
The (graded) betti numbers
i24 : betti C
0 1 2 3
o24 = total: 1 3 3 1
0: 1 . . .
1: . 3 1 .
2: . . 2 1
o24 : BettiTally
|
Use
help (betti,ChainComplex) for a detailed description of what this display means. Basically, it says that I has three generators of degree 2, one syzygy of degree 3, 2 syzygies of degree 4, and one second syzygy of degree 5. The free resolution of a module which is not a cokernel:
i25 : C = res Nbar
4 6 2
o25 = R <-- R <-- R <-- 0
0 1 2 3
o25 : ChainComplex
|
i26 : betti C
0 1 2
o26 = total: 4 6 2
0: . 1 .
1: 4 1 .
2: . 4 2
o26 : BettiTally
|
i27 : C.dd
4 6
o27 = 0 : R <----------------------------------------------------------- R
{1} | 0 0 ce-bf -cd+be+ce-bf e2-df 0 |
{1} | 0 a -be bd-be 0 e2-df |
{1} | -1 0 b2-ac 0 bd-ae-be+af cd-be-ce+bf |
{1} | 1 0 0 0 0 0 |
6 2
1 : R <--------------------- R : 2
{1} | 0 0 |
{2} | e2-df 0 |
{3} | -d+e e-f |
{3} | -e f |
{3} | b -c |
{3} | -a b |
2
2 : R <----- 0 : 3
0
-----------------------------------------------------------------------
: 1
o27 : ChainComplexMap
|
Here is a problem to experiment with. What different betti diagrams are possible with an ideal generated by 3 homogeneous quadric polynomials, in a polynomial ring in any number of variables? Here is one to get you started.
i28 : R = QQ[a..h];
|
i29 : J = ideal(a*c+b*d,a*e+b*f,a*g+b*h)
o29 = ideal (a*c + b*d, a*e + b*f, a*g + b*h)
o29 : Ideal of R
|
i30 : betti res J
0 1 2 3
o30 = total: 1 3 4 2
0: 1 . . .
1: . 3 . .
2: . . 4 2
o30 : BettiTally
|
After that, try ideals generated by 4 quadrics.
D. Subquotients
Recall that the module N/N0 above displayed as something called a subquotient module. As
Macaulay2 often returns such objects, it is useful to understand and be able to manipulate them. P The most common modules are quotients of free modules, or submodules of free modules. A useful generalization, which covers both of these types, are subquotients: submodules of quotients of free modules. P A subquotient module is determined by two matrices f : R
m --> R
n and g : R
p --> R
n. The subquotient module with generators f, relations g is by definition the module M = (image f) + (image g) / (image g). Thus, if f is the identity map, M = coker g, and if g = 0, then M = image f.
i31 : use ring M
o31 = QQ [a, b, c, d, e, f]
o31 : PolynomialRing
|
i32 : M
o32 = cokernel | a b d e |
| b c e f |
2
o32 : QQ [a, b, c, d, e, f]-module, quotient of (QQ [a, b, c, d, e, f])
|
i33 : N = a*M
o33 = subquotient (| a 0 |, | a b d e |)
| 0 a | | b c e f |
2
o33 : QQ [a, b, c, d, e, f]-module, subquotient of (QQ [a, b, c, d, e, f])
|
i34 : M/N
o34 = cokernel | a 0 a b d e |
| 0 a b c e f |
2
o34 : QQ [a, b, c, d, e, f]-module, quotient of (QQ [a, b, c, d, e, f])
|
The two matrices f and g mentioned above are recovered using the routines: generators, relations.
i35 : generators N
o35 = | a 0 |
| 0 a |
2 2
o35 : Matrix (QQ [a, b, c, d, e, f]) <--- (QQ [a, b, c, d, e, f])
|
i36 : relations N
o36 = | a b d e |
| b c e f |
2 4
o36 : Matrix (QQ [a, b, c, d, e, f]) <--- (QQ [a, b, c, d, e, f])
|
It is often necessary to find a presentation matrix for such modules.
i37 : presentation N
o37 = {1} | e d b a |
{1} | f e c b |
2 4
o37 : Matrix (QQ [a, b, c, d, e, f]) <--- (QQ [a, b, c, d, e, f])
|
Often the given representation of a module is not very efficient. Use trim to keep the module as a subquotient of the same ambient free module, but change the generators and relations to be minimal, or in the nonlocal or non-graded case, at least more efficient.
i38 : trim N
o38 = subquotient (| 0 0 |, | e d b a |)
| b a | | f e c b |
2
o38 : QQ [a, b, c, d, e, f]-module, subquotient of (QQ [a, b, c, d, e, f])
|
Use minimalPresentation to also allow the ambient free module to be improved. This returns a quotient of a free module, but in the future might not do that.
i39 : minimalPresentation N
o39 = cokernel {1} | e d b a |
{1} | f e c b |
2
o39 : QQ [a, b, c, d, e, f]-module, quotient of (QQ [a, b, c, d, e, f])
|
prune is a synonym for minimalPresentation N
i40 : prune N
o40 = cokernel {1} | e d b a |
{1} | f e c b |
2
o40 : QQ [a, b, c, d, e, f]-module, quotient of (QQ [a, b, c, d, e, f])
|
Given a subquotient module N, there are several useful modules associated to N. The free module of which N is a subquotient is obtained using ambient.
i41 : ambient N
2
o41 = (QQ [a, b, c, d, e, f])
o41 : QQ [a, b, c, d, e, f]-module, free
|
This is the same as the target of either the generator or relation matrix.
i42 : ambient N == target generators N
o42 = true
|
i43 : ambient N == target relations N
o43 = true
|
N is a submodule of a quotient module R
n/image(g). The routine super returns this quotient module
i44 : super N
o44 = cokernel | a b d e |
| b c e f |
2
o44 : QQ [a, b, c, d, e, f]-module, quotient of (QQ [a, b, c, d, e, f])
|
This is the same as
i45 : super N == coker relations N
o45 = true
|
The cover of N is basically the source of the matrix of generators.
i46 : cover N
2
o46 = (QQ [a, b, c, d, e, f])
o46 : QQ [a, b, c, d, e, f]-module, free, degrees {1, 1}
|
i47 : cover N == source generators N
o47 = true
|
E. Homomorphisms between modules
A homomorphism f : M --> N is represented as a matrix from the generators of M to the generators of N.
i48 : A = QQ[x,y]/(y^2-x^3)
o48 = A
o48 : QuotientRing
|
i49 : M = module ideal(x,y)
o49 = image | x y |
1
o49 : A-module, submodule of A
|
One homomorphism F : M --> A is x-->y, y-->x
2 (multiplication by y/x) We write this as:
i50 : F = map(A^1,M,matrix{{y,x^2}})
o50 = | y x2 |
o50 : Matrix
|
Notice that as is usual in
Macaulay2, the target comes before the source.
i51 : source F == M
o51 = true
|
i52 : target F == A^1
o52 = true
|
i53 : matrix F
o53 = | y x2 |
1 2
o53 : Matrix A <--- A
|
The image of F lies in the submodule M of A
1. To obtain the map M --> M, we use //. But first we need the inclusion map of M into A
1: Later we explain this, but for now, we just write down this map:
i54 : inducedMap(A^1,M)
o54 = | x y |
o54 : Matrix
|
Now we use // to lift F : M --> A along M --> A
1, to get M --> M:
i55 : G = F // inducedMap(A^1,M)
o55 = {1} | 0 x |
{1} | 1 0 |
o55 : Matrix
|
i56 : source G
o56 = image | x y |
1
o56 : A-module, submodule of A
|
i57 : target G
o57 = image | x y |
1
o57 : A-module, submodule of A
|
G is now a map from M --> M.
i58 : isWellDefined G
o58 = true
|
F. Canonical maps associated with modules
Let’s start with a module M, and a submodule N.
i59 : R = QQ[x,y,z,w]
o59 = R
o59 : PolynomialRing
|
i60 : M = ideal(x,y,z)/ideal(x^2,y^2,z*w)
o60 = subquotient (| x y z |, | x2 y2 zw |)
1
o60 : R-module, subquotient of R
|
i61 : N = z*M
o61 = subquotient (| xz yz z2 |, | x2 y2 zw |)
1
o61 : R-module, subquotient of R
|
i62 : M/N
o62 = subquotient (| x y z |, | xz yz z2 x2 y2 zw |)
1
o62 : R-module, subquotient of R
|
If two modules have the same ambient free module, then there is often a canonical map between them. Some modules having the same ambient free module:
i63 : M
o63 = subquotient (| x y z |, | x2 y2 zw |)
1
o63 : R-module, subquotient of R
|
i64 : ambient M
1
o64 = R
o64 : R-module, free
|
i65 : N = z*M
o65 = subquotient (| xz yz z2 |, | x2 y2 zw |)
1
o65 : R-module, subquotient of R
|
i66 : ambient(M/N)
1
o66 = R
o66 : R-module, free
|
i67 : super M
o67 = cokernel | x2 y2 zw |
1
o67 : R-module, quotient of R
|
i68 : super N
o68 = cokernel | x2 y2 zw |
1
o68 : R-module, quotient of R
|
i69 : image generators M
o69 = image | x y z |
1
o69 : R-module, submodule of R
|
If two modules M and N have the same ambient module R
n, then inducedMap(M,N) makes the canonical map N --> M between them, if one exists. If a map doesn’t exist, the returned map might not be a homomorphism.
i70 : inducedMap(M,M) == id_M
o70 = true
|
i71 : inducedMap(super M,M) == map(super id_M) -- the map (P+Q)/Q --> R^n/Q, where M=(P+Q)/Q.
o71 = true
|
i72 : inducedMap(super M,ambient M) -- the quotient map R^n --> R^n/Q
o72 = | 1 |
o72 : Matrix
|
i73 : inducedMap(M,N) -- the inclusion map
o73 = {1} | z 0 0 |
{1} | 0 z 0 |
{1} | 0 0 z |
o73 : Matrix
|
The projection map M --> M/N
i74 : inducedMap(M/N,M) -- the projection map
o74 = {1} | 1 0 0 |
{1} | 0 1 0 |
{1} | 0 0 1 |
o74 : Matrix
|
The projection map N --> M/N, which is the zero map
i75 : inducedMap(M/N,N) -- the zero map
o75 = 0
o75 : Matrix
|
Not all such maps can be defined. The functions ’inducedMap’ normally checks that the result is a well-defined homomorphism. The option ’Verify’ controls that behavior.
i76 : inducedMap(M,M/N,Verify => false)
o76 = {1} | 1 0 0 |
{1} | 0 1 0 |
{1} | 0 0 1 |
o76 : Matrix
|
i77 : inducedMap(M/N,x*M)
o77 = {1} | 0 y 0 |
{1} | 0 0 0 |
{1} | 0 0 0 |
o77 : Matrix
|
i78 : inducedMap(M/N,M) * inducedMap(M,x*M) == inducedMap(M/N,x*M)
o78 = true
|
Before doing interesting homomorphisms, let’s see how to write down some canonical homomorphisms associated to M. exercises: 1. isomorphism theorems. Given submodules M and N of a module P, (a) find (M+N)/M (b) find N/(M ∩N) (c) find in
Macaulay2, an isomorphism between them.
2. Given a homomorphism M --> A. Suppose that the image lies in M (M is a submodule of A
1). Find the map M --> M.
G. Homomorphisms and Hom
i79 : A = QQ[x,y,Degrees=>{2,3}]/(y^2-x^3)
o79 = A
o79 : QuotientRing
|
i80 : M = module ideal(x,y)
o80 = image | x y |
1
o80 : A-module, submodule of A
|
i81 : H = Hom(M,M)
o81 = subquotient ({0} | 1 0 |, {0} | 0 y 0 x2 |)
{1} | 0 1 | {1} | 0 -x 0 -y |
{-1} | 0 x | {-1} | y 0 x2 0 |
{0} | 1 0 | {0} | -x 0 -y 0 |
4
o81 : A-module, subquotient of A
|
The elements of H correspond to homomorphisms M --> A. The homomorphism associated to elements of H may be obtained using the routine homomorphism.
i82 : F = homomorphism(H_{0})
o82 = {2} | 1 0 |
{3} | 0 1 |
o82 : Matrix
|
i83 : G = homomorphism(H_{1})
o83 = {2} | 0 x |
{3} | 1 0 |
o83 : Matrix
|
i84 : source F == M
o84 = true
|
i85 : target F == M
o85 = true
|
i86 : ker F
o86 = image 0
1
o86 : A-module, submodule of A
|
i87 : coker F
o87 = subquotient (| x y |, | x y |)
1
o87 : A-module, subquotient of A
|
i88 : m = matrix{{x,y},{y,x}}
o88 = | x y |
| y x |
2 2
o88 : Matrix A <--- A
|
i89 : Hom(m,A^2)
o89 = {-3} | x 0 y 0 |
{-3} | 0 x 0 y |
{-3} | y 0 x 0 |
{-3} | 0 y 0 x |
4 4
o89 : Matrix A <--- A
|
i90 : Hom(A^2,m)
o90 = | x y 0 0 |
| y x 0 0 |
| 0 0 x y |
| 0 0 y x |
4 4
o90 : Matrix A <--- A
|
H. Tensor products
In
Macaulay2, ** denotes the tensor product operator.
i91 : m ** m
o91 = | x2 xy xy y2 |
| xy x2 y2 xy |
| xy y2 x2 xy |
| y2 xy xy x2 |
4 4
o91 : Matrix A <--- A
|
i92 : (coker m) ** (coker m)
o92 = cokernel | x y 0 0 x y 0 0 |
| y x 0 0 0 0 x y |
| 0 0 x y y x 0 0 |
| 0 0 y x 0 0 y x |
4
o92 : A-module, quotient of A
|
Notice that tensor products of matrices and of modules are very different.
i93 : M = coker m
o93 = cokernel | x y |
| y x |
2
o93 : A-module, quotient of A
|
i94 : M2 = prune(M ** M)
o94 = cokernel | 0 -x y x x 0 |
| -x 0 x y 0 x |
| x 0 0 0 y 0 |
| 0 x 0 0 0 y |
4
o94 : A-module, quotient of A
|
i95 : A = QQ[a,b,c]
o95 = A
o95 : PolynomialRing
|
i96 : A ** A
o96 = QQ [a, b, c, a, b, c, Degrees => {{1, 0}, {1, 0}, {1, 0}, {0, 1}, {0,
-----------------------------------------------------------------------
1}, {0, 1}}, MonomialOrder => {GRevLex => {1, 1, 1}, Position => Up,
-----------------------------------------------------------------------
GRevLex => {1, 1, 1}, Position => Up}]
o96 : PolynomialRing
|
Oops!
Macaulay2 doesn’t know what a should be!
i97 : B = oo
o97 = B
o97 : PolynomialRing
|
i98 : a == B_3
o98 = true
|
i99 : a == B_0
o99 = false
|
To remedy this, one can give the variables as an option to tensor.
i100 : tensor(A,A,Variables=>{a,b,c,d,e,f})
o100 = QQ [a, b, c, d, e, f, Degrees => {{1, 0}, {1, 0}, {1, 0}, {0, 1}, {0,
----------------------------------------------------------------------
1}, {0, 1}}, MonomialOrder => {GRevLex => {1, 1, 1}, Position => Up,
----------------------------------------------------------------------
GRevLex => {1, 1, 1}, Position => Up}]
o100 : PolynomialRing
|