Пример #1
0
    def symmetrizer(self):
        """
        Return the symmetrizer of ``self``.

        EXAMPLES::

            sage: cm = CartanMatrix([[2,-5],[-2,2]])
            sage: cm.symmetrizer()
            Finite family {0: 2, 1: 5}

        TESTS:

        Check that the symmetrizer computed from the Cartan matrix agrees
        with the values given by the Cartan type::

            sage: ct = CartanType(['B',4,1])
            sage: ct.symmetrizer()
            Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
            sage: ct.cartan_matrix().symmetrizer()
            Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
        """
        sym = self.is_symmetrizable(True)
        if not sym:
            raise ValueError("the Cartan matrix is not symmetrizable")
        iset = self.index_set()
        # The result from is_symmetrizable needs to be scaled
        # to integer coefficients
        from sage.arith.all import LCM
        from sage.rings.all import QQ
        scalar = LCM([QQ(x).denominator() for x in sym])
        return Family({iset[i]: ZZ(val * scalar) for i, val in enumerate(sym)})
Пример #2
0
    def padic_height(self, prec=20):
        r"""
        Return the canonical `p`-adic height function on the original curve.

        INPUT:

        - ``prec`` -- the `p`-adic precision, default is 20.

        OUTPUT:

        - A function that can be evaluated on rational points of `E`.

        EXAMPLES::

            sage: e = EllipticCurve('130a1')
            sage: eq = e.tate_curve(5)
            sage: h = eq.padic_height(prec=10)
            sage: P = e.gens()[0]
            sage: h(P)
            2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + O(5^9)

        Check that it is a quadratic function::

            sage: h(3*P)-3^2*h(P)
            O(5^9)
        """
        if not self.is_split():
            raise NotImplementedError(
                "The p-adic height is not implemented for non-split multiplicative reduction."
            )

        p = self._p

        # we will have to do it properly with David Harvey's _multiply_point(E, R, Q)
        n = LCM(self._E.tamagawa_numbers()) * (p - 1)

        # this function is a closure, I don't see how to doctest it (PZ)
        def _height(P, check=True):
            if check:
                assert P.curve(
                ) == self._E, "the point P must lie on the curve from which the height function was created"
            Q = n * P
            cQ = denominator(Q[0])
            q = self.parameter(prec=prec)
            nn = q.valuation()
            precp = prec + nn + 2
            uQ = self.lift(Q, prec=precp)
            si = self.__padic_sigma_square(uQ, prec=precp)
            q = self.parameter(prec=precp)
            nn = q.valuation()
            qEu = q / p**nn
            res = -(log(si * self._Csquare(prec=precp) / cQ) +
                    log(uQ)**2 / log(qEu)) / n**2
            R = Qp(self._p, prec)
            return R(res)

        return _height
Пример #3
0
    def __call__(self, g):
        """
        Evaluate ``self`` on a group element ``g``.

        OUTPUT:

        An element in
        :meth:`~sage.groups.abelian_gps.dual_abelian_group.DualAbelianGroup_class.base_ring`.

        EXAMPLES::

            sage: F = AbelianGroup(5, [2,3,5,7,8], names="abcde")
            sage: a,b,c,d,e = F.gens()
            sage: Fd = F.dual_group(names="ABCDE")
            sage: A,B,C,D,E = Fd.gens()
            sage: A*B^2*D^7
            A*B^2
            sage: A(a)
            -1
            sage: B(b)
            zeta840^140 - 1
            sage: CC(B(b))    # abs tol 1e-8
            -0.499999999999995 + 0.866025403784447*I
            sage: A(a*b)
            -1

        TESTS::

            sage: F = AbelianGroup(1, [7], names="a")
            sage: a, = F.gens()
            sage: Fd = F.dual_group(names="A", base_ring=GF(29))
            sage: A, = Fd.gens()
            sage: A(a)
            16
        """
        F = self.parent().base_ring()
        expsX = self.exponents()
        expsg = g.exponents()
        order = self.parent().gens_orders()
        N = LCM(order)
        order_not = [N / o for o in order]
        zeta = F.zeta(N)
        return F.prod(zeta**(expsX[i] * expsg[i] * order_not[i])
                      for i in range(len(expsX)))
