Exemplo n.º 1
0
    def im_gens(self):
        r"""
        Return the images of the generators under this map.

        EXAMPLES::

            sage: K.<a, b> = NumberField( [x^3 + 2, x^2 + x + 1] )
            sage: K.hom(a, K).im_gens()
            [a, b]
        """
        try:
            return self.__im_gens
        except AttributeError:
            pass
        D = self.domain()
        C = self.codomain()
        v = Sequence([self(x) for x in D.gens()], universe=C, check=False, immutable=True)
        self.__im_gens = v
        return v
Exemplo n.º 2
0
    def atkin_lehner_eigenvalue_numerical(self, t):
        (tau1, z, tau2) = t
        from sage.libs.mpmath import mp
        from sage.libs.mpmath.mp import exp, pi
        from sage.libs.mpmath.mp import j as i

        if not Integer(self.__level()).is_prime():
            raise ValueError(
                "The Atkin Lehner involution is only unique if the level is a prime"
            )

        precision = ParamodularFormD2Filter_trace(self.precision())

        s = Sequence([tau1, z, tau2])
        if not is_ComplexField(s):
            mp_precision = 30
        else:
            mp_precision = ceil(3.33 * s.universe().precision())
        mp.dps = mp_precision

        (tau1, z, tau2) = tuple(s)
        (tau1p, zp, tau2p) = (self.level() * tau1, self.level() * z,
                              self.level() * tau2)

        (e_tau1, e_z, e_tau2) = (exp(2 * pi * i * tau1), exp(2 * pi * i * z),
                                 exp(2 * pi * i * tau2))
        (e_tau1p, e_zp, e_tau2p) = (exp(2 * pi * i * tau1p),
                                    exp(2 * pi * i * zp),
                                    exp(2 * pi * i * tau2p))

        self_value = s.universe().zero()
        trans_value = s.universe().zero()

        for k in precision:
            (a, b, c) = apply_GL_to_form(self._P1List()(k[1]), k[0])

            self_value = self_value + self[k] * (e_tau1**a * e_z**b *
                                                 e_tau2**c)
            trans_value = trans_value + self[k] * (e_tau1p**a * e_zp**b *
                                                   e_tau2p**c)

        return trans_value / self_value
Exemplo n.º 3
0
    def list(self):
        """
        Return a list of all the elements of self (for which the domain
        is a relative number field).

        EXAMPLES::

            sage: K.<a, b> = NumberField([x^2 + x + 1, x^3 + 2])
            sage: End(K).list()
            [
            Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field
              Defn: a |--> a
                    b |--> b,
            ...
            Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field
              Defn: a |--> a
                    b |--> -b*a - b
            ]

        An example with an absolute codomain::

            sage: K.<a, b> = NumberField([x^2 - 3, x^2 + 2])
            sage: Hom(K, CyclotomicField(24, 'z')).list()
            [
            Relative number field morphism:
              From: Number Field in a with defining polynomial x^2 - 3 over its base field
              To:   Cyclotomic Field of order 24 and degree 8
              Defn: a |--> z^6 - 2*z^2
                    b |--> -z^5 - z^3 + z,
            ...
            Relative number field morphism:
              From: Number Field in a with defining polynomial x^2 - 3 over its base field
              To:   Cyclotomic Field of order 24 and degree 8
              Defn: a |--> -z^6 + 2*z^2
                    b |--> z^5 + z^3 - z
            ]
        """
        D = self.domain()
        C = self.codomain()
        D_abs = D.absolute_field('a')
        v = [self(f, check=False) for f in D_abs.Hom(C).list()]
        return Sequence(v, universe=self, check=False, immutable=True, cr=v!=[])
Exemplo n.º 4
0
    def list(self):
        """
        Return a list of all the elements of self (for which the domain
        is a cyclotomic field).

        EXAMPLES::

            sage: K.<z> = CyclotomicField(12)
            sage: G = End(K); G
            Automorphism group of Cyclotomic Field of order 12 and degree 4
            sage: [g(z) for g in G]
            [z, z^3 - z, -z, -z^3 + z]
            sage: L.<a, b> = NumberField([x^2 + x + 1, x^4 + 1])
            sage: L
            Number Field in a with defining polynomial x^2 + x + 1 over its base field
            sage: Hom(CyclotomicField(12), L)[3]
            Ring morphism:
              From: Cyclotomic Field of order 12 and degree 4
              To:   Number Field in a with defining polynomial x^2 + x + 1 over its base field
              Defn: zeta12 |--> -b^2*a
            sage: list(Hom(CyclotomicField(5), K))
            []
            sage: Hom(CyclotomicField(11), L).list()
            []
        """
        D = self.domain()
        C = self.codomain()
        z = D.gen()
        n = z.multiplicative_order()
        if not n.divides(C.zeta_order()):
            v = []
        else:
            if D == C:
                w = z
            else:
                w = C.zeta(n)
            v = [self([w**k], check=False) for k in Zmod(n) if k.is_unit()]
        return Sequence(v,
                        universe=self,
                        check=False,
                        immutable=True,
                        cr=v != [])
Exemplo n.º 5
0
    def lcm(self, other):
        r"""
        Return the lcm of two factorizations.

        If the two factorizations have different universes, this
        method will attempt to find a common universe for the
        lcm.  A TypeError is raised if this is impossible.

        EXAMPLES::

            sage: factor(-10).lcm(factor(-16))
            2^4 * 5
            sage: factor(lcm(-10,16))
            2^4 * 5

            sage: R.<x> = ZZ[]
            sage: (factor(-20).lcm(factor(5*x+10))).universe()
            Univariate Polynomial Ring in x over Integer Ring
        """
        if not isinstance(other, Factorization):
            raise NotImplementedError, "can't take lcm of factorization and non-factorization"

        if len(self) and len(other):
            try:
                # first get the two factorizations to have the same
                # universe
                U = Sequence([self[0][0], other[0][0]]).universe()
                self = self.base_change(U)
                other = other.base_change(U)
            except TypeError:
                raise TypeError, "Cannot take the lcm of %s and %s because they cannot be coerced into a common universe" % (
                    self, other)

        if self.is_commutative() and other.is_commutative():
            d1 = dict(self)
            d2 = dict(other)
            s = {}
            for a in set(d1.keys()).union(set(d2.keys())):
                s[a] = max(d1.get(a, 0), d2.get(a, 0))
            return Factorization(list(s.iteritems()))
        else:
            raise NotImplementedError, "lcm is not implemented for non-commutative factorizations"
Exemplo n.º 6
0
    def __init__(self, L, index_object):
        r"""
        \code{index_object} must be a Sage object with an _iter_ method
        containing the same number of elements as self, which is a
        list of elements taken from a field.

        EXAMPLES:
            sage: J = range(10)
            sage: A = [1/10 for j in J]
            sage: s = IndexedSequence(A,J)
            sage: s
            Indexed sequence: [1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
            sage: s.dict()
            {0: 1/10,
             1: 1/10,
             2: 1/10,
             3: 1/10,
             4: 1/10,
             5: 1/10,
             6: 1/10,
             7: 1/10,
             8: 1/10,
             9: 1/10}
            sage: s.list()
            [1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10]
            sage: s.index_object()
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
            sage: s.base_ring()
            Rational Field
        """
        try:
            ind = index_object.list()
        except AttributeError:
            ind = list(index_object)
        self._index_object = index_object
        self._list = Sequence(L)
        self._base_ring = self._list.universe()
        dict = {}
        for i in range(len(ind)):
            dict[ind[i]] = L[i]
        self._dict = dict
Exemplo n.º 7
0
    def automorphisms(self):
        r"""
        Return all Galois automorphisms of ``self``.

        OUTPUT:

        - a sequence containing just the identity morphism

        EXAMPLES::

            sage: QQ.automorphisms()
            [
            Ring endomorphism of Rational Field
              Defn: 1 |--> 1
            ]
        """
        return Sequence([self.hom(1, self)],
                        cr=True,
                        immutable=False,
                        check=False)
