# HG changeset patch
# User Rob Beezer <beezer@ups.edu>
# Date 1264309004 28800
# Node ID fd30b4d4509853ce1580103dd09f634e3ef79c3a
# Parent 6c4190c4ba571ea4615296cce5a44a3d87c2cd0c
[mq]: 8018modularformeigen
diff r 6c4190c4ba57 r fd30b4d45098 sage/modular/modform/numerical.py
a

b


18  18  from sage.misc.misc import verbose 
19  19  from sage.rings.all import CDF, Integer, QQ, next_prime, prime_range 
20  20  from sage.misc.prandom import randint 
 21  from sage.matrix.constructor import matrix 
 22  
 23  # This variable controls importing the SciPy library sparingly 
 24  scipy=None 
21  25  
22  26  class NumericalEigenforms(SageObject): 
23  27  """ 
… 
… 

27  31  
28  32   ``group``  a congruence subgroup of a Dirichlet character of 
29  33  order 1 or 2 
30   
 34  
31  35   ``weight``  an integer >= 2 
32   
 36  
33  37   ``eps``  a small float; abs( ) < eps is what "equal to zero" is 
34  38  interpreted as for floating point numbers. 
35   
 39  
36  40   ``delta``  a smallish float; eigenvalues are considered distinct 
37  41  if their difference has absolute value at least delta 
38   
 42  
39  43   ``tp``  use the Hecke operators T_p for p in tp when searching 
40  44  for a random Hecke operator with distinct Hecke eigenvalues. 
41   
 45  
42  46  OUTPUT: 
43  47  
44  48  A numerical eigenforms object, with the following useful methods: 
… 
… 

51  55  [[eigenvalues of T_2], 
52  56  [eigenvalues of T_3], 
53  57  [eigenvalues of T_5], ...] 
54   
 58  
55  59   :meth:`systems_of_eigenvalues`  a list of the systems of 
56  60  eigenvalues of eigenforms such that the chosen random linear 
57  61  combination of Hecke operators has multiplicity 1 eigenvalues. 
58  62  
59  63  EXAMPLES:: 
60   
 64  
61  65  sage: n = numerical_eigenforms(23) 
62  66  sage: n == loads(dumps(n)) 
63  67  True 
… 
… 

86  90  Create a new space of numerical eigenforms. 
87  91  
88  92  EXAMPLES:: 
89   
 93  
90  94  sage: numerical_eigenforms(61) # indirect doctest 
91  95  Numerical Hecke eigenvalues for Congruence Subgroup Gamma0(61) of weight 2 
92  96  """ 
… 
… 

107  111  symbols, and 1 otherwise. 
108  112  
109  113  EXAMPLES:: 
110   
 114  
111  115  sage: n = numerical_eigenforms(23) 
112  116  sage: n.__cmp__(loads(dumps(n))) 
113  117  0 
… 
… 

124  128  Return the level of this set of modular eigenforms. 
125  129  
126  130  EXAMPLES:: 
127   
 131  
128  132  sage: n = numerical_eigenforms(61) ; n.level() 
129  133  61 
130  134  """ 
… 
… 

135  139  Return the weight of this set of modular eigenforms. 
136  140  
137  141  EXAMPLES:: 
138   
 142  
139  143  sage: n = numerical_eigenforms(61) ; n.weight() 
140  144  2 
141  145  """ 
… 
… 

146  150  Print string representation of self. 
147  151  
148  152  EXAMPLES:: 
149   
 153  
150  154  sage: n = numerical_eigenforms(61) ; n 
151  155  Numerical Hecke eigenvalues for Congruence Subgroup Gamma0(61) of weight 2 
152  156  
… 
… 

162  166  set of modular eigenforms. 
163  167  
164  168  EXAMPLES:: 
165   
 169  
