示例#1
0
    def __add__(self, other):
        """
        Return the sum of two subgroups.

        EXAMPLES::

            sage: C = J0(22).cuspidal_subgroup()
            sage: C.gens()
            [[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]
            sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])
            sage: A + B == C
            True

        An example where the parent abelian varieties are different::

            A = J0(48); A[0].cuspidal_subgroup() + A[1].cuspidal_subgroup()
            Finite subgroup with invariants [2, 4, 4] over QQ of Abelian subvariety of dimension 2 of J0(48)
        """
        if not isinstance(other, FiniteSubgroup):
            raise TypeError("only addition of two finite subgroups is defined")
        A = self.abelian_variety()
        B = other.abelian_variety()
        if not A.in_same_ambient_variety(B):
            raise ValueError("self and other must be in the same ambient Jacobian")
        K = coercion_model.common_parent(self.field_of_definition(), other.field_of_definition())
        lattice = self.lattice() + other.lattice()
        if A != B:
            C = A + B
            lattice += C.lattice()
            return FiniteSubgroup_lattice(C, lattice, field_of_definition=K)
        else:
            return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=K)
示例#2
0
    def __add__(self, other):
        """
        Return the sum of two subgroups.

        EXAMPLES::

            sage: C = J0(22).cuspidal_subgroup()
            sage: C.gens()
            [[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]
            sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])
            sage: A + B == C
            True
        """
        if not isinstance(other, FiniteSubgroup):
            raise TypeError("only addition of two finite subgroups is defined")
        A = self.abelian_variety()
        B = other.abelian_variety()
        if not A.in_same_ambient_variety(B):
            raise ValueError("self and other must be in the same ambient Jacobian")
        K = coercion_model.common_parent(self.field_of_definition(), other.field_of_definition())
        lattice = self.lattice() + other.lattice()
        if A != B:
            lattice += C.lattice()

        return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=K)
示例#3
0
    def __add__(self, other):
        """
        Return the sum of two subgroups.

        EXAMPLES::

            sage: C = J0(22).cuspidal_subgroup()
            sage: C.gens()
            [[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]
            sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])
            sage: A + B == C
            True
        """
        if not isinstance(other, FiniteSubgroup):
            raise TypeError("only addition of two finite subgroups is defined")
        A = self.abelian_variety()
        B = other.abelian_variety()
        if not A.in_same_ambient_variety(B):
            raise ValueError(
                "self and other must be in the same ambient Jacobian")
        K = coercion_model.common_parent(self.field_of_definition(),
                                         other.field_of_definition())
        lattice = self.lattice() + other.lattice()
        if A != B:
            lattice += C.lattice()

        return FiniteSubgroup_lattice(self.abelian_variety(),
                                      lattice,
                                      field_of_definition=K)
示例#4
0
        def cup_product(self, cochain):
            """
            Return the cup product with another cochain

            INPUT:

            - ``cochain`` -- cochain over the same cell complex

            EXAMPLES::

                sage: T2 = simplicial_complexes.Torus()
                sage: C1 = T2.n_chains(1, base_ring=ZZ, cochains=True)
                sage: def l(i, j):
                ....:      return C1(Simplex([i, j]))
                sage: l1 = l(1, 3) + l(1, 4) + l(1, 6) + l(2, 4) - l(4, 5) + l(5, 6)
                sage: l2 = l(1, 6) - l(2, 3) - l(2, 5) + l(3, 6) - l(4, 5) + l(5, 6)

            The two one-cocycles are cohomology generators::

                sage: l1.is_cocycle(), l1.is_coboundary()
                (True, False)
                sage: l2.is_cocycle(), l2.is_coboundary()
                (True, False)

            Their cup product is a two-cocycle that is again non-trivial in
            cohomology::

                sage: l12 = l1.cup_product(l2)
                sage: l12
                \chi_(1, 3, 6) - \chi_(2, 4, 5) - \chi_(4, 5, 6)
                sage: l1.parent().degree(), l2.parent().degree(), l12.parent().degree()
                (1, 1, 2)
                sage: l12.is_cocycle(), l12.is_coboundary()
                (True, False)
            """
            if not isinstance(cochain.parent(), Cochains):
                raise ValueError('argument must be a cochain')
            if cochain.parent().cell_complex() != self.parent().cell_complex():
                raise ValueError('cochain must be over the same cell complex')
            left_deg = self.parent().degree()
            right_deg = cochain.parent().degree()
            left_chains = self.parent().dual()
            right_chains = cochain.parent().dual()
            base_ring = coercion_model.common_parent(left_chains.base_ring(),
                                                     right_chains.base_ring())
            cx = self.parent().cell_complex()
            codomain = cx.n_chains(left_deg + right_deg,
                                   base_ring=base_ring,
                                   cochains=True)
            accumulator = codomain.zero()
            for cell in codomain.indices():
                for (coeff, left_cell,
                     right_cell) in cx.alexander_whitney(cell, left_deg):
                    if not coeff:
                        continue
                    left = left_chains(left_cell)
                    right = right_chains(right_cell)
                    accumulator += codomain(cell) * coeff * self.eval(
                        left) * cochain.eval(right)
            return accumulator