Exemplo n.º 8
0
    def interreduced_basis(self):
        """
        A fully symmetrically reduced generating set (type :class:`~sage.structure.sequence.Sequence`) of self.

        This does essentially the same as :meth:`interreduction` with
        the option 'tailreduce', but it returns a
        :class:`~sage.structure.sequence.Sequence` rather than a
        :class:`~sage.rings.polynomial.symmetric_ideal.SymmetricIdeal`.

        EXAMPLES::

            sage: X.<x> = InfinitePolynomialRing(QQ)
            sage: I=X*(x[1]+x[2],x[1]*x[2])
            sage: I.interreduced_basis()
            [-x_1^2, x_2 + x_1]

        """
        return Sequence(self.interreduction(tailreduce=True).gens(),
                        self.ring(),
                        check=False)
Exemplo n.º 9
0
    def __init__(self, L, index_object):
        r"""
        Initialize ``self``.

        EXAMPLES::

            sage: J = range(10)
            sage: A = [1/10 for j in J]
            sage: s = IndexedSequence(A,J)
            sage: s
            Indexed sequence: [1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
            sage: s.dict()
            {0: 1/10,
             1: 1/10,
             2: 1/10,
             3: 1/10,
             4: 1/10,
             5: 1/10,
             6: 1/10,
             7: 1/10,
             8: 1/10,
             9: 1/10}
            sage: s.list()
            [1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10]
            sage: s.index_object()
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
            sage: s.base_ring()
            Rational Field
        """
        try:
            ind = index_object.list()
        except AttributeError:
            ind = list(index_object)
        self._index_object = index_object
        self._list = Sequence(L)
        self._base_ring = self._list.universe()
        dict = {}
        for i in range(len(ind)):
            dict[ind[i]] = L[i]
        self._dict = dict
Exemplo n.º 10
0
    def ap(self, p):
        """
        Return a list of the eigenvalues of the Hecke operator `T_p`
        on all the computed eigenforms.  The eigenvalues match up
        between one prime and the next.

        INPUT:

        - ``p`` - integer, a prime number

        OUTPUT:

        - ``list`` - a list of double precision complex numbers

        EXAMPLES::

            sage: n = numerical_eigenforms(11,4)
            sage: n.ap(2) # random order
            [9.0, 9.0, 2.73205080757, -0.732050807569]
            sage: n.ap(3) # random order
            [28.0, 28.0, -7.92820323028, 5.92820323028]
            sage: m = n.modular_symbols()
            sage: x = polygen(QQ, 'x')
            sage: m.T(2).charpoly('x').factor()
            (x - 9)^2 * (x^2 - 2*x - 2)
            sage: m.T(3).charpoly('x').factor()
            (x - 28)^2 * (x^2 + 2*x - 47)
        """
        p = Integer(p)
        if not p.is_prime():
            raise ValueError("p must be a prime")
        try:
            return self._ap[p]
        except AttributeError:
            self._ap = {}
        except KeyError:
            pass
        a = Sequence(self.eigenvalues([p])[0], immutable=True)
        self._ap[p] = a
        return a
Exemplo n.º 11
0
    def eisenstein_params(self):
        """
        Return parameters that define all Eisenstein series in self.

        OUTPUT: an immutable Sequence

        EXAMPLES::

            sage: m = ModularForms(Gamma0(22), 2)
            sage: v = m.eisenstein_params(); v
            [(Dirichlet character modulo 22 of conductor 1 mapping 13 |--> 1, Dirichlet character modulo 22 of conductor 1 mapping 13 |--> 1, 2), (Dirichlet character modulo 22 of conductor 1 mapping 13 |--> 1, Dirichlet character modulo 22 of conductor 1 mapping 13 |--> 1, 11), (Dirichlet character modulo 22 of conductor 1 mapping 13 |--> 1, Dirichlet character modulo 22 of conductor 1 mapping 13 |--> 1, 22)]
            sage: type(v)
            <class 'sage.structure.sequence.Sequence_generic'>
        """
        eps = self.character()
        if eps is None:
            if arithgroup.is_Gamma1(self.group()):
                eps = self.level()
            else:
                raise NotImplementedError
        params = eis_series.compute_eisenstein_params(eps, self.weight())
        return Sequence(params, immutable=True)
Exemplo n.º 12
0
    def __init__(self, X, v, check=True):
        """
        The Python constructor.

        See :class:`SchemeMorphism_point_affine` for details.

        TESTS::

            sage: from sage.schemes.affine.affine_point import SchemeMorphism_point_affine
            sage: A3.<x,y,z> = AffineSpace(QQ, 3)
            sage: SchemeMorphism_point_affine(A3(QQ), [1, 2, 3])
            (1, 2, 3)
        """
        SchemeMorphism.__init__(self, X)
        if check:
            from sage.rings.ring import CommutativeRing
            if is_SchemeMorphism(v):
                v = list(v)
            else:
                try:
                    if isinstance(v.parent(), CommutativeRing):
                        v = [v]
                except AttributeError:
                    pass
            # Verify that there are the right number of coords
            d = self.codomain().ambient_space().ngens()
            if len(v) != d:
                raise TypeError("argument v (=%s) must have %s coordinates" %
                                (v, d))
            if not isinstance(v, (list, tuple)):
                raise TypeError(
                    "argument v (= %s) must be a scheme point, list, or tuple"
                    % str(v))
            # Make sure the coordinates all lie in the appropriate ring
            v = Sequence(v, X.value_ring())
            # Verify that the point satisfies the equations of X.
            X.extended_codomain()._check_satisfies_equations(v)
        self._coords = tuple(v)
Exemplo n.º 13
0
    def _check_satisfies_equations(self, v):
        """
        Return True if `v` defines a point on the scheme self; raise a
        TypeError otherwise.

        EXAMPLES::

            sage: A = AffineSpace(3, ZZ)
            sage: A._check_satisfies_equations([1, 1, 0])
            True
            sage: A._check_satisfies_equations((0, 1, 0))
            True
            sage: A._check_satisfies_equations([0, 0, 0])
            True
            sage: A._check_satisfies_equations([1, 2, 3, 4, 5])
            Traceback (most recent call last):
            ...
            TypeError: The list v=[1, 2, 3, 4, 5] must have 3 components
            sage: A._check_satisfies_equations([1/2, 1, 1])
            Traceback (most recent call last):
            ...
            TypeError: The components of v=[1/2, 1, 1] must be elements of Integer Ring
            sage: A._check_satisfies_equations(5)
            Traceback (most recent call last):
            ...
            TypeError: The argument v=5 must be a list or tuple
        """
        if not isinstance(v, (list, tuple)):
            raise TypeError('The argument v=%s must be a list or tuple' % v)
        n = self.ngens()
        if not len(v) == n:
            raise TypeError('The list v=%s must have %s components' % (v, n))
        R = self.base_ring()
        from sage.structure.sequence import Sequence
        if not Sequence(v).universe() == R:
            raise TypeError('The components of v=%s must be elements of %s' %
                            (v, R))
        return True
Exemplo n.º 14
0
    def __init__(self, invariants, names, number_field, gens, S, proof=True):
        r"""
        Create an S-class group.

        EXAMPLES::
        
            sage: K.<a> = QuadraticField(-14)
            sage: I = K.ideal(2,a)                  
            sage: S = (I,)
            sage: K.S_class_group(S)
            S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14
            sage: K.<a> = QuadraticField(-105)
            sage: K.S_class_group([K.ideal(13, a + 8)])
            S-class group of order 4 with structure C2 x C2 of Number Field in a with defining polynomial x^2 + 105
        """
        AbelianGroup_class.__init__(self, len(invariants), invariants, names)
        self._proof_flag = proof
        self.__number_field = number_field
        self.__S = S
        self.__gens = Sequence([SFractionalIdealClass(self, x) for x in gens],
                               immutable=True,
                               universe=self,
                               check=False)
