Class to flatten polynomial rings over polynomial ring

For example QQ['a','b'],['x','y'] flattens to QQ['a','b','x','y'].

EXAMPLES:

sage: R = QQ['x']['y']['s','t']['X']
sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: phi = FlatteningMorphism(R); phi
Flattening morphism:
  From: Univariate Polynomial Ring in X
        over Multivariate Polynomial Ring in s, t
        over Univariate Polynomial Ring in y
        over Univariate Polynomial Ring in x over Rational Field
  To:   Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
sage: phi('x*y*s + t*X').parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
>>> from sage.all import *
>>> R = QQ['x']['y']['s','t']['X']
>>> from sage.rings.polynomial.flatten import FlatteningMorphism
>>> phi = FlatteningMorphism(R); phi
Flattening morphism:
  From: Univariate Polynomial Ring in X
        over Multivariate Polynomial Ring in s, t
        over Univariate Polynomial Ring in y
        over Univariate Polynomial Ring in x over Rational Field
  To:   Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
>>> phi('x*y*s + t*X').parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
R = QQ['x']['y']['s','t']['X']
from sage.rings.polynomial.flatten import FlatteningMorphism
phi = FlatteningMorphism(R); phi
phi('x*y*s + t*X').parent()

Authors:

Vincent Delecroix, Ben Hutz (July 2016): initial implementation

class sage.rings.polynomial.flatten.FlatteningMorphism(domain)[source]

Bases: Morphism

EXAMPLES:

sage: R = QQ['a','b']['x','y','z']['t1','t2']
sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: f = FlatteningMorphism(R)
sage: f.codomain()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field
sage: p = R('(a+b)*x + (a^2-b)*t2*(z+y)')
sage: p
((a^2 - b)*y + (a^2 - b)*z)*t2 + (a + b)*x
sage: f(p)
a^2*y*t2 + a^2*z*t2 - b*y*t2 - b*z*t2 + a*x + b*x
sage: f(p).parent()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field
>>> from sage.all import *
>>> R = QQ['a','b']['x','y','z']['t1','t2']
>>> from sage.rings.polynomial.flatten import FlatteningMorphism
>>> f = FlatteningMorphism(R)
>>> f.codomain()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field
>>> p = R('(a+b)*x + (a^2-b)*t2*(z+y)')
>>> p
((a^2 - b)*y + (a^2 - b)*z)*t2 + (a + b)*x
>>> f(p)
a^2*y*t2 + a^2*z*t2 - b*y*t2 - b*z*t2 + a*x + b*x
>>> f(p).parent()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field
R = QQ['a','b']['x','y','z']['t1','t2']
from sage.rings.polynomial.flatten import FlatteningMorphism
f = FlatteningMorphism(R)
f.codomain()
p = R('(a+b)*x + (a^2-b)*t2*(z+y)')
p
f(p)
f(p).parent()

Also works when univariate polynomial ring are involved:

sage: R = QQ['x']['y']['s','t']['X']
sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: f = FlatteningMorphism(R)
sage: f.codomain()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
sage: p = R('((x^2 + 1) + (x+2)*y + x*y^3)*(s+t) + x*y*X')
sage: p
x*y*X + (x*y^3 + (x + 2)*y + x^2 + 1)*s + (x*y^3 + (x + 2)*y + x^2 + 1)*t
sage: f(p)
x*y^3*s + x*y^3*t + x^2*s + x*y*s + x^2*t + x*y*t + x*y*X + 2*y*s + 2*y*t + s + t
sage: f(p).parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
>>> from sage.all import *
>>> R = QQ['x']['y']['s','t']['X']
>>> from sage.rings.polynomial.flatten import FlatteningMorphism
>>> f = FlatteningMorphism(R)
>>> f.codomain()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
>>> p = R('((x^2 + 1) + (x+2)*y + x*y^3)*(s+t) + x*y*X')
>>> p
x*y*X + (x*y^3 + (x + 2)*y + x^2 + 1)*s + (x*y^3 + (x + 2)*y + x^2 + 1)*t
>>> f(p)
x*y^3*s + x*y^3*t + x^2*s + x*y*s + x^2*t + x*y*t + x*y*X + 2*y*s + 2*y*t + s + t
>>> f(p).parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
R = QQ['x']['y']['s','t']['X']
from sage.rings.polynomial.flatten import FlatteningMorphism
f = FlatteningMorphism(R)
f.codomain()
p = R('((x^2 + 1) + (x+2)*y + x*y^3)*(s+t) + x*y*X')
p
f(p)
f(p).parent()
inverse()[source]

Return the inverse of this flattening morphism.

