Beispiel #1
0
def CRT_nf(reslist, Ilist, check=True):
    r"""
    Solve Chinese remainder problem over a number field.

    INPUT:

    - ``reslist`` -- a list of residues, i.e. integral number field elements

    - ``Ilist`` -- a list of integral ideas, assumed pairsise coprime

    - ``check`` (boolean, default True) -- if True, result is checked

    OUTPUT:

    An integral element x such that x-reslist[i] is in Ilist[i] for all i.
    """
    n = len(reslist)
    if n == 0:
        # we have no parent field so this is all we can do
        return 0
    if n == 1:
        return reslist[0]
    if n > 2:
        # use induction / recursion
        x = CRT_nf([reslist[0], CRT_nf(reslist[1:], Ilist[1:])],
                   [Ilist[0], prod(Ilist[1:])])
        if check:
            check_CRT_nf(reslist, Ilist, x)
        return x
    # now n=2
    r = Ilist[0].element_1_mod(Ilist[1])
    x = ((1 - r) * reslist[0] + r * reslist[1]).mod(prod(Ilist))
    if check:
        check_CRT_nf(reslist, Ilist, x)
    return x
Beispiel #2
0
def factorization(original_poly):
    poly = ZZT(original_poly)
    assert poly[0] == 1
    if poly == 1:
        return [1]
    try:
        facts = poly.factor()
    except NotImplementedError:
        try:
            # try to sort out the memory leak
            PolynomialRing(
                ZZ, 'T',
                implementation='NTL')([1] + [0] * (len(original_poly) - 2) +
                                      [1])._pari_with_name().factor()
            facts = PolynomialRing(
                ZZ, 'T', implementation='NTL')(original_poly).factor()
        except NotImplementedError:
            raise
    # if the factor is -1+T^2, replace it by 1-T^2
    # this should happen an even number of times, mod powers
    out = [[-g if g[0] == -1 else g, e] for g, e in facts]
    assert prod(
        g**e
        for g, e in out) == poly, "%s != %s" % (prod([g**e]
                                                     for g, e in out), poly)
    return [[g.list(), e] for g, e in out]
Beispiel #3
0
def CRT_nf(reslist, Ilist, check=True):
    r"""
    Solve Chinese remainder problem over a number field.

    INPUT:

    - ``reslist`` -- a list of residues, i.e. integral number field elements

    - ``Ilist`` -- a list of integral ideas, assumed pairsise coprime

    - ``check`` (boolean, default True) -- if True, result is checked

    OUTPUT:

    An integral element x such that x-reslist[i] is in Ilist[i] for all i.
    """
    n = len(reslist)
    if n == 0:
        # we have no parent field so this is all we can do
        return 0
    if n == 1:
        return reslist[0]
    if n > 2:
        # use induction / recursion
        x = CRT_nf([reslist[0], CRT_nf(reslist[1:], Ilist[1:])],
                   [Ilist[0], prod(Ilist[1:])])
        if check:
            check_CRT_nf(reslist, Ilist, x)
        return x
    # now n=2
    r = Ilist[0].element_1_mod(Ilist[1])
    x = ((1 - r) * reslist[0] + r * reslist[1]).mod(prod(Ilist))
    if check:
        check_CRT_nf(reslist, Ilist, x)
    return x
Beispiel #4
0
def upper_bound_index_cusps_in_JG_torsion(G, d, bound=60):
    """
    INPUT:
        
    - G - a congruence subgroup
    - d - integer, the size of the rational cuspidal subgroup
    - bound (optional, default = 60) - the bound for the primes p up to which to use
      the hecke matrix `T_p - <p> - p` for bounding the torsion subgroup
    
    OUTPUT:
        
    - an integer `i` such that `(\#J_G(\QQ)_{tors})/d` is a divisor of `i`.
    
    EXAMPLES::

        sage: from mdsage import *
        sage: d = rational_cuspidal_classgroup(Gamma1(23)).cardinality()
        sage: upper_bound_index_cusps_in_JG_torsion(Gamma1(23),d)
        1

    """
    N = G.level()
    M = ModularSymbols(G)
    Sint = cuspidal_integral_structure(M)
    kill_mat = (M.star_involution().matrix().restrict(Sint) - 1)
    kill = kill_mat.transpose().change_ring(ZZ).row_module()
    for p in prime_range(3, bound):
        if not N % p == 0:
            kill += kill_torsion_coprime_to_q(
                p, M).restrict(Sint).change_ring(ZZ).transpose().row_module()
        if kill.matrix().is_square() and kill.matrix().determinant() == d:
            #print p
            break
    kill_mat = kill.matrix().transpose()
    #print N,"index of torsion in stuff killed",kill.matrix().determinant()/d
    if kill.matrix().determinant() == d:
        return 1

    pm = integral_period_mapping(M)
    period_images1 = [
        sum([M.coordinate_vector(M([c, infinity])) for c in cusps]) * pm
        for cusps in galois_orbits(G)
    ]

    m = (Matrix(period_images1) * kill_mat).stack(kill_mat)
    diag = m.change_ring(ZZ).echelon_form().diagonal()
    #print diag,prod(diag)
    assert prod(diag) == kill.matrix().determinant() / d

    period_images2 = [
        M.coordinate_vector(M([c, infinity])) * pm for c in G.cusps()
        if c != Cusp(oo)
    ]
    m = (Matrix(period_images2) * kill_mat).stack(kill_mat)
    m, denom = m._clear_denom()
    diag = (m.change_ring(ZZ).echelon_form() / denom).diagonal()
    #print diag
    #print prod(i.numerator() for i in diag),"if this is 1 then :)"
    return prod(i.numerator() for i in diag)
Beispiel #5
0
    def from_factors(factors, data={}):
        """
        one may pass precomputed data via optional data parameter, e.g., euler factors
        """
        assert len(factors) >= 2
        factors.sort(key = lambda elt: (elt.degree, elt.conductor, elt.positive_zeros_arb[0]))
        data['motivic_weight'] = factors[0].motivic_weight
        assert all(data['motivic_weight'] == elt.motivic_weight for elt in factors)
        data['order_of_vanishing'] = sum(elt.order_of_vanishing for elt in factors)
        data['positive_zeros_arb'] = sorted(sum(elt.positive_zeros_arb for elt in factors, []))
        data['conductor'] = prod(elt.conductor for elt in factors)


        if all(hasattr(elt, 'Lhash') for elt in factors):
            data['Lhash'] = ','.join(elt.Lhash)

        if all(hasattr(elt, 'label') for elt in factors):
            data['factors'] = [elt.label for elt in factors]

        if all(hasattr(elt, 'trace_hash') for elt in factors):
            data['trace_hash'] = sum(elt.trace_hash for elt in factors) % 0x1FFFFFFFFFFFFFFF # mod 2^61 -1

        if all(hasattr(elt, 'leading_term_arb') for elt in factors):
            data['leading_term_arb'] = prod(elt.leading_term_arb)

        if all(hasattr(elt, 'root_number_acb') for elt in factors):
            data['root_number_acb'] = prod(elt.leading_term_arbroot_number_acb)
        else:
            # we will use this for comparisons
            arg = sum(elt.root_angle for elt in factors) % 1
            while arg > 0.5:
                arg -= 1
            while arg >= -0.5:
                arg += 1
            data['root_angle'] = arg

        if all(hasattr(elt, 'special_values_acb') for elt in factors):
            data['special_values_acb'] = [prod(sv) for sv in zip(*(elt.special_values_acb for elt in factors))]

        if all(hasattr(elt, 'plot_delta') and hasattr(elt, 'plot_values') for elt in factors):
            factor_plot_values = [ [ ( j * elt.plot_delta,  z) for j, z in enumerate(elt.values) ] for elt in factors]
            interpolations = [spline(elt) for elt in factor_plot_values]
            plot_range = 64.0/data['degree']
            data['plot_delta'] = plot_delta = plot_range/256
            # we cannot hope to get a finer resolution
            assert data['plot_delta'] >= max(elt.plot_delta for elt in factors)
            # we don't want to extrapolate data
            assert all(plot_range <= elt[-1][0] for elt in factor_plot_values)
            data['plot_values'] = [prod([elt(i) for elt in interpolations]) for i in srange(0, plot_range + plot_delta, plot_delta)]
            assert len(data['plot_values']) == 257

        if all(hasattr(elt, 'gamma_factors') for elt in factors):
            data['gamma_factors'] = [sum(elt['gamma_factors'][i] for elt in factors)
                                     for i in range(2)]


        return lfunction_element(data)