Exemplo n.º 15
0
    def parallelotope(self, generators):
        r"""
        Return the parallelotope spanned by the generators.

        The parallelotope is the multi-dimensional generalization of a
        parallelogram (2 generators) and a parallelepiped (3 generators).

        INPUT:

        - ``generators`` -- a list vector of vectors of same dimension

        EXAMPLES::

            sage: polytopes.parallelotope([ (1,0), (0,1) ])
            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
            sage: polytopes.parallelotope([[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]])
            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 16 vertices

            sage: K = QuadraticField(2, 'sqrt2')
            sage: sqrt2 = K.gen()
            sage: polytopes.parallelotope([ (1,sqrt2), (1,-1) ])
            A 2-dimensional polyhedron in (Number Field in sqrt2 with defining
            polynomial x^2 - 2)^2 defined as the convex hull of 4 vertices
        """
        from sage.modules.free_module_element import vector
        from sage.structure.sequence import Sequence
        generators = map(vector, generators)
        V = Sequence(generators).universe()
        R = V.base_ring()

        from itertools import combinations
        par = [V.zero()]
        par.extend(
            sum(c) for k in range(1,
                                  len(generators) + 1)
            for c in combinations(generators, k))
        return Polyhedron(vertices=par, base_ring=R)
Exemplo n.º 16
0
    def __init__(self, parent, im_gens, base_map=None, check=True):
        """
        EXAMPLES::

            sage: L = LieAlgebra(QQ, 'x,y,z')
            sage: Lyn = L.Lyndon()
            sage: H = L.Hall()
            sage: phi = Lyn.coerce_map_from(H)

        We skip the category test because the Homset's element class
        does not match this class::

            sage: TestSuite(phi).run(skip=['_test_category'])
        """
        Morphism.__init__(self, parent)
        if not isinstance(im_gens, Sequence_generic):
            if not isinstance(im_gens, (tuple, list)):
                im_gens = [im_gens]
            im_gens = Sequence(im_gens, parent.codomain(), immutable=True)
        if check:
            if len(im_gens) != len(parent.domain().lie_algebra_generators()):
                raise ValueError(
                    "number of images must equal number of generators")
            if base_map is not None and not (
                    base_map.domain() is parent.domain().base_ring()
                    and parent.codomain().base_ring().has_coerce_map_from(
                        base_map.codomain())):
                raise ValueError("Invalid base homomorphism")
            # TODO: Implement a (meaningful) _is_valid_homomorphism_()
            #if not parent.domain()._is_valid_homomorphism_(parent.codomain(), im_gens, base_map=base_map):
            #    raise ValueError("relations do not all (canonically) map to 0 under map determined by images of generators.")
        if not im_gens.is_immutable():
            import copy
            im_gens = copy.copy(im_gens)
            im_gens.set_immutable()
        self._im_gens = im_gens
        self._base_map = base_map
Exemplo n.º 17
0
    def characters(self):
        r"""
        Return the pair of characters (either of `\QQ_p^*` or of some quadratic
        extension) corresponding to this representation.

        EXAMPLES::

            sage: f = [f for f in Newforms(63, 4, names='a') if f[2] == 1][0]
            sage: f.local_component(3).characters()
            [
            Character of Q_3*, of level 1, mapping 2 |--> -1, 3 |--> d,
            Character of Q_3*, of level 1, mapping 2 |--> -1, 3 |--> -d - 2
            ]
        """
        minchars = self._min_twist.characters()
        G = minchars[0].parent()
        chi = self._chi
        if self.species() == "Supercuspidal":
            H = SmoothCharacterGroupQp(self.prime(), chi.base_ring())
            Hchi = H.from_dirichlet(~chi)
            Gchi = G.compose_with_norm(Hchi)
        else:
            Gchi = G.from_dirichlet(~chi)
        return Sequence([c * Gchi for c in minchars], cr=True, universe=G)
Exemplo n.º 18
0
    def basis(self):
        r"""
        Returns a basis of ``self``.

        OUTPUT:

        -  ``Sequence`` - an immutable sequence whose universe is ambient space of ``self``.

        EXAMPLES::

            sage: C = codes.HammingCode(GF(2), 3)
            sage: C.basis()
            [
            (1, 0, 0, 0, 0, 1, 1),
            (0, 1, 0, 0, 1, 0, 1),
            (0, 0, 1, 0, 1, 1, 0),
            (0, 0, 0, 1, 1, 1, 1)
            ]
            sage: C.basis().universe()
            Vector space of dimension 7 over Finite Field of size 2
        """
        gens = self.gens()
        from sage.structure.sequence import Sequence
        return Sequence(gens, universe=self.ambient_space(), check = False, immutable=True, cr=True)
    def right_angle_triangle(w, h):
        r"""
        TESTS::

            sage: from flatsurf import *
            sage: R = similarity_surfaces.right_angle_triangle(2, 3)
            sage: R
            ConeSurface built from 2 polygons
            sage: TestSuite(R).run()
        """
        from sage.modules.free_module_element import vector

        F = Sequence([w, h]).universe()

        if not F.is_field():
            F = F.fraction_field()
        V = VectorSpace(F, 2)
        P = ConvexPolygons(F)
        s = Surface_list(base_ring=F)
        s.add_polygon(P([V((w, 0)), V((-w, h)), V((0, -h))]))  # gets label 0
        s.add_polygon(P([V((0, h)), V((-w, -h)), V((w, 0))]))  # gets label 1
        s.change_polygon_gluings(0, [(1, 2), (1, 1), (1, 0)])
        s.set_immutable()
        return ConeSurface(s)
Exemplo n.º 20
0
    def __init__(self, X, v, check=True):
        """
        The Python constructor.

        EXAMPLES::

            sage: P = ProjectiveSpace(2, QQ)
            sage: P(2, 3/5, 4)
            (1/2 : 3/20 : 1)

        ::

            sage: P = ProjectiveSpace(1, ZZ)
            sage: P([0, 1])
            (0 : 1)

        ::

            sage: P = ProjectiveSpace(1, ZZ)
            sage: P([0, 0, 1])
            Traceback (most recent call last):
            ...
            TypeError: v (=[0, 0, 1]) must have 2 components

        ::

            sage: P = ProjectiveSpace(3, QQ)
            sage: P(0,0,0,0)
            Traceback (most recent call last):
            ...
            ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0

        It is possible to avoid the possibly time-consuming checks, but be careful!! ::

            sage: P = ProjectiveSpace(3, QQ)
            sage: P.point([0,0,0,0], check=False)
            (0 : 0 : 0 : 0)

        ::

            sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
            sage: X = P.subscheme([x^2-y*z])
            sage: X([2, 2, 2])
            (2 : 2 : 2)

        ::

            sage: R.<t> = PolynomialRing(ZZ)
            sage: P = ProjectiveSpace(1, R.quo(t^2+1))
            sage: P([2*t, 1])
            (2*tbar : 1)

        ::

            sage: P = ProjectiveSpace(ZZ,1)
            sage: P.point(Infinity)
            (1 : 0)
            sage: P(infinity)
            (1 : 0)

        ::

            sage: P = ProjectiveSpace(ZZ,2)
            sage: P(Infinity)
            Traceback (most recent call last):
            ...
            ValueError: +Infinity not well defined in dimension > 1
            sage: P.point(infinity)
            Traceback (most recent call last):
            ...
            ValueError: +Infinity not well defined in dimension > 1
        """
        SchemeMorphism.__init__(self, X)
        if check:
            from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field
            from sage.rings.ring import CommutativeRing
            d = X.codomain().ambient_space().ngens()

            if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field):
                v = list(v)
            else:
                try:
                    if isinstance(v.parent(), CommutativeRing):
                        v = [v]
                except AttributeError:
                    pass
            if not isinstance(v, (list, tuple)):
                raise TypeError("argument v (= %s) must be a scheme point, list, or tuple"%str(v))
            if len(v) != d and len(v) != d-1:
                raise TypeError("v (=%s) must have %s components"%(v, d))

            R = X.value_ring()
            v = Sequence(v, R)
            if len(v) == d-1:     # very common special case
                v.append(R(1))

            n = len(v)
            all_zero = True
            for i in range(n):
                last = n-1-i
                if v[last]:
                    all_zero = False
                    break
            if all_zero:
                raise ValueError("%s does not define a valid point since all entries are 0"%repr(v))

            X.extended_codomain()._check_satisfies_equations(v)

        self._coords = tuple(v)
