next | previous | forward | backward | up | top | index | toc | Macaulay2 web site
Macaulay2Doc > modules > right modules or left modules?

right modules or left modules?

Macaulay2 can handle non-commutative rings, and for such rings there is a difference between left modules and right modules. In Macaulay2, all the modules are left modules, but matrices act on the left, too. The usual convention would be to have the matrices act on the right, so the homomorphism rule (f(av)=af(v)) becomes a consequence of associativity of matrix-vector-scalar multiplication ((av)f=a(vf)). Macaulay2 makes things come out okay in the end -- a left R-module can be regarded naturally as a right R'-module, where R' is the opposite ring of R, obtained from the ring R by reversing the multiplication. Thus matrices over R' can act on R-modules from the left. Matrices over R in Macaulay2 are really matrices over R'.

We illustrate this state of affairs with an example over a (noncommutative) Weyl algebra. First observe the noncommutativity.

i1 : R = QQ[x,dx,WeylAlgebra=>{x=>dx}]

o1 = R

o1 : PolynomialRing
i2 : x*dx

o2 = x*dx

o2 : R
i3 : dx*x

o3 = x*dx + 1

o3 : R
Now verify the module is a left module by checking associativity.
i4 : M = R^2

      2
o4 = R

o4 : R-module, free
i5 : v = M_0

o5 = | 1 |
     | 0 |

      2
o5 : R
i6 : dx*v

o6 = | dx |
     |  0 |

      2
o6 : R
i7 : x*(dx*v)

o7 = | xdx |
     |  0  |

      2
o7 : R
i8 : (x*dx)*v

o8 = | xdx |
     |  0  |

      2
o8 : R
i9 : x*(dx*v) == (x*dx)*v

o9 = true
Now make a matrix and check that left multiplication by it is a homomorphism from M to M.
i10 : f = dx * id_M

o10 = | dx 0  |
      | 0  dx |

              2       2
o10 : Matrix R  <--- R
i11 : f*(x*v)

o11 = | xdx |
      |  0  |

       2
o11 : R
i12 : x*(f*v)

o12 = | xdx |
      |  0  |

       2
o12 : R
i13 : f*(x*v) == x*(f*v)

o13 = true
Now we make another matrix and check that matrix multiplication treats the entries of the matrices as residing in the opposite ring, R'.
i14 : g = x * id_M

o14 = | x 0 |
      | 0 x |

              2       2
o14 : Matrix R  <--- R
i15 : f*g

o15 = | xdx 0   |
      | 0   xdx |

              2       2
o15 : Matrix R  <--- R
i16 : f*g == (x*dx) * id_M

o16 = true
i17 : (dx * id_M)*(x * id_M) == (x*dx) * id_M

o17 = true
Here we check that multiplication of a scalar times a matrix is compatible with multiplication of a scalar times a vector.
i18 : x * ( (dx * id_M) * v )

o18 = | xdx |
      |  0  |

       2
o18 : R
i19 : (x *  (dx * id_M) ) * v

o19 = | xdx |
      |  0  |

       2
o19 : R
i20 : (x *  (dx * id_M) ) * v == x * ( (dx * id_M) * v )      

o20 = true
One desirable associativity rule does not hold, the one for RingElement * Matrix * Matrix, as we see in this example.
i21 : x * ( id_M * ( dx * id_M ) )

o21 = | xdx 0   |
      | 0   xdx |

              2       2
o21 : Matrix R  <--- R
i22 : (x * id_M) * ( dx * id_M )

o22 = | xdx+1 0     |
      | 0     xdx+1 |

              2       2
o22 : Matrix R  <--- R
i23 : x * ( id_M * ( dx * id_M ) ) == (x * id_M) * ( dx * id_M )

o23 = false
The reason for this discrepancy is that, as explained above, matrix multiplication is done over R', not over R.

Currently, tensor product of a module M by a ring R works on either side and does the same thing. In other words, you can write R**M or M**R. That may change in the future.