Opened 8 years ago

Closed 8 years ago

#12724 closed enhancement (fixed)

Allow different normalizations for Eisenstein series q-expansion

Reported by: davidloeffler Owned by: craigcitro
Priority: major Milestone: sage-5.1
Component: modular forms Keywords:
Cc: Merged in: sage-5.1.beta0
Authors: David Loeffler Reviewers: Alex Ghitza, Martin Albrecht, David Roe
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: #11375 Stopgaps:

Description (last modified by davidloeffler)

This came up as part of my review of #12043, but it's of independent interest.

The level 1 Eisenstein series can be normalized in three natural ways: so the linear coefficient is 1; so the constant term is 1; or so the coefficients are integers with no common factor. Renormalizing is no problem if you're working over QQ but over finite characteristic base rings it is a total pain (try computing Ep-1 mod p2).

The patch below modifies eisenstein_series_qexp so the following works:

sage: eisenstein_series_qexp(6, 5, normalization="constant") 
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 + O(q^5)
sage: eisenstein_series_qexp(6, 10, K=Zmod(49), normalization="constant")        
1 + 35*q + 28*q^2 + 14*q^3 + 42*q^5 + 21*q^6 + 35*q^7 + 35*q^8 + 7*q^9 + O(q^10)

Attachments (3)

trac_12724.patch (8.0 KB) - added by davidloeffler 8 years ago.
Patch against 5.0.beta8
trac_12724-add_example.patch (777 bytes) - added by davidloeffler 8 years ago.
Apply over previous patch
trac_12724-poly_bug.patch (1.1 KB) - added by davidloeffler 8 years ago.
Apply over previous patches

Download all attachments as: .zip

Change History (22)

Changed 8 years ago by davidloeffler

Patch against 5.0.beta8

comment:1 Changed 8 years ago by davidloeffler

  • Description modified (diff)
  • Status changed from new to needs_review

comment:2 Changed 8 years ago by davidloeffler

  • Description modified (diff)

comment:3 Changed 8 years ago by davidloeffler

  • Dependencies set to #11375

Adding dependency on #11375 so the patchbot knows how to apply it to Sage 4.8.

comment:4 Changed 8 years ago by AlexGhitza

  • Cc AlexGhitza added

comment:5 Changed 8 years ago by AlexGhitza

  • Cc AlexGhitza removed
  • Reviewers set to Alex Ghitza
  • Status changed from needs_review to needs_info

David,

This is great. I have run into this exact thing before and worked around it; it will be good to have it properly in Sage.

I have one minor request: would you mind including a Hasse invariant example, e.g.:

sage: eisenstein_series_qexp(12, 50, K=GF(13), normalization="constant")
1 + O(q^50)

For some reason it feels like it belongs here.

Changed 8 years ago by davidloeffler

Apply over previous patch

comment:6 Changed 8 years ago by davidloeffler

I agree, that's a good idea.

Apply trac_12724.patch, trac_12724-add_example.patch

(for patchbot).

comment:7 Changed 8 years ago by davidloeffler

  • Status changed from needs_info to needs_review

comment:8 Changed 8 years ago by AlexGhitza

  • Status changed from needs_review to positive_review

Great, thanks!

comment:9 Changed 8 years ago by jdemeyer

  • Status changed from positive_review to needs_work

Some of these don't work on OS X 10.4 PPC (and I'm guessing all other 32-bit systems):

sage -t  --long -force_lib devel/sage/sage/modular/modform/eis_series.py
**********************************************************************
File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/devel/sage-main/sage/modular/modform/eis_series.py", line 105:
    sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="integral")
Exception raised:
    Traceback (most recent call last):
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/bin/ncadoctest.py", line 1231, in run_one_test
        self.run_one_example(test, example, filename, compileflags)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/bin/sagedoctest.py", line 38, in run_one_example
        OrigDocTestRunner.run_one_example(self, test, example, filename, compileflags)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/bin/ncadoctest.py", line 1172, in run_one_example
        compileflags, 1) in test.globs
      File "<doctest __main__.example_1[15]>", line 1, in <module>
        eisenstein_series_qexp(Integer(12), Integer(5), K = Zmod(Integer(2)), normalization="integral")###line 105:
    sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="integral")
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/lib/python/site-packages/sage/modular/modform/eis_series.py", line 169, in eisenstein_series_qexp
        return R(eisenstein_series_poly(k, prec).list(), prec=prec, check=True)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/lib/python/site-packages/sage/rings/power_series_ring.py", line 628, in __call__
        return self.__power_series_class(self, f, prec, check=check)
      File "power_series_poly.pyx", line 55, in sage.rings.power_series_poly.PowerSeries_poly.__init__ (sage/rings/power_series_poly.c:2568)
      File "parent.pyx", line 1060, in sage.structure.parent.Parent.__call__ (sage/structure/parent.c:7960)
      File "coerce_maps.pyx", line 100, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_with_args (sage/structure/coerce_maps.c:3729)
      File "coerce_maps.pyx", line 90, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_with_args (sage/structure/coerce_maps.c:3555)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/lib/python/site-packages/sage/rings/polynomial/polynomial_ring.py", line 366, in _element_constructor_
        return C(self, x, check=check, is_gen=False,construct=construct)
      File "polynomial_gf2x.pyx", line 53, in sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:10211)
      File "polynomial_template.pxi", line 138, in sage.rings.polynomial.polynomial_gf2x.Polynomial_template.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:4984)
      File "polynomial_gf2x.pyx", line 53, in sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:10211)
      File "polynomial_template.pxi", line 119, in sage.rings.polynomial.polynomial_gf2x.Polynomial_template.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:4754)
    OverflowError: Python int too large to convert to C long