示例#5
0
 def extend_scalars(self, *pts):
     r"""
     Extend the ground field so that the new field contains pts.
     """
     Dops = self.parent()
     Pols = Dops.base_ring()
     Scalars = Pols.base_ring()
     if all(Scalars.has_coerce_map_from(pt.parent()) for pt in pts):
         return (self, ) + pts
     gen = Scalars.gen()
     try:
         # Largely redundant with the other branch, but may do a better job
         # in some cases, e.g. pushout(QQ, QQ(α)), where as_enf_elts() would
         # invent new generator names.
         NF0 = coercion_model.common_parent(Scalars, *pts)
         if not is_NumberField(NF0):
             raise CoercionException
         NF, hom = utilities.good_number_field(NF0)
         gen1 = hom(NF0.coerce(gen))
         pts1 = tuple(hom(NF0.coerce(pt)) for pt in pts)
     except (CoercionException, TypeError):
         NF, val1 = as_embedded_number_field_elements((gen, ) + pts)
         gen1, pts1 = val1[0], tuple(val1[1:])
     hom = Scalars.hom([gen1], codomain=NF)
     Dops1 = OreAlgebra(Pols.change_ring(NF), (Dops.variable_name(), {}, {
         Pols.gen(): Pols.one()
     }))
     dop1 = Dops1([pol.map_coefficients(hom) for pol in self])
     dop1 = PlainDifferentialOperator(dop1)
     assert dop1.base_ring().base_ring() is NF
     return (dop1, ) + pts1
示例#6
0
文件: chains.py 项目: mcognetta/sage
        def cup_product(self, cochain):
            """
            Return the cup product with another cochain

            INPUT:

            - ``cochain`` -- cochain over the same cell complex

            EXAMPLES::

                sage: T2 = simplicial_complexes.Torus()
                sage: C1 = T2.n_chains(1, base_ring=ZZ, cochains=True)
                sage: def l(i, j):
                ....:      return C1(Simplex([i, j]))
                sage: l1 = l(1, 3) + l(1, 4) + l(1, 6) + l(2, 4) - l(4, 5) + l(5, 6)
                sage: l2 = l(1, 6) - l(2, 3) - l(2, 5) + l(3, 6) - l(4, 5) + l(5, 6)

            The two one-cocycles are cohomology generators::

                sage: l1.is_cocycle(), l1.is_coboundary()
                (True, False)
                sage: l2.is_cocycle(), l2.is_coboundary()
                (True, False)

            Their cup product is a two-cocycle that is again non-trivial in
            cohomology::

                sage: l12 = l1.cup_product(l2)
                sage: l12
                \chi_(1, 3, 6) - \chi_(2, 4, 5) - \chi_(4, 5, 6)
                sage: l1.parent().degree(), l2.parent().degree(), l12.parent().degree()
                (1, 1, 2)
                sage: l12.is_cocycle(), l12.is_coboundary()
                (True, False)
            """
            if not isinstance(cochain.parent(), Cochains):
                raise ValueError('argument must be a cochain')
            if cochain.parent().cell_complex() != self.parent().cell_complex():
                raise ValueError('cochain must be over the same cell complex')
            left_deg = self.parent().degree()
            right_deg = cochain.parent().degree()
            left_chains = self.parent().dual()
            right_chains = cochain.parent().dual()
            base_ring = coercion_model.common_parent(
                left_chains.base_ring(), right_chains.base_ring())
            cx = self.parent().cell_complex()
            codomain = cx.n_chains(
                left_deg + right_deg, base_ring=base_ring, cochains=True)
            accumulator = codomain.zero()
            for cell in codomain.indices():
                for (coeff, left_cell, right_cell) in cx.alexander_whitney(cell, left_deg):
                        if not coeff:
                            continue
                        left = left_chains(left_cell)
                        right = right_chains(right_cell)
                        accumulator += codomain(cell) * coeff * self.eval(left) * cochain.eval(right)
            return accumulator