Пример #4
0
    def __call__(self, g):
        """
        Evaluate ``self`` on a group element ``g``.

        OUTPUT:

        An element in
        :meth:`~sage.groups.abelian_gps.dual_abelian_group.DualAbelianGroup_class.base_ring`.

        EXAMPLES::

            sage: F = AbelianGroup(5, [2,3,5,7,8], names="abcde")
            sage: a,b,c,d,e = F.gens()
            sage: Fd = F.dual_group(names="ABCDE")
            sage: A,B,C,D,E = Fd.gens()
            sage: A*B^2*D^7
            A*B^2
            sage: A(a)
            -1
            sage: B(b)
            zeta840^140 - 1
            sage: CC(B(b))    # abs tol 1e-8
            -0.499999999999995 + 0.866025403784447*I
            sage: A(a*b)
            -1
        """
        F = self.parent().base_ring()
        expsX = self.exponents()
        expsg = g.exponents()
        order = self.parent().gens_orders()
        N = LCM(order)
        if is_ComplexField(F):
            from sage.symbolic.constants import pi
            I = F.gen()
            PI = F(pi)
            ans = prod([(2 * PI * I * expsX[i] * expsg[i] / order[i]).exp()
                        for i in range(len(expsX))])
            return ans
        ans = F(1)  ## assumes F is the cyclotomic field
        zeta = F.gen()
        for i in range(len(expsX)):
            order_noti = N / order[i]
            ans = ans * zeta**(expsX[i] * expsg[i] * order_noti)
        return ans
Пример #5
0
def spol(f,g):
    """
    Computes the S-polynomial of f and g.

    INPUT:

    -  ``f,g`` - polynomials

    OUTPUT:

    -  The S-polynomial of f and g.

    EXAMPLES::

        sage: R.<x,y,z> = PolynomialRing(QQ,3)
        sage: from sage.rings.polynomial.toy_buchberger import spol
        sage: spol(x^2 - z - 1, z^2 - y - 1)
        x^2*y - z^3 + x^2 - z^2
    """
    fg_lcm = LCM(LM(f),LM(g))
    return fg_lcm//LT(f)*f - fg_lcm//LT(g)*g
Пример #6
0
def select(P):
    """
    The normal selection strategy

    INPUT:

    - ``P`` - a list of critical pairs

    OUTPUT:

        an element of P

    EXAMPLES::

        sage: from sage.rings.polynomial.toy_buchberger import select
        sage: R.<x,y,z> = PolynomialRing(QQ,3, order='lex')
        sage: ps = [x^3 - z -1, z^3 - y - 1, x^5 - y - 2]
        sage: pairs = [[ps[i],ps[j]] for i in range(3) for j in range(i+1,3)]
        sage: select(pairs)
        [x^3 - z - 1, -y + z^3 - 1]
    """
    return min(P, key=lambda fi_fj: LCM(LM(fi_fj[0]), LM(fi_fj[1])).total_degree())
Пример #7
0
    def order(self):
        """
        Return the order of this element.

        OUTPUT:

        An integer or ``infinity``.

        EXAMPLES::

            sage: F = AbelianGroup(3,[7,8,9])
            sage: Fd = F.dual_group()
            sage: A,B,C = Fd.gens()
            sage: (B*C).order()
            72

            sage: F = AbelianGroup(3,[7,8,9]); F
            Multiplicative Abelian group isomorphic to C7 x C8 x C9
            sage: F.gens()[2].order()
            9
            sage: a,b,c = F.gens()
            sage: (b*c).order()
            72
            sage: G = AbelianGroup(3,[7,8,9])
            sage: type((G.0 * G.1).order())==Integer
            True
        """
        M = self.parent()
        order = M.gens_orders()
        L = self.exponents()
        N = LCM([
            order[i] / GCD(order[i], L[i]) for i in range(len(order))
            if L[i] != 0
        ])
        if N == 0:
            return infinity
        else:
            return ZZ(N)