This is the same as calling section().

EXAMPLES:

sage: f = QQ['x,y']['u,v'].flattening_morphism()
sage: f.inverse()
Unflattening morphism:
  From: Multivariate Polynomial Ring in x, y, u, v over Rational Field
  To:   Multivariate Polynomial Ring in u, v
        over Multivariate Polynomial Ring in x, y over Rational Field
>>> from sage.all import *
>>> f = QQ['x,y']['u,v'].flattening_morphism()
>>> f.inverse()
Unflattening morphism:
  From: Multivariate Polynomial Ring in x, y, u, v over Rational Field
  To:   Multivariate Polynomial Ring in u, v
        over Multivariate Polynomial Ring in x, y over Rational Field
f = QQ['x,y']['u,v'].flattening_morphism()
f.inverse()
section()[source]

Inverse of this flattening morphism.

EXAMPLES:

sage: R = QQ['a','b','c']['x','y','z']
sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: h = FlatteningMorphism(R)
sage: h.section()
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, c, x, y, z over Rational Field
  To:   Multivariate Polynomial Ring in x, y, z
        over Multivariate Polynomial Ring in a, b, c over Rational Field
>>> from sage.all import *
>>> R = QQ['a','b','c']['x','y','z']
>>> from sage.rings.polynomial.flatten import FlatteningMorphism
>>> h = FlatteningMorphism(R)
>>> h.section()
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, c, x, y, z over Rational Field
  To:   Multivariate Polynomial Ring in x, y, z
        over Multivariate Polynomial Ring in a, b, c over Rational Field
R = QQ['a','b','c']['x','y','z']
from sage.rings.polynomial.flatten import FlatteningMorphism
h = FlatteningMorphism(R)
h.section()
sage: R = ZZ['a']['b']['c']
sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: FlatteningMorphism(R).section()
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, c over Integer Ring
  To:   Univariate Polynomial Ring in c over Univariate Polynomial Ring in b
        over Univariate Polynomial Ring in a over Integer Ring
>>> from sage.all import *
>>> R = ZZ['a']['b']['c']
>>> from sage.rings.polynomial.flatten import FlatteningMorphism
>>> FlatteningMorphism(R).section()
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, c over Integer Ring
  To:   Univariate Polynomial Ring in c over Univariate Polynomial Ring in b
        over Univariate Polynomial Ring in a over Integer Ring
R = ZZ['a']['b']['c']
from sage.rings.polynomial.flatten import FlatteningMorphism
FlatteningMorphism(R).section()
>>> from sage.all import *
>>> R = ZZ['a']['b']['c']
>>> from sage.rings.polynomial.flatten import FlatteningMorphism
>>> FlatteningMorphism(R).section()
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, c over Integer Ring
  To:   Univariate Polynomial Ring in c over Univariate Polynomial Ring in b
        over Univariate Polynomial Ring in a over Integer Ring
R = ZZ['a']['b']['c']
from sage.rings.polynomial.flatten import FlatteningMorphism
FlatteningMorphism(R).section()
class sage.rings.polynomial.flatten.FractionSpecializationMorphism(domain, D)[source]

Bases: Morphism

A specialization morphism for fraction fields over (stacked) polynomial rings

class sage.rings.polynomial.flatten.SpecializationMorphism(domain, D)[source]

Bases: Morphism

Morphisms to specialize parameters in (stacked) polynomial rings.

EXAMPLES:

sage: R.<c> = PolynomialRing(QQ)
sage: S.<x,y,z> = PolynomialRing(R)
sage: D = dict({c:1})
sage: from sage.rings.polynomial.flatten import SpecializationMorphism
sage: f = SpecializationMorphism(S, D)
sage: g = f(x^2 + c*y^2 - z^2); g
x^2 + y^2 - z^2
sage: g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('c',)); (c,) = R._first_ngens(1)
>>> S = PolynomialRing(R, names=('x', 'y', 'z',)); (x, y, z,) = S._first_ngens(3)
>>> D = dict({c:Integer(1)})
>>> from sage.rings.polynomial.flatten import SpecializationMorphism
>>> f = SpecializationMorphism(S, D)
>>> g = f(x**Integer(2) + c*y**Integer(2) - z**Integer(2)); g
x^2 + y^2 - z^2
>>> g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field
R.<c> = PolynomialRing(QQ)
S.<x,y,z> = PolynomialRing(R)
D = dict({c:1})
from sage.rings.polynomial.flatten import SpecializationMorphism
f = SpecializationMorphism(S, D)
g = f(x^2 + c*y^2 - z^2); g
g.parent()
sage: R.<c> = PolynomialRing(QQ)
sage: S.<z> = PolynomialRing(R)
sage: from sage.rings.polynomial.flatten import SpecializationMorphism
sage: xi = SpecializationMorphism(S, {c:0}); xi
Specialization morphism:
  From: Univariate Polynomial Ring in z
        over Univariate Polynomial Ring in c over Rational Field
  To:   Univariate Polynomial Ring in z over Rational Field