示例#7
0
        def eval(self, other):
            """
            Evaluate this cochain on the chain ``other``.

            INPUT:

            - ``other`` -- a chain for the same cell complex in the
              same dimension with the same base ring

            OUTPUT: scalar

            EXAMPLES::

                sage: S2 = simplicial_complexes.Sphere(2)
                sage: C_2 = S2.n_chains(1)
                sage: C_2_co = S2.n_chains(1, cochains=True)
                sage: x = C_2.basis()[Simplex((0,2))]
                sage: y = C_2.basis()[Simplex((1,3))]
                sage: z = x+2*y
                sage: a = C_2_co.basis()[Simplex((1,3))]
                sage: b = C_2_co.basis()[Simplex((0,3))]
                sage: c = 3*a-2*b
                sage: z
                (0, 2) + 2*(1, 3)
                sage: c
                -2*\chi_(0, 3) + 3*\chi_(1, 3)
                sage: c.eval(z)
                6

            TESTS::

                sage: z.eval(c) # z is not a cochain
                Traceback (most recent call last):
                ...
                AttributeError: 'Chains_with_category.element_class' object has no attribute 'eval'
                sage: c.eval(c) # can't evaluate a cochain on a cochain
                Traceback (most recent call last):
                ...
                ValueError: argument is not a chain
            """
            if not isinstance(other.parent(), Chains):
                raise ValueError('argument is not a chain')
            if other.parent().indices() != self.parent().indices():
                raise ValueError('the cells are not compatible')
            result = sum(coeff * other.coefficient(cell)
                         for cell, coeff in self)
            R = self.base_ring()
            if R != other.base_ring():
                R = coercion_model.common_parent(R, other.base_ring())
            return R(result)
示例#8
0
文件: chains.py 项目: mcognetta/sage
        def eval(self, other):
            """
            Evaluate this cochain on the chain ``other``.

            INPUT:

            - ``other`` -- a chain for the same cell complex in the
              same dimension with the same base ring

            OUTPUT: scalar

            EXAMPLES::

                sage: S2 = simplicial_complexes.Sphere(2)
                sage: C_2 = S2.n_chains(1)
                sage: C_2_co = S2.n_chains(1, cochains=True)
                sage: x = C_2.basis()[Simplex((0,2))]
                sage: y = C_2.basis()[Simplex((1,3))]
                sage: z = x+2*y
                sage: a = C_2_co.basis()[Simplex((1,3))]
                sage: b = C_2_co.basis()[Simplex((0,3))]
                sage: c = 3*a-2*b
                sage: z
                (0, 2) + 2*(1, 3)
                sage: c
                -2*\chi_(0, 3) + 3*\chi_(1, 3)
                sage: c.eval(z)
                6

            TESTS::

                sage: z.eval(c) # z is not a cochain
                Traceback (most recent call last):
                ...
                AttributeError: 'Chains_with_category.element_class' object has no attribute 'eval'
                sage: c.eval(c) # can't evaluate a cochain on a cochain
                Traceback (most recent call last):
                ...
                ValueError: argument is not a chain
            """
            if not isinstance(other.parent(), Chains):
                raise ValueError('argument is not a chain')
            if other.parent().indices() != self.parent().indices():
                raise ValueError('the cells are not compatible')
            result = sum(coeff * other.coefficient(cell)
                         for cell, coeff in self)
            R = self.base_ring()
            if R != other.base_ring():
                R = coercion_model.common_parent(R, other.base_ring())
            return R(result)