Пример #8
0
    def level(self):
        r"""
        Determines the level of the quadratic form over a PID, which is a
        generator for the smallest ideal `N` of `R` such that N * (the matrix of
        2*Q)^(-1) is in R with diagonal in 2*R.

        Over `\ZZ` this returns a non-negative number.

        (Caveat: This always returns the unit ideal when working over a field!)

        EXAMPLES::

            sage: Q = QuadraticForm(ZZ, 2, range(1,4))
            sage: Q.level()
            8

            sage: Q1 = QuadraticForm(QQ, 2, range(1,4))
            sage: Q1.level()      # random
            UserWarning: Warning -- The level of a quadratic form over a field is always 1.  Do you really want to do this?!?
            1

            sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
            sage: Q.level()
            420

        """
        ## Try to return the cached level
        try:
            return self.__level
        except AttributeError:

            ## Check that the base ring is a PID
            if not isinstance(self.base_ring(), PrincipalIdealDomain):
                raise TypeError("Oops!  The level (as a number) is only defined over a Principal Ideal Domain.  Try using level_ideal().")


            ## Warn the user if the form is defined over a field!
            if self.base_ring().is_field():
                warn("Warning -- The level of a quadratic form over a field is always 1.  Do you really want to do this?!?")
                #raise RuntimeError, "Warning -- The level of a quadratic form over a field is always 1.  Do you really want to do this?!?"


            ## Check invertibility and find the inverse
            try:
                mat_inv = self.matrix()**(-1)
            except ZeroDivisionError:
                raise TypeError("Oops!  The quadratic form is degenerate (i.e. det = 0). =(")

            ## Compute the level
            inv_denoms = []
            for i in range(self.dim()):
                for j in range(i, self.dim()):
                    if (i == j):
                        inv_denoms += [denominator(mat_inv[i,j] / 2)]
                    else:
                        inv_denoms += [denominator(mat_inv[i,j])]
            lvl = LCM(inv_denoms)
            lvl = Ideal(self.base_ring()(lvl)).gen()
            ##############################################################
            ## To do this properly, the level should be the inverse of the
            ## fractional ideal (over R) generated by the entries whose
            ## denominators we take above. =)
            ##############################################################

            ## Normalize the result over ZZ
            if self.base_ring() == IntegerRing():
                lvl = abs(lvl)

            ## Cache and return the level
            self.__level = lvl
            return lvl
Пример #9
0
def update(G,B,h):
    """
    Update ``G`` using the list of critical pairs ``B`` and the
    polynomial ``h`` as presented in [BW93]_, page 230. For this,
    Buchberger's first and second criterion are tested.

    This function implements the Gebauer-Moeller Installation.

    INPUT:

    - ``G`` - an intermediate Groebner basis
    - ``B`` - a list of critical pairs
    - ``h`` - a polynomial

    OUTPUT:

        a tuple of an intermediate Groebner basis and a list of
        critical pairs

    EXAMPLES::

        sage: from sage.rings.polynomial.toy_buchberger import update
        sage: R.<x,y,z> = PolynomialRing(QQ,3)
        sage: set_verbose(0)
        sage: update(set(),set(),x*y*z)
        ({x*y*z}, set())
        sage: G,B = update(set(),set(),x*y*z-1)
        sage: G,B = update(G,B,x*y^2-1)
        sage: G,B
        ({x*y*z - 1, x*y^2 - 1}, {(x*y^2 - 1, x*y*z - 1)})
    """
    R = h.parent()

    C = set([(h,g) for g in G])
    D = set()

    while C != set():
        (h,g) = C.pop()

        lcm_divides = lambda rhs: R.monomial_divides( LCM(LM(h),LM(rhs[1])), LCM(LM(h),LM(g)))

        if R.monomial_pairwise_prime(LM(h),LM(g)) or \
           (\
               not any( lcm_divides(f) for f in C ) \
               and
               not any( lcm_divides(f) for f in D ) \
            ):
            D.add( (h,g) )

    E = set()

    while D != set():
        (h,g) = D.pop()
        if not R.monomial_pairwise_prime(LM(h),LM(g)):
            E.add( (h,g) )

    B_new = set()

    while B != set():
        g1,g2 = B.pop()
        if not R.monomial_divides( LM(h),  LCM(LM(g1),LM(g2)) ) or \
               R.monomial_lcm(LM(g1),LM( h)) == LCM(LM(g1),LM(g2)) or \
               R.monomial_lcm(LM( h),LM(g2)) == LCM(LM(g1),LM(g2)) :
            B_new.add( (g1,g2) )

    B_new = B_new.union( E )

    G_new = set()

    while G != set():
        g = G.pop()
        if not R.monomial_divides(LM(h), LM(g)):
            G_new.add(g)

    G_new.add(h)

    return G_new,B_new
