# Basic operations on noncommutative algebras

The NCAlgebra package contains a number of methods for studying noncommutative rings - primarily graded rings. The following three extended examples highlight the capabilities of the package. For a detailed account of the Groebner basis calculations underlying nearly all of these methods, see Using the Bergman interface.

Our first example concerns a three-dimensional Sklyanin algebra. This example is a PI-ring. We define the ring as a quotient of the tensor algebra on three generators by the two-sided ideal generated by the three elements listed.

 i1 : A = QQ{x,y,z} o1 = A o1 : NCPolynomialRing

Users familiar with Macaulay2 will recognize the notation for a ring of noncommutative polynomials is identical to that for local rings, see Ring List. Thus the previous line does not generate an error if you forget to load the NCAlgebra package.

 i2 : f = y*z + z*y - x^2 2 o2 = zy+yz-x o2 : A i3 : g = x*z + z*x - y^2 2 o3 = zx-y +xz o3 : A i4 : h = z^2 - x*y - y*x 2 o4 = z -yx-xy o4 : A i5 : B = A/ncIdeal{f,g,h} --Calling Bergman for NCGB calculation. Complete! o5 = B o5 : NCQuotientRing

It is known that this algebra has a unique (up to rescaling) central element of degree 3. We can verify this claim computationally using centralElements and check that the element is regular to a given degree. See isLeftRegular.

 i6 : centralElements(B,3) o6 = | y^3-y*x*z+x*y*z-x^3 | o6 : NCMatrix i7 : j = y^3+x*y*z-y*x*z-x^3 3 3 o7 = y -yxz+xyz-x o7 : B i8 : isCentral j o8 = true i9 : apply(5,i->isLeftRegular(j,i+1)) o9 = {true, true, true, true, true} o9 : List

In fact, we can see that j is (up to scaling) the only normal element of degree 3. See the discussion above for interpreting the output of normalElements.

 i10 : normalElements(B,3,n,o) Normal monomials of degree 3: none Components of the normal variety, excluding normal monomials: o10 = {| n_(y^2*z) n_(y*x*z)+n_(x*y*z) n_(x^2*z) n_(y^3)-n_(x*y*z) n_(x*y^2) ----------------------------------------------------------------------- n_(y*x*y) n_(x^2*y) n_(x*y*x) n_(x^3)+n_(x*y*z) |} o10 : List i11 : basis(3,B) o11 = | x^3 x*y*x x^2*y y*x*y x*y^2 y^3 x^2*z y*x*z x*y*z y^2*z | o11 : NCMatrix

Recently, we studied noncommutative matrix factorizations over noncommutative hypersurfaces. Here is a simple example. The hypersurface is B/(j). However, iterated quotients are not yet implemented, so we define this ring as a quotient of the tensor algebra. Note the use of "promote" to ensure j is thought of as an element of the tensor algebra.

 i12 : use A o12 = A o12 : NCPolynomialRing i13 : I = B.ideal 2 2 2 o13 = Two-sided ideal {zy+yz-x , zx-y +xz, z -yx-xy} o13 : NCIdeal i14 : J = ncIdeal promote(j,A) 3 3 o14 = Two-sided ideal {y -yxz+xyz-x } o14 : NCIdeal i15 : B' = A/(I+J) --Calling Bergman for NCGB calculation. Complete! o15 = B' o15 : NCQuotientRing

