Ticket #6635: trac_6635.patch

File trac_6635.patch, 6.1 KB (added by was, 14 years ago)

part 1

  • sage/modular/hecke/algebra.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1248671600 25200
    # Node ID 76300afe4ef3e9b04aead99088cf8616fa083d37
    # Parent  477bba399cd15e671888c157b9286d4ea131133b
    trac 6635 -- implement more critical Hecke algebra functionality: index in saturation, discriminant (part 1)
    
    diff -r 477bba399cd1 -r 76300afe4ef3 sage/modular/hecke/algebra.py
    a b  
    493493        return self.__M.hecke_matrix(n)
    494494
    495495
     496    def _basis_over_QQ(self, ops, r, integral=False, bound=10):
     497        """
     498       
     499        """
     500        assert len(ops) >= r, "len of ops must be at least r"
     501
     502        from sage.rings.all import ZZ, QQ
     503        from random import randrange
     504        from sage.modules.all import span, vector
     505        from sage.matrix.all import matrix
     506
     507       
     508        if r == 0:
     509            return [], matrix(QQ,0,0), vector(QQ,0)
     510
     511        tm = verbose("Computing Hecke matrices...")
     512        M = self.module()
     513        if integral:
     514            T = [M.integral_hecke_matrix(k) for k in ops]
     515        else:
     516            T = [self.hecke_operator(k).matrix() for k in ops]           
     517        verbose("Done computing all Hecke matrices", tm)
     518        n = M.rank()
     519        v = vector(QQ, [ZZ.random_element(-bound,bound) for _ in range(n)])
     520        while True:
     521            tm = verbose("Computing images of random vector...")
     522            # Apply Hecke operators to v
     523            Z  = matrix([v*t for t in T])
     524            tm = verbose("Done computing the images", tm)
     525           
     526            p    = ZZ(randrange(1000,20000)).next_prime()
     527            Z, d = Z._clear_denom()
     528            Zmod = Z._reduce(p)
     529            rr   = Zmod.rank()
     530            verbose("Got rank (mod %s) = %s"%(p,rr),tm)
     531           
     532            assert rr <= r, "bug in _basis_over_QQ, since we must have rr <= r"
     533            if rr >= r: break
     534           
     535            # Change 1 random entry, and try again
     536            v[randrange(n)] += ZZ.random_element()
     537        # end while
     538       
     539        return Zmod.transpose().pivots(), Z, d*v
     540
     541    def _discriminant(self, ops, r):
     542        r"""
     543        Return the discriminant of this Hecke algebra, assuming it is
     544        generated over ZZ by the Hecke operators `T_n` with `n` in ops
     545        and that the rank of this Hecke algebra is `r` as a
     546        `\ZZ`-module.
     547
     548        INPUT:
     549
     550            - ``ops`` -- list of positive integers
     551
     552            - ``r`` -- nonnegative integer (the rank)
     553        """
     554        from sage.rings.all import ZZ, QQ
     555        from sage.matrix.all import matrix
     556        from random import randrange
     557
     558        F, A, _ = self._basis_over_QQ(ops, r)
     559        tm = verbose("start computing ZZ module...")
     560        d1 = A.row_module(ZZ).basis_matrix().determinant()
     561        verbose('done!', tm)
     562        d2 = A.matrix_from_rows(F).determinant()
     563        T = [self.hecke_matrix(ops[n]) for n in F]
     564
     565        m = len(F)
     566        B = matrix(QQ, m)
     567        for i in range(m):
     568            for j in range(i,m):
     569                tr = (T[i]*T[j]).trace()
     570                B[i,j] = tr
     571                if i != j:
     572                    B[j,i] = tr
     573        d3 = B.determinant()
     574
     575        return ZZ(d3 / (d2/d1)**2)
     576
     577    def _index_in_saturation_naive(self, ops, r):
     578        from sage.rings.all import ZZ
     579        from sage.modules.all import span
     580
     581        M = self.module()
     582        V = ZZ**(M.rank()**2)
     583        T = [V(M.integral_hecke_matrix(n).list()) for n in ops]
     584        S = span(T,ZZ)
     585        return S.index_in_saturation()
     586
     587    def _index_in_saturation(self, ops, r, bound=10):
     588        from sage.rings.all import ZZ, QQ
     589        from sage.matrix.all import matrix
     590        from sage.modules.all import span
     591        from random import randrange
     592
     593        M = self.module()
     594        T = [M.integral_hecke_matrix(k) for k in ops]
     595        W = None
     596        F = None
     597        while True:
     598            F0, A, v = self._basis_over_QQ(ops, r, integral=True, bound=bound)
     599            if F is not None and F0 != F:
     600                continue
     601            F = F0
     602            tm = verbose("start computing ZZ module...")
     603            B = A.row_module(ZZ)
     604            X = B.span_of_basis(A.matrix_from_rows(F).rows())
     605            C = B.saturation()
     606            Q = C/B
     607            if len(Q.gens()) == 0:
     608                # easy special case
     609                return (ZZ**len(F))/(ZZ**len(F))
     610            fail = False
     611            W0 = span([X.coordinate_vector(g.lift()) for g in Q.gens()], ZZ) + ZZ**r
     612            if W is None:
     613                W = W0
     614            else:
     615                W = W.intersection(W0)
     616            Z = []
     617            for z in W.basis():
     618                a = sum([z[i]*T[F[i]] for i in range(len(z))])
     619                if a.denominator() != 1:
     620                    fail = True
     621                    break
     622                Z.append(a)
     623            if not fail:
     624                S = span([v*a for a in Z], ZZ)
     625                return (S+B) / B
     626
     627
    496628class HeckeAlgebra_full(HeckeAlgebra_base):
    497629    r"""
    498630    A full Hecke algebra (including the operators `T_n` where `n` is not
  • sage/modular/modsym/space.py

    diff -r 477bba399cd1 -r 76300afe4ef3 sage/modular/modsym/space.py
    a b  
    15981598            self.__integral_hecke_matrix = {}
    15991599        except KeyError:
    16001600            pass
    1601         #raise NotImplementedError, "code past this point is broken / not done"  # todo
    1602         A = self.ambient_hecke_module()
    1603         T = A.hecke_matrix(n)
    1604         S = T.restrict(self.integral_structure()).change_ring(ZZ)
     1601       
     1602        # The following is a very common special case:
     1603        if self.module().basis_matrix() == self.integral_structure().basis_matrix():
     1604            S = self.hecke_matrix(n)
     1605        else:
     1606            A = self.ambient_hecke_module()
     1607            T = A.hecke_matrix(n)
     1608            S = T.restrict(self.integral_structure()).change_ring(ZZ)
    16051609        self.__integral_hecke_matrix[n] = S
    16061610        return S
    16071611