Пример #10
0
def BCHCode(n, delta, F, b=0):
    r"""
    A 'Bose-Chaudhuri-Hockenghem code' (or BCH code for short) is the
    largest possible cyclic code of length n over field F=GF(q), whose
    generator polynomial has zeros (which contain the set)
    `Z = \{a^{b},a^{b+1}, ..., a^{b+delta-2}\}`, where a is a
    primitive `n^{th}` root of unity in the splitting field
    `GF(q^m)`, b is an integer `0\leq b\leq n-delta+1`
    and m is the multiplicative order of q modulo n. (The integers
    `b,...,b+delta-2` typically lie in the range
    `1,...,n-1`.) The integer `delta \geq 1` is called
    the "designed distance". The length n of the code and the size q of
    the base field must be relatively prime. The generator polynomial
    is equal to the least common multiple of the minimal polynomials of
    the elements of the set `Z` above.

    Special cases are b=1 (resulting codes are called 'narrow-sense'
    BCH codes), and `n=q^m-1` (known as 'primitive' BCH
    codes).

    It may happen that several values of delta give rise to the same
    BCH code. The largest one is called the Bose distance of the code.
    The true minimum distance, d, of the code is greater than or equal
    to the Bose distance, so `d\geq delta`.

    EXAMPLES::

        sage: FF.<a> = GF(3^2,"a")
        sage: x = PolynomialRing(FF,"x").gen()
        sage: L = [b.minpoly() for b in [a,a^2,a^3]]; g = LCM(L)
        sage: f = x^(8)-1
        sage: g.divides(f)
        True
        sage: C = codes.CyclicCode(8,g); C
        Linear code of length 8, dimension 4 over Finite Field of size 3
        sage: C.minimum_distance()
        4
        sage: C = codes.BCHCode(8,3,GF(3),1); C
        Linear code of length 8, dimension 4 over Finite Field of size 3
        sage: C.minimum_distance()
        4
        sage: C = codes.BCHCode(8,3,GF(3)); C
        Linear code of length 8, dimension 5 over Finite Field of size 3
        sage: C.minimum_distance()
        3
        sage: C = codes.BCHCode(26, 5, GF(5), b=1); C
        Linear code of length 26, dimension 10 over Finite Field of size 5

    """
    q = F.order()
    R = IntegerModRing(n)
    m = R(q).multiplicative_order()
    FF = GF(q**m, "z")
    z = FF.gen()
    e = z.multiplicative_order() / n
    a = z**e  # order n
    P = PolynomialRing(F, "x")
    x = P.gen()
    L1 = []
    for coset in R.cyclotomic_cosets(q, range(b, b + delta - 1)):
        L1.extend(P((a**j).minpoly()) for j in coset)
    g = P(LCM(L1))

    if not (g.divides(x**n - 1)):
        raise ValueError("BCH codes does not exist with the given input.")
    return CyclicCodeFromGeneratingPolynomial(n, g)