示例#9
0
    def _from_polymake_polytope(cls, parent, polymake_polytope):
        r"""
        Initializes a polyhedron from a polymake Polytope object.

        TESTS::

            sage: from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake
            sage: from sage.geometry.polyhedron.parent import Polyhedra
            sage: P=Polyhedron(ieqs=[[1, 0, 2], [3, 0, -2], [3, 2, -2]])
            sage: PP = polymake(P)        # optional - polymake
            sage: parent = Polyhedra(QQ, 2, backend='polymake')   # optional - polymake
            sage: Q=Polyhedron_polymake._from_polymake_polytope(parent, PP)   # optional - polymake
        """
        if parent is None:
            from .parent import Polyhedra
            from sage.rings.rational_field import QQ
            from sage.rings.qqbar import AA
            if polymake_polytope.typeof(
            )[0] == 'Polymake::polytope::Polytope__Rational':
                base_ring = QQ
            else:
                from sage.structure.element import coercion_model
                data = [
                    g.sage()
                    for g in itertools.chain(polymake_polytope.VERTICES,
                                             polymake_polytope.LINEALITY_SPACE,
                                             polymake_polytope.FACETS,
                                             polymake_polytope.AFFINE_HULL)
                ]
                if data:
                    base_ring = coercion_model.common_parent(*data).base_ring()
                else:
                    base_ring = QQ
            ambient_dim = polymake_polytope.AMBIENT_DIM().sage()
            parent = Polyhedra(base_ring=base_ring,
                               ambient_dim=ambient_dim,
                               backend='polymake')
        return cls(parent, None, None, polymake_polytope=polymake_polytope)
示例#10
0
    def __add__(self, other):
        """
        Return the sum of two subgroups.

        EXAMPLES::

            sage: C = J0(22).cuspidal_subgroup()
            sage: C.gens()
            [[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]
            sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])
            sage: A + B == C
            True

        An example where the parent abelian varieties are different::

            A = J0(48); A[0].cuspidal_subgroup() + A[1].cuspidal_subgroup()
            Finite subgroup with invariants [2, 4, 4] over QQ of Abelian subvariety of dimension 2 of J0(48)
        """
        if not isinstance(other, FiniteSubgroup):
            raise TypeError("only addition of two finite subgroups is defined")
        A = self.abelian_variety()
        B = other.abelian_variety()
        if not A.in_same_ambient_variety(B):
            raise ValueError(
                "self and other must be in the same ambient Jacobian")
        K = coercion_model.common_parent(self.field_of_definition(),
                                         other.field_of_definition())
        lattice = self.lattice() + other.lattice()
        if A != B:
            C = A + B
            lattice += C.lattice()
            return FiniteSubgroup_lattice(C, lattice, field_of_definition=K)
        else:
            return FiniteSubgroup_lattice(self.abelian_variety(),
                                          lattice,
                                          field_of_definition=K)
示例#11
0
    def intersection(self, other):
        """
        Return the intersection of the finite subgroups self and other.

        INPUT:


        -  ``other`` - a finite group


        OUTPUT: a finite group

        EXAMPLES::

            sage: E11a0, E11a1, B = J0(33)
            sage: G = E11a0.torsion_subgroup(6); H = E11a0.torsion_subgroup(9)
            sage: G.intersection(H)
            Finite subgroup with invariants [3, 3] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
            sage: W = E11a1.torsion_subgroup(15)
            sage: G.intersection(W)
            Finite subgroup with invariants [] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
            sage: E11a0.intersection(E11a1)[0]
            Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)

        We intersect subgroups of different abelian varieties.

        ::

            sage: E11a0, E11a1, B = J0(33)
            sage: G = E11a0.torsion_subgroup(5); H = E11a1.torsion_subgroup(5)
            sage: G.intersection(H)
            Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
            sage: E11a0.intersection(E11a1)[0]
            Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)

        We intersect abelian varieties with subgroups::

            sage: t = J0(33).hecke_operator(7)
            sage: G = t.kernel()[0]; G
            Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3
            sage: A = J0(33).old_subvariety()
            sage: A.intersection(G)
            Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)
            sage: A.hecke_operator(7).kernel()[0]
            Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)
            sage: B = J0(33).new_subvariety()
            sage: B.intersection(G)
            Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)
            sage: B.hecke_operator(7).kernel()[0]
            Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)
            sage: A.intersection(B)[0]
            Finite subgroup with invariants [3, 3] over QQ of Abelian subvariety of dimension 2 of J0(33)
        """
        from .abvar import is_ModularAbelianVariety
        A = self.abelian_variety()
        if is_ModularAbelianVariety(other):
            amb = other
            B = other
            M = B.lattice().scale(Integer(1)/self.exponent())
            K = coercion_model.common_parent(self.field_of_definition(), other.base_field())
        else:
            amb = A
            if not isinstance(other, FiniteSubgroup):
                raise TypeError("only intersection with a finite subgroup or "
                        "modular abelian variety is defined")
            B = other.abelian_variety()
            if A.ambient_variety() != B.ambient_variety():
                raise TypeError("finite subgroups must be in the same ambient product Jacobian")
            M = other.lattice()
            K = coercion_model.common_parent(self.field_of_definition(), other.field_of_definition())

        L = self.lattice()
        if A != B:
            # TODO: This might be way slower than what we could do if
            # we think more carefully.
            C = A + B
            L = L + C.lattice()
            M = M + C.lattice()
        W = L.intersection(M).intersection(amb.vector_space())
        return FiniteSubgroup_lattice(amb, W, field_of_definition=K)
