# flattenRing -- write a ring as a (quotient of a) polynomial ring

## Synopsis

• Usage:
flattenRing R
flattenRing I
flattenRing G
• Inputs:
• Optional inputs:
• CoefficientRing => ..., -- optionally specify the desired coefficient ring of the flattened ring
• Result => ..., -- optionally specify which output(s) to return (see Description for details)
• Outputs:
• S, a ring, a ring isomorphic to R, but represented as a (quotient of a) polynomial ring, or
• J, an ideal, the ideal of S corresponding to (isomorphic to) I
• F, , the isomorphism from R to S
• G, , the isomorphism from S to R

## Description

Use flattenRing to get an isomorphic representation of a ring over a different coefficient ring.

For instance the following ring R is defined to have indeterminates y,z, and coefficients in the quotient ring ℤ[x]/(x2-3).

 `i1 : A = ZZ[x] / (x^2-3); R = A[y,z] / (x*y^2-z^2, y^3);` ```i3 : describe R A[y, z] o3 = --------------- 2 2 3 (x*y - z , y )```

To work with the isomorphic ring S = ℤ[x,y,z]/(x2-3,x*y2-z2,y3) instead, use flattenRing.

 ```i4 : flattenRing R ZZ[y, z, x] ZZ[y, z, x] o4 = (----------------------, map(----------------------,R,{y, z, x})) 2 2 2 3 2 2 2 3 (x - 3, y x - z , y ) (x - 3, y x - z , y ) o4 : Sequence```

The default output is the sequence (S, F), where S is the flattened ring, and F is the RingMap from R to S. Here we demonstrate how to store and use the map F.

 ```i5 : I = ideal(y^2 - 3*x*z) 2 o5 = ideal(y - 3x*z) o5 : Ideal of R``` `i6 : (S, F) = flattenRing R;` ```i7 : F(I) 2 o7 = ideal(y - 3z*x) o7 : Ideal of S```

Flattening an ideal instead of a quotient ring can save a lot of time spent computing the GrÃ¶bner basis of the resulting ideal, if the flattened quotient is not needed. Notice that the ring map in the following example is not the same as the previous example; the following ring map is from R to ℤ[x,y,z], while the previous map was from R to ℤ[x,y,z]/(x2-3,x*y2-z2,y3).

 `i8 : A = ZZ[x] / (x^2-3); R = A[y,z] / (x*y^2-z^2, y^3);` ```i10 : I = ideal(y^2 - 3*x*z); o10 : Ideal of R``` ```i11 : (J, F) = flattenRing I 2 2 2 3 2 o11 = (ideal (x - 3, y x - z , y , y - 3z*x), map(ZZ[y, z, x],R,{y, z, x})) o11 : Sequence```

flattenRing can also be used to represent GaloisFields as quotients of polynomial rings. If K is the Galois field of order pn, flattenRing(K) will represent K as a quotient of p[a].

 ```i12 : K = GF(5^3) o12 = K o12 : GaloisField``` ```i13 : flattenRing K ZZ ZZ --[a] --[a] 5 5 o13 = (-----------, map(-----------,K,{a})) 3 3 a - 2a - 2 a - 2a - 2 o13 : Sequence```

Or, if a different variable was specified in the construction of K, flattenRing K will follow suit.

 `i14 : L = GF(7, 5, Variable => z);` ```i15 : flattenRing L ZZ ZZ --[z] --[z] 7 7 o15 = (----------, map(----------,L,{z})) 5 5 z + z - 3 z + z - 3 o15 : Sequence```

