Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- 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
Authors:
Vincent Delecroix, Ben Hutz (July 2016): initial implementation """
#***************************************************************************** # Copyright (C) 2016 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
r""" 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
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 """ """ The Python constructor
EXAMPLES::
sage: R = ZZ['a', 'b', 'c']['x', 'y', 'z'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: FlatteningMorphism(R) Flattening morphism: From: Multivariate Polynomial Ring in x, y, z over Multivariate Polynomial Ring in a, b, c over Integer Ring To: Multivariate Polynomial Ring in a, b, c, x, y, z over Integer Ring
::
sage: R = ZZ['a']['b']['c'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: FlatteningMorphism(R) Flattening morphism: From: Univariate Polynomial Ring in c over Univariate Polynomial Ring in b over Univariate Polynomial Ring in a over Integer Ring To: Multivariate Polynomial Ring in a, b, c over Integer Ring
::
sage: R = ZZ['a']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: FlatteningMorphism(R) Traceback (most recent call last): ... ValueError: clash in variable names
::
sage: K.<v> = NumberField(x^3 - 2) sage: R = K['x','y']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f(R('v*a*x^2 + b^2 + 1/v*y')) (v)*x^2*a + b^2 + (1/2*v^2)*y
::
sage: R = QQbar['x','y']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y')) 1.414213562373095?*x^2*a + b^2 + I*y
::
sage: R.<z> = PolynomialRing(QQbar,1) sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f.domain(), f.codomain() (Multivariate Polynomial Ring in z over Algebraic Field, Multivariate Polynomial Ring in z over Algebraic Field)
::
sage: R.<z> = PolynomialRing(QQbar) sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f.domain(), f.codomain() (Univariate Polynomial Ring in z over Algebraic Field, Univariate Polynomial Ring in z over Algebraic Field) """ raise ValueError("domain should be a polynomial ring")
else:
r""" Evaluate an flattening morphism.
EXAMPLES::
sage: R = QQ['a','b','c']['x','y','z'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: h = FlatteningMorphism(R)('2*a*x + b*z'); h 2*a*x + b*z sage: h.parent() Multivariate Polynomial Ring in a, b, c, x, y, z over Rational Field
TESTS::
sage: R = QQ['x']['y']['s','t'] sage: p = R('s*x + y*t + x^2*s + 1 + t') sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f._call_(p) x^2*s + x*s + y*t + t + 1 """ #If we are just specializing a univariate polynomial, then #the flattening morphism is the identity return p
else: raise RuntimeError
def section(self): """ 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
::
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 """
r""" Inverses for :class:`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
::
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 """
""" The Python constructor
EXAMPLES::
sage: R = QQ['x']['y']['s','t']['X'] sage: p = R.random_element() sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: g = f.section() sage: g(f(p)) == p True
::
sage: R = QQ['a','b','x','y'] sage: S = ZZ['a','b']['x','z'] sage: from sage.rings.polynomial.flatten import UnflatteningMorphism sage: UnflatteningMorphism(R, S) Traceback (most recent call last): ... ValueError: rings must have same base ring
::
sage: R = QQ['a','b','x','y'] sage: S = QQ['a','b']['x','z','w'] sage: from sage.rings.polynomial.flatten import UnflatteningMorphism sage: UnflatteningMorphism(R, S) Traceback (most recent call last): ... ValueError: rings must have the same number of variables """ raise ValueError("domain should be a multivariate polynomial ring") raise ValueError("codomain should be a polynomial ring")
""" Evaluate an unflattening morphism.
TESTS::
sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: for R in [ZZ['x']['y']['a,b,c'], GF(4)['x','y']['a','b'], ....: AA['x']['a','b']['y'], QQbar['a1','a2']['t']['X','Y']]: ....: f = FlatteningMorphism(R) ....: g = f.section() ....: for _ in range(10): ....: p = R.random_element() ....: assert p == g(f(p)) """
r""" 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
::
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
::
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 """
""" The Python constructor
EXAMPLES::
sage: S.<x,y> = PolynomialRing(QQ) sage: D = dict({x:1}) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: phi = SpecializationMorphism(S, D); phi Specialization morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in y over Rational Field sage: phi(x^2 + y^2) y^2 + 1
::
sage: R.<a,b,c> = PolynomialRing(ZZ) sage: S.<x,y,z> = PolynomialRing(R) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: xi = SpecializationMorphism(S, {a:1/2}) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer
The following was fixed in :trac:`23811`::
sage: R.<c>=RR[] sage: P.<z>=AffineSpace(R,1) sage: H=End(P) sage: f=H([z^2+c]) sage: f.specialization({c:1}) Scheme endomorphism of Affine Space of dimension 1 over Real Field with 53 bits of precision Defn: Defined on coordinates by sending (z) to (z^2 + 1.00000000000000)
""" raise TypeError("domain should be a polynomial ring")
# We use this composition where "flat" is a flattened # polynomial ring. # # phi D psi # domain → flat → flat → R # │ │ │ # └─────────┴───────────────┘ # _flattening_morph _eval_morph # = phi = psi ∘ D
# Change domain of D to "flat" and ensure that the values lie # in the base ring.
# Construct unflattened codomain R
# Construct unflattening map psi (only defined on the variables # of "flat" which are not involved in D) # Pass in the names of the variables else: # Map variables in "new" to R
# Compose D with psi else:
""" Evaluate a specialization morphism.
EXAMPLES::
sage: R.<a,b,c> = PolynomialRing(ZZ) sage: S.<x,y,z> = PolynomialRing(R) sage: D = dict({a:1, b:2, c:3}) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: xi = SpecializationMorphism(S, D) sage: xi(a*x + b*y + c*z) x + 2*y + 3*z """ |