Exemplo n.º 21
0
def AbelianGroupWithValues(values,
                           n,
                           gens_orders=None,
                           names='f',
                           check=False,
                           values_group=None):
    """
    Construct an Abelian group with values associated to the generators.

    INPUT:

    - ``values`` -- a list/tuple/iterable of values that you want to
      associate to the generators.

    - ``n`` -- integer (optional). If not specified, will be derived
       from ``gens_orders``.

    - ``gens_orders`` -- a list of non-negative integers in the form
       `[a_0, a_1, \dots, a_{n-1}]`, typically written in increasing
       order. This list is padded with zeros if it has length less
       than n. The orders of the commuting generators, with `0`
       denoting an infinite cyclic factor.

    -  ``names`` -- (optional) names of generators

    - ``values_group`` -- a parent or ``None`` (default). The common
      parent of the values. This might be a group, but can also just
      contain the values. For example, if the values are units in a
      ring then the ``values_group`` would be the whole ring. If
      ``None`` it will be derived from the values.

    EXAMPLES::

        sage: G = AbelianGroupWithValues([-1], [6])
        sage: g = G.gen(0)
        sage: for i in range(7):
        ....:     print((i, g^i, (g^i).value()))
        (0, 1, 1)
        (1, f, -1)
        (2, f^2, 1)
        (3, f^3, -1)
        (4, f^4, 1)
        (5, f^5, -1)
        (6, 1, 1)
        sage: G.values_group()
        Integer Ring

    The group elements come with a coercion embedding into the
    :meth:`values_group`, so you can use them like their
    :meth:`~sage.groups.abelian_gps.value.AbelianGroupWithValuesElement.value`
    ::

        sage: G.values_embedding()
        Generic morphism:
          From: Multiplicative Abelian group isomorphic to C6
          To:   Integer Ring
        sage: g.value()
        -1
        sage: 0 + g
        -1
        sage: 1 + 2*g
        -1
    """
    if check:
        raise NotImplementedError(
            'checking that the values are a homomorphism is not implemented')
    gens_orders, names = _normalize(n, gens_orders, names)
    if values_group is None:
        from sage.structure.sequence import Sequence
        values_group = Sequence(values).universe()
    values = tuple(values_group(val) for val in values)
    M = AbelianGroupWithValues_class(gens_orders, names, values, values_group)
    return M
