Exemplo n.º 1
0
    def integral_basis_of_unramified_subfield(self, precision=5):
        r"""
        Return an (approximate) integral basis of the maximal unramified subfield.

        INPUT:

        - ``precison`` -- a positive integer

        OUTPUT:

        A list `\alpha=(\alpha_0,\ldots,\alpha_{m-1})` of elements of `K_0`
        which approximate (with precision `p^N` an integral basis of the
        maximal unramified subfield.

        """
        if not hasattr(self, "_integral_basis_of_unramified_subfield") or precision > 5:
            m = self.inertia_degree()
            if m == 1:
                return [QQ.one()]

            p = self.p()
            fb = GF(p**m, 'zeta').polynomial()
            f = fb.change_ring(self.number_field())
            fx = f.derivative()
            vK = self.valuation()
            k = vK.residue_field()
            zetab = fb.change_ring(k).roots()[0][0]
            assert fb(zetab) == 0
            zeta = vK.lift(zetab)
            while vK(f(zeta)) <= precision:
                zeta = zeta - f(zeta)/fx(zeta)
                zeta = self.reduce(zeta, precision +1)
            # now zeta is an approximate generator of the maximal unramified subfield
            self._integral_basis_of_unramified_subfield = [self.reduce(zeta**i, precision +1) for i in range(m)]
        return self._integral_basis_of_unramified_subfield
def handle_term(n, den_tuple):
    r"""
    Entry point for reduction of generalized multiple zeta values into standard
    multiple zeta values.

    EXAMPLES::

        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import handle_term, is_convergent

        sage: M = Multizetas(QQ)

        sage: V1 = FreeModule(ZZ, 1)
        sage: v = V1((1,)); v.set_immutable()
        sage: dt = ((v,3),)
        sage: assert is_convergent(1, dt) and handle_term(1, dt) == M((3,))


        sage: V2 = FreeModule(ZZ, 2)
        sage: va = V2((1,0)); va.set_immutable()
        sage: vb = V2((0,1)); vb.set_immutable()
        sage: vc = V2((1,1)); vc.set_immutable()
        sage: dt = ((va,2), (vc,3))
        sage: assert is_convergent(2, dt) and handle_term(2, dt) == M((2,3))
        sage: dt1 = ((va,2),(vb,3))
        sage: dt2 = ((va,3),(vb,2))
        sage: assert is_convergent(2,dt1) and is_convergent(2,dt2) and handle_term(2, ((va,2), (vb,3))) == handle_term(2, ((va,3), (vb,2))) == M((2,)) * M((3,))

        sage: V3 = FreeModule(ZZ, 3)
        sage: va = V3((1,0,0)); va.set_immutable()
        sage: vb = V3((0,1,0)); vb.set_immutable()
        sage: vc = V3((0,0,1)); vc.set_immutable()
        sage: vd = V3((1,1,0)); vd.set_immutable()
        sage: ve = V3((1,0,1)); ve.set_immutable()
        sage: vf = V3((0,1,1)); vf.set_immutable()
        sage: vg = V3((1,1,1)); vg.set_immutable()
        sage: assert handle_term(3, ((va,2), (vd,3), (vg,4))) == M((2,3,4))
        sage: assert handle_term(3, ((va,2), (vb,3), (vc,4))) == handle_term(3, ((va,3), (vb,2), (vc,4))) == M((2,)) * M((3,)) * M((4,))
        sage: assert handle_term(3, ((va,1), (vc,2), (vd,3))) == handle_term(3, ((va,1), (vb,2), (ve,3))) == handle_term(3, ((va,2), (vb,1), (vf,3))) ==  M((2,)) * M((1,3))
    """
    if n == 1:
        M = Multizetas(QQ)
        ans = M.zero()
        for v, p in den_tuple:
            # sum (v[0]x)^p
            ans += QQ.one() / v[0]**p * M((p, ))
        return ans

    elif n == 2:
        dat = to_Z2(den_tuple)
        if dat is None:
            raise NotImplementedError("generalized mzv {}".format(den_tuple))
        return Z2(*dat)

    elif n == 3:
        dat = to_Z3(den_tuple)
        if dat is None:
            raise NotImplementedError("generalized mzv {}".format(den_tuple))
        return Z3(*dat)

    return _handle_term(den_tuple, n)
def kill_relation(n, den_tuple, i, relation):
    r"""
    Make calls to `apply_relation` until we get rid of term

    EXAMPLES::

        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import kill_relation

        sage: V = FreeModule(ZZ, 2)
        sage: va = V((1,0)); va.set_immutable()
        sage: vb = V((0,1)); vb.set_immutable()
        sage: vc = V((1,1)); vc.set_immutable()

        sage: den_tuple = ((va,2),(vb,3),(vc,4))
        sage: kill_relation(2, den_tuple, 2, [1,1,0])
        [(1, (((0, 1), 3), ((1, 1), 6))),
         (2, (((0, 1), 2), ((1, 1), 7))),
         (1, (((1, 0), 2), ((1, 1), 7))),
         (3, (((0, 1), 1), ((1, 1), 8))),
         (3, (((1, 0), 1), ((1, 1), 8)))]
    """
    assert len(relation) == len(den_tuple)
    assert 0 <= i < len(den_tuple)
    assert sum(relation[j] * den_tuple[j][0]
               for j in range(len(den_tuple))) == den_tuple[i][0]
    D = {den_tuple: QQ.one()}
    todo = [den_tuple]
    while todo:
        den_tuple = todo.pop(0)
        coeff1 = D.pop(den_tuple)
        for coeff, new_den_tuple in apply_relation(n, den_tuple, i, relation):
            coeff *= coeff1
            if new_den_tuple in D:
                D[new_den_tuple] += coeff
            elif any(not new_den_tuple[j][1] for j in range(len(den_tuple))):
                new_den_tuple = tuple(x for x in new_den_tuple if x[1])
                if new_den_tuple not in D:
                    D[new_den_tuple] = coeff
                else:
                    D[new_den_tuple] += coeff
            else:
                todo.append(new_den_tuple)
                D[new_den_tuple] = coeff

    return [(coeff, new_den_tuple) for new_den_tuple, coeff in D.items()]