#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.