Beispiel #6
0
def lambda_helper(phi, NN, p=pp):
    """ Helper function for affine and projective factorization probabilities.
    """
    d = deg_fp(phi)
    return prod([
        prod([NN(j, p) - i for i in range(m1(phi, j))]) //
        prod([factorial(m2(phi, [j, i])) for i in range(1, d + 1)])
        for j in range(1, d + 1)
    ])
Beispiel #7
0
    def dbd(self, d):
        """
        Return matrix of <d>.

        INPUT:

            - `d` -- integer

        OUTPUT:

            - a matrix modulo 2

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.dbd(2)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.dbd(2)^14==1
            True
            sage: C.dbd(2)[0]
            (0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1)
        """
        d=ZZ(d)
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print "dbd start"
        try: return self._dbd[d % self.p]
        except AttributeError: pass
        # Find generators of the integers modulo p:
        gens = Integers(self.p).unit_gens()
        orders = [g.multiplicative_order() for g in gens]
        # Compute corresponding <z> operator on integral cuspidal modular symbols
        
        X = [self.M.diamond_bracket_operator(z).matrix() for z in gens]
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "create d"
        X = [x.restrict(self.S_integral, check=False) for x in X]
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "restrict d"
        
        X = [matrix_modp(x) for x in X]
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "mod d"
        # Take combinations to make list self._dbd of all dbd's such that
        # self._dbd[d] = <d>
        from itertools import product
        v = [None] * self.p
        for ei in product(*[range(i) for i in orders]):
            di = prod(g**e for e,g in zip(ei,gens)).lift()
            m = prod(g**e for e,g in zip(ei,X))
            v[di] = m
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "mul"

        assert v.count(None) == (self.p-euler_phi(self.p))
        self._dbd = v
        if self.verbose: print "time and mem", cputime(tm), get_memory_usage(mem), "bdb finnished"
        return v[d % self.p]
Beispiel #8
0
    def dbd(self, d):
        """
        Return matrix of <d>.

        INPUT:

            - `d` -- integer

        OUTPUT:

            - a matrix modulo 2

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.dbd(2)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.dbd(2)^14==1
            True
            sage: C.dbd(2)[0]
            (0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1)
        """
        d=ZZ(d)
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("dbd start")
        try: return self._dbd[d % self.p]
        except AttributeError: pass
        # Find generators of the integers modulo p:
        gens = Integers(self.p).unit_gens()
        orders = [g.multiplicative_order() for g in gens]
        # Compute corresponding <z> operator on integral cuspidal modular symbols
        
        X = [self.M.diamond_bracket_operator(z).matrix() for z in gens]
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "create d")
        X = [x.restrict(self.S_integral, check=False) for x in X]
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "restrict d")
        
        X = [matrix_modp(x) for x in X]
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "mod d")
        # Take combinations to make list self._dbd of all dbd's such that
        # self._dbd[d] = <d>
        from itertools import product
        v = [None] * self.p
        for ei in product(*[list(range(i)) for i in orders]):
            di = prod(g**e for e,g in zip(ei,gens)).lift()
            m = prod(g**e for e,g in zip(ei,X))
            v[di] = m
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "mul")

        assert v.count(None) == (self.p-euler_phi(self.p))
        self._dbd = v
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "bdb finnished")
        return v[d % self.p]
Beispiel #9
0
def upper_bound_index_cusps_in_JG_torsion(G,d, bound = 60):
    """
    INPUT:
        
    - G - a congruence subgroup
    - d - integer, the size of the rational cuspidal subgroup
    - bound (optional, default = 60) - the bound for the primes p up to which to use
      the hecke matrix `T_p - <p> - p` for bounding the torsion subgroup
    
    OUTPUT:
        
    - an integer `i` such that `(\#J_G(\QQ)_{tors})/d` is a divisor of `i`.
    
    EXAMPLES::

        sage: from mdsage import *
        sage: d = rational_cuspidal_classgroup(Gamma1(23)).cardinality()
        sage: upper_bound_index_cusps_in_JG_torsion(Gamma1(23),d)
        1

    """
    N = G.level()
    M=ModularSymbols(G);
    Sint=cuspidal_integral_structure(M)
    kill_mat=(M.star_involution().matrix().restrict(Sint)-1)
    kill=kill_mat.transpose().change_ring(ZZ).row_module()
    for p in prime_range(3,bound):
        if not N % p ==0:
            kill+=kill_torsion_coprime_to_q(p,M).restrict(Sint).change_ring(ZZ).transpose().row_module()
        if kill.matrix().is_square() and kill.matrix().determinant()==d:
            #print p
            break
    kill_mat=kill.matrix().transpose()
    #print N,"index of torsion in stuff killed",kill.matrix().determinant()/d
    if kill.matrix().determinant()==d:
        return 1
        
    pm=integral_period_mapping(M)
    period_images1=[sum([M.coordinate_vector(M([c,infinity])) for c in cusps])*pm for cusps in galois_orbits(G)]
    
    m=(Matrix(period_images1)*kill_mat).stack(kill_mat)
    diag=m.change_ring(ZZ).echelon_form().diagonal()
    #print diag,prod(diag)
    assert prod(diag)==kill.matrix().determinant()/d
    
    period_images2=[M.coordinate_vector(M([c,infinity]))*pm for c in G.cusps() if c != Cusp(oo)]
    m=(Matrix(period_images2)*kill_mat).stack(kill_mat)
    m,denom=m._clear_denom()
    diag=(m.change_ring(ZZ).echelon_form()/denom).diagonal()
    #print diag
    #print prod(i.numerator() for i in diag),"if this is 1 then :)"
    return prod(i.numerator() for i in diag)
Beispiel #10
0
def monom(par):
    '''
    Given a partition ``par`` = :math:`\\left[0^{i_0},1^{i_1},\\ldots,n^{i_n}\\right]` return a monomial (in Multivariate Polynomial Ring over Q) :math:`{t_0}^{i_0}\\cdot\\ldots\\cdot{t_n}^{i_n} \\big/ {i_0}!\\cdot\\ldots\\cdot{i_n}!`.
    
    EXAMPLE:
    
    Here we generate all monomials of weight 5::
    
        sage: from cvolume.series import monom
        sage: [monom(l) for l in Partitions(5)]
        [t4, t0*t3, t1*t2, 1/2*t0^2*t2, 1/2*t0*t1^2, 1/6*t0^3*t1, 1/120*t0^5]
    '''
    exp = par.to_exp()
    return prod(ZZ(1)/factorial(k) for k in exp)*prod([T_vars[i-1] for i in par])
Beispiel #11
0
def mittag_leffler_e(alpha, beta=1):
    alpha = QQ.coerce(alpha)
    if alpha <= QQ.zero():
        raise ValueError
    num, den = alpha.numerator(), alpha.denominator()
    dop0 = prod(alpha * x * Dx + beta - num + t for t in range(num)) - x**den
    expo = dop0.indicial_polynomial(x).roots(QQ, multiplicities=False)
    pre = prod((x * Dx - k) for k in range(den) if QQ(k) not in expo)
    dop = pre * dop0  # homogenize
    dop = dop.numerator().primitive_part()
    expo = sorted(dop.indicial_polynomial(x).roots(QQ, multiplicities=False))
    assert len(expo) == dop.order()
    ini = [(1 / funs.gamma(alpha * k + beta) if k in ZZ else 0) for k in expo]
    return IVP(0, dop, ini)