Use Result => 1 to return the ring only. The default behavior is equivalent to Return => 2. Use Result => 3 to return the ring, the isomorphism F:R→S, and the inverse map F-1:R→S.

 ```i16 : flattenRing(R, Result => 1) ZZ[y, z, x] o16 = ---------------------- 2 2 2 3 (x - 3, y x - z , y ) o16 : QuotientRing``` ```i17 : flattenRing(R, Result => 2) ZZ[y, z, x] ZZ[y, z, x] o17 = (----------------------, map(----------------------,R,{y, z, x})) 2 2 2 3 2 2 2 3 (x - 3, y x - z , y ) (x - 3, y x - z , y ) o17 : Sequence``` ```i18 : flattenRing(R, Result => 3) ZZ[y, z, x] ZZ[y, z, x] o18 = (----------------------, map(----------------------,R,{y, z, x}), 2 2 2 3 2 2 2 3 (x - 3, y x - z , y ) (x - 3, y x - z , y ) ----------------------------------------------------------------------- ZZ[y, z, x] map(R,----------------------,{y, z, x})) 2 2 2 3 (x - 3, y x - z , y ) o18 : Sequence```

These are the only numeric options for Result. However, we can also specify the output(s) desired with a sequence of length 1, 2, or 3. The elements of the sequence correspond to the Result => 1, Result => 2, and Result => 3 output sequences, respectively. Any element of the sequence can be suppressed by asking for Nothing instead. For example, to return the map F only, we ask for the sequence of length 2, (S, F), but suppress S:

 ```i19 : flattenRing(R, Result => (Nothing, RingMap)) o19 = (, map(ZZ[y, z, x],R,{y, z, x})) o19 : Sequence```

Note that Result => RingMap is NOT a valid way to return F only, because an output of length 1 can only have a ring or an ideal.

Similarly, to return S and F-1 only:

 ```i20 : flattenRing(R, Result => (Ring, Nothing, RingMap)) ZZ[y, z, x] ZZ[y, z, x] o20 = (----------------------, , map(R,----------------------,{y, z, x})) 2 2 2 3 2 2 2 3 (x - 3, y x - z , y ) (x - 3, y x - z , y ) o20 : Sequence```

Omitting an element of the sequence is equivalent to asking for it to be returned.

 ```i21 : flattenRing(R, Result => (Nothing, )) o21 = (, map(ZZ[y, z, x],R,{y, z, x})) o21 : Sequence``` ```i22 : flattenRing(R, Result => ( , Nothing, ) ) ZZ[y, z, x] ZZ[y, z, x] o22 = (----------------------, , map(R,----------------------,{y, z, x})) 2 2 2 3 2 2 2 3 (x - 3, y x - z , y ) (x - 3, y x - z , y ) o22 : Sequence```

When running flattenRing(Ideal), there are additional choices for the Result option: the first element of the sequence, which is always the ring in the flattenRing(Ring) case, can now be either the new ring or the corresponding new ideal. The default is to return the ideal, including when using numeric options for Result or omitting an object type in the sequence.

 ```i23 : flattenRing(I, Result => 1) 2 2 2 3 2 o23 = ideal (x - 3, y x - z , y , y - 3z*x) o23 : Ideal of ZZ[y, z, x]``` ```i24 : flattenRing(I, Result => 3) 2 2 2 3 2 o24 = (ideal (x - 3, y x - z , y , y - 3z*x), map(ZZ[y, z, x],R,{y, z, x}), ----------------------------------------------------------------------- map(R,ZZ[y, z, x],{y, z, x})) o24 : Sequence``` ```i25 : flattenRing(R, Result => ( , Nothing, ) ) ZZ[y, z, x] ZZ[y, z, x] o25 = (----------------------, , map(R,----------------------,{y, z, x})) 2 2 2 3 2 2 2 3 (x - 3, y x - z , y ) (x - 3, y x - z , y ) o25 : Sequence``` ```i26 : flattenRing(I, Result => (Ring, Nothing, RingMap)) ZZ[y, z, x] o26 = (---------------------------------, , 2 2 2 3 2 (x - 3, y x - z , y , y - 3z*x) ----------------------------------------------------------------------- ZZ[y, z, x] map(R,---------------------------------,{y, z, x})) 2 2 2 3 2 (x - 3, y x - z , y , y - 3z*x) o26 : Sequence``` ```i27 : flattenRing(I, Result => (Ring, RingMap)) ZZ[y, z, x] o27 = (---------------------------------, 2 2 2 3 2 (x - 3, y x - z , y , y - 3z*x) ----------------------------------------------------------------------- ZZ[y, z, x] map(---------------------------------,R,{y, z, x})) 2 2 2 3 2 (x - 3, y x - z , y , y - 3z*x) o27 : Sequence``` ```i28 : flattenRing(I, Result => Ideal) 2 2 2 3 2 o28 = ideal (x - 3, y x - z , y , y - 3z*x) o28 : Ideal of ZZ[y, z, x]```