Exemplo n.º 22
0
def coefficients_from_j(j, minimal_twist=True):
    """
    Return Weierstrass coefficients `(a_1, a_2, a_3, a_4, a_6)` for an
    elliptic curve with given `j`-invariant.

    INPUT:

    See :func:`EllipticCurve_from_j`.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.constructor import coefficients_from_j
        sage: coefficients_from_j(0)
        [0, 0, 1, 0, 0]
        sage: coefficients_from_j(1728)
        [0, 0, 0, -1, 0]
        sage: coefficients_from_j(1)
        [1, 0, 0, 36, 3455]

    The ``minimal_twist`` parameter (ignored except over `\\QQ` and
    True by default) controls whether or not a minimal twist is
    computed::

        sage: coefficients_from_j(100)
        [0, 1, 0, 3392, 307888]
        sage: coefficients_from_j(100, minimal_twist=False)
        [0, 0, 0, 488400, -530076800]
    """
    try:
        K = j.parent()
    except AttributeError:
        K = rings.RationalField()
    if K not in _Fields:
        K = K.fraction_field()

    char = K.characteristic()
    if char == 2:
        if j == 0:
            return Sequence([0, 0, 1, 0, 0], universe=K)
        else:
            return Sequence([1, 0, 0, 0, 1 / j], universe=K)
    if char == 3:
        if j == 0:
            return Sequence([0, 0, 0, 1, 0], universe=K)
        else:
            return Sequence([0, j, 0, 0, -j**2], universe=K)

    if K is rings.RationalField():
        # we construct the minimal twist, i.e. the curve with minimal
        # conductor with this j_invariant:
        if j == 0:
            return Sequence([0, 0, 1, 0, 0], universe=K)  # 27a3
        if j == 1728:
            return Sequence([0, 0, 0, -1, 0], universe=K)  # 32a2

        if not minimal_twist:
            k = j - 1728
            return Sequence([0, 0, 0, -3 * j * k, -2 * j * k**2], universe=K)

        n = j.numerator()
        m = n - 1728 * j.denominator()
        a4 = -3 * n * m
        a6 = -2 * n * m**2

        # Now E=[0,0,0,a4,a6] has j-invariant j=n/d
        from sage.sets.set import Set
        for p in Set(n.prime_divisors() + m.prime_divisors()):
            e = min(a4.valuation(p) // 2, a6.valuation(p) // 3)
            if e > 0:
                p = p**e
                a4 /= p**2
                a6 /= p**3

        # Now E=[0,0,0,a4,a6] is minimal at all p != 2,3
        tw = [-1, 2, -2, 3, -3, 6, -6]
        E1 = EllipticCurve([0, 0, 0, a4, a6])
        Elist = [E1] + [E1.quadratic_twist(t) for t in tw]
        Elist.sort(key=lambda E: E.conductor())
        return Sequence(Elist[0].ainvs())

    # defaults for all other fields:
    if j == 0:
        return Sequence([0, 0, 0, 0, 1], universe=K)
    if j == 1728:
        return Sequence([0, 0, 0, 1, 0], universe=K)
    k = j - 1728
    return Sequence([0, 0, 0, -3 * j * k, -2 * j * k**2], universe=K)
Exemplo n.º 23
0
    def characters(self):
        r"""
        Return the two conjugate characters of `K^\times`, where `K` is some
        quadratic extension of `\QQ_p`, defining this representation. This is
        fully implemented only in the case where the power of `p` dividing the
        level of the form is even, in which case `K` is the unique unramified
        quadratic extension of `\QQ_p`.

        EXAMPLES:

        The first example from _[LW11]::

            sage: f = Newform('50a')
            sage: Pi = LocalComponent(f, 5)
            sage: chars = Pi.characters(); chars
            [
            Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> d, 5 |--> 1,
            Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -d - 1, 5 |--> 1
            ]
            sage: chars[0].base_ring()
            Number Field in d with defining polynomial x^2 + x + 1

        These characters are interchanged by the Frobenius automorphism of `\mathbb{F}_{25}`::

            sage: chars[0] == chars[1]**5
            True

        A more complicated example (higher weight and nontrivial central character)::

            sage: f = Newforms(GammaH(25, [6]), 3, names='j')[0]; f
            q + j0*q^2 + 1/3*j0^3*q^3 - 1/3*j0^2*q^4 + O(q^6)
            sage: Pi = LocalComponent(f, 5)
            sage: Pi.characters()
            [
            Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> d, 5 |--> 5,
            Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -d - 1/3*j0^3, 5 |--> 5
            ]
            sage: Pi.characters()[0].base_ring()
            Number Field in d with defining polynomial x^2 + 1/3*j0^3*x - 1/3*j0^2 over its base field

        .. warning::

            The above output isn't actually the same as in Example 2 of
            _[LW11], due to an error in the published paper (correction
            pending) -- the published paper has the inverses of the above
            characters.

        A higher level example::

            sage: f = Newform('81a', names='j'); f
            q + j0*q^2 + q^4 - j0*q^5 + O(q^6)
            sage: LocalComponent(f, 3).characters()  # long time (12s on sage.math, 2012)
            [
            Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> -2*d - j0, 4 |--> 1, 3*s + 1 |--> -j0*d - 2, 3 |--> 1,
            Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> 2*d + j0, 4 |--> 1, 3*s + 1 |--> j0*d + 1, 3 |--> 1
            ]

        In the ramified case, it's not fully implemented, and just returns a
        string indicating which ramified extension is being considered::

            sage: Pi = LocalComponent(Newform('27a'), 3)
            sage: Pi.characters()
            'Character of Q_3(sqrt(-3))'
            sage: Pi = LocalComponent(Newform('54a'), 3)
            sage: Pi.characters()
            'Character of Q_3(sqrt(3))'
        """
        T = self.type_space()
        if self.conductor() % 2 == 0:

            G = SmoothCharacterGroupUnramifiedQuadratic(
                self.prime(), self.coefficient_field())
            n = self.conductor() // 2
            g = G.quotient_gen(n)
            m = g.matrix().change_ring(ZZ).list()
            tr = (~T.rho(m)).trace()

            # The inverse is needed here because T is the *homological* type space,
            # which is dual to the cohomological one that defines the local component.

            X = polygen(self.coefficient_field())
            theta_poly = X**2 - (-1)**n * tr * X + self.central_character()(
                g.norm())
            if theta_poly.is_irreducible():
                F = self.coefficient_field().extension(theta_poly, "d")
                G = G.base_extend(F)
            chi1, chi2 = [
                G.extend_character(n, self.central_character(), x[0])
                for x in theta_poly.roots(G.base_ring())
            ]

            # Consistency checks
            assert chi1.restrict_to_Qp() == chi2.restrict_to_Qp(
            ) == self.central_character()
            assert chi1 * chi2 == chi1.parent().compose_with_norm(
                self.central_character())

            return Sequence([chi1, chi2], check=False, cr=True)

        else:
            # The ramified case.

            p = self.prime()

            if p == 2:
                # The ramified 2-adic representations aren't classified by admissible pairs. Die.
                raise NotImplementedError(
                    "Computation with ramified 2-adic representations not implemented"
                )

            if p % 4 == 3:
                a = ZZ(-1)
            else:
                a = ZZ(Zmod(self.prime()).quadratic_nonresidue())

            tr1 = (~T.rho([0, 1, a * p, 0])).trace()
            tr2 = (~T.rho([0, 1, p, 0])).trace()

            if tr1 == tr2 == 0:
                # This *can* happen. E.g. if the central character satisfies
                # chi(-1) = -1, then we have theta(pi) + theta(-pi) = theta(pi)
                # * (1 + -1) = 0. In this case, one can presumably identify
                # the character and the extension by some more subtle argument
                # but I don't know of a good way to automate the process.
                raise NotImplementedError(
                    "Can't identify ramified quadratic extension -- both traces zero"
                )
            elif tr1 == 0:
                return "Character of Q_%s(sqrt(%s))" % (p, p)

            elif tr2 == 0:
                return "Character of Q_%s(sqrt(%s))" % (p, a * p)

            else:
                # At least one of the traces is *always* 0, since the type
                # space has to be isomorphic to its twist by the (ramified
                # quadratic) character corresponding to the quadratic
                # extension.
                raise RuntimeError("Can't get here!")
Exemplo n.º 24
0
def permutation_action(g, v):
    r"""
    Returns permutation of rows g\*v. Works on lists, matrices,
    sequences and vectors (by permuting coordinates). The code requires
    switching from i to i+1 (and back again) since the SymmetricGroup
    is, by convention, the symmetric group on the "letters" 1, 2, ...,
    n (not 0, 1, ..., n-1).

    EXAMPLES::

        sage: V = VectorSpace(GF(3),5)
        sage: v = V([0,1,2,0,1])
        sage: G = SymmetricGroup(5)
        sage: g = G([(1,2,3)])
        sage: permutation_action(g,v)
        (1, 2, 0, 0, 1)
        sage: g = G([()])
        sage: permutation_action(g,v)
        (0, 1, 2, 0, 1)
        sage: g = G([(1,2,3,4,5)])
        sage: permutation_action(g,v)
        (1, 2, 0, 1, 0)
        sage: L = Sequence([1,2,3,4,5])
        sage: permutation_action(g,L)
        [2, 3, 4, 5, 1]
        sage: MS = MatrixSpace(GF(3),3,7)
        sage: A = MS([[1,0,0,0,1,1,0],[0,1,0,1,0,1,0],[0,0,0,0,0,0,1]])
        sage: S5 = SymmetricGroup(5)
        sage: g = S5([(1,2,3)])
        sage: A
        [1 0 0 0 1 1 0]
        [0 1 0 1 0 1 0]
        [0 0 0 0 0 0 1]
        sage: permutation_action(g,A)
        [0 1 0 1 0 1 0]
        [0 0 0 0 0 0 1]
        [1 0 0 0 1 1 0]

    It also works on lists and is a "left action"::

        sage: v = [0,1,2,0,1]
        sage: G = SymmetricGroup(5)
        sage: g = G([(1,2,3)])
        sage: gv = permutation_action(g,v); gv
        [1, 2, 0, 0, 1]
        sage: permutation_action(g,v) == g(v)
        True
        sage: h = G([(3,4)])
        sage: gv = permutation_action(g,v)
        sage: hgv = permutation_action(h,gv)
        sage: hgv == permutation_action(h*g,v)
        True

    AUTHORS:

    - David Joyner, licensed under the GPL v2 or greater.
    """
    v_type_list = False
    if isinstance(v, list):
        v_type_list = True
        v = Sequence(v)
    if isinstance(v, Sequence_generic):
        V = v.universe()
    else:
        V = v.parent()
    n = len(list(v))
    gv = []
    for i in range(n):
        gv.append(v[g(i + 1) - 1])
    if v_type_list:
        return gv
    return V(gv)
Exemplo n.º 25
0
    def create_key_and_extra_args(self,
                                  x=None,
                                  y=None,
                                  j=None,
                                  minimal_twist=True,
                                  **kwds):
        """
        Return a ``UniqueFactory`` key and possibly extra parameters.

        INPUT:

        See the documentation for :class:`EllipticCurveFactory`.

        OUTPUT:

        A pair ``(key, extra_args)``:

        - ``key`` has the form `(R, (a_1, a_2, a_3, a_4, a_6))`,
          representing a ring and the Weierstrass coefficients of an
          elliptic curve over that ring;

        - ``extra_args`` is a dictionary containing additional data to
          be inserted into the elliptic curve structure.

        EXAMPLES::

            sage: EllipticCurve.create_key_and_extra_args(j=8000)
            ((Rational Field, (0, -1, 0, -3, -1)), {})

        When constructing a curve over `\\QQ` from a Cremona or LMFDB
        label, the invariants from the database are returned as
        ``extra_args``::

            sage: key, data = EllipticCurve.create_key_and_extra_args('389.a1')
            sage: key
            (Rational Field, (0, 1, 1, -2, 0))
            sage: data['conductor']
            389
            sage: data['cremona_label']
            '389a1'
            sage: data['lmfdb_label']
            '389.a1'
            sage: data['rank']
            2
            sage: data['torsion_order']
            1

        User-specified keywords are also included in ``extra_args``::

            sage: key, data = EllipticCurve.create_key_and_extra_args((0, 0, 1, -23737, 960366), rank=4)
            sage: data['rank']
            4

        Furthermore, keywords takes precedence over data from the
        database, which can be used to specify an alternative set of
        generators for the Mordell-Weil group::

            sage: key, data = EllipticCurve.create_key_and_extra_args('5077a1', gens=[[1, -1], [-2, 3], [4, -7]])
            sage: data['gens']
            [[1, -1], [-2, 3], [4, -7]]
            sage: E = EllipticCurve.create_object(0, key, **data)
            sage: E.gens()
            [(-2 : 3 : 1), (1 : -1 : 1), (4 : -7 : 1)]

        Note that elliptic curves are equal if and only they have the
        same base ring and Weierstrass equation; the data in
        ``extra_args`` do not influence comparison of elliptic curves.
        A consequence of this is that passing keyword arguments only
        works when constructing an elliptic curve the first time::

            sage: E = EllipticCurve('433a1', gens=[[-1, 1], [3, 4]])
            sage: E.gens()
            [(-1 : 1 : 1), (3 : 4 : 1)]
            sage: E = EllipticCurve('433a1', gens=[[-1, 0], [0, 1]])
            sage: E.gens()
            [(-1 : 1 : 1), (3 : 4 : 1)]

        .. WARNING::

            Manually specifying extra data is almost never necessary
            and is not guaranteed to have any effect, as the above
            example shows.  Almost no checking is done, so specifying
            incorrect data may lead to wrong results of computations
            instead of errors or warnings.

        """
        R = None
        if is_Ring(x):
            (R, x) = (x, y)

        if j is not None:
            if R is not None:
                try:
                    j = R(j)
                except (ZeroDivisionError, ValueError, TypeError):
                    raise ValueError(
                        "First parameter must be a ring containing %s" % j)
            elif x is not None:
                raise ValueError(
                    "First parameter (if present) must be a ring when j is specified"
                )
            x = coefficients_from_j(j, minimal_twist)

        if is_SymbolicEquation(x):
            x = x.lhs() - x.rhs()

        if parent(x) is SR:
            x = x._polynomial_(rings.QQ['x', 'y'])

        if is_MPolynomial(x):
            if y is None:
                x = coefficients_from_Weierstrass_polynomial(x)
            else:
                x = coefficients_from_cubic(x, y, morphism=False)

        if isinstance(x, string_types):
            # Interpret x as a Cremona or LMFDB label.
            from sage.databases.cremona import CremonaDatabase
            x, data = CremonaDatabase().coefficients_and_data(x)
            # User-provided keywords may override database entries.
            data.update(kwds)
            kwds = data

        if not isinstance(x, (list, tuple)):
            raise TypeError("invalid input to EllipticCurve constructor")

        if len(x) == 2:
            x = (0, 0, 0, x[0], x[1])
        elif len(x) != 5:
            raise ValueError(
                "sequence of coefficients must have length 2 or 5")

        if R is None:
            R = Sequence(x).universe()
            if R in (rings.ZZ, ) + integer_types:
                R = rings.QQ

        return (R, tuple(R(a) for a in x)), kwds
Exemplo n.º 26
0
def Polyhedron(vertices=None,
               rays=None,
               lines=None,
               ieqs=None,
               eqns=None,
               ambient_dim=None,
               base_ring=None,
               minimize=True,
               verbose=False,
               backend=None):
    """
    Construct a polyhedron object.

    You may either define it with vertex/ray/line or
    inequalities/equations data, but not both. Redundant data will
    automatically be removed (unless ``minimize=False``), and the
    complementary representation will be computed.

    INPUT:

    - ``vertices`` -- list of point. Each point can be specified as
      any iterable container of ``base_ring`` elements. If ``rays`` or
      ``lines`` are specified but no ``vertices``, the origin is
      taken to be the single vertex.

    - ``rays`` -- list of rays. Each ray can be specified as any
      iterable container of ``base_ring`` elements.

    - ``lines`` -- list of lines. Each line can be specified as any
      iterable container of ``base_ring`` elements.

    - ``ieqs`` -- list of inequalities. Each line can be specified as any
      iterable container of ``base_ring`` elements. An entry equal to
      ``[-1,7,3,4]`` represents the inequality `7x_1+3x_2+4x_3\geq 1`.

    - ``eqns`` -- list of equalities. Each line can be specified as
      any iterable container of ``base_ring`` elements. An entry equal to
      ``[-1,7,3,4]`` represents the equality `7x_1+3x_2+4x_3= 1`.

    - ``base_ring`` -- a sub-field of the reals implemented in
      Sage. The field over which the polyhedron will be defined. For
      ``QQ`` and algebraic extensions, exact arithmetic will be
      used. For ``RDF``, floating point numbers will be used. Floating
      point arithmetic is faster but might give the wrong result for
      degenerate input.

    - ``ambient_dim`` -- integer. The ambient space dimension. Usually
      can be figured out automatically from the H/Vrepresentation
      dimensions.

    - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are

      * ``'cdd'``: use cdd
        (:mod:`~sage.geometry.polyhedron.backend_cdd`) with `\QQ` or
        `\RDF` coefficients depending on ``base_ring``.

      * ``'ppl'``: use ppl
        (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\ZZ` or
        `\QQ` coefficients depending on ``base_ring``.

      * ``'field'``: use python implementation
        (:mod:`~sage.geometry.polyhedron.backend_field`) for any field

    Some backends support further optional arguments:

    - ``minimize`` -- boolean (default: ``True``). Whether to
      immediately remove redundant H/V-representation data. Currently
      not used.

    - ``verbose`` -- boolean (default: ``False``). Whether to print
      verbose output for debugging purposes. Only supported by the cdd
      backends.

    OUTPUT:

    The polyhedron defined by the input data.

    EXAMPLES:

    Construct some polyhedra::

        sage: square_from_vertices = Polyhedron(vertices = [[1, 1], [1, -1], [-1, 1], [-1, -1]])
        sage: square_from_ieqs = Polyhedron(ieqs = [[1, 0, 1], [1, 1, 0], [1, 0, -1], [1, -1, 0]])
        sage: list(square_from_ieqs.vertex_generator())
        [A vertex at (1, -1),
         A vertex at (1, 1),
         A vertex at (-1, 1),
         A vertex at (-1, -1)]
        sage: list(square_from_vertices.inequality_generator())
        [An inequality (1, 0) x + 1 >= 0,
         An inequality (0, 1) x + 1 >= 0,
         An inequality (-1, 0) x + 1 >= 0,
         An inequality (0, -1) x + 1 >= 0]
        sage: p = Polyhedron(vertices = [[1.1, 2.2], [3.3, 4.4]], base_ring=RDF)
        sage: p.n_inequalities()
        2

    The same polyhedron given in two ways::

        sage: p = Polyhedron(ieqs = [[0,1,0,0],[0,0,1,0]])
        sage: p.Vrepresentation()
        (A line in the direction (0, 0, 1),
         A ray in the direction (1, 0, 0),
         A ray in the direction (0, 1, 0),
         A vertex at (0, 0, 0))
        sage: q = Polyhedron(vertices=[[0,0,0]], rays=[[1,0,0],[0,1,0]], lines=[[0,0,1]])
        sage: q.Hrepresentation()
        (An inequality (1, 0, 0) x + 0 >= 0,
         An inequality (0, 1, 0) x + 0 >= 0)

    Finally, a more complicated example. Take `\mathbb{R}_{\geq 0}^6` with
    coordinates `a, b, \dots, f` and

      * The inequality `e+b \geq c+d`
      * The inequality `e+c \geq b+d`
      * The equation `a+b+c+d+e+f = 31`

    ::

        sage: positive_coords = Polyhedron(ieqs=[
        ...       [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0],
        ...       [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]])
        sage: P = Polyhedron(ieqs=positive_coords.inequalities() + (
        ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]), eqns=[[-31,1,1,1,1,1,1]])
        sage: P
        A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices
        sage: P.dim()
        5
        sage: P.Vrepresentation()
        (A vertex at (31, 0, 0, 0, 0, 0), A vertex at (0, 0, 0, 0, 0, 31),
         A vertex at (0, 0, 0, 0, 31, 0), A vertex at (0, 0, 31/2, 0, 31/2, 0),
         A vertex at (0, 31/2, 31/2, 0, 0, 0), A vertex at (0, 31/2, 0, 0, 31/2, 0),
         A vertex at (0, 0, 0, 31/2, 31/2, 0))

    .. NOTE::

      * Once constructed, a ``Polyhedron`` object is immutable.

      * Although the option ``field=RDF`` allows numerical data to
        be used, it might not give the right answer for degenerate
        input data - the results can depend upon the tolerance
        setting of cdd.
    """
    # Clean up the arguments
    vertices = _make_listlist(vertices)
    rays = _make_listlist(rays)
    lines = _make_listlist(lines)
    ieqs = _make_listlist(ieqs)
    eqns = _make_listlist(eqns)

    got_Vrep = (len(vertices + rays + lines) > 0)
    got_Hrep = (len(ieqs + eqns) > 0)

    if got_Vrep and got_Hrep:
        raise ValueError('You cannot specify both H- and V-representation.')
    elif got_Vrep:
        deduced_ambient_dim = _common_length_of(vertices, rays, lines)[1]
    elif got_Hrep:
        deduced_ambient_dim = _common_length_of(ieqs, eqns)[1] - 1
    else:
        if ambient_dim is None:
            deduced_ambient_dim = 0
        else:
            deduced_ambient_dim = ambient_dim
        if base_ring is None:
            base_ring = ZZ

    # set ambient_dim
    if ambient_dim is not None and deduced_ambient_dim != ambient_dim:
        raise ValueError(
            'Ambient space dimension mismatch. Try removing the "ambient_dim" parameter.'
        )
    ambient_dim = deduced_ambient_dim

    # figure out base_ring
    from sage.misc.flatten import flatten
    values = flatten(vertices + rays + lines + ieqs + eqns)
    if base_ring is not None:
        try:
            convert = not all(x.parent() is base_ring for x in values)
        except AttributeError:  # No x.parent() method?
            convert = True
    else:
        from sage.rings.integer import is_Integer
        from sage.rings.rational import is_Rational
        from sage.rings.real_double import is_RealDoubleElement
        if all(is_Integer(x) for x in values):
            if got_Vrep:
                base_ring = ZZ
            else:  # integral inequalities usually do not determine a lattice polytope!
                base_ring = QQ
            convert = False
        elif all(is_Rational(x) for x in values):
            base_ring = QQ
            convert = False
        elif all(is_RealDoubleElement(x) for x in values):
            base_ring = RDF
            convert = False
        else:
            try:
                for v in values:
                    ZZ(v)
                if got_Vrep:
                    base_ring = ZZ
                else:
                    base_ring = QQ
                convert = True
            except (TypeError, ValueError):
                from sage.structure.sequence import Sequence
                values = Sequence(values)
                common_ring = values.universe()
                if QQ.has_coerce_map_from(common_ring):
                    base_ring = QQ
                    convert = True
                elif common_ring is RR:  # DWIM: replace with RDF
                    base_ring = RDF
                    convert = True
                else:
                    base_ring = common_ring
                    convert = True

    # Add the origin if necesarry
    if got_Vrep and len(vertices) == 0:
        vertices = [[0] * ambient_dim]

    # Specific backends can override the base_ring
    from sage.geometry.polyhedron.parent import Polyhedra
    parent = Polyhedra(base_ring, ambient_dim, backend=backend)
    base_ring = parent.base_ring()

    # finally, construct the Polyhedron
    Hrep = Vrep = None
    if got_Hrep:
        Hrep = [ieqs, eqns]
    if got_Vrep:
        Vrep = [vertices, rays, lines]
    return parent(Vrep, Hrep, convert=convert, verbose=verbose)
Exemplo n.º 27
0
    def __init__(self, number_field, proof=True, S=None):
        """
        Create a unit group of a number field.

        INPUT:

        - ``number_field`` - a number field
        - ``proof`` - boolean (default True): proof flag
        - ``S`` - tuple of prime ideals, or an ideal, or a single
          ideal or element from which an ideal can be constructed, in
          which case the support is used.  If None, the global unit
          group is constructed; otherwise, the S-unit group is
          constructed.

        The proof flag is passed to pari via the ``pari_bnf()`` function
        which computes the unit group.  See the documentation for the
        number_field module.

        EXAMPLES::

            sage: x = polygen(QQ)
            sage: K.<a> = NumberField(x^2-38)
            sage: UK = K.unit_group(); UK
            Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38
            sage: UK.gens()
            (u0, u1)
            sage: UK.gens_values()
            [-1, 6*a - 37]

            sage: K.<a> = QuadraticField(-3)
            sage: UK = K.unit_group(); UK
            Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3
            sage: UK.gens()
            (u,)
            sage: UK.gens_values()
            [-1/2*a + 1/2]

            sage: K.<z> = CyclotomicField(13)
            sage: UK = K.unit_group(); UK
            Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12
            sage: UK.gens()
            (u0, u1, u2, u3, u4, u5)
            sage: UK.gens_values() # random
            [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z]
            sage: SUK = UnitGroup(K,S=2); SUK
            S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),)

            """
        proof = get_flag(proof, "number_field")
        K = number_field
        pK = K.pari_bnf(proof)
        self.__number_field = K
        self.__pari_number_field = pK

        # process the parameter S:
        if not S:
            S = self.__S = ()
        else:
            if isinstance(S, list):
                S = tuple(S)
            if not isinstance(S, tuple):
                try:
                    S = tuple(K.ideal(S).prime_factors())
                except (NameError, TypeError, ValueError):
                    raise ValueError("Cannot make a set of primes from %s" %
                                     (S, ))
            else:
                try:
                    S = tuple(K.ideal(P) for P in S)
                except (NameError, TypeError, ValueError):
                    raise ValueError("Cannot make a set of primes from %s" %
                                     (S, ))
                if not all([P.is_prime() for P in S]):
                    raise ValueError(
                        "Not all elements of %s are prime ideals" % (S, ))
            self.__S = S
            self.__pS = pS = [P.pari_prime() for P in S]

        # compute the fundamental units via pari:
        fu = [K(u) for u in pK.bnfunit()]
        self.__nfu = len(fu)

        # compute the additional S-unit generators:
        if S:
            self.__S_unit_data = pK.bnfsunit(pS)
            su = [K(u) for u in self.__S_unit_data[0]]
        else:
            su = []
        self.__nsu = len(su)
        self.__rank = self.__nfu + self.__nsu

        # compute a torsion generator and pick the 'simplest' one:
        n, z = pK.nfrootsof1()
        n = ZZ(n)
        self.__ntu = n
        z = K(z)

        # If we replaced z by another torsion generator we would need
        # to allow for this in the dlog function!  So we do not.

        # Store the actual generators (torsion first):
        gens = [z] + fu + su
        values = Sequence(gens, immutable=True, universe=self, check=False)
        # Construct the abtract group:
        gens_orders = tuple([ZZ(n)] + [ZZ(0)] * (self.__rank))
        AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values,
                                              number_field)