As in the commutative case, any minimal free resolution of a finitely generated module over a noncommutative hypersurface is eventually given by a matrix factorization. We resolve the trivial module for B' by expressing it as the cokernel of a homogeneous matrix.

 i16 : k = ncMatrix {gens B'} o16 = | x y z | o16 : NCMatrix i17 : M = rightKernelBergman rightKernelBergman k --Calling Bergman for NCGB calculation. Complete! --Calling Bergman for NCGB calculation. Complete! --Calling Bergman for NCGB calculation. Complete! --Calling Bergman for NCGB calculation. Complete! --Calling Bergman for NCGB calculation. Complete! --Calling Bergman for NCGB calculation. Complete! o17 = | -z y*z -y^2 -y*x-2*x*y | | x y*x+x*y y*z+x^2 -y^2+3*x*z | | y -x*z -x*y x^2 | | 0 -2*y -2*x -2*z | o17 : NCMatrix i18 : N = rightKernelBergman M --Calling Bergman for NCGB calculation. Complete! --Calling Bergman for NCGB calculation. Complete! o18 = | 0 2*y*x 2*y^2-2*x*z -y*x*z-x^3 | | -z x y -y^2+x*z | | x y -z -y*z+x^2 | | -y -z -x 0 | o18 : NCMatrix

As discussed in Using the Bergman interface, the method rightKernelBergman only computes the kernel of a module map to a certain homogeneous degree. Applying a theorem of Cassidy and Shelton, we can be sure the matrices in any minimal graded free resolution of the trivial module of B' will have entries of homogeneous degree at most 3. Thus we conclude M is the third syzygy module and N is the fourth. If we lift these matrices we see that M and N are nearly a factorization of the central element j.

 i19 : BprimeToB = ncMap(B,B',gens B) o19 = NCRingMap B <--- B' o19 : NCRingMap i20 : liftM = BprimeToB M o20 = | -z y*z -y^2 -y*x-2*x*y | | x y*x+x*y y*z+x^2 -y^2+3*x*z | | y -x*z -x*y x^2 | | 0 -2*y -2*x -2*z | o20 : NCMatrix i21 : liftN = BprimeToB N o21 = | 0 2*y*x 2*y^2-2*x*z -y*x*z-x^3 | | -z x y -y^2+x*z | | x y -z -y*z+x^2 | | -y -z -x 0 | o21 : NCMatrix i22 : liftM*liftN o22 = | 0 2*y^3-2*y*x*z+2*x*y*z-2*x^3 0 0 | | 2*y^3-2*y*x*z+2*x*y*z-2*x^3 0 0 0 | | 0 0 2*y^3-2*y*x*z+2*x*y*z-2*x^3 0 | | 0 0 0 2*y^3-2*y*x*z+2*x*y*z-2*x^3 | o22 : NCMatrix

It appears that a change of basis will produce a matrix factorization. In general, Bergman returns a generating set for the kernel, but it need not have any nice properties. Here the NCAlgebra package can help by factoring a map. We would like M*M' = M'*M = j*I where I is the identity matrix.

 i23 : jId = promote(j,B)*(ncMatrix applyTable(entries id_(ZZ^4), i -> promote(i,B))) o23 = | y^3-y*x*z+x*y*z-x^3 0 0 0 | | 0 y^3-y*x*z+x*y*z-x^3 0 0 | | 0 0 y^3-y*x*z+x*y*z-x^3 0 | | 0 0 0 y^3-y*x*z+x*y*z-x^3 | o23 : NCMatrix i24 : assignDegrees(jId,{2,2,2,3},{5,5,5,6});

The matrix jId is diagonal, and we have assigned degrees to make it compatible with M. Now we factor the lift of M through jId.

 i25 : M' = jId // liftM --Calling Bergman for NCGB calculation. Complete! o25 = | y*x 0 y^2-x*z -1/2*y*x*z-1/2*x^3 | | 1/2*x -1/2*z 1/2*y -1/2*y^2+1/2*x*z | | 1/2*y 1/2*x -1/2*z -1/2*y*z+1/2*x^2 | | -1/2*z -1/2*y -1/2*x 0 | o25 : NCMatrix i26 : N o26 = | 0 2*y*x 2*y^2-2*x*z -y*x*z-x^3 | | -z x y -y^2+x*z | | x y -z -y*z+x^2 | | -y -z -x 0 | o26 : NCMatrix

We see that M' and N describe the same submodule and we check that the factorization worked:

 i27 : liftM*M' o27 = | y^3-y*x*z+x*y*z-x^3 0 0 0 | | 0 y^3-y*x*z+x*y*z-x^3 0 0 | | 0 0 y^3-y*x*z+x*y*z-x^3 0 | | 0 0 0 y^3-y*x*z+x*y*z-x^3 | o27 : NCMatrix i28 : M'*liftM o28 = | y^3-y*x*z+x*y*z-x^3 0 0 0 | | 0 y^3-y*x*z+x*y*z-x^3 0 0 | | 0 0 y^3-y*x*z+x*y*z-x^3 0 | | 0 0 0 y^3-y*x*z+x*y*z-x^3 | o28 : NCMatrix

The user can create noncommutative rings in ways other than specifying a presentation. For our second example, consider a skew polynomial ring on four generators, where generators skew-commute (but are not nilpotent). See skewPolynomialRing for more details.

 i29 : C = skewPolynomialRing(QQ,(-1)_QQ,{x,y,z,w}) --Calling Bergman for NCGB calculation. Complete! o29 = C o29 : NCQuotientRing

Let us briefly note that the user can also define a skew polynomial ring with coefficients in a commutative ring.

 i30 : R = QQ[q]/ideal{q^4+q^3+q^2+q+1} o30 = R o30 : QuotientRing i31 : B = skewPolynomialRing(R,q,{x,y,z,w}) o31 = B o31 : NCQuotientRing i32 : x*y == q*y*x o32 = true

Returning to the main example, we can define a graded Ore extension of C by specifying an automorphism. The function ncMap is used to define a ring map. Note that ring maps are linear and multiplicative by definition but are not assumed to be well-defined.

 i33 : use C o33 = C o33 : NCQuotientRing i34 : sigma = ncMap(C,C,{y,z,w,x}) o34 = NCRingMap C <--- C o34 : NCRingMap i35 : isWellDefined sigma o35 = true

We form the Ore extension of C by sigma. See oreExtension.

 i36 : D = oreExtension(C,sigma,a) --Calling Bergman for NCGB calculation. Complete! o36 = D o36 : NCQuotientRing

The new generator a is normal and regular in D. Regularity (on the left or right) can be checked one homogeneous degree at a time. See isLeftRegular. Thus a determines a graded automorphism f:D->D via a*r=f(r)*a.

 i37 : isNormal a o37 = true i38 : apply(5,i-> isLeftRegular(a,i+1)) o38 = {true, true, true, true, true} o38 : List i39 : sigmaD = normalAutomorphism a o39 = NCRingMap D <--- D o39 : NCRingMap

Given an automorphism, one can check to see which elements it normalizes in any given degree.

 i40 : normalElements(sigmaD,1) o40 = | a | o40 : NCMatrix i41 : normalElements(sigmaD,2) o41 = 0 1 o41 : Matrix QQ <--- 0

One can check for the presence of normal elements more generally. In our example, since a is normal, a^2 will also be normal. It is the only normal monomial of degree 2. A complete description of the normal elements in a given degree is given by normalElements.

 i42 : normalElements(D,2,P,Q) Normal monomials of degree 2: 2 a Components of the normal variety, excluding normal monomials: o42 = {| P_(w*a) P_(z*a) P_(y*a) P_(x*a) P_(z*w) P_(y*w) P_(x*w) P_(y*z) ----------------------------------------------------------------------- P_(x*z) P_(x*y) P_(z^2)^2-P_(y^2)P_(w^2) P_(y^2)P_(z^2)-P_(x^2)P_(w^2) ----------------------------------------------------------------------- P_(x^2)P_(z^2)-P_(w^2)^2 P_(y^2)^2-P_(w^2)^2 ----------------------------------------------------------------------- P_(x^2)P_(y^2)-P_(z^2)P_(w^2) P_(x^2)^2-P_(y^2)P_(w^2) |} o42 : List

Each component of the "normal variety" is a set of polynomial equations which must be satisfied by the coefficients of the monomial basis for an element expressed in that basis to be normal. In this case, the basis of D in degree 2 is

 i43 : basis(2,D) o43 = | x^2 x*y y^2 x*z y*z z^2 x*w y*w z*w w^2 x*a y*a z*a w*a a^2 | o43 : NCMatrix

The output of normalElements tells us that in order for a degree 2 element of D to be normal, it must be an expression in powers of the generators. The coefficients of these powers must satisfy the six equations listed.

 i44 : isNormal (x^2+z^2-y^2-w^2) o44 = true

In Macaulay2, the user can define a polynomial ring to be commutative or skew-commutative (the exterior algebra). The user can convert these rings (and their quotients) to a type compatible with the NCAlgebra package using toNCRing.

 i45 : E' = QQ[x,y,z,w,SkewCommutative=>true] o45 = E' o45 : PolynomialRing, 4 skew commutative variables i46 : E = toNCRing E' --Calling Bergman for NCGB calculation. Complete! o46 = E o46 : NCQuotientRing i47 : f = ncMap(E,C,gens E) o47 = NCRingMap E <--- C o47 : NCRingMap i48 : f x^2 o48 = 0 o48 : E i49 : use C o49 = C o49 : NCQuotientRing i50 : x^2 == 0 o50 = false

Conversely, the user can convert an NCRing to a (quotient of a) polynomial ring in the usual sense of Macaulay2 using toM2Ring. This method works on any NCRing - the result is the abelianization or "exterior-ization" of the given ring. For example, if we abelianize the skew polynomial ring C, we get a ring in which only powers of the generators are nonzero. On the other hand, if we "exterior-ize" C, we get the exterior algebra.

 i51 : C' = toM2Ring C o51 = C' o51 : QuotientRing i52 : x*y o52 = 0 o52 : C' i53 : x*x 2 o53 = x o53 : C' i54 : C'' = toM2Ring(C,SkewCommutative=>true) o54 = C'' o54 : PolynomialRing, 4 skew commutative variables i55 : y*x o55 = -x*y o55 : C'' i56 : y*y o56 = 0 o56 : C''

Finally, we can construct the opposite ring. The opposite ring of D will be the Ore extension by the inverse of sigma. See oppositeRing.

 i57 : Dop = oppositeRing D --Calling Bergman for NCGB calculation. Complete! o57 = Dop o57 : NCQuotientRing i58 : a*x == w*a o58 = true i59 : use D o59 = D o59 : NCQuotientRing i60 : a*w == x*a o60 = true

Our last extended example illustrates how to obtain a presentation for the endomorphism ring of a module over a commutative ring. First we define a hypersurface ring and a high syzygy module.

 i61 : Q = QQ[a,b,c] o61 = Q o61 : PolynomialRing i62 : R = Q/ideal{a*b-c^2} o62 = R o62 : QuotientRing i63 : kRes = res(coker vars R, LengthLimit=>7); i64 : M = coker kRes.dd_5 o64 = cokernel {4} | 0 -a 0 -c | {4} | -b 0 -c 0 | {4} | c 0 a 0 | {4} | 0 c 0 b | 4 o64 : R-module, quotient of R

The endomorphism ring is computed using endomorphismRing. This method computes a presentation, but the presentation is typically not minimal. We see from the following calculation that X_3 = X_0X_2.

 i65 : B = endomorphismRing(M,X); i66 : gensI = gens ideal B o66 = {X X +-X , -X +X X , -X +X X , X X , X X , X X +-X , X X , X X +-X , 0 1 0 3 0 2 2 1 2 0 3 1 3 2 3 2 1 0 2 0 1 ----------------------------------------------------------------------- 2 2 2 2 X X , X X +-X , X X , X X , X , X +-X , X , X +-X } 2 1 3 0 0 3 1 3 2 0 1 1 2 3 3 o66 : List

To eliminate redundant generators and relations, use minimizeRelations. This method makes several passes through the presentation, and stops if no minimization occurs.

 i67 : gensIMin = minimizeRelations(gensI, Verbosity=>1) Eliminating variable X 1 Eliminating variable X 3 Reducing X_0*X_2*X_0+-X_0 (1 of 12) (Pass 1) Reducing X_2*X_0*X_2+-X_2 (2 of 12) (Pass 1) Reducing X_0^2*X_2 (3 of 12) (Pass 1) Reducing X_2*X_0^2*X_2 (4 of 12) (Pass 1) Reducing X_2*X_0^2 (5 of 12) (Pass 1) Reducing X_2^2*X_0 (6 of 12) (Pass 1) Reducing X_0*X_2^2*X_0 (7 of 12) (Pass 1) Reducing X_0*X_2^2 (8 of 12) (Pass 1) Reducing X_0^2 (9 of 12) (Pass 1) Reducing X_2*X_0*X_2*X_0+-X_2*X_0 (10 of 12) (Pass 1) Reducing X_2^2 (11 of 12) (Pass 1) Reducing X_0*X_2*X_0*X_2+-X_0*X_2 (12 of 12) (Pass 1) Reducing X_0*X_2*X_0+-X_0 (1 of 4) (Pass 2) Reducing X_2*X_0*X_2+-X_2 (2 of 4) (Pass 2) Reducing X_0^2 (3 of 4) (Pass 2) Reducing X_2^2 (4 of 4) (Pass 2) Reducing X_0*X_2*X_0+-X_0 (1 of 4) (Pass 1) Reducing X_2*X_0*X_2+-X_2 (2 of 4) (Pass 1) Reducing X_0^2 (3 of 4) (Pass 1) Reducing X_2^2 (4 of 4) (Pass 1) 2 2 o67 = {X X X +-X , X X X +-X , X , X } 0 2 0 0 2 0 2 2 0 2 o67 : List

We see a substantial reduction in the number of relations and that X_1 and X_3 are redundant generators. The endomorphisms themselves are cached, and can be accessed via endomorphismRingGens. As an example, we explicitly verify that X_3 is redundant.

 i68 : maps = B.cache.endomorphismRingGens o68 = {{4} | 0 0 1 0 |, {4} | 0 0 0 0 |, {4} | 0 0 0 0 |, {4} | 1 0 0 0 |} {4} | 0 0 0 0 | {4} | 0 1 0 0 | {4} | 0 0 0 1 | {4} | 0 0 0 0 | {4} | 0 0 0 0 | {4} | 0 0 1 0 | {4} | 1 0 0 0 | {4} | 0 0 0 0 | {4} | 0 1 0 0 | {4} | 0 0 0 0 | {4} | 0 0 0 0 | {4} | 0 0 0 1 | o68 : List i69 : maps#3 == maps#0*maps#2 o69 = true