示例#12
0
    def intersection(self, other):
        """
        Return the intersection of the finite subgroups self and other.

        INPUT:


        -  ``other`` - a finite group


        OUTPUT: a finite group

        EXAMPLES::

            sage: E11a0, E11a1, B = J0(33)
            sage: G = E11a0.torsion_subgroup(6); H = E11a0.torsion_subgroup(9)
            sage: G.intersection(H)
            Finite subgroup with invariants [3, 3] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
            sage: W = E11a1.torsion_subgroup(15)
            sage: G.intersection(W)
            Finite subgroup with invariants [] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
            sage: E11a0.intersection(E11a1)[0]
            Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)

        We intersect subgroups of different abelian varieties.

        ::

            sage: E11a0, E11a1, B = J0(33)
            sage: G = E11a0.torsion_subgroup(5); H = E11a1.torsion_subgroup(5)
            sage: G.intersection(H)
            Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
            sage: E11a0.intersection(E11a1)[0]
            Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)

        We intersect abelian varieties with subgroups::

            sage: t = J0(33).hecke_operator(7)
            sage: G = t.kernel()[0]; G
            Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3
            sage: A = J0(33).old_subvariety()
            sage: A.intersection(G)
            Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)
            sage: A.hecke_operator(7).kernel()[0]
            Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)
            sage: B = J0(33).new_subvariety()
            sage: B.intersection(G)
            Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)
            sage: B.hecke_operator(7).kernel()[0]
            Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)
            sage: A.intersection(B)[0]
            Finite subgroup with invariants [3, 3] over QQ of Abelian subvariety of dimension 2 of J0(33)
        """
        from .abvar import is_ModularAbelianVariety
        A = self.abelian_variety()
        if is_ModularAbelianVariety(other):
            amb = other
            B = other
            M = B.lattice().scale(Integer(1) / self.exponent())
            K = coercion_model.common_parent(self.field_of_definition(),
                                             other.base_field())
        else:
            amb = A
            if not isinstance(other, FiniteSubgroup):
                raise TypeError("only intersection with a finite subgroup or "
                                "modular abelian variety is defined")
            B = other.abelian_variety()
            if A.ambient_variety() != B.ambient_variety():
                raise TypeError(
                    "finite subgroups must be in the same ambient product Jacobian"
                )
            M = other.lattice()
            K = coercion_model.common_parent(self.field_of_definition(),
                                             other.field_of_definition())

        L = self.lattice()
        if A != B:
            # TODO: This might be way slower than what we could do if
            # we think more carefully.
            C = A + B
            L = L + C.lattice()
            M = M + C.lattice()
        W = L.intersection(M).intersection(amb.vector_space())
        return FiniteSubgroup_lattice(amb, W, field_of_definition=K)