sage: xi(z^2+c)
z^2
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('c',)); (c,) = R._first_ngens(1)
>>> S = PolynomialRing(R, names=('z',)); (z,) = S._first_ngens(1)
>>> from sage.rings.polynomial.flatten import SpecializationMorphism
>>> xi = SpecializationMorphism(S, {c:Integer(0)}); xi
Specialization morphism:
  From: Univariate Polynomial Ring in z
        over Univariate Polynomial Ring in c over Rational Field
  To:   Univariate Polynomial Ring in z over Rational Field
>>> xi(z**Integer(2)+c)
z^2
R.<c> = PolynomialRing(QQ)
S.<z> = PolynomialRing(R)
from sage.rings.polynomial.flatten import SpecializationMorphism
xi = SpecializationMorphism(S, {c:0}); xi
xi(z^2+c)
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('c',)); (c,) = R._first_ngens(1)
>>> S = PolynomialRing(R, names=('z',)); (z,) = S._first_ngens(1)
>>> from sage.rings.polynomial.flatten import SpecializationMorphism
>>> xi = SpecializationMorphism(S, {c:Integer(0)}); xi
Specialization morphism:
  From: Univariate Polynomial Ring in z
        over Univariate Polynomial Ring in c over Rational Field
  To:   Univariate Polynomial Ring in z over Rational Field
>>> xi(z**Integer(2)+c)
z^2
R.<c> = PolynomialRing(QQ)
S.<z> = PolynomialRing(R)
from sage.rings.polynomial.flatten import SpecializationMorphism
xi = SpecializationMorphism(S, {c:0}); xi
xi(z^2+c)
sage: R1.<u,v> = PolynomialRing(QQ)
sage: R2.<a,b,c> = PolynomialRing(R1)
sage: S.<x,y,z> = PolynomialRing(R2)
sage: D = dict({a:1, b:2, x:0, u:1})
sage: from sage.rings.polynomial.flatten import SpecializationMorphism
sage: xi = SpecializationMorphism(S, D); xi
Specialization morphism:
  From: Multivariate Polynomial Ring in x, y, z
        over Multivariate Polynomial Ring in a, b, c
        over Multivariate Polynomial Ring in u, v over Rational Field
  To:   Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in c
        over Univariate Polynomial Ring in v over Rational Field
sage: xi(a*(x*z+y^2)*u+b*v*u*(x*z+y^2)*y^2*c+c*y^2*z^2)
2*v*c*y^4 + c*y^2*z^2 + y^2
>>> from sage.all import *
>>> R1 = PolynomialRing(QQ, names=('u', 'v',)); (u, v,) = R1._first_ngens(2)
>>> R2 = PolynomialRing(R1, names=('a', 'b', 'c',)); (a, b, c,) = R2._first_ngens(3)
>>> S = PolynomialRing(R2, names=('x', 'y', 'z',)); (x, y, z,) = S._first_ngens(3)
>>> D = dict({a:Integer(1), b:Integer(2), x:Integer(0), u:Integer(1)})
>>> from sage.rings.polynomial.flatten import SpecializationMorphism
>>> xi = SpecializationMorphism(S, D); xi
Specialization morphism:
  From: Multivariate Polynomial Ring in x, y, z
        over Multivariate Polynomial Ring in a, b, c
        over Multivariate Polynomial Ring in u, v over Rational Field
  To:   Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in c
        over Univariate Polynomial Ring in v over Rational Field
