def __init__(self, domain, codomain): """ 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 """ if not is_MPolynomialRing(domain): raise ValueError("domain should be a multivariate polynomial ring") if not is_PolynomialRing(codomain) and not is_MPolynomialRing( codomain): raise ValueError("codomain should be a polynomial ring") ring = codomain intermediate_rings = [] while True: is_polynomial_ring = is_PolynomialRing(ring) if not (is_polynomial_ring or is_MPolynomialRing(ring)): break intermediate_rings.append((ring, is_polynomial_ring)) ring = ring.base_ring() if domain.base_ring() != intermediate_rings[-1][0].base_ring(): raise ValueError("rings must have same base ring") if domain.ngens() != sum([R.ngens() for R, _ in intermediate_rings]): raise ValueError("rings must have the same number of variables") self._intermediate_rings = intermediate_rings hom = Homset(domain, codomain, base=ring, check=False) Morphism.__init__(self, hom) self._repr_type_str = 'Unflattening'
def __init__(self, domain): """ 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) Flattening morphism: From: Multivariate Polynomial Ring in a, b over Univariate Polynomial Ring in a over Integer Ring To: Multivariate Polynomial Ring in a, a0, b over Integer Ring :: 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) TESTS:: sage: Pol = QQ['x']['x0']['x'] sage: fl = FlatteningMorphism(Pol) sage: fl Flattening morphism: From: Univariate Polynomial Ring in x over Univariate Polynomial Ring in x0 over Univariate Polynomial Ring in x over Rational Field To: Multivariate Polynomial Ring in x, x0, x1 over Rational Field sage: p = Pol([[[1,2],[3,4]],[[5,6],[7,8]]]) sage: fl.section()(fl(p)) == p True """ if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain): raise ValueError("domain should be a polynomial ring") ring = domain variables = [] intermediate_rings = [] while is_PolynomialRing(ring) or is_MPolynomialRing(ring): intermediate_rings.append(ring) v = ring.variable_names() variables.extend(reversed(v)) ring = ring.base_ring() self._intermediate_rings = intermediate_rings variables.reverse() for i, a in enumerate(variables): if a in variables[:i]: for index in itertools.count(): b = a + str(index) if b not in variables: # not just variables[:i]! break variables[i] = b if is_MPolynomialRing(domain): codomain = PolynomialRing(ring, variables, len(variables)) else: codomain = PolynomialRing(ring, variables) hom = Homset(domain, codomain, base=ring, check=False) Morphism.__init__(self, hom) self._repr_type_str = 'Flattening'
def _Hom_(X, Y, category): # here we overwrite the Rings._Hom_ implementation return Homset(X, Y, category=category)