166  170  sage: n = numerical_eigenforms(61) ; n.modular_symbols() 
167  171  Modular Symbols space of dimension 5 for Gamma_0(61) of weight 2 with sign 1 over Rational Field 
168  172  """ 
… 
… 

177  181  return M 
178  182  
179  183  def _eigenvectors(self): 
180   """ 
 184  r""" 
181  185  Find numerical approximations to simultaneous eigenvectors in 
182  186  self.modular_symbols() for all T_p in self._tp. 
183  187  
184  188  EXAMPLES:: 
185   
 189  
186  190  sage: n = numerical_eigenforms(61) 
187  191  sage: n._eigenvectors() # random order 
188  192  [ 1.0 0.289473640239 0.176788851952 0.336707726757 2.4182243084e16] 
… 
… 

190  194  [ 0 0.413171180356 0.141163094698 0.0923242547901 0.707106781187] 
191  195  [ 0 0.826342360711 0.282326189397 0.18464850958 6.79812569682e16] 
192  196  [ 0 0.2402380858 0.792225196393 0.905370774276 4.70805946682e16] 
 197  
 198  TESTS: 
 199  
 200  This tests if this routine selects only eigenvectors with 
 201  multiplicity one. Two of the eigenvalues are 
 202  (roughly) 92.21 and 90.30 so if we set ``eps = 2.0`` 
 203  then they should compare as equal, causing both eigenvectors 
 204  to be absent from the matrix returned. The remaining eigenvalues 
 205  (ostensibly unique) are visible in the test, which should be 
 206  indepedent of which eigenvectors are returned, but it does presume 
 207  an ordering of these eigenvectors for the test to succeed. 
 208  This exercises a correction in Trac 8018. :: 
 209  
 210  sage: n = numerical_eigenforms(61, eps=2.0) 
 211  sage: evectors = n._eigenvectors() 
 212  sage: evalues = diagonal_matrix(CDF, [283.0, 108.522012456, 142.0]) 
 213  sage: diff = n._hecke_matrix*evectors  evectors*evalues 
 214  sage: sum([abs(diff[i,j]) for i in range(5) for j in range(3)]) < 1.0e9 
 215  True 
193  216  """ 
194  217  try: 
195  218  return self.__eigenvectors 
… 
… 

206  229  t += randint(50,50)*M.T(p).matrix() 
207  230  
208  231  self._hecke_matrix = t 
209   # evals, B = t.change_ring(CDF).right_eigenvectors() 
210   from sage.matrix.constructor import matrix 
211   spectrum = t.change_ring(CDF).right_eigenvectors() 
212   evals = [spectrum[i][0] for i in range(len(spectrum))] 
213   B = matrix(CDF, [spectrum[i][1][0] for i in range(len(spectrum))]).transpose() 
214   
215   # Find the eigenvalues that occur with multiplicity 1 up 
216   # to the given eps. 
 232  
 233  global scipy 
 234  if scipy is None: 
 235  import scipy 
 236  import scipy.linalg 
 237  evals,eig = scipy.linalg.eig(self._hecke_matrix.numpy(), right=True, left=False) 
 238  B = matrix(eig) 
 239  v = [CDF(evals[i]) for i in range(len(evals))] 
 240  
 241  # Determine the eigenvectors with eigenvalues of multiplicity 
 242  # one, with equality controlled by the value of eps 
 243  # Keep just these eigenvectors 
217  244  eps = self._eps 
218   v = list(evals) 
219   v.sort() 
220  245  w = [] 
221  246  for i in range(len(v)): 
222  247  e = v[i] 
223  248  uniq = True 
224  249  for j in range(len(v)): 
225   if i != j and abs(ev[j]) < eps: 
 250  if uniq and i != j and abs(ev[j]) < eps: 
226  251  uniq = False 
227  252  if uniq: 
228  253  w.append(i) 
229  254  self.__eigenvectors = B.matrix_from_columns(w) 
230   return B 
 255  return self.__eigenvectors 
231  256  
232  257  def _easy_vector(self): 
233  258  """ 
… 
… 

245  270  appropriate multiple. Repeat. 
246  271  
247  272  EXAMPLES:: 
248   
 273  
249  274  sage: n = numerical_eigenforms(37) 
250  275  sage: n._easy_vector() # slightly random output 
251  276  (1.0, 1.0, 0) 
… 
… 

265  290  x = (CDF**E.nrows()).zero_vector() 
266  291  if E.nrows() == 0: 
267  292  return x 
268   
269   
 293  
 294  
270  295  
271  296  def best_row(M): 
272  297  """ 
… 
… 

274  299  with the most entries supported outside [delta, delta]. 
275  300  
276  301  EXAMPLES:: 
277   
 302  
278  303  sage: numerical_eigenforms(61)._easy_vector() # indirect doctest 
279  304  (1.0, 1.0, 0, 0, 0) 
280  305  """ 
… 
… 

298  323  i, f = best_row(C) 
299  324  x[i] += 1 # simplistic 
300  325  e = x*E 
301   
 326  
302  327  self.__easy_vector = x 
303  328  return x 
304  329  
… 
… 

307  332  Return all eigendata for self._easy_vector(). 
308  333  
309  334  EXAMPLES:: 
310   
 335  
311  336  sage: numerical_eigenforms(61)._eigendata() # random order 
312  337  ((1.0, 0.668205013164, 0.219198805797, 0.49263343893, 0.707106781187), (1.0, 1.49654668896, 4.5620686498, 2.02990686579, 1.41421356237), [0, 1], (1.0, 1.0)) 
313  338  """ 
… 
… 