Exemplo n.º 28
0
    def __init__(self, X, v, check=True):
        """
        The Python constructor.

        See :class:`SchemeMorphism_point_projective_ring` for details.

        This function still normalizes points so that the rightmost non-zero coordinate is 1.
        This is to maintain functionality with current
        implementations of curves in projectives space (plane, conic, elliptic, etc).
        The :class:`SchemeMorphism_point_projective_ring` is for general use.

        EXAMPLES::

            sage: P = ProjectiveSpace(2, QQ)
            sage: P(2, 3/5, 4)
            (1/2 : 3/20 : 1)

        ::

            sage: P = ProjectiveSpace(3, QQ)
            sage: P(0, 0, 0, 0)
            Traceback (most recent call last):
            ...
            ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0

        ::

            sage: P.<x, y, z> = ProjectiveSpace(2, QQ)
            sage: X = P.subscheme([x^2-y*z])
            sage: X([2, 2, 2])
            (1 : 1 : 1)

        ::

            sage: P = ProjectiveSpace(1, GF(7))
            sage: Q=P([2, 1])
            sage: Q[0].parent()
            Finite Field of size 7

        ::

            sage: P = ProjectiveSpace(QQ,1)
            sage: P.point(Infinity)
            (1 : 0)
            sage: P(infinity)
            (1 : 0)

        ::

            sage: P = ProjectiveSpace(QQ,2)
            sage: P(infinity)
            Traceback (most recent call last):
            ...
            ValueError: +Infinity not well defined in dimension > 1
            sage: P.point(infinity)
            Traceback (most recent call last):
            ...
            ValueError: +Infinity not well defined in dimension > 1
        """
        SchemeMorphism.__init__(self, X)
        if check:
            from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field
            from sage.rings.ring import CommutativeRing
            d = X.codomain().ambient_space().ngens()
            if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field):
                v = list(v)
            else:
                try:
                    if isinstance(v.parent(), CommutativeRing):
                        v = [v]
                except AttributeError:
                    pass
            if not isinstance(v, (list,tuple)):
                raise TypeError("argument v (= %s) must be a scheme point, list, or tuple"%str(v))
            if len(v) != d and len(v) != d-1:
                raise TypeError("v (=%s) must have %s components"%(v, d))

            R = X.value_ring()
            v = Sequence(v, R)
            if len(v) == d-1:     # very common special case
                v.append(R(1))

            n = len(v)
            all_zero = True
            for i in range(n):
                last = n-1-i
                if v[last]:
                    all_zero = False
                    c = v[last]
                    if c == R.one():
                        break
                    for j in range(last):
                        v[j] /= c
                    v[last] = R.one()
                    break
            if all_zero:
                raise ValueError("%s does not define a valid point since all entries are 0"%repr(v))

            X.extended_codomain()._check_satisfies_equations(v)

        self._coords = tuple(v)
