def expand(self): """ EXAMPLES:: sage: X = SchubertPolynomialRing(ZZ) sage: X([2,1,3]).expand() x0 sage: map(lambda x: x.expand(), [X(p) for p in Permutations(3)]) [1, x0 + x1, x0, x0*x1, x0^2, x0^2*x1] TESTS: Calling .expand() should always return an element of an MPolynomialRing :: sage: X = SchubertPolynomialRing(ZZ) sage: f = X([1]); f X[1] sage: type(f.expand()) <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'> sage: f.expand() 1 sage: f = X([1,2]) sage: type(f.expand()) <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'> sage: f = X([1,3,2,4]) sage: type(f.expand()) <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'> """ p = symmetrica.t_SCHUBERT_POLYNOM(self) if not is_MPolynomial(p): R = PolynomialRing(self.parent().base_ring(), 1, 'x') p = R(p) return p
def __call__(self, v): """ Apply the affine transformation to ``v``. INPUT: - ``v`` -- a multivariate polynomial, a vector, or anything that can be converted into a vector. OUTPUT: The image of ``v`` under the affine group element. EXAMPLES:: sage: G = AffineGroup(2, QQ) sage: g = G([0,1,-1,0],[2,3]); g [ 0 1] [2] x |-> [-1 0] x + [3] sage: v = vector([4,5]) sage: g(v) (7, -1) sage: R.<x,y> = QQ[] sage: g(x), g(y) (y + 2, -x + 3) sage: p = x^2 + 2*x*y + y + 1 sage: g(p) -2*x*y + y^2 - 5*x + 10*y + 20 The action on polynomials is such that it intertwines with evaluation. That is:: sage: p(*g(v)) == g(p)(*v) True Test that the univariate polynomial ring is covered:: sage: H = AffineGroup(1, QQ) sage: h = H([2],[3]); h x |-> [2] x + [3] sage: R.<z> = QQ[] sage: h(z+1) 3*z + 2 """ from sage.rings.polynomial.polynomial_element import is_Polynomial from sage.rings.polynomial.multi_polynomial import is_MPolynomial parent = self.parent() if is_Polynomial(v) and parent.degree() == 1: ring = v.parent() return ring([self._A[0, 0], self._b[0]]) if is_MPolynomial(v) and parent.degree() == v.parent().ngens(): ring = v.parent() from sage.modules.all import vector image_coords = self._A * vector(ring, ring.gens()) + self._b return v(*image_coords) v = parent.vector_space()(v) return self._A * v + self._b
def _element_constructor_(self, x): """ Coerce x into self. EXAMPLES:: sage: X = SchubertPolynomialRing(QQ) sage: X._element_constructor_([2,1,3]) X[2, 1] sage: X._element_constructor_(Permutation([2,1,3])) X[2, 1] sage: R.<x1, x2, x3> = QQ[] sage: X(x1^2*x2) X[3, 2, 1] TESTS: We check that :trac:`12924` is fixed:: sage: X = SchubertPolynomialRing(QQ) sage: X._element_constructor_([1,2,1]) Traceback (most recent call last): ... ValueError: The input [1, 2, 1] is not a valid permutation """ if isinstance(x, list): #checking the input to avoid symmetrica crashing Sage, see trac 12924 if not x in Permutations(): raise ValueError("The input %s is not a valid permutation" % (x)) perm = permutation.Permutation(x).remove_extra_fixed_points() return self._from_dict({perm: self.base_ring()(1)}) elif isinstance(x, permutation.Permutation): if not list(x) in Permutations(): raise ValueError("The input %s is not a valid permutation" % (x)) perm = x.remove_extra_fixed_points() return self._from_dict({perm: self.base_ring()(1)}) elif is_MPolynomial(x): return symmetrica.t_POLYNOM_SCHUBERT(x) else: raise TypeError
def _element_constructor_(self, x): """ Coerce x into self. EXAMPLES:: sage: X = SchubertPolynomialRing(QQ) sage: X._element_constructor_([2,1,3]) X[2, 1] sage: X._element_constructor_(Permutation([2,1,3])) X[2, 1] sage: R.<x1, x2, x3> = QQ[] sage: X(x1^2*x2) X[3, 2, 1] TESTS: We check that :trac:`12924` is fixed:: sage: X = SchubertPolynomialRing(QQ) sage: X._element_constructor_([1,2,1]) Traceback (most recent call last): ... ValueError: The input [1, 2, 1] is not a valid permutation """ if isinstance(x, list): #checking the input to avoid symmetrica crashing Sage, see trac 12924 if not x in Permutations(): raise ValueError("The input %s is not a valid permutation"%(x)) perm = permutation.Permutation(x).remove_extra_fixed_points() return self._from_dict({ perm: self.base_ring()(1) }) elif isinstance(x, permutation.Permutation): if not list(x) in Permutations(): raise ValueError("The input %s is not a valid permutation"%(x)) perm = x.remove_extra_fixed_points() return self._from_dict({ perm: self.base_ring()(1) }) elif is_MPolynomial(x): return symmetrica.t_POLYNOM_SCHUBERT(x) else: raise TypeError
def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): """ Construct a new polynomial sequence object. INPUT: - ``arg1`` - a multivariate polynomial ring, an ideal or a matrix - ``arg2`` - an iterable object of parts or polynomials (default:``None``) - ``immutable`` - if ``True`` the sequence is immutable (default: ``False``) - ``cr`` - print a line break after each element (default: ``False``) - ``cr_str`` - print a line break after each element if 'str' is called (default: ``None``) EXAMPLES:: sage: P.<a,b,c,d> = PolynomialRing(GF(127),4) sage: I = sage.rings.ideal.Katsura(P) If a list of tuples is provided, those form the parts:: sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c, a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] sage: F.nparts() 2 If an ideal is provided, the generators are used:: sage: Sequence(I) [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] If a list of polynomials is provided, the system has only one part:: sage: F = Sequence(I.gens(), I.ring()); F [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] sage: F.nparts() 1 """ from sage.matrix.matrix import is_Matrix if is_MPolynomialRing(arg1) or is_QuotientRing(arg1): ring = arg1 gens = arg2 elif is_MPolynomialRing(arg2) or is_QuotientRing(arg2): ring = arg2 gens = arg1 elif is_Matrix(arg1) and arg2 is None: ring = arg1.base_ring() gens = arg1.list() elif isinstance(arg1, MPolynomialIdeal) and arg2 is None: ring = arg1.ring() gens = arg1.gens() elif isinstance(arg1, (list,tuple,GeneratorType)) and arg2 is None: gens = arg1 try: e = iter(gens).next() except StopIteration: raise ValueError("Cannot determine ring from provided information.") if is_MPolynomial(e) or isinstance(e, QuotientRingElement): ring = e.parent() else: ring = iter(e).next().parent() else: raise TypeError("Cannot understand input.") try: e = iter(gens).next() if is_MPolynomial(e) or isinstance(e, QuotientRingElement): gens = tuple(gens) parts = (gens,) if not all(f.parent() is ring for f in gens): parts = ((ring(f) for f in gens),) else: parts = [] _gens = [] for part in gens: _part = [] for gen in part: if not gen.parent() is ring: ring(gen) _part.append(gen) _gens.extend(_part) parts.append(tuple(_part)) gens = _gens except StopIteration: gens = tuple() parts = ((),) k = ring.base_ring() try: c = k.characteristic() except NotImplementedError: c = -1 if c != 2: return PolynomialSequence_generic(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str) elif k.degree() == 1: return PolynomialSequence_gf2(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str) elif k.degree() > 1: return PolynomialSequence_gf2e(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
def __call__(self, v): """ Apply the affine transformation to ``v``. INPUT: - ``v`` -- a polynomial, a multivariate polynomial, a polyhedron, a vector, or anything that can be converted into a vector. OUTPUT: The image of ``v`` under the affine group element. EXAMPLES:: sage: G = AffineGroup(2, QQ) sage: g = G([0,1,-1,0],[2,3]); g [ 0 1] [2] x |-> [-1 0] x + [3] sage: v = vector([4,5]) sage: g(v) (7, -1) sage: R.<x,y> = QQ[] sage: g(x), g(y) (y + 2, -x + 3) sage: p = x^2 + 2*x*y + y + 1 sage: g(p) -2*x*y + y^2 - 5*x + 10*y + 20 The action on polynomials is such that it intertwines with evaluation. That is:: sage: p(*g(v)) == g(p)(*v) True Test that the univariate polynomial ring is covered:: sage: H = AffineGroup(1, QQ) sage: h = H([2],[3]); h x |-> [2] x + [3] sage: R.<z> = QQ[] sage: h(z+1) 3*z + 2 The action on a polyhedron is defined (see :trac:`30327`):: sage: F = AffineGroup(3, QQ) sage: M = matrix(3, [-1, -2, 0, 0, 0, 1, -2, 1, -1]) sage: v = vector(QQ,(1,2,3)) sage: f = F(M, v) sage: cube = polytopes.cube() sage: f(cube) A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices """ parent = self.parent() # start with the most probable case, i.e., v is in the vector space if v in parent.vector_space(): return self._A * v + self._b from sage.rings.polynomial.polynomial_element import is_Polynomial if is_Polynomial(v) and parent.degree() == 1: ring = v.parent() return ring([self._A[0, 0], self._b[0]]) from sage.rings.polynomial.multi_polynomial import is_MPolynomial if is_MPolynomial(v) and parent.degree() == v.parent().ngens(): ring = v.parent() from sage.modules.free_module_element import vector image_coords = self._A * vector(ring, ring.gens()) + self._b return v(*image_coords) import sage.geometry.abc if isinstance(v, sage.geometry.abc.Polyhedron): return self._A * v + self._b # otherwise, coerce v into the vector space v = parent.vector_space()(v) return self._A * v + self._b