示例#13
0
    def __call__(self, *values):
        """
        Replace the generators of the free group by corresponding
        elements of the iterable ``values`` in the group element
        ``self``.

        INPUT:

        - ``*values`` -- a sequence of values, or a
          list/tuple/iterable of the same length as the number of
          generators of the free group.

        OUTPUT:

        The product of ``values`` in the order and with exponents
        specified by ``self``.

        EXAMPLES::

            sage: G.<a,b> = FreeGroup()
            sage: w = a^2 * b^-1 * a^3
            sage: w(1, 2)
            1/2
            sage: w(2, 1)
            32
            sage: w.subs(b=1, a=2)   # indirect doctest
            32

        TESTS::

            sage: w([1, 2])
            1/2
            sage: w((1, 2))
            1/2
            sage: w(i+1 for i in range(2))
            1/2

        Check that :trac:`25017` is fixed::

            sage: F = FreeGroup(2)
            sage: x0, x1 = F.gens()
            sage: u = F(1)
            sage: parent(u.subs({x1:x0})) is F
            True

            sage: F = FreeGroup(2)
            sage: x0, x1 = F.gens()
            sage: u = x0*x1
            sage: u.subs({x0:3, x1:2})
            6
            sage: u.subs({x0:1r, x1:2r})
            2
            sage: M0 = matrix(ZZ,2,[1,1,0,1])
            sage: M1 = matrix(ZZ,2,[1,0,1,1])
            sage: u.subs({x0: M0, x1: M1})
            [2 1]
            [1 1]

        TESTS::

            sage: F.<x,y> = FreeGroup()
            sage: F.one().subs(x=x, y=1)
            Traceback (most recent call last):
            ...
            TypeError: no common canonical parent for objects with parents: 'Free Group on generators {x, y}' and 'Integer Ring'
        """
        if len(values) == 1:
            try:
                values = list(values[0])
            except TypeError:
                pass
        G = self.parent()
        if len(values) != G.ngens():
            raise ValueError('number of values has to match the number of generators')
        replace = dict(zip(G.gens(), values))
        new_parent = coercion_model.common_parent(*[parent(v) for v in values])
        try:
            return new_parent.prod(replace[gen] ** power
                                   for gen, power in self.syllables())
        except AttributeError:
            return prod(new_parent(replace[gen]) ** power
                        for gen, power in self.syllables())
示例#14
0
    def __call__(self, *values):
        """
        Replace the generators of the free group by corresponding
        elements of the iterable ``values`` in the group element
        ``self``.

        INPUT:

        - ``*values`` -- a sequence of values, or a
          list/tuple/iterable of the same length as the number of
          generators of the free group.

        OUTPUT:

        The product of ``values`` in the order and with exponents
        specified by ``self``.

        EXAMPLES::

            sage: G.<a,b> = FreeGroup()
            sage: w = a^2 * b^-1 * a^3
            sage: w(1, 2)
            1/2
            sage: w(2, 1)
            32
            sage: w.subs(b=1, a=2)   # indirect doctest
            32

        TESTS::

            sage: w([1, 2])
            1/2
            sage: w((1, 2))
            1/2
            sage: w(i+1 for i in range(2))
            1/2

        Check that :trac:`25017` is fixed::

            sage: F = FreeGroup(2)
            sage: x0, x1 = F.gens()
            sage: u = F(1)
            sage: parent(u.subs({x1:x0})) is F
            True

            sage: F = FreeGroup(2)
            sage: x0, x1 = F.gens()
            sage: u = x0*x1
            sage: u.subs({x0:3, x1:2})
            6
            sage: u.subs({x0:1r, x1:2r})
            2
            sage: M0 = matrix(ZZ,2,[1,1,0,1])
            sage: M1 = matrix(ZZ,2,[1,0,1,1])
            sage: u.subs({x0: M0, x1: M1})
            [2 1]
            [1 1]

        TESTS::

            sage: F.<x,y> = FreeGroup()
            sage: F.one().subs(x=x, y=1)
            Traceback (most recent call last):
            ...
            TypeError: no common canonical parent for objects with parents: 'Free Group on generators {x, y}' and 'Integer Ring'
        """
        if len(values) == 1:
            try:
                values = list(values[0])
            except TypeError:
                pass
        G = self.parent()
        if len(values) != G.ngens():
            raise ValueError(
                'number of values has to match the number of generators')
        replace = dict(zip(G.gens(), values))
        new_parent = coercion_model.common_parent(*[parent(v) for v in values])
        try:
            return new_parent.prod(replace[gen]**power
                                   for gen, power in self.syllables())
        except AttributeError:
            return prod(
                new_parent(replace[gen])**power
                for gen, power in self.syllables())