Exemplo n.º 29
0
    def __init__(self, number_field, proof=True, S=None):
        """
        Create a unit group of a number field.

        INPUT:

        - ``number_field`` - a number field
        - ``proof`` - boolean (default True): proof flag
        - ``S`` - tuple of prime ideals, or an ideal, or a single
          ideal or element from which an ideal can be constructed, in
          which case the support is used.  If None, the global unit
          group is constructed; otherwise, the S-unit group is
          constructed.

        The proof flag is passed to pari via the ``pari_bnf()`` function
        which computes the unit group.  See the documentation for the
        number_field module.

        EXAMPLES::

            sage: x = polygen(QQ)
            sage: K.<a> = NumberField(x^2-38)
            sage: UK = K.unit_group(); UK
            Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38
            sage: UK.gens()
            (u0, u1)
            sage: UK.gens_values()
            [-1, 6*a - 37]

            sage: K.<a> = QuadraticField(-3)
            sage: UK = K.unit_group(); UK
            Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
            sage: UK.gens()
            (u,)
            sage: UK.gens_values()
            [1/2*a + 1/2]

            sage: K.<z> = CyclotomicField(13)
            sage: UK = K.unit_group(); UK
            Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12
            sage: UK.gens()
            (u0, u1, u2, u3, u4, u5)
            sage: UK.gens_values() # random
            [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z]
            sage: SUK = UnitGroup(K,S=2); SUK
            S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),)

        TESTS:

        Number fields defined by non-monic and non-integral
        polynomials are supported (:trac:`252`);
        the representation depends on the PARI version::

            sage: K.<a> = NumberField(7/9*x^3 + 7/3*x^2 - 56*x + 123)
            sage: K.unit_group()
            Unit group with structure C2 x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
            sage: UnitGroup(K, S=tuple(K.primes_above(7)))
            S-unit group with structure C2 x Z x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 with S = (Fractional ideal (...),)
            sage: K.primes_above(7)[0] in (7/225*a^2 - 7/75*a - 42/25, 28/225*a^2 + 77/75*a - 133/25)
            True

        Conversion from unit group to a number field and back
        gives the right results (:trac:`25874`)::

            sage: K = QuadraticField(-3).composite_fields(QuadraticField(2))[0]
            sage: U = K.unit_group()
            sage: tuple(U(K(u)) for u in U.gens()) == U.gens()
            True
            sage: US = K.S_unit_group(3)
            sage: tuple(US(K(u)) for u in US.gens()) == US.gens()
            True

        """
        proof = get_flag(proof, "number_field")
        K = number_field
        pK = K.pari_bnf(proof)
        self.__number_field = K
        self.__pari_number_field = pK

        # process the parameter S:
        if not S:
            S = self.__S = ()
        else:
            if isinstance(S, list):
                S = tuple(S)
            if not isinstance(S, tuple):
                try:
                    S = tuple(K.ideal(S).prime_factors())
                except (NameError, TypeError, ValueError):
                    raise ValueError("Cannot make a set of primes from %s" %
                                     (S, ))
            else:
                try:
                    S = tuple(K.ideal(P) for P in S)
                except (NameError, TypeError, ValueError):
                    raise ValueError("Cannot make a set of primes from %s" %
                                     (S, ))
                if not all(P.is_prime() for P in S):
                    raise ValueError(
                        "Not all elements of %s are prime ideals" % (S, ))
            self.__S = S
            self.__pS = pS = [P.pari_prime() for P in S]

        # compute the fundamental units via pari:
        fu = [K(u, check=False) for u in pK.bnfunit()]
        self.__nfu = len(fu)

        # compute the additional S-unit generators:
        if S:
            self.__S_unit_data = pK.bnfsunit(pS)
            su = [K(u, check=False) for u in self.__S_unit_data[0]]
        else:
            su = []
        self.__nsu = len(su)
        self.__rank = self.__nfu + self.__nsu

        # compute a torsion generator and pick the 'simplest' one:
        n, z = pK[7][
            3]  # number of roots of unity and bnf.tu as in pari documentation
        n = ZZ(n)
        self.__ntu = n
        z = K(z, check=False)

        # If we replaced z by another torsion generator we would need
        # to allow for this in the dlog function!  So we do not.

        # Store the actual generators (torsion first):
        gens = [z] + fu + su
        values = Sequence(gens, immutable=True, universe=self, check=False)
        # Construct the abtract group:
        gens_orders = tuple([ZZ(n)] + [ZZ(0)] * (self.__rank))
        AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values,
                                              number_field)