Beispiel #12
0
    def __get_lcm(self, input):
        r'''
            Auxiliary method for computing the lcm of a sequence.

            Private method for computing a common multiple of a sequence given in ``input``.
            This method relies on the Sage implementation of ``lcm`` and, if this fails tries
            to compute a least common multiple using the GCD of the sequence:

            .. MATH::

                lcm(a_1,\ldots,a_n) = \frac{a_1 \cdots a_n}{gcd(a_1,\ldots,a_n)}.

            In case the computation of the gcd fails again, we just return the product of all
            the elements of the input.
        '''
        try:
            return lcm(input)
        except AttributeError:
            ## No lcm for this class, implementing a general lcm
            try:
                ## Relying on gcd
                p = self.__parent
                res = p(1)
                for el in input:
                    res = p((res * el) / gcd(res, el))
                return res
            except AttributeError:
                ## Returning the product of everything
                return prod(input)
Beispiel #13
0
    def _prod_f_A_G(Gs, kappa, psi, psi2):
        """
        Used in the computation of product. Do not call directly.
        """
        result = 1
        G = Gs.G.strataG
        for v in range(1, G.num_vertices() + 1):
            result *= prod(
                (sum((kappa.get((j, w), 0) for w in Gs.alpha_inv[v]))**f
                 for j, f in G.kappa_on_v(v))) * prod(
                     (Gs.psi_no_loop(edge, v, ex, psi)
                      for edge, ex in G.psi_no_loop_on_v(v))) * prod(
                          (Gs.psi_loop(edge, v, ex1, ex2, psi, psi2)
                           for edge, ex1, ex2 in G.psi_loop_on_v(v)))

        return result
    def __init__(self, tiling_engine, bits_prec=53):

        self.RIF = RealIntervalField(bits_prec)
        self.CIF = ComplexIntervalField(bits_prec)

        self.baseTetInCenter = FinitePoint(
            self.CIF(tiling_engine.baseTetInCenter.z),
            self.RIF(tiling_engine.baseTetInCenter.t))

        self.generator_matrices = {
            g: m.change_ring(self.CIF)
            for g, m in tiling_engine.mcomplex.GeneratorMatrices.items()
        }

        self.max_values = {}

        for tile in tiling_engine.all_tiles():
            if tile.word:
                matrix = prod(self.generator_matrices[g] for g in tile.word)
                tileCenter = FinitePoint(self.CIF(tile.center.z),
                                         self.RIF(tile.center.t))
                err = tileCenter.dist(
                    self.baseTetInCenter.translate_PSL(matrix)).upper()
                l = len(tile.word)
                self.max_values[l] = max(err, self.max_values.get(l, err))
    def __init__(self, tiling_engine, bits_prec=2 * 53):
        self.RIF = RealIntervalField(bits_prec)
        self.CIF = ComplexIntervalField(bits_prec)

        self.baseTetInCenter = vector(
            self.RIF,
            complex_and_height_to_R13_time_vector(
                tiling_engine.baseTetInCenter.z,
                tiling_engine.baseTetInCenter.t))

        self.generator_matrices = {
            g: matrix(self.RIF, PSL2C_to_O13(m))
            for g, m in tiling_engine.mcomplex.GeneratorMatrices.items()
        }

        self.max_values = {}

        for tile in tiling_engine.all_tiles():
            if tile.word:
                m = prod(self.generator_matrices[g] for g in tile.word)
                tileCenter = vector(
                    self.RIF,
                    complex_and_height_to_R13_time_vector(
                        tile.center.z, tile.center.t))

                #print("=====")
                #print(tileCenter)
                #print(m * self.baseTetInCenter)
                #print(inner_prod(m * self.baseTetInCenter, tileCenter).endpoints())

                err = my_dist(m * self.baseTetInCenter, tileCenter).upper()
                l = len(tile.word)
                self.max_values[l] = max(err, self.max_values.get(l, err))
def fractional_CRT_split(residues, ps_roots, K, BI_coordinates = None):
    if K is QQ:
        return fractional_CRT_QQ(residues, ps_roots);

    OK = K.ring_of_integers();
    BOK = OK.basis();

    residues_ZZ = [ r.lift() for r in residues];
    primes = [p for p, _ in ps_roots];
    lift = CRT_list(residues_ZZ, primes);
    lift_coordinates = OK.coordinates(lift);

    if BI_coordinates is None:
        p_ideals = [ OK.ideal(p, K.gen() - root) for p, root in ps_roots ];
        I = prod(p_ideals);
        BI = I.basis(); # basis as a ZZ-module
        BI_coordinates = [ OK.coordinates(b) for b in BI ];

    M = Matrix(Integers(), [ [ kronecker_delta(i,j) for j,_ in enumerate(BOK) ] + [ lift_coordinates[i] ] + [ b[i] for b in BI_coordinates ] for i in range(len(BOK)) ])
    # v = short_vector
    Kernel_Basis =  Matrix(Integers(), M.transpose().kernel().basis())
    v =Kernel_Basis.LLL()[0];
    #print v[:len(BOK)]
    if v[len(BOK)] == 0:
        return 0;
    return (-1/v[len(BOK)]) * sum( v[i] * b for i, b in enumerate(BOK));