By default flattenRing attempts to define a new ring over either ZZ or a base field.

In the following example, the coefficient ring of the result is the fraction field K.

 ```i29 : K = frac(ZZ[a]) o29 = K o29 : FractionField``` ```i30 : B = K[x,y,z]/(a*x^2-y^2-z^2, y^3, z^3) o30 = B o30 : QuotientRing``` ```i31 : (D, F) = flattenRing B o31 = (B, map(B,B,{x, y, z, a})) o31 : Sequence``` ```i32 : describe D K[x, y, z] o32 = ------------------------ 2 2 2 3 3 (a*x - y - z , y , z )```

Once a ring has been declared to be a field with toField then it will be used as the coefficient ring.

 `i33 : A = QQ[a]/(a^2-3);` ```i34 : L = toField A o34 = L o34 : PolynomialRing``` ```i35 : B = L[x,y,z]/(a*x^2-y^2-z^2, y^3, z^3) o35 = B o35 : QuotientRing``` ```i36 : (D, F) = flattenRing(B[s,t]) o36 = (D, map(D,B[s, t],{s, t, x, y, z, a})) o36 : Sequence``` ```i37 : describe D L[s, t, x, y, z] o37 = ------------------------ 2 2 2 3 3 (a*x - y - z , y , z )```

Use the CoefficientRing option to specify a different base field or ring.

 ```i38 : (D, F) = flattenRing(B[s,t], CoefficientRing => QQ) o38 = (D, map(D,B[s, t],{s, t, x, y, z, a})) o38 : Sequence``` ```i39 : describe D QQ[s, t, x, y, z, a] o39 = ------------------------------- 2 2 2 2 3 3 (a - 3, x a - y - z , y , z )```

Here is a more complicated example.

 ```i40 : use L o40 = L o40 : PolynomialRing``` `i41 : C1 = L[s,t];` `i42 : C2 = C1/(a*s-t^2);` `i43 : C3 = C2[p_0..p_4]/(a*s*p_0)[q]/(q^2-a*p_1);` ```i44 : (D, F) = flattenRing(C3, CoefficientRing=>C2) o44 = (D, map(D,C3,{q, p , p , p , p , p , s, t, a})) 0 1 2 3 4 o44 : Sequence``` ```i45 : describe D C2[q, p , p , p , p , p ] 0 1 2 3 4 o45 = ------------------------- 2 (a*s*p , q - a*p ) 0 1``` ```i46 : (D, F) = flattenRing(C3, CoefficientRing=>QQ) o46 = (D, map(D,C3,{q, p , p , p , p , p , s, t, a})) 0 1 2 3 4 o46 : Sequence``` ```i47 : describe D QQ[q, p , p , p , p , p , s, t, a] 0 1 2 3 4 o47 = ------------------------------------- 2 2 2 (a - 3, - t + s*a, p s*a, q - p a) 0 1```

Multiple calls to flattenRing may result in defining multiple rings that are regarded as different objects by Macaulay2. (See rings or working with multiple rings for more information.)

 ```i48 : flattenRing(B[s,t]) === flattenRing(B[s,t]) o48 = false```