>>> xi(a*(x*z+y**Integer(2))*u+b*v*u*(x*z+y**Integer(2))*y**Integer(2)*c+c*y**Integer(2)*z**Integer(2))
2*v*c*y^4 + c*y^2*z^2 + y^2
R1.<u,v> = PolynomialRing(QQ)
R2.<a,b,c> = PolynomialRing(R1)
S.<x,y,z> = PolynomialRing(R2)
D = dict({a:1, b:2, x:0, u:1})
from sage.rings.polynomial.flatten import SpecializationMorphism
xi = SpecializationMorphism(S, D); xi
xi(a*(x*z+y^2)*u+b*v*u*(x*z+y^2)*y^2*c+c*y^2*z^2)
>>> from sage.all import *
>>> R1 = PolynomialRing(QQ, names=('u', 'v',)); (u, v,) = R1._first_ngens(2)
>>> R2 = PolynomialRing(R1, names=('a', 'b', 'c',)); (a, b, c,) = R2._first_ngens(3)
>>> S = PolynomialRing(R2, names=('x', 'y', 'z',)); (x, y, z,) = S._first_ngens(3)
>>> D = dict({a:Integer(1), b:Integer(2), x:Integer(0), u:Integer(1)})
>>> from sage.rings.polynomial.flatten import SpecializationMorphism
>>> xi = SpecializationMorphism(S, D); xi
Specialization morphism:
  From: Multivariate Polynomial Ring in x, y, z
        over Multivariate Polynomial Ring in a, b, c
        over Multivariate Polynomial Ring in u, v over Rational Field
  To:   Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in c
        over Univariate Polynomial Ring in v over Rational Field
>>> xi(a*(x*z+y**Integer(2))*u+b*v*u*(x*z+y**Integer(2))*y**Integer(2)*c+c*y**Integer(2)*z**Integer(2))
2*v*c*y^4 + c*y^2*z^2 + y^2
R1.<u,v> = PolynomialRing(QQ)
R2.<a,b,c> = PolynomialRing(R1)
S.<x,y,z> = PolynomialRing(R2)
D = dict({a:1, b:2, x:0, u:1})
from sage.rings.polynomial.flatten import SpecializationMorphism
xi = SpecializationMorphism(S, D); xi
xi(a*(x*z+y^2)*u+b*v*u*(x*z+y^2)*y^2*c+c*y^2*z^2)
class sage.rings.polynomial.flatten.UnflatteningMorphism(domain, codomain)[source]

Bases: Morphism

Inverses for FlatteningMorphism.

EXAMPLES:

sage: R = QQ['c','x','y','z']
sage: S = QQ['c']['x','y','z']
sage: from sage.rings.polynomial.flatten import UnflatteningMorphism
sage: f = UnflatteningMorphism(R, S)
sage: g = f(R('x^2 + c*y^2 - z^2'));g
x^2 + c*y^2 - z^2
sage: g.parent()
Multivariate Polynomial Ring in x, y, z
 over Univariate Polynomial Ring in c over Rational Field
>>> from sage.all import *
>>> R = QQ['c','x','y','z']
>>> S = QQ['c']['x','y','z']
>>> from sage.rings.polynomial.flatten import UnflatteningMorphism
>>> f = UnflatteningMorphism(R, S)
>>> g = f(R('x^2 + c*y^2 - z^2'));g
x^2 + c*y^2 - z^2
>>> g.parent()
Multivariate Polynomial Ring in x, y, z
 over Univariate Polynomial Ring in c over Rational Field
R = QQ['c','x','y','z']
S = QQ['c']['x','y','z']
from sage.rings.polynomial.flatten import UnflatteningMorphism
f = UnflatteningMorphism(R, S)
g = f(R('x^2 + c*y^2 - z^2'));g
g.parent()
sage: R = QQ['a','b', 'x','y']
sage: S = QQ['a','b']['x','y']
sage: from sage.rings.polynomial.flatten import UnflatteningMorphism
sage: UnflatteningMorphism(R, S)
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, x, y over Rational Field
  To:   Multivariate Polynomial Ring in x, y
        over Multivariate Polynomial Ring in a, b over Rational Field
>>> from sage.all import *
>>> R = QQ['a','b', 'x','y']
>>> S = QQ['a','b']['x','y']
>>> from sage.rings.polynomial.flatten import UnflatteningMorphism
>>> UnflatteningMorphism(R, S)
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, x, y over Rational Field
  To:   Multivariate Polynomial Ring in x, y
        over Multivariate Polynomial Ring in a, b over Rational Field
R = QQ['a','b', 'x','y']
S = QQ['a','b']['x','y']
from sage.rings.polynomial.flatten import UnflatteningMorphism
UnflatteningMorphism(R, S)
>>> from sage.all import *
>>> R = QQ['a','b', 'x','y']
>>> S = QQ['a','b']['x','y']
>>> from sage.rings.polynomial.flatten import UnflatteningMorphism
>>> UnflatteningMorphism(R, S)
Unflattening morphism:
  From: Multivariate Polynomial Ring in a, b, x, y over Rational Field
  To:   Multivariate Polynomial Ring in x, y
        over Multivariate Polynomial Ring in a, b over Rational Field
R = QQ['a','b', 'x','y']
S = QQ['a','b']['x','y']
from sage.rings.polynomial.flatten import UnflatteningMorphism
UnflatteningMorphism(R, S)