# tensor(Ring,Ring) -- tensor product

## Description

This is the same as A ** B except that options are allowed, see Monoid ** Monoid and Ring ** Ring. This method allows many of the options available for monoids, see monoid for details. This method essentially combines the variables of A and B into one monoid or ring.

 ```i1 : kk = ZZ/101 o1 = kk o1 : QuotientRing``` ```i2 : A = kk[a,b] o2 = A o2 : PolynomialRing``` ```i3 : B = kk[c,d,e] o3 = B o3 : PolynomialRing```

The simplest version is to simply use **:

 ```i4 : describe(A**B) o4 = kk[a..e, Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2] {0} {1} {GRevLex => {2:1} } {Position => Up } {GRevLex => {3:1} }```

If you wish to change the variable names:

 ```i5 : describe tensor(A,B,VariableBaseName=>p) o5 = kk[p ..p , Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2] 0 4 {0} {1} {GRevLex => {2:1} } {Position => Up } {GRevLex => {3:1} }``` ```i6 : describe tensor(A,B,Variables=>{a1,a2,b1,b2,b3}) o6 = kk[a1, a2, b1, b2, b3, Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2] {0} {1} {GRevLex => {2:1} } {Position => Up } {GRevLex => {3:1} }```

The tensor product of two singly graded rings is bigraded. Sometimes you want a singly graded ring. Here is one way to get it:

 ```i7 : describe (C = tensor(A,B,DegreeRank=>1,Degrees=>{5:1})) o7 = kk[a..e, Degrees => {5:1}, Heft => {1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 1] {GRevLex => {2:1} } {Position => Up } {GRevLex => {3:1} }``` ```i8 : degreeLength C o8 = 1``` ```i9 : degreesRing C o9 = ZZ[T] o9 : PolynomialRing```

Packing monomials into smaller space is more efficient, but less flexible. The default is 32 bits, so if you want to pack them into 8 bit exponents, use:

 ```i10 : describe tensor(A,B,MonomialSize=>8) o10 = kk[a..e, Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 8 }, DegreeRank => 2] {0} {1} {MonomialSize => 32} {GRevLex => {2:1} } {Position => Up } {GRevLex => {3:1} }```

The default monomial order for tensor products is a product order. Sometimes other orders are more desirable, e.g. GRevLex, or an elimination order:

 ```i11 : describe (C = tensor(A,B,MonomialOrder=>Eliminate numgens A)) o11 = kk[a..e, Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2] {0} {1} {Weights => {2:1} } {GRevLex => {5:1} } {Position => Up }``` ```i12 : describe (C = tensor(A,B,MonomialOrder=>GRevLex)) o12 = kk[a..e, Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2] {0} {1} {GRevLex => {5:1} } {Position => Up }```

If you tensor two skew-commutative rings, (or one skew commutative ring with a commutative polynomial ring), then all of the skew-commuting variables skew commute with each other:

 ```i13 : As = kk[a,b,SkewCommutative=>true] o13 = As o13 : PolynomialRing, 2 skew commutative variables``` ```i14 : D = kk[c,d,e,SkewCommutative=>true] o14 = D o14 : PolynomialRing, 3 skew commutative variables``` ```i15 : E = tensor(As,D) o15 = E o15 : PolynomialRing, 5 skew commutative variables``` ```i16 : describe E o16 = kk[a..e, Degrees => {2:{1}, 3:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2, SkewCommutative => {0, 1, 2, 3, 4}] {0} {1} {GRevLex => {2:1} } {Position => Up } {GRevLex => {3:1} }``` ```i17 : c*a o17 = -a*c o17 : E```

Similarly, tensoring two Weyl algebras (or one and a polynomial ring) produces a Weyl algebra with both sets of non-commuting pairs.

 ```i18 : E = kk[x,Dx,WeylAlgebra=>{x=>Dx}] o18 = E o18 : PolynomialRing, 1 differential variables``` ```i19 : tensor(E,E,Variables=>{x,Dx,y,Dy}) o19 = kk[x, Dx, y, Dy] o19 : PolynomialRing, 2 differential variables``` ```i20 : describe oo o20 = kk[x, Dx, y, Dy, Degrees => {2:{1}, 2:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2, WeylAlgebra => {0 => 1, 2 => 3}] {0} {1} {GRevLex => {2:1} } {Position => Up } {GRevLex => {2:1} }```

Two polynomial rings must have the same coefficient ring, otherwise an error is issued. Currently, there is no way to specify other rings over which to define the tensor product.

 ```i21 : A = ZZ/101[a,b] o21 = A o21 : PolynomialRing``` ```i22 : B = A[x,y] o22 = B o22 : PolynomialRing``` ```i23 : C = tensor(B,B,Variables=>{x1,y1,x2,y2}) o23 = C o23 : PolynomialRing``` ```i24 : describe C o24 = A[x1, y1, x2, y2, Degrees => {2:{1}, 2:{0}}, Heft => {2:1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2] {0} {1} {GRevLex => {2:1} } {Position => Up } {GRevLex => {2:1} }```
The flat monoid with the all variables visible, including those from the base ring, can be obtained as follows.
 ```i25 : C.FlatMonoid o25 = monoid[x1, y1, x2, y2, a..b, Degrees => {2:{1}, 2:{0}, 2:{0}}, Heft => {3:1}, MonomialOrder => {MonomialSize => 32 }, DegreeRank => 3] {0} {1} {0} {GRevLex => {2:1} } {0} {0} {1} {Position => Up } {2:(GRevLex => {1, 1})} o25 : GeneralOrderedMonoid```

## Caveat

Not all of the options for monoid are useful here. Some are silently ignored.