#18061: Implement (correct) action of Atkin-Lehner operators on newforms
-------------------------------------+-------------------------------------
       Reporter:  pbruin             |        Owner:
           Type:  defect             |       Status:  needs_review
       Priority:  major              |    Milestone:  sage-6.6
      Component:  modular forms      |   Resolution:
       Keywords:  newform Atkin-     |    Merged in:
  Lehner operator                    |    Reviewers:
        Authors:  Peter Bruin        |  Work issues:
Report Upstream:  N/A                |       Commit:
         Branch:                     |  7c5d21343137b57b0ce5d4686317092402960170
  u/pbruin/18061-atkin_lehner_action |     Stopgaps:
   Dependencies:  #18068, #18072,    |
  #18086                             |
-------------------------------------+-------------------------------------

Comment (by davidloeffler):

 Hi Peter! It's great that someone has got around to implementing this at
 last. But there are some things needing a little more work:

 - I think it's not good that the new implementation returns
 {{{NotImplementedError}}} on some cases where the ''old'' implementation
 was correct and valid:
 {{{
 # old implementation
 sage: F = Newforms(169,names='a')[0]
 sage: F[13]
 0
 sage: F.atkin_lehner_eigenvalue(169)
 -1
 }}}
  Here the A-L operator on the modular symbols space is actually a diagonal
 matrix, so taking its top left entry is the right thing to do:
 {{{
 sage: F.modular_symbols(sign=0).atkin_lehner_operator(169).matrix()
 [-1  0  0  0]
 [ 0 -1  0  0]
 [ 0  0 -1  0]
 [ 0  0  0 -1]
 }}}
  With your patch this bombs out at {{{NotImplementedError: action of W_Q
 is not implemented if a_Q(f) = 0}}}. If I'm not mistaken, the old
 implementation is correct if (and maybe only if) the character is trivial,
 while your new implementation will refuse to handle any case where the
 character is trivial and the base field is not Q. (The old algorithm can
 be easily patched up to work whenever the Q-part of the character is
 trivial.)

 - The error message returned if Q is not an exact divisor of N is very
 uninformative:
 {{{

 sage: F = Newforms(20, 8, names='a')[1]; F
 q - a1*q^3 + 125*q^5 + O(q^6)
 sage: F.atkin_lehner_action(2)
 ---------------------------------------------------------------------------
 IndexError                                Traceback (most recent call
 last)
 <ipython-input-36-b33b9d9d015f> in <module>()
 ----> 1 F.atkin_lehner_action(Integer(2))

 /storage/masiao/sage/local/lib/python2.7/site-
 packages/sage/modular/modform/element.pyc in atkin_lehner_action(self, d,
 embedding)
    1224         Q = q**e
    1225         M = d // Q
 -> 1226         eps_Q = [eps for eps in self.character().decomposition()
 if eps.modulus() == Q][0]
    1227         eps = eps_Q(M)
    1228         if embedding is not None:

 IndexError: list index out of range
 }}}
  I would actually favour handing the special case where Q is a prime
 separately (interpreting it as W_p^e^ where p^e^ is the power of p
 dividing N). The {{{atkin_lehner_operator}}} method of modular symbol
 spaces does something along these lines. But in any case it should react
 more intelligently than this.

 - This error message is misleading:
 {{{
 sage: F.atkin_lehner_action(4)
 ---------------------------------------------------------------------------
 NotImplementedError                       Traceback (most recent call
 last)
 <ipython-input-77-65866aefe137> in <module>()
 ----> 1 F.atkin_lehner_action(Integer(4))

 /storage/masiao/sage/local/lib/python2.7/site-
 packages/sage/modular/modform/element.pyc in atkin_lehner_action(self, d,
 embedding)
    1229             eps = embedding(eps)
    1230         eta0, g0 = self.atkin_lehner_action(M, embedding)
 -> 1231         eta1, g1 = g0._atkin_lehner_action_prime_power(Q,
 embedding)
    1232         return eps * eta0 * eta1, g1
    1233

 /storage/masiao/sage/local/lib/python2.7/site-
 packages/sage/modular/modform/element.pyc in
 _atkin_lehner_action_prime_power(self, Q, embedding)
    1135         a_Q = self[Q]
    1136         if not a_Q:
 -> 1137             raise NotImplementedError("action of W_Q is not
 implemented if a_Q(f) = 0")
    1138         epsilon = self.character()
    1139         eps_Q = [eps for eps in epsilon.decomposition() if
 eps.modulus() == Q][0]

 NotImplementedError: action of W_Q is not implemented if a_Q(f) = 0
 }}}
  This action '''is''' implemented in some cases -- when the base ring is Q
 (and it should be implemented in more). We don't want to sell our
 capabilities short here.

  - Your implementation will always fail for odd weights:
 {{{
 sage: Newforms(Gamma1(15), 3, names='a')
 [q - q^2 + 3*q^3 - 3*q^4 - 5*q^5 + O(q^6),
  q + q^2 - 3*q^3 - 3*q^4 + 5*q^5 + O(q^6),
  q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6),
  q + a3*q^2 + (3/5*a3^3 + 11/5*a3^2 + 22/5*a3 - 11/5)*q^3 + (-8/5*a3^3 -
 31/5*a3^2 - 72/5*a3 + 16/5)*q^4 + (a3^3 + 4*a3^2 + 6*a3 - 6)*q^5 + O(q^6)]
 sage: f = _[2]
 sage: f.atkin_lehner_eigenvalue(5)
 ---------------------------------------------------------------------------
 TypeError                                 Traceback (most recent call
 last)
 <ipython-input-87-4262769bbfb2> in <module>()
 ----> 1 f.atkin_lehner_eigenvalue(Integer(5))

 /storage/masiao/sage/local/lib/python2.7/site-
 packages/sage/modular/modform/element.pyc in atkin_lehner_eigenvalue(self,
 d, embedding)
    1285         if d is None:
    1286             d = self.level()
 -> 1287         eta, g = self.atkin_lehner_action(d, embedding)
    1288         if g != self:
    1289             raise ValueError("%r is not an eigenform for W_%r" %
 (self, d))

 /storage/masiao/sage/local/lib/python2.7/site-
 packages/sage/modular/modform/element.pyc in atkin_lehner_action(self, d,
 embedding)
    1229             eps = embedding(eps)
    1230         eta0, g0 = self.atkin_lehner_action(M, embedding)
 -> 1231         eta1, g1 = g0._atkin_lehner_action_prime_power(Q,
 embedding)
    1232         return eps * eta0 * eta1, g1
    1233

 /storage/masiao/sage/local/lib/python2.7/site-
 packages/sage/modular/modform/element.pyc in
 _atkin_lehner_action_prime_power(self, Q, embedding)
    1149         lambda_Q = g / a_Q
    1150         Q = lambda_Q.parent()(Q)
 -> 1151         return Q**(self.weight()/2 - 1) * lambda_Q, f_star
    1152
    1153     def atkin_lehner_action(self, d, embedding=None):

 /storage/masiao/sage/src/sage/structure/element.pyx in
 sage.structure.element.RingElement.__mul__
 (build/cythonized/sage/structure/element.c:17184)()
    1905         elif PyInt_CheckExact(left):
    1906             return
 (<ModuleElement>right)._mul_long(PyInt_AS_LONG(left))
 -> 1907         return coercion_model.bin_op(left, right, mul)
    1908
    1909     cpdef RingElement _mul_(self, RingElement right):

 /storage/masiao/sage/src/sage/structure/coerce.pyx in
 sage.structure.coerce.CoercionModel_cache_maps.bin_op
 (build/cythonized/sage/structure/coerce.c:9131)()
    1044         # We should really include the underlying error.
    1045         # This causes so much headache.
 -> 1046         raise TypeError, arith_error_message(x,y,op)
    1047
    1048     cpdef canonical_coercion(self, x, y):

 TypeError: unsupported operand parent(s) for '*': 'Symbolic Ring' and
 'Number Field in a2 with defining polynomial x^2 + 5'
 }}}
  Sage doesn't know which square root of 5 to take here, so it returns
 sqrt(5) in the symbolic ring, which of course causes an error when you try
 to multiply it by something in the base ring of f. Are you trying to
 renormalise the Atkin--Lehner operator so as to be an involution in all
 weights? This can't be done Galois-equivariantly, and is inconsistent with
 normalisations elsewhere in Sage. (There's a great quote from Deligne re
 these normalisations: "Langlands is very sure he knows what the square
 root of p is. I have never been so sure".) I personally favour the
 normalisation where W_Q^2^ is Q^(k/2 - 1)^ up to a root of unity, which
 '''is''' Galois equivariant.

--
Ticket URL: <http://trac.sagemath.org/ticket/18061#comment:11>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.

Reply via email to