316  341  except AttributeError: 
317  342  pass 
318  343  x = self._easy_vector() 
319   
 344  
320  345  B = self._eigenvectors() 
321  346  def phi(y): 
322  347  """ 
… 
… 

324  349  linear combination of basis vectors. 
325  350  
326  351  EXAMPLES:: 
327   
 352  
328  353  sage: n = numerical_eigenforms(61) # indirect doctest 
329  354  sage: n._eigendata() # random order 
330   ((1.0, 0.668205013164, 0.219198805797, 0.49263343893, 0.707106781187), (1.0, 1.49654668896, 4.5620686498, 2.02990686579, 1.41421356237), [0, 1], (1.0, 1.0)) 
 355  ((1.0, 0.668205013164, 0.219198805797, 0.49263343893, 0.707106781187), (1.0, 1.49654668896, 4.5620686498, 2.02990686579, 1.41421356237), [0, 1], (1.0, 1.0)) 
331  356  """ 
332  357  return y.element() * B 
333   
 358  
334  359  phi_x = phi(x) 
335  360  V = phi_x.parent() 
336  361  phi_x_inv = V([a**(1) for a in phi_x]) 
… 
… 

355  380   ``list``  a list of double precision complex numbers 
356  381  
357  382  EXAMPLES:: 
358   
 383  
359  384  sage: n = numerical_eigenforms(11,4) 
360  385  sage: n.ap(2) # random order 
361  386  [9.0, 9.0, 2.73205080757, 0.732050807569] 
… 
… 

380  405  a = Sequence(self.eigenvalues([p])[0], immutable=True) 
381  406  self._ap[p] = a 
382  407  return a 
383   
 408  
384  409  def eigenvalues(self, primes): 
385  410  """ 
386  411  Return the eigenvalues of the Hecke operators corresponding 
387  412  to the primes in the input list of primes. The eigenvalues 
388   match up between one prime and the next. 
 413  match up between one prime and the next. 
389  414  
390  415  INPUT: 
391  416  
392  417   ``primes``  a list of primes 
393  418  
394  419  OUTPUT: 
395   
 420  
396  421  list of lists of eigenvalues. 
397  422  
398  423  EXAMPLES:: 
399   
 424  
400  425  sage: n = numerical_eigenforms(1,12) 
401  426  sage: n.eigenvalues([3,5,13]) 
402  427  [[177148.0, 252.0], [48828126.0, 4830.0], [1.79216039404e+12, 577737.999...]] 
… 
… 

413  438  linear combination of basis vectors. 
414  439  
415  440  EXAMPLES:: 
416   
 441  
417  442  sage: n = numerical_eigenforms(1,12) # indirect doctest 
418  443  sage: n.eigenvalues([3,5,13]) 
419  444  [[177148.0, 252.0], [48828126.0, 4830.0], [1.79216039404e+12, 577737.999...]] 
… 
… 

434  459  up to bound. 
435  460  
436  461  EXAMPLES:: 
437   
 462  
438  463  sage: numerical_eigenforms(61).systems_of_eigenvalues(10) 
439  464  [ 
440  465  [1.48119430409..., 0.806063433525..., 3.15632517466..., 0.675130870567...], 
… 
… 

454  479  v.sort() 
455  480  v.set_immutable() 
456  481  return v 
457   
 482  
458  483  def systems_of_abs(self, bound): 
459  484  """ 
460  485  Return the absolute values of all systems of eigenvalues for 
461  486  self for primes up to bound. 
462  487  
463  488  EXAMPLES:: 
464   
 489  
465  490  sage: numerical_eigenforms(61).systems_of_abs(10) 
466  491  [ 
467  492  [0.311107817466, 2.90321192591, 2.52542756084, 3.21431974338], 
… 
… 

488  513  indices where `v` is larger than eps. 
489  514  
490  515  EXAMPLES:: 
491   
 516  
492  517  sage: sage.modular.modform.numerical.support( numerical_eigenforms(61)._easy_vector(), 1.0 ) 
493  518  [] 
494   
 519  
495  520  sage: sage.modular.modform.numerical.support( numerical_eigenforms(61)._easy_vector(), 0.5 ) 
496  521  [0, 1] 
497  522  
… 
… 

499  524  return [i for i in range(v.degree()) if abs(v[i]) > eps] 
500  525  
501  526  
502   
 527  