Ticket #6836 (closed defect: fixed)

Opened 4 years ago

Last modified 3 years ago

The Sturm bound for modular forms gives the wrong result sometimes

Reported by: ljpk Owned by: craigcitro
Priority: major Milestone: sage-4.4
Component: modular forms Keywords: sturm bound character
Cc: Work issues:
Report Upstream: N/A Reviewers: David Loeffler
Authors: Lloyd Kilford, Alex Ghitza Merged in: sage-4.4.alpha0
Dependencies: Stopgaps:

Description

In the documentation for the Sturm bound, the following appears:

"Kevin Buzzard pointed out to me (William Stein) in Fall 2002 that the above bound is fine for Gamma1 with character, as one sees by taking a power of f. More precisely, if fcong 0pmod{p} for first s coefficients, then f^r = 0 pmod{p} for first s r coefficients. Since the weight of f^r is r weight(f), it follows that if s >= the sturm bound for Gamma_0 at weight(f), then f^r has valuation large enough to be forced to be 0 at r * weight(f) by Sturm bound (which is valid if we choose r right). Thus f cong 0 pmod{p}. Conclusion: For Gamma_1 with fixed character, the Sturm bound is *exactly* the same as for Gamma_0. "

However, this does not seem to be the case:

sage: CuspForms(DG144.1^2,3).sturm_bound()
3457
sage: CuspForms(Gamma0(144),3).sturm_bound()
73

I believe that this is due to the following code in the sturm_bound method for modular forms:

if M is not None:
            raise NotImplementedError
        if self.__sturm_bound is None:
            # the +1 below is because O(q^prec) has precision prec.
            self.__sturm_bound =      self.group().sturm_bound(self.weight())+1
        return self.__sturm_bound

where self.group()' gives the wrong answer in the case of Gamma_1 with fixed character, because it returns Gamma_1 rather than Gamma_0`.

I propose that the code above should be of the form

if M is not None:
            raise NotImplementedError
        if self.__sturm_bound is None:
            # the +1 below is because O(q^prec) has precision prec.
            G=self.group()
            if G=Gamma1(G.level()) and self.character() in DirichletGroup(self.level()):
                G=Gamma0(G.level())
            self.__sturm_bound = G.sturm_bound(self.weight())+1
        return self.__sturm_bound

before the sturm_bound variable is set, which would implement the remark of Buzzard given above.

Attachments

trac_6836.patch Download (2.6 KB) - added by AlexGhitza 3 years ago.
trac_6836-trivial-doc.patch Download (803 bytes) - added by jhpalmieri 3 years ago.

Change History

comment:1 Changed 3 years ago by AlexGhitza

  • Keywords sturm bound character added
  • Priority changed from minor to major
  • Report Upstream set to N/A
  • Status changed from new to needs_review
  • Authors set to Lloyd Kilford, Alex Ghitza

Implemented Lloyd's suggestion (with some changes to the code). See the patch.

Changed 3 years ago by AlexGhitza

comment:2 Changed 3 years ago by davidloeffler

  • Status changed from needs_review to positive_review
  • Reviewers set to David Loeffler

Looks fine to me, and tests pass on 4.3.5 (with all the other patches in the positive_review pile already applied).

Changed 3 years ago by jhpalmieri

comment:3 Changed 3 years ago by jhpalmieri

Here's a patch to make the docs build without error.

comment:4 Changed 3 years ago by jhpalmieri

  • Status changed from positive_review to closed
  • Resolution set to fixed
  • Merged in set to sage-4.4.alpha0

Merged in 4.4.alpha0:

  • trac_6836.patch
  • trac_6836-trivial-doc.patch
Note: See TracTickets for help on using tickets.