Exemplo n.º 30
0
def d_basis(F, strat=True):
    r"""
    Return the `d`-basis for the Ideal ``F`` as defined in [BW93]_.

    INPUT:

    - ``F`` - an ideal
    - ``strat`` - use update strategy (default: ``True``)

    EXAMPLE::

        sage: from sage.rings.polynomial.toy_d_basis import d_basis
        sage: A.<x,y> = PolynomialRing(ZZ, 2)
        sage: f = -y^2 - y + x^3 + 7*x + 1
        sage: fx = f.derivative(x)
        sage: fy = f.derivative(y)
        sage: I = A.ideal([f,fx,fy])
        sage: gb = d_basis(I); gb
        [x - 2020, y - 11313, 22627]
    """
    R = F.ring()
    K = R.base_ring()

    G = set(inter_reduction(F.gens()))
    B = set(filter(lambda (x, y): x != y, [(f1, f2) for f1 in G for f2 in G]))
    D = set()
    C = set(B)

    LCM = R.monomial_lcm
    divides = R.monomial_divides
    divides_ZZ = lambda x, y: ZZ(x).divides(ZZ(y))

    while B != set():
        while C != set():
            f1, f2 = select(C)
            C.remove((f1, f2))
            lcm_lmf1_lmf2 = LCM(LM(f1), LM(f2))
            if not any( divides(LM(g), lcm_lmf1_lmf2) and \
                        divides_ZZ( LC(g), LC(f1) ) and \
                        divides_ZZ( LC(g), LC(f2) ) \
                        for g in G):
                h = gpol(f1, f2)
                h0 = h.reduce(G)
                if h0.lc() < 0:
                    h0 *= -1
                if not strat:
                    D = D.union([(g, h0) for g in G])
                    G.add(h0)
                else:
                    G, D = update(G, D, h0)
                G = inter_reduction(G)

        f1, f2 = select(B)
        B.remove((f1, f2))
        h = spol(f1, f2)
        h0 = h.reduce(G)
        if h0 != 0:
            if h0.lc() < 0:
                h0 *= -1
            if not strat:
                D = D.union([(g, h0) for g in G])
                G.add(h0)
            else:
                G, D = update(G, D, h0)

        B = B.union(D)
        C = D
        D = set()

    return Sequence(sorted(inter_reduction(G), reverse=True))