# modules in Macaulay2

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} | cd-be 0 e2-df ce-bf | {1} | -bd+ae e2-df 0 -be+af | {1} | b2-ac -ce+bf -be+af 0 | {1} | 0 cd-be bd-ae 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} | cd-be 0 e2-df ce-bf | {1} | -bd+ae e2-df 0 -be+af | {1} | b2-ac -ce+bf -be+af 0 | {1} | 0 cd-be bd-ae 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. Ni defines a matrix R1 --> 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*N1, but it turns out that a ** N1 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```
 ```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,GradedModule) 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 that 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 {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 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 : Rm --> Rn and g : Rp --> Rn. 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 (| a 0 |, | e d b a |) | 0 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 Rn/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-->x2 (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 A1. To obtain the map M --> M, we use //. But first we need the inclusion map of M into A1: 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 --> A1, 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

 ```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 Rn, 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 A1). 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] 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] o100 : PolynomialRing```