**********************************************************************
File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/devel/sage-main/sage/modular/modform/eis_series.py", line 107:
    sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="constant")
Exception raised:
    Traceback (most recent call last):
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/bin/ncadoctest.py", line 1231, in run_one_test
        self.run_one_example(test, example, filename, compileflags)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/bin/sagedoctest.py", line 38, in run_one_example
        OrigDocTestRunner.run_one_example(self, test, example, filename, compileflags)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/bin/ncadoctest.py", line 1172, in run_one_example
        compileflags, 1) in test.globs
      File "<doctest __main__.example_1[16]>", line 1, in <module>
        eisenstein_series_qexp(Integer(12), Integer(5), K = Zmod(Integer(2)), normalization="constant")###line 107:
    sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="constant")
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/lib/python/site-packages/sage/modular/modform/eis_series.py", line 167, in eisenstein_series_qexp
        return a0fac*R(eisenstein_series_poly(k, prec).list(), prec=prec, check=True)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/lib/python/site-packages/sage/rings/power_series_ring.py", line 628, in __call__
        return self.__power_series_class(self, f, prec, check=check)
      File "power_series_poly.pyx", line 55, in sage.rings.power_series_poly.PowerSeries_poly.__init__ (sage/rings/power_series_poly.c:2568)
      File "parent.pyx", line 1060, in sage.structure.parent.Parent.__call__ (sage/structure/parent.c:7960)
      File "coerce_maps.pyx", line 100, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_with_args (sage/structure/coerce_maps.c:3729)
      File "coerce_maps.pyx", line 90, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_with_args (sage/structure/coerce_maps.c:3555)
      File "/Users/buildbot/build/sage/moufang-1/moufang_full/build/sage-5.0.beta14/local/lib/python/site-packages/sage/rings/polynomial/polynomial_ring.py", line 366, in _element_constructor_
        return C(self, x, check=check, is_gen=False,construct=construct)
      File "polynomial_gf2x.pyx", line 53, in sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:10211)
      File "polynomial_template.pxi", line 138, in sage.rings.polynomial.polynomial_gf2x.Polynomial_template.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:4984)
      File "polynomial_gf2x.pyx", line 53, in sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:10211)
      File "polynomial_template.pxi", line 119, in sage.rings.polynomial.polynomial_gf2x.Polynomial_template.__init__ (sage/rings/polynomial/polynomial_gf2x.cpp:4754)
    OverflowError: Python int too large to convert to C long
**********************************************************************

comment:10 Changed 8 years ago by davidloeffler

This isn't so much a bug in the code, as a preexisting bug in polynomials over GF(2) which my code has just revealed:

sage: R.<x> = Zmod(2)[]
sage: R([2^80]) # boom!

Curiously there is no problem with moduli other than 2.

comment:11 Changed 8 years ago by davidloeffler

Here's a tiny patch to the __init__ method of mod 2 polynomials which should fix the problem.

Apply trac_12724.patch, trac_12724-add_example.patch, trac_12724-add_example.patch

(for patchbot).

comment:12 Changed 8 years ago by davidloeffler

  • Status changed from needs_work to needs_review

comment:13 Changed 8 years ago by davidloeffler

Apply trac_12724.patch, trac_12724-add_example.patch, trac_12724-poly_bug.patch

(for patchbot -- oops!)

comment:14 Changed 8 years ago by davidloeffler

Patchbot spotted a rogue trailing space...

Apply trac_12724.patch, trac_12724-add_example.patch, trac_12724-poly_bug.patch

comment:15 follow-up: Changed 8 years ago by malb

mod 2 bit looks alright, but perhaps we should avoid the %2 if x.parent() is GF(2) already?

Changed 8 years ago by davidloeffler

Apply over previous patches

comment:16 in reply to: ↑ 15 Changed 8 years ago by davidloeffler

Replying to malb:

mod 2 bit looks alright, but perhaps we should avoid the %2 if x.parent() is GF(2) already?

True, there's no need to reduce mod 2 in this case. I've rearranged things to avoid this.

Apply trac_12724.patch, trac_12724-add_example.patch, trac_12724-poly_bug.patch

comment:17 Changed 8 years ago by roed

  • Reviewers changed from Alex Ghitza to Alex Ghitza, Martin Albrecht, David Roe
  • Status changed from needs_review to positive_review

The change looks good to me.

comment:18 Changed 8 years ago by jdemeyer

  • Milestone changed from sage-5.0 to sage-5.1

comment:19 Changed 8 years ago by jdemeyer

  • Merged in set to sage-5.1.beta0
  • Resolution set to fixed
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.