Beispiel #17
0
def _sqrt(f):
    if not f:
        return f
    li = list(f.factor())
    if any(e % 2 for _, e in li):
        raise ValueError('not a square')
    return f.parent(prod(a**(e//2) for (a,e) in li))
def _perform_word_moves(matrices, G):
    mats = [None] + matrices
    moves = G._word_moves()
    while moves:
        a = moves.pop(0)
        if a >= len(mats):  # new generator added
            n = moves.index(a)  # end symbol location
            word, moves = moves[:n], moves[n + 1:]
            mats.append(
                prod([mats[g] if g > 0 else _adjoint2(mats[-g])
                      for g in word]))
        else:
            b = moves.pop(0)
            if a == b:  # generator removed
                mats[a] = mats[-1]
                mats = mats[:-1]
            elif a == -b:  # invert generator
                mats[a] = _adjoint2(mats[a])
            else:  #handle slide
                A, B = mats[abs(a)], mats[abs(b)]
                if a * b < 0:
                    B = _adjoint2(B)
                mats[abs(a)] = A * B if a > 0 else B * A

    return mats[1:G.num_generators() + 1]
Beispiel #19
0
def HermiteInterpolation(points_list):
    """
    return a polynomial that pass trough the given points with the given derivatives.

    Each element of points_list is a triple
    (x,y,d)
    and the given polynomial satisfies P(x)=y and P'(x)=d

    EXAMPLES :

    sage : P=HermiteInterpolation( [  (1,14,7),(3,64,51),(-2,-16,31)    ] )
    sage: P.simplify_full()
    2*x^3 - x^2 + 3*x + 10

    """
    x = var('x')
    n = len(points_list)
    xx = {i: points_list[i][0] for i in range(0, n)}
    y = {i: points_list[i][1] for i in range(0, n)}
    d = {i: points_list[i][2] for i in range(0, n)}

    b = {i: (x - xx[i])**2 for i in range(0, n)}

    Q = {}
    for j in range(0, n):
        Q[j] = prod([b[i] for i in range(0, n) if i <> j])
    P = {}
    for j in range(0, n):
        parenthese = 1 - (x - xx[j]) * Q[j].diff(x)(xx[j]) / Q[j](xx[j])
        P[j] = (Q[j](x) / Q[j](xx[j])) * (parenthese * y[j] +
                                          (x - xx[j]) * d[j])
    f = sum(P.values())
    return phyFunction(f.expand())
Beispiel #20
0
 def pgl2_matrix_for_path(self, p):
     if p:
         return prod([self.pgl2_matrix_for_edge(e) for e in p[::-1]])
     else:
         RF = self.vertex_gram_matrices[0].base_ring()
         CF = RF.complex_field()
         return matrix.identity(CF, 2)
Beispiel #21
0
def global_minimality_class(E):
    r"""
    Returns the ideal class representing the obstruction to this
    elliptic curve having a global minimal model.

    INPUT:

    - ``E`` -- an elliptic curve over a number field

    OUTPUT:

    An ideal class of the base number field, which is trivial if and
    only if E has a global minimal model, and which can be used to
    find global and semi-global minimal models.
    """
    K = E.base_field()
    Cl = K.class_group()
    if K.class_number() == 1:
        return Cl(1)
    D = E.discriminant()
    dat = E.local_data()
    primes = [d.prime() for d in dat]
    vals = [d.discriminant_valuation() for d in dat]
    I = prod([P ** ((D.valuation(P) - v) // 12) for P, v in zip(primes, vals)],
             E.base_field().ideal(1))
    return Cl(I)
def NonCubicSet(K,S, verbose=False):
    u = -1 if K==QQ else  K(K.unit_group().torsion_generator())
    from KSp import IdealGenerator
    Sx = [u] + [IdealGenerator(P) for P in S]
    r = len(Sx)
    d123 = r + binomial(r,2) + binomial(r,3)
    vecP = vec123(K,Sx)
    A = Matrix(GF(2),0,d123)
    N = prod(S,1)

    primes = primes_iter(K,None)
    T = []
    while A.rank() < d123:
        p = primes.next()
        while p.divides(N):
            p = primes.next()
        v = vecP(p)
        if verbose:
            print("v={}".format(v))
        A1 = A.stack(vector(v))
        if A1.rank() > A.rank():
            A = A1
            T.append(p)
            if verbose:
                print("new A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols()))
                print("T increases to {}".format(T))
    return T
Beispiel #23
0
def get_T2(K, S, unit_first=True, verbose=False):
   u = -1 if K==QQ else  K(K.unit_group().torsion_generator())
   from KSp import IdealGenerator
   Sx = [IdealGenerator(P) for P in S]
   if unit_first:
      Sx = [u] + Sx
   else:
      Sx = Sx + [u]
   r = len(Sx)
   r2 = r*(r-1)//2
   N = prod(S,1)
   T2 = {}
   primes = primes_iter(K,1)
   p = primes.next()
   while len(T2)<r+r2:
      p = primes.next()
      while p.divides(N):
         p = primes.next()
      # Compute the values alpha_p(Delta) for Delta in Sx:
      ro = alphalist(p,Sx)
      # Compute the set I(P) of i for which alpha_p(Delta_i)=1:
      ij = Set([i for i,vi in enumerate(ro) if vi])
      if verbose:
         print("P={}, I(P)={}".format(p,ij))
      # Keep I(p) and p if #I(p)=1 or 2 and it's a new subset@
      if len(ij) in [1,2] and not ij in T2:
         T2[ij] = p
   return T2
 def __init__(self, K, F, minimal_ramification=1):
     minimal_ramification = ZZ(minimal_ramification)
     # print "entering WeakPadicGaloisExtension with"
     # print "F = %s"%F
     # if F is a polynomial, replace it by the list of its irreducible factors
     # if isinstance(F, Polynomial):
     #     F = [f for f, m in F.factor()]
     assert K.is_Qp(), "for the moment, K has to be Q_p"
     # assert not K.p().divides(minimal_ramification), "minimal_ramification has to be prime to p"
     if not isinstance(F, Polynomial):
         if F == []:
             F = PolynomialRing(K.number_field(), 'x')(1)
         else:
             F = prod(F)
     self._base_field = K
     L = K.weak_splitting_field(F)
     e = ZZ(L.absolute_ramification_degree() /
            K.absolute_ramification_degree())
     if not minimal_ramification.divides(e):
         # enlarge the absolute ramification index of vL
         # such that minimal_ramification divides e(vL/vK):
         m = ZZ(minimal_ramification / e.gcd(minimal_ramification))
         # assert not self.p().divides(m), "p = %s, m = %s, e = %s,\nminimal_ramification = %s"%(self.p(), m, e, minimal_ramification)
         L = L.ramified_extension(m)
         # if m was not prime to p, L/K may not be weak Galois anymore
     else:
         m = ZZ(1)
     self._extension_field = L
     self._ramification_degree = e * m
     self._degree = ZZ(L.absolute_degree() / K.absolute_degree())
     self._inertia_degree = ZZ(L.absolute_inertia_degree() /
                               K.absolute_inertia_degree())
     assert self._degree == self._ramification_degree * self._inertia_degree
Beispiel #25
0
    def cardinality(self):
        r"""
        Return the cardinality of self

        EXAMPLES::

            sage: S = Subsets([1,1,2,3],submultiset=True)
            sage: S.cardinality()
            12
            sage: len(S.list())
            12

            sage: S = Subsets([1,1,2,2,3],submultiset=True)
            sage: S.cardinality()
            18
            sage: len(S.list())
            18

            sage: S = Subsets([1,1,1,2,2,3],submultiset=True)
            sage: S.cardinality()
            24
            sage: len(S.list())
            24
        """
        from sage.all import prod
        return Integer(prod(k + 1 for k in self._d.values()))
Beispiel #26
0
def taylor_processor_factored(new_ring, Phi, scalar, alpha, I, omega):
    k = alpha.nrows() - 1
    tau = SR.var('tau')
    y = [SR('y%d' % i) for i in range(k + 1)]

    R = PolynomialRing(QQ, len(y), y)
    beta = [a * Phi for a in alpha]

    ell = len(I)

    def f(i):
        if i == 0:
            return QQ(scalar) * y[0] * exp(tau * omega[0])
        elif i in I:
            return tau / (1 - exp(tau * omega[i]))
        else:
            return 1 / (1 - y[i] * exp(tau * omega[i]))

    H = [
        f(i).series(tau, ell + 1).truncate().collect(tau) for i in range(k + 1)
    ]

    for i in range(k + 1):
        H[i] = [H[i].coefficient(tau, j) for j in range(ell + 1)]

    r = []

    # Get coefficient of tau^ell in prod(H)

    for w in NonnegativeCompositions(ell, k + 1):
        r = prod(
            CyclotomicRationalFunction.from_split_expression(H[i][
                w[i]], y, R).monomial_substitution(new_ring, beta)
            for i in range(k + 1))
        yield r
Beispiel #27
0
    def cardinality(self):
        r"""
        Return the cardinality of self

        EXAMPLES::

            sage: S = Subsets([1,1,2,3],submultiset=True)
            sage: S.cardinality()
            12
            sage: len(S.list())
            12

            sage: S = Subsets([1,1,2,2,3],submultiset=True)
            sage: S.cardinality()
            18
            sage: len(S.list())
            18

            sage: S = Subsets([1,1,1,2,2,3],submultiset=True)
            sage: S.cardinality()
            24
            sage: len(S.list())
            24
        """
        from sage.all import prod
        return Integer(prod(k+1 for k in self._d.values()))
Beispiel #28
0
def global_minimality_class(E):
    r"""
    Returns the ideal class representing the obstruction to this
    elliptic curve having a global minimal model.

    INPUT:

    - ``E`` -- an elliptic curve over a number field

    OUTPUT:

    An ideal class of the base number field, which is trivial if and
    only if E has a global minimal model, and which can be used to
    find global and semi-global minimal models.
    """
    K = E.base_field()
    Cl = K.class_group()
    if K.class_number() == 1:
        return Cl(1)
    D = E.discriminant()
    dat = E.local_data()
    primes = [d.prime() for d in dat]
    vals = [d.discriminant_valuation() for d in dat]
    I = prod([P**((D.valuation(P) - v) // 12) for P, v in zip(primes, vals)],
             E.base_field().ideal(1))
    return Cl(I)
Beispiel #29
0
def operator(Poly):
    '''
    Return the result of application of :math:`\\mathcal{Z}`-operator to the polynomial.
    '''
    return sum(
        Poly.monomial_coefficient(monom) *
        prod(replmon(k) for k in monom.exponents()[0])
        for monom in Poly.monomials())
Beispiel #30
0
def convert_laurent_to_poly(elt, expshift, P):
    if elt == 0:
        return P(0)
    return sum([
        c * prod([g**e for g, e in zip(P.gens(),
                                       vector(exps) + expshift)])
        for c, exps in zip(elt.coefficients(), uniform_poly_exponents(elt))
    ])
def fractional_CRT_QQ(residues, ps_roots):
    residues_ZZ = [ r.lift() for r in residues];
    primes = [p for p, _ in ps_roots]
    lift = CRT_list(residues_ZZ, primes);
    N = prod(primes);
    M = Matrix([[1 ,lift, N]]);
    short_vector = Matrix(M.transpose().kernel().basis()).LLL()[0]
    return -short_vector[0]/short_vector[1];
Beispiel #32
0
def an_dict_from_ap(ap, N, B):
    r"""
    Give a dict ``ap`` of the `a_p`, for primes with norm up to `B`,
    return the dictionary giving all `a_I` for all ideals `I` up to
    norm `B`.

    NOTE: This code is specific to Dirichlet series of elliptic
    curves.

    INPUT:
        - ``ap`` -- dictionary of ap, as output, e.g., by the ap_dict function
        - `N` -- ideal; conductor of the elliptic curve
        - `B` -- positive integer
    
    OUTPUT: dictionary mapping reduced rep of primes (N(p),p.reduced_gens()) of ideals to integers

    NOTE: This should be really, really slow.  It's really just a toy
    reference implementation.
    """
    from sage.all import prod  # used below

    F = N.number_field()
    A = F.ideals_of_bdd_norm(B)

    an = dict(ap)

    for n in sorted(A.keys()):
        X = A[n]
        for I in X:
            if reduced_rep(I) in an:
                # prime case, already done
                pass
            else:
                # composite case
                fac = I.factor()
                if len(fac) == 0:
                    # unit ideal
                    an[reduced_rep(I)] = ZZ(1)
                elif len(fac) > 1:
                    # not a prime power, so just multiply together
                    # already known Dirichlet coefficients, for
                    # prime power divisors (which are all known).
                    an[reduced_rep(I)] = prod(an[reduced_rep(p**e)]
                                              for p, e in fac)
                else:
                    p, e = fac[0]
                    # a prime power
                    if p.divides(N):
                        # prime divides level
                        an[reduced_rep(I)] = an[reduced_rep(p)]**e
                    else:
                        # prime doesn't divide conductor: a_{p^e} = a_p*a_{p^(e-1)} - Norm(p)*a_{p^(e-2)}
                        assert e >= 2
                        an[reduced_rep(I)] = (
                            an[reduced_rep(p)] * an[reduced_rep(p**(e - 1))] -
                            p.norm() * an[reduced_rep(p**(e - 2))])

    return an
def allgens(line):
    r""" Parses one line from an allgens file.  Returns the label and
    a dict containing fields with keys 'conductor', 'iso', 'number',
    'ainvs', 'jinv', 'cm', 'rank', 'gens', 'torsion_order', 'torsion_structure',
    'torsion_generators', all values being strings or ints.

    Input line fields:

    conductor iso number ainvs rank torsion_structure gens torsion_gens

    Sample input line:

    20202 i 2 [1,0,0,-298389,54947169] 1 [2,4] [-570:6603:1] [-622:311:1] [834:19239:1]
    """
    data = split(line)
    label = data[0] + data[1] + data[2]
    rank = int(data[4])
    t = data[5]
    if t == '[]':
        t = []
    else:
        t = [int(c) for c in t[1:-1].split(",")]
    torsion = int(prod([ti for ti in t], 1))
    ainvs = parse_ainvs(data[3])
    E = EllipticCurve([ZZ(a) for a in ainvs])
    jinv = unicode(str(E.j_invariant()))
    if E.has_cm():
        cm = int(E.cm_discriminant())
    else:
        cm = int(0)

    content = {
        'conductor':
        int(data[0]),
        'iso':
        data[0] + data[1],
        'number':
        int(data[2]),
        'ainvs':
        ainvs,
        'jinv':
        jinv,
        'cm':
        cm,
        'rank':
        int(data[4]),
        'gens': ["(%s)" % gen[1:-1] for gen in data[6:6 + rank]],
        'torsion':
        torsion,
        'torsion_structure': ["%s" % tor for tor in t],
        'torsion_generators':
        ["%s" % parse_tgens(tgens[1:-1]) for tgens in data[6 + rank:]],
    }
    extra_data = make_extra_data(label, content['number'], ainvs,
                                 content['gens'])
    content.update(extra_data)

    return label, content
Beispiel #34
0
def get_T0_mod3(K,S, flist=None, verbose=False):
   # Compute all absolutely irreducible quartics unramified outside S
   # if not supplied:
   if flist == None:
      from S4 import abs_irred_extensions
      flist = abs_irred_extensions(K,S)
   if verbose:
      print("quartics: {}".format(flist))

# Append a poly with lam3=0
   x = polygen(K)
   flist0 = flist + [x**3]
   n = len(flist)

# Starting with no primes, compute the lambda matrix
   plist = []
   vlist = [lamvec(f,plist,lam3) for f in flist0]
   ij = equal_vecs(vlist)
   if verbose:
      print("With plist={}, vlist={}, ij={}".format(plist,vlist,ij));
   N = prod(S,1) * prod([f.discriminant() for f in flist])
# As long as the vectors in vlist are not all distinct, find two
# indices i,j for which they are the same and find a new prime which
# distinguishes these two, add it to the list and update.  The primes
# must not be in S or divide the discriminant of any of the quartics.
   while ij:
      i,j = ij
      if j==n:
         p = get_p_1(K,flist[i],N, lam3)
      else:
         p = get_p_2(K,flist[i],flist[j],N, lam3)
      plist = plist + [p]
      if verbose:
         print("plist = {}".format(plist))
      vlist = [lamvec(f,plist,lam3) for f in flist0]
      ij = equal_vecs(vlist)
      if verbose:
         print("With plist={}, vlist={}, ij={}".format(plist,vlist,ij));
   vlist = vlist[:-1]

   # Sort the primes into order and recompute the vectors:
   plist.sort()
   vlist = [lamvec(f,plist,lam3) for f in flist]
   return flist, plist, vlist
Beispiel #35
0
def an_dict_from_ap(ap, N, B):
    r"""
    Give a dict ``ap`` of the `a_p`, for primes with norm up to `B`,
    return the dictionary giving all `a_I` for all ideals `I` up to
    norm `B`.

    NOTE: This code is specific to Dirichlet series of elliptic
    curves.

    INPUT:
        - ``ap`` -- dictionary of ap, as output, e.g., by the ap_dict function
        - `N` -- ideal; conductor of the elliptic curve
        - `B` -- positive integer
    
    OUTPUT: dictionary mapping reduced rep of primes (N(p),p.reduced_gens()) of ideals to integers

    NOTE: This should be really, really slow.  It's really just a toy
    reference implementation.
    """
    from sage.all import prod   # used below
 
    F = N.number_field()
    A = F.ideals_of_bdd_norm(B)

    an = dict(ap)
    
    for n in sorted(A.keys()):
        X = A[n]
        for I in X:
            if an.has_key(reduced_rep(I)):
                # prime case, already done
                pass
            else:
                # composite case
                fac = I.factor()
                if len(fac) == 0:
                    # unit ideal
                    an[reduced_rep(I)] = ZZ(1)
                elif len(fac) > 1:
                    # not a prime power, so just multiply together
                    # already known Dirichlet coefficients, for
                    # prime power divisors (which are all known).
                    an[reduced_rep(I)] = prod(an[reduced_rep(p**e)] for p, e in fac)
                else:
                    p, e = fac[0]
                    # a prime power
                    if p.divides(N):
                        # prime divides level
                        an[reduced_rep(I)] = an[reduced_rep(p)]**e
                    else:
                        # prime doesn't divide conductor: a_{p^e} = a_p*a_{p^(e-1)} - Norm(p)*a_{p^(e-2)}
                        assert e >= 2
                        an[reduced_rep(I)] = (an[reduced_rep(p)] * an[reduced_rep(p**(e-1))]
                                                - p.norm()*an[reduced_rep(p**(e-2))])
                        
    return an
Beispiel #36
0
def ppower_norm_ideal_from_label(K, lab):
    r""" return the ideal of prime-power norm from its label.
    """
    n, i = [int(c) for c in lab.split(".")]
    p, f = ZZ(n).factor()[0]
    make_keys(K, p)
    PP = K.primes_dict[p]
    ff = [P.residue_class_degree() for P in PP]
    vec = exp_vec_wt(f, ff)[i - 1]
    return prod([P**v for P, v in zip(PP, vec)])
Beispiel #37
0
def euler_p_factor(root_list, PREC):
    ''' computes the coefficients of the pth Euler factor expanded as a geometric series
      ax^n is the Dirichlet series coefficient p^(-ns)
    '''
    PREC = floor(PREC)
    # return satake_list
    R = LaurentSeriesRing(CF, 'x')
    x = R.gens()[0]
    ep = prod([1 / (1 - a * x) for a in root_list])
    return ep + O(x ** (PREC + 1))
Beispiel #38
0
def factorization(original_poly):
    poly = ZZT(original_poly)
    assert poly[0] == 1
    if poly == 1:
        return [1]
    try:
        facts = poly.factor()
    except NotImplementedError:
        try:
            # try to sort out the memory leak
            PolynomialRing(ZZ, 'T', implementation='NTL')([1] + [0]*(len(original_poly) - 2) + [1])._pari_with_name().factor()
            facts = PolynomialRing(ZZ, 'T', implementation='NTL')(original_poly).factor()
        except NotImplementedError:
            raise
    # if the factor is -1+T^2, replace it by 1-T^2
    # this should happen an even number of times, mod powers
    out = [[-g if g[0] == -1 else g, e] for g, e in facts]
    assert prod( g**e for g, e in out ) == poly, "%s != %s" % (prod( [g**e] for g, e in out ), poly)
    return [[g.list(), e] for g,e  in out]
Beispiel #39
0
def level_attributes(level):
    # returns level_radical, level_primes, level_is_prime, level_is_prime_power, level_is_squarefree, level_is_square
    fact = Integer(level).factor()
    level_primes = [elt[0] for elt in fact]
    level_radical = prod(level_primes)
    level_is_prime_power = len(fact) == 1
    level_is_prime = level_is_prime_power and level_radical == level
    level_is_square = all( elt[1] % 2 == 0 for elt in fact)
    level_is_squarefree = all( elt[1] == 1 for elt in fact)
    return [level_radical, level_primes, level_is_prime, level_is_prime_power, level_is_squarefree, level_is_square]
Beispiel #40
0
def euler_p_factor(root_list, PREC):
    ''' computes the coefficients of the pth Euler factor expanded as a geometric series
      ax^n is the Dirichlet series coefficient p^(-ns)
    '''
    PREC = floor(PREC)
    # return satake_list
    R = LaurentSeriesRing(CF, 'x')
    x = R.gens()[0]
    ep = prod([1 / (1 - a * x) for a in root_list])
    return ep + O(x ** (PREC + 1))
Beispiel #41
0
def ppower_norm_ideal_from_label(K,lab):
    r""" return the ideal of prime-power norm from its label.
    """
    n, i = [int(c) for c in lab.split(".")]
    p, f = ZZ(n).factor()[0]
    make_keys(K,p)
    PP = K.primes_dict[p]
    ff = [P.residue_class_degree() for P in PP]
    vec = exp_vec_wt(f,ff)[i-1]
    return prod([P**v for P,v in zip(PP,vec)])
Beispiel #42
0
    def make_mwbsd(self):
        mwbsd = self.mwbsd = db.ec_mwbsd.lookup(self.lmfdb_label)

        # Some components are in the main table:

        mwbsd['rank'] = r = self.rank
        mwbsd['torsion'] = self.torsion
        mwbsd['reg'] = self.regulator
        mwbsd['sha'] = self.sha
        mwbsd['sha2'] = latex_sha(self.sha)

        # Integral points

        xintcoords = mwbsd['xcoord_integral_points']
        a1, _, a3, _, _ = ainvs = self.ainvs
        if a1 or a3:
            int_pts = sum([[(x, y) for y in make_y_coords(ainvs, x)]
                           for x in xintcoords], [])
            mwbsd['int_points'] = ', '.join(web_latex(P) for P in int_pts)
        else:
            int_pts = [(x, make_y_coords(ainvs, x)[0]) for x in xintcoords]
            mwbsd['int_points'] = ', '.join(pm_pt(P) for P in int_pts)

        # Generators (mod torsion) and heights:
        mwbsd['generators'] = [
            web_latex(weighted_proj_to_affine_point(P)) for P in mwbsd['gens']
        ] if mwbsd['ngens'] else ''

        # Torsion structure and generators:
        if mwbsd['torsion'] == 1:
            mwbsd['tor_struct'] = ''
            mwbsd['tor_gens'] = ''
        else:
            mwbsd['tor_struct'] = r' \times '.join(
                [r'\Z/{%s}\Z' % n for n in self.torsion_structure])
            mwbsd['tor_gens'] = ', '.join(
                web_latex(weighted_proj_to_affine_point(P))
                for P in mwbsd['torsion_generators'])

        # BSD invariants
        if r >= 2:
            mwbsd['lder_name'] = "L^{(%s)}(E,1)/%s!" % (r, r)
        elif r:
            mwbsd['lder_name'] = "L'(E,1)"
        else:
            mwbsd['lder_name'] = "L(E,1)"

        tamagawa_numbers = [ld['tamagawa_number'] for ld in self.local_data]
        cp_fac = [ZZ(cp).factor() for cp in tamagawa_numbers]
        cp_fac = [
            latex(cp) if len(cp) < 2 else '(' + latex(cp) + ')'
            for cp in cp_fac
        ]
        mwbsd['tamagawa_factors'] = r'\cdot'.join(cp_fac)
        mwbsd['tamagawa_product'] = prod(tamagawa_numbers)
Beispiel #43
0
def get_coeffs_p_over_nf(curve, prime_number, accuracy=20 , conductor=None):
    """                                                                         
    Computes the inverse of product of L_prime on all primes above prime_number,
    then returns power series of L_p up to desired accuracy.                    
    But will not return power series if need not do so (depends on accuracy).   
    """
    if conductor is None:
        conductor = curve.conductor()
    primes = curve.base_field().prime_factors(prime_number)
    series_p = [get_factor_over_nf(curve, prime_id, prime_number, conductor, accuracy) for prime_id in primes]
    return ( prod(series_p).O(accuracy) )**(-1)
Beispiel #44
0
def ideals_of_norm(K,n):
    r""" Return a list of all ideals of norm n (sorted).  Cached.
    """
    if not hasattr(K,'ideal_norm_dict'):
        K.ideal_norm_dict = {}
    if not n in K.ideal_norm_dict:
        if n==1:
            K.ideal_norm_dict[n] = [K.ideal(1)]
        else:
            K.ideal_norm_dict[n] = [prod(Q) for Q in cartesian_product_iterator([ppower_norm_ideals(K,p,e) for p,e in n.factor()])]
    return K.ideal_norm_dict[n]
Beispiel #45
0
def X_to_kappa(f,kappa):
    """
    f -- A polynomial in X. The constant term is ignored.
    kappa -- A function so that kappa(a) is kappa_a.
    
    Returns::
        A polynomial in kappas, converting ...
    """
    psi_list = []
    for expon,coef in f.dict().items():
        #print expon[0], coef
        if expon[0] !=0:
            psi_list += [expon[0]]*coef
        
    #print psi_list
    result = 0 
    for p in SetPartitions(range(len(psi_list))):   
        #print p  
        #print [ kappa( sum((psi_list[i] for i in s)) ) for s in p]
        result +=   prod((factorial(len(s) - 1) for s in p)) * prod(( kappa( sum((psi_list[i] for i in s)) ) for s in p ))
    return result
Beispiel #46
0
    def alpha_alt(roots, p):
        """ Computes invariant alpha in the 'ALT' case
        """
        from sage.all import prod, Permutation
        tmp = prod(roots[i] - roots[j] for i in range(len(roots)) for j in range(i))
        try:
            frob_perm = Permutation(alternating_group(frobenius_permutation(roots, p)))
        except TypeError:
            raise TypeError("The Frobenius element does not generate an element of the alternating group")

        sign = -(-1) ** are_conjugate_in_alternating(frob_perm, data_perm)
        return tmp * sign
Beispiel #47
0
    def test_spanning_trees(self):
        r"""
        Test coset representatives obtained from spanning trees for even
        subgroup (Kulkarni's method with generators ``S2``, ``S3`` and Verrill's
        method with generators ``L``, ``S2``).

        EXAMPLES::

            sage: from sage.modular.arithgroup.tests import Test
            sage: Test().test_spanning_trees() #random
        """
        from sage.all import prod
        from all import SL2Z
        from arithgroup_perm import S2m,S3m,Lm

        G = random_even_arithgroup(self.index)

        m = {'l':Lm, 's':S2m}
        tree,reps,wreps,gens = G._spanning_tree_verrill()
        assert reps[0] == SL2Z([1,0,0,1])
        assert wreps[0] == ''
        for i in xrange(1,self.index):
            assert prod(m[letter] for letter in wreps[i]) == reps[i]
        tree,reps,wreps,gens = G._spanning_tree_verrill(on_right=False)
        assert reps[0] == SL2Z([1,0,0,1])
        assert wreps[0] == ''
        for i in xrange(1,self.index):
            assert prod(m[letter] for letter in wreps[i]) == reps[i]

        m = {'s2':S2m, 's3':S3m}
        tree,reps,wreps,gens = G._spanning_tree_kulkarni()
        assert reps[0] == SL2Z([1,0,0,1])
        assert wreps[0] == []
        for i in xrange(1,self.index):
            assert prod(m[letter] for letter in wreps[i]) == reps[i]
        tree,reps,wreps,gens = G._spanning_tree_kulkarni(on_right=False)
        assert reps[0] == SL2Z([1,0,0,1])
        assert wreps[0] == []
        for i in xrange(1,self.index):
            assert prod(m[letter] for letter in wreps[i]) == reps[i]
Beispiel #48
0
    def _prod_f_A_G(Gs, kappa, psi, psi2):
        """
        Used in the computation of product. Do not call directly.
        """
        result = 1
        G = Gs.G.strataG
        A = Gs.A.strataG
        for v in range(1,G.num_vertices()+1):
            #print "Gs", Gs
            #print "G,g",v
            result *= prod(( sum((kappa.get((j,w),0) for w in Gs.alpha_inv[v]))**f for j,f in G.kappa_on_v(v))) * prod(( Gs.psi_no_loop(edge,v,ex,psi) for edge, ex in G.psi_no_loop_on_v(v) )) * prod(( Gs.psi_loop(edge,v, ex1, ex2, psi,psi2) for edge, ex1, ex2 in G.psi_loop_on_v(v) ))

        return result                    
Beispiel #49
0
def ppower_norm_ideals(K,p,f):
    r""" Return a sorted list of ideals of K of norm p^f with p prime
    """
    make_keys(K,p)
    if not hasattr(K,'ppower_dict'):
        K.ppower_dict = {}
    if not (p,f) in K.ppower_dict:
        PP = K.primes_dict[p]
        # These vectors are sorted, first by unweighted weight (sum of
        # values) then lexicographically with the reverse ordering on Z:
        vv = exp_vec_wt(f,[P.residue_class_degree() for P in PP])
        Qs = [prod([P**v for P,v in zip(PP,v)]) for v in vv]
        K.ppower_dict[(p,f)] = Qs
    return K.ppower_dict[(p,f)]
Beispiel #50
0
def galrep(line, new_format=True):
    r""" Parses one line from a galrep file.  Returns the label and a
    dict containing two fields: 'nonmax_primes', a list of
    primes p for which the Galois representation modulo p is not
    maximal, 'modp_images', a list of strings
    encoding the image when not maximal, following Sutherland's
    coding scheme for subgroups of GL(2,p).  Note that these codes
    start with a 1 or 2 digit prime followed a letter in
    ['B','C','N','S'].

    Input line fields (new_format=False):

    conductor iso number ainvs rank torsion codes

    Sample input line:

    66 c 3 [1,0,0,-10065,-389499] 0 2 2B 5B.1.2

    Input line fields (new_format=True):

    label codes

    Sample input line:

    66c3 2B 5B.1.2

    """
    data = split(line)
    if new_format:
        label = data[0]
        image_codes = data[1:]
    else:
        label = data[0] + data[1] + data[2]
        image_codes = data[6:]

    pr = [ int(split_galois_image_code(s)[0]) for s in image_codes]

    if new_format:
        d = {
            'nonmax_primes': pr,
            'nonmax_rad': prod(pr),
            'modp_images': image_codes,
        }
    else:
        d = {
            'non-surjective_primes': pr,
            'galois_images': image_codes,
        }

    return label, d
Beispiel #51
0
def allgens(line):
    r""" Parses one line from an allgens file.  Returns the label and
    a dict containing fields with keys 'conductor', 'iso', 'number',
    'ainvs', 'jinv', 'cm', 'rank', 'gens', 'torsion_order', 'torsion_structure',
    'torsion_generators', all values being strings or ints.

    Input line fields:

    conductor iso number ainvs rank torsion_structure gens torsion_gens

    Sample input line:

    20202 i 2 [1,0,0,-298389,54947169] 1 [2,4] [-570:6603:1] [-622:311:1] [834:19239:1]
    """
    data = split(line)
    label = data[0] + data[1] + data[2]
    rank = int(data[4])
    t = data[5]
    if t=='[]':
        t = []
    else:
        t = [int(c) for c in t[1:-1].split(",")]
    torsion = int(prod([ti for ti in t], 1))
    ainvs = parse_ainvs(data[3])
    E = EllipticCurve([ZZ(a) for a in ainvs])
    jinv = unicode(str(E.j_invariant()))
    if E.has_cm():
        cm = int(E.cm_discriminant())
    else:
        cm = int(0)

    content = {
        'conductor': int(data[0]),
        'iso': data[0] + data[1],
        'number': int(data[2]),
        'ainvs': ainvs,
        'jinv': jinv,
        'cm': cm,
        'rank': int(data[4]),
        'gens': ["(%s)" % gen[1:-1] for gen in data[6:6 + rank]],
        'torsion': torsion,
        'torsion_structure': ["%s" % tor for tor in t],
        'torsion_generators': ["%s" % parse_tgens(tgens[1:-1]) for tgens in data[6 + rank:]],
    }
    extra_data = make_extra_data(label,content['number'],ainvs,content['gens'])
    content.update(extra_data)

    return label, content
Beispiel #52
0
def minimal_discriminant_ideal(E):
    r"""
    Return the minimal discriminant ideal of this elliptic curve.

    INPUT:

    - ``E`` -- an elliptic curve over a number field

    OUTPUT:

    The integral ideal D whose valuation at every prime P is that of the
    local minimal model for E at P.
    """
    dat = E.local_data()
    return prod([d.prime() ** d.discriminant_valuation() for d in dat],
                E.base_field().ideal(1))
Beispiel #53
0
def get_T1(K, S, unit_first=True, verbose=False):
# Sx is a list of generators of K(S,2) with the unit first or last, assuming h(K)=1
   u = -1 if K==QQ else  K(K.unit_group().torsion_generator())
   from KSp import IdealGenerator
   Sx = [IdealGenerator(P) for P in S]
   if unit_first:
      Sx = [u] + Sx
   else:
      Sx = Sx + [u]
   r = len(Sx)
   N = prod(S,1)
# Initialize T1 to be empty and A to be a matric with 0 rows and r=#Sx columns
   T1 = []
   A = Matrix(GF(2),0,len(Sx))
   primes = primes_iter(K,1)
   p = primes.next()
# Repeat the following until A has full rank: take the next prime p
# from the iterator, skip if it divides N (=product over S), form the
# vector v, and keep p and append v to the bottom of A if it increases
# the rank:
   while A.rank() < r:
      p = primes.next()
      while p.divides(N):
         p = primes.next()
      if verbose:
         print("A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols()))
      v = vector(alphalist(p, Sx))
      if verbose:
         print("v={}".format(v))
      A1 = A.stack(v)
      if A1.rank() > A.rank():
         A = A1
         T1 = T1 + [p]
         if verbose:
            print("new A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols()))
            print("T1 increases to {}".format(T1))

   # the last thing returned is a "decoder" which returns the
   # discriminant Delta given the splitting beavious at the primes in
   # T1:
   B = A.inverse()
   def decoder(alphalist):
      e = list(B*vector(alphalist))
      return prod([D**ZZ(ei) for D,ei in zip(Sx,e)], 1)

   return T1, A, decoder
Beispiel #54
0
def _find_limits_original(tau,gtau,level,v0):
    if tau.parent().is_exact():
        p = v0.codomain().prime()
    else:
        p = tau.parent().prime()
    opt_evals = None
    opt_V = None
    for lmb,uu in find_lambda(gtau,p,n_results = 1):
        #verbose('trying lambda = %s, u = (-)p^%s'%(lmb,uu.valuation(p)))
        dec = decompose(gtau,lmb,uu)
        assert prod(dec) == gtau
        V,n_evals = get_limits_from_decomp(tau,dec,v0)
        # verbose('n_evals = %s'%n_evals)
        if opt_evals is None or n_evals < opt_evals:
            opt_V = V
            opt_evals = n_evals
    return opt_V
Beispiel #55
0
def JG_torsion_upperbound(G, bound = 60):
    """
    INPUT:
        
    - G - a congruence subgroup
    - bound (optional, default = 60) - the bound for the primes p up to which to use
      the hecke matrix `T_p - <p> - p` for bounding the torsion subgroup
    
    OUTPUT:
        
    - A subgroup of `(S_2(G) \otimes \QQ) / S_2(G)` that is guaranteed to contain
      the rational torison subgroup, together with a subgroup generated by the
      rational cusps.
      The subgroup is given as a subgroup of `S_2(G)/NS_2(G)` for a suitable integer N

    EXAMPLES::
        
        sage: from mdsage import *
        sage: d = rational_cuspidal_classgroup(Gamma1(23)).cardinality()
        sage: upper_bound_index_cusps_in_JG_torsion(Gamma1(23),d)
        1

    """
    N = G.level()
    M=ModularSymbols(G);
    Sint=cuspidal_integral_structure(M)
    kill_mat=(M.star_involution().matrix().restrict(Sint)-1)
    kill=kill_mat.transpose().change_ring(ZZ).row_module()
    for p in prime_range(3,bound):
        if not N % p ==0:
            kill+=kill_torsion_coprime_to_q(p,M).restrict(Sint).change_ring(ZZ).transpose().row_module()
        #if kill.matrix().is_square() and kill.matrix().determinant()==d:
        #    #print p
        #    break
    kill_mat=kill.matrix().transpose()
    #print N,"index of torsion in stuff killed",kill.matrix().determinant()/d
    #if kill.matrix().determinant()==d:
    #    return 1
    d = prod(kill_mat.smith_form()[0].diagonal())    
    pm=integral_period_mapping(M)
    #period_images1=[sum([M.coordinate_vector(M([c,infinity])) for c in cusps])*pm for cusps in galois_orbits(G)]
    period_images2=[M.coordinate_vector(M([c,infinity]))*pm for c in G.cusps() if c != Cusp(oo)]
    
    m=(Matrix(period_images2)*kill_mat).stack(kill_mat)
    m,d2=m._clear_denom()
    d=gcd(d,d2)
Beispiel #56
0
def compute_dirichlet_series(p_list, PREC):
    ''' computes the dirichlet series for a Lfunction_SMF2_scalar_valued
    '''
    # p_list is a list of pairs (p,y) where p is a prime and y is the list of roots of the Euler factor at x
    LL = [0] * PREC
    # create an empty list of the right size and now populate it with the powers of p
    for (p, y) in p_list:
        # FIXME p_prec is never used, but perhaps it should be?
        # p_prec = log(PREC) / log(p) + 1
        ep = euler_p_factor(y, PREC)
        for n in range(ep.prec()):
            if p ** n < PREC:
                LL[p ** n] = ep.coefficients()[n]
    for i in range(1, PREC):
        f = factor(i)
        if len(f) > 1:  # not a prime power
            LL[i] = prod([LL[p ** e] for (p, e) in f])
    return LL[1:]
Beispiel #57
0
def get_T0(K,S, flist=None, verbose=False):
   # Compute all cubics unramified outside S if not supplied:
   if flist == None:
      from C2C3S3 import C3S3_extensions
      flist = C3S3_extensions(K,S)
   if verbose:
      print("cubics: {}".format(flist))

# Append the reducible cubic
   x = polygen(K)
   flist0 = flist + [x**3]
   n = len(flist)

# Starting with no primes, compute the lambda matrix
   plist = []
   vlist = [lamvec(f,plist) for f in flist0]
   ij = equal_vecs(vlist)
   if verbose:
      print("With plist={}, vlist={}, ij={}".format(plist,vlist,ij));
   N = prod(S,1)
# As long as the vectors in vlist are not all distinct, find two
# indices i,j for which they are the same and find a new prime which
# distinguishes these two, add it to the list and update:
   while ij:
      i,j = ij
      if j==n:
         p = get_p_1(K,flist[i],N)
      else:
         p = get_p_2(K,flist[i],flist[j],N)
      plist = plist + [p]
      if verbose:
         print("plist = {}".format(plist))
      vlist = [lamvec(f,plist) for f in flist0]
      ij = equal_vecs(vlist)
      if verbose:
         print("With plist={}, vlist={}, ij={}".format(plist,vlist,ij));
   vlist = vlist[:-1]

   # Sort the primes into order and recompute the vectors:
   plist.sort()
   vlist = [lamvec(f,plist) for f in flist]
   return flist, plist, vlist
Beispiel #58
0
def count_structure(n, sty="S1"):
    pat = S[sty]
    rows = []
    for i in pat:
        if i==1:
            rows.append([(0,) + ((1,)*(n-2)) + (0,)])
        elif i==0:
            rows.append([(0,)*i + (1,) + (0,)*(n-i-2) + (1,)
                for i in range(1, n-i-1)])
        else:
            rows.append([(0,)+l for l in product([0,1], repeat=n-1)
                if l.count(1) > 1 and l.count(0) < n-2])

    ret = []
    proditer = ([p1,p2,p3] for p1,p2,p3 in product(*rows) if p1!=p2 and p2!=p3 and p1!=p3)
    for M in ProgressBar(maxval=prod(map(len, rows)))(imap(matrix, proditer)):
        if not any(S in ret for S in row_orbit(M)):
            ret.append(M)

    return ret
Beispiel #59
0
    def make_bsd(self):
        bsd = self.bsd = {}
        r = self.rank
        if r >= 2:
            bsd['lder_name'] = "L^{(%s)}(E,1)/%s!" % (r,r)
        elif r:
            bsd['lder_name'] = "L'(E,1)"
        else:
            bsd['lder_name'] = "L(E,1)"

        bsd['reg'] = self.regulator
        bsd['omega'] = self.real_period
        bsd['sha'] = self.sha
        bsd['lder'] = self.special_value

        tamagawa_numbers = [ZZ(_ld['cp']) for _ld in self.local_data]
        cp_fac = [cp.factor() for cp in tamagawa_numbers]
        cp_fac = [latex(cp) if len(cp)<2 else '('+latex(cp)+')' for cp in cp_fac]
        bsd['tamagawa_factors'] = r'\cdot'.join(cp_fac)
        bsd['tamagawa_product'] = prod(tamagawa_numbers)