# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1321321277 28800
# Node ID 06d60d896e52fe9474699e928b4944bdde019a71
# Parent d95ee8f31642cba95103e54dc10ee356c831c7f0
trac 12034: improve doctest coverage of matrix/benchmark.py to 100%
diff git a/sage/matrix/benchmark.py b/sage/matrix/benchmark.py
a

b


4  4  
5  5  timeout = 60 
6  6  
7   def report(F, title): 
8   systems = ['sage', 'magma'] 
9   print '\n\n' 
 7  def report(F, title, systems = ['sage', 'magma']): 
 8  """ 
 9  Run benchmarks with default arguments for each function in the list F. 
 10  
 11  EXAMPLES:: 
 12  
 13  sage: import sage.matrix.benchmark as b 
 14  sage: b.report([b.det_ZZ], 'Test', systems=['sage']) 
 15  ====================================================================== 
 16  Test 
 17  ====================================================================== 
 18  ... 
 19  ====================================================================== 
 20  """ 
 21  if len(systems) > 2: 
 22  raise NotImplementedError, "at most two systems ('sage' or 'magma')" 
10  23  print '='*70 
11  24  print ' '*10 + title 
12  25  print '='*70 
… 
… 

25  38  t = timeout 
26  39  alarm(0) 
27  40  w.append(float(t)) 
28   if w[1] == 0: 
29   w.append(0.0) 
30   else: 
31   w.append(w[0]/w[1]) 
 41  if len(w) > 1: 
 42  if w[1] == 0: 
 43  w.append(0.0) 
 44  else: 
 45  w.append(w[0]/w[1]) 
 46  
32  47  w = tuple(w) 
33   
34  48  print ('%15.3f'*len(w))%w 
 49  print '='*70 
35  50  
36  51  
37  52  ####################################################################### 
38  53  # Dense Benchmarks over ZZ 
39  54  ####################################################################### 
40  55  
41   def report_ZZ(): 
 56  def report_ZZ(**kwds): 
42  57  """ 
43  58  Reports all the benchmarks for integer matrices and few 
44  59  rational matrices. 
45   TODO: Probably I should start report_QQ as well. 
 60  
 61  EXAMPLES:: 
 62  
 63  sage: import sage.matrix.benchmark as b 
 64  sage: b.report_ZZ(systems=['sage']) 
 65  ====================================================================== 
 66  Dense benchmarks over ZZ 
 67  ====================================================================== 
 68  ... 
 69  ====================================================================== 
46  70  """ 
47  71  F = [vecmat_ZZ, rank_ZZ, rank2_ZZ, charpoly_ZZ, smithform_ZZ, 
48  72  det_ZZ, det_QQ, matrix_multiply_ZZ, matrix_add_ZZ, 
… 
… 

50  74  nullspace_ZZ] 
51  75  
52  76  title = 'Dense benchmarks over ZZ' 
53   report(F, title) 
 77  report(F, title, **kwds) 
54  78  
55  79  # Integer Nullspace 
56  80  
57   def nullspace_ZZ(n=400, min=0, max=2**32, system='sage'): 
 81  def nullspace_ZZ(n=200, min=0, max=2**32, system='sage'): 
58  82  """ 
59  83  Nullspace over ZZ: 
60  84  Given a n+1 x n (with n=400) matrix over ZZ with random entries 
61  85  with 32 bits, compute the nullspace. 
 86  
 87  EXAMPLES:: 
 88  
 89  sage: import sage.matrix.benchmark as b 
 90  sage: ts = b.nullspace_ZZ(200) 
 91  sage: tm = b.nullspace_ZZ(200, system='magma') # optional  magma 
62  92  """ 
63  93  if system == 'sage': 
64  94  A = random_matrix(ZZ, n+1, n, x=min, y=max+1).change_ring(QQ) 
… 
… 

80  110  raise ValueError, 'unknown system "%s"'%system 
81  111  
82  112  
83   def charpoly_ZZ(n=300, min=0, max=9, system='sage'): 
 113  def charpoly_ZZ(n=100, min=0, max=9, system='sage'): 
84  114  """ 
85  115  Characteristic polynomial over ZZ: 
86  116  Given a n x n (with n=300) matrix over ZZ with random entries 
87  117  between min=0 and max=9, compute the charpoly. 
 118  
 119  EXAMPLES:: 
 120  
 121  sage: import sage.matrix.benchmark as b 
 122  sage: ts = b.charpoly_ZZ(100) 
 123  sage: tm = b.charpoly_ZZ(100, system='magma') # optional  magma 
88  124  """ 
89  125  if system == 'sage': 
90  126  A = random_matrix(ZZ, n, n, x=min, y=max+1) 
… 
… 

111  147  Rank over ZZ: 
112  148  Given a n x (n+10) (with n=700) matrix over ZZ with random entries 
113  149  between min=0 and max=9, compute the rank. 
 150  
 151  
 152  EXAMPLES:: 
 153  
 154  sage: import sage.matrix.benchmark as b 
 155  sage: ts = b.rank_ZZ(300) 
 156  sage: tm = b.rank_ZZ(300, system='magma') # optional  magma 
114  157  """ 
115  158  if system == 'sage': 
116  159  A = random_matrix(ZZ, n, n+10, x=min, y=max+1) 
… 
… 

136  179  Rank 2 over ZZ: 
137  180  Given a (n + 10) x n (with n=400) matrix over ZZ with random entries 
138  181  between with 64 bits, compute the rank. 
 182  
 183  EXAMPLES:: 
 184  
 185  sage: import sage.matrix.benchmark as b 
 186  sage: ts = b.rank2_ZZ(300) 
 187  sage: tm = b.rank2_ZZ(300, system='magma') # optional  magma 
139  188  """ 
140  189  if system == 'sage': 
141  190  A = random_matrix(ZZ, n+10, n, x=min, y=max+1) 
… 
… 

163  212  Smith Form over ZZ: 
164  213  Given a n x n (with n=128) matrix over ZZ with random entries 
165  214  between min=0 and max=9, compute the Smith normal form. 
 215  
 216  EXAMPLES:: 
 217  
 218  sage: import sage.matrix.benchmark as b 
 219  sage: ts = b.smithform_ZZ(100) 
 220  sage: tm = b.smithform_ZZ(100, system='magma') # optional  magma 
166  221  """ 
167  222  if system == 'sage': 
168  223  A = random_matrix(ZZ, n, n, x=min, y=max+1) 
… 
… 

189  244  Matrix multiplication over ZZ 
190  245  Given an n x n (with n=300) matrix A over ZZ with random entries 
191  246  between min=9 and max=9, inclusive, compute A * (A+1). 
 247  
 248  EXAMPLES:: 
 249  
 250  sage: import sage.matrix.benchmark as b 
 251  sage: ts = b.matrix_multiply_ZZ(200) 
 252  sage: tm = b.matrix_multiply_ZZ(200, system='magma') # optional  magma 
192  253  """ 
193  254  if system == 'sage': 
194  255  A = random_matrix(ZZ, n, n, x=min, y=max+1) 
… 
… 

214  275  else: 
215  276  raise ValueError, 'unknown system "%s"'%system 
216  277  
217   def matrix_add_ZZ(n=500, min=9, max=9, system='sage', times=50): 
 278  def matrix_add_ZZ(n=200, min=9, max=9, system='sage', times=50): 
218  279  """ 
219  280  Matrix addition over ZZ 
220  281  Given an n x n (with n=500) matrix A and B over ZZ with random entries 
221  282  between min=9 and max=9, inclusive, compute A + B 50 times. 
 283  
 284  EXAMPLES:: 
 285  
 286  sage: import sage.matrix.benchmark as b 
 287  sage: ts = b.matrix_add_ZZ(200) 
 288  sage: tm = b.matrix_add_ZZ(200, system='magma') # optional  magma 
222  289  """ 
223  290  if system == 'sage': 
224  291  A = random_matrix(ZZ, n, n, x=min, y=max+1) 
… 
… 

246  313  else: 
247  314  raise ValueError, 'unknown system "%s"'%system 
248  315  
249   def matrix_add_ZZ_2(n=500, bits=16, system='sage', times=50): 
 316  def matrix_add_ZZ_2(n=200, bits=16, system='sage', times=50): 
250  317  """ 
251  318  Matrix addition over ZZ. 
252  319  Given an n x n (with n=500) matrix A and B over ZZ with random 16bit 
253  320  entries, compute A + B 50 times. 
 321  
 322  EXAMPLES:: 
 323  
 324  sage: import sage.matrix.benchmark as b 
 325  sage: ts = b.matrix_add_ZZ_2(200) 
 326  sage: tm = b.matrix_add_ZZ_2(200, system='magma') # optional  magma 
254  327  """ 
255  328  b = 2**bits 
256  329  return matrix_add_ZZ(n=n, min=b, max=b,system=system, times=times) 
257  330  
258   def det_ZZ(n=400, min=1, max=100, system='sage'): 
 331  def det_ZZ(n=200, min=1, max=100, system='sage'): 
259  332  """ 
260  333  Dense integer determinant over ZZ. 
261  334  Given an n x n (with n=400) matrix A over ZZ with random entries 
262  335  between min=1 and max=100, inclusive, compute det(A). 
 336  
 337  EXAMPLES:: 
 338  
 339  sage: import sage.matrix.benchmark as b 
 340  sage: ts = b.det_ZZ(200) 
 341  sage: tm = b.det_ZZ(200, system='magma') # optional  magma 
263  342  """ 
264  343  if system == 'sage': 
265  344  A = random_matrix(ZZ, n, n, x=min, y=max+1) 
… 
… 

287  366  Given an n x n (with n=300) matrix A over QQ with random entries 
288  367  with numerator and denominator between min=10 and 10, 
289  368  inclusive, compute det(A). 
 369  
 370  EXAMPLES:: 
 371  
 372  sage: import sage.matrix.benchmark as b 
 373  sage: ts = b.det_QQ(200) 
 374  sage: ts = b.det_QQ(10, num_bound=100000, den_bound=10000) 
 375  sage: tm = b.det_QQ(200, system='magma') # optional  magma 
290  376  """ 
291  377  if system == 'sage': 
292  378  A = random_matrix(QQ, n, n, num_bound=num_bound, den_bound=den_bound) 
… 
… 

308  394  raise ValueError, 'unknown system "%s"'%system 
309  395  
310  396  
311   def vecmat_ZZ(n=750, system='sage', min=9, max=9, times=200): 
 397  def vecmat_ZZ(n=300, system='sage', min=9, max=9, times=200): 
312  398  """ 
313  399  Vector matrix multiplication over ZZ. 
314  400  
315  401  Given an n x n (with n=750) matrix A over ZZ with random entries 
316  402  between min=9 and max=9, inclusive, and v the first row of A, 
317   compute the product v * A 200 times. 
 403  compute the product v * A 200 times. 
 404  
 405  EXAMPLES:: 
 406  
 407  sage: import sage.matrix.benchmark as b 
 408  sage: ts = b.vecmat_ZZ(300) 
 409  sage: tm = b.vecmat_ZZ(300, system='magma') # optional  magma 
318  410  """ 
319  411  if system == 'sage': 
320  412  A = random_matrix(ZZ, n, n, x=min, y=max+1) 
… 
… 

347  439  # Dense Benchmarks over GF(p), for small p. 
348  440  ####################################################################### 
349  441  
350   def report_GF(p=16411): 
 442  def report_GF(p=16411, **kwds): 
351  443  """ 
352  444  Runs all the reports for finite field matrix operations, for 
353  445  prime p=16411. 
354  446  Note: right now, even though p is an input, it is being ignored! 
355  447  If you need to check the performance for other primes, you can 
356  448  call individual benchmark functions. 
 449  
 450  EXAMPLES:: 
 451  
 452  sage: import sage.matrix.benchmark as b 
 453  sage: b.report_GF(systems=['sage']) 
 454  ====================================================================== 
 455  Dense benchmarks over GF with prime 16411 
 456  ====================================================================== 
 457  ... 
 458  ====================================================================== 
357  459  """ 
358  460  F = [rank_GF, rank2_GF, nullspace_GF, charpoly_GF, 
359  461  matrix_multiply_GF, det_GF] 
360  462  title = 'Dense benchmarks over GF with prime %i' % p 
361   report(F, title) 
 463  report(F, title, **kwds) 
362  464  
363  465  # Nullspace over GF 
364  466  
… 
… 

366  468  """ 
367  469  Given a n+1 x n (with n=300) matrix over GF(p) p=16411 with random 
368  470  entries, compute the nullspace. 
 471  
 472  EXAMPLES:: 
 473  
 474  sage: import sage.matrix.benchmark as b 
 475  sage: ts = b.nullspace_GF(300) 
 476  sage: tm = b.nullspace_GF(300, system='magma') # optional  magma 
369  477  """ 
370  478  if system == 'sage': 
371  479  A = random_matrix(GF(p), n, n+1) 
… 
… 

393  501  """ 
394  502  Given a n x n (with n=100) matrix over GF with random entries, 
395  503  compute the charpoly. 
 504  
 505  EXAMPLES:: 
 506  
 507  sage: import sage.matrix.benchmark as b 
 508  sage: ts = b.charpoly_GF(100) 
 509  sage: tm = b.charpoly_GF(100, system='magma') # optional  magma 
396  510  """ 
397  511  if system == 'sage': 
398  512  A = random_matrix(GF(p), n, n) 
… 
… 

417  531  """ 
418  532  Given two n x n (with n=1000) matrix over GF with random entries, 
419  533  add them. 
 534  
 535  EXAMPLES:: 
 536  
 537  sage: import sage.matrix.benchmark as b 
 538  sage: ts = b.matrix_add_GF(500, p=19) 
 539  sage: tm = b.matrix_add_GF(500, p=19, system='magma') # optional  magma 
420  540  """ 
421  541  if system == 'sage': 
422  542  A = random_matrix(GF(p), n, n) 
… 
… 

450  570  """ 
451  571  Given an n x n (with n=100) matrix A over GF(p) with random 
452  572  entries, compute A * (A+1). 
 573  
 574  EXAMPLES:: 
 575  
 576  sage: import sage.matrix.benchmark as b 
 577  sage: ts = b.matrix_multiply_GF(100, p=19) 
 578  sage: tm = b.matrix_multiply_GF(100, p=19, system='magma') # optional  magma 
453  579  """ 
454  580  if system == 'sage': 
455  581  A = random_matrix(GF(p), n) 
… 
… 

481  607  Rank over GF: 
482  608  Given a n x (n+10) (with n=500) matrix over ZZ with random entries 
483  609  between min=0 and max=9, compute the rank. 
 610  
 611  EXAMPLES:: 
 612  
 613  sage: import sage.matrix.benchmark as b 
 614  sage: ts = b.rank_GF(1000) 
 615  sage: tm = b.rank_GF(1000, system='magma') # optional  magma 
484  616  """ 
485  617  if system == 'sage': 
486  618  A = random_matrix(GF(p), n, n+10) 
… 
… 

506  638  Rank over GF(p): 
507  639  Given a (n + 10) x n (with n=500) matrix over GF(p) with random entries 
508  640  between min=0 and max=9, compute the rank. 
 641  
 642  EXAMPLES:: 
 643  
 644  sage: import sage.matrix.benchmark as b 
 645  sage: ts = b.rank2_GF(500) 
 646  sage: tm = b.rank2_GF(500, system='magma') # optional  magma 
509  647  """ 
510  648  if system == 'sage': 
511  649  A = random_matrix(GF(p), n+10, n) 
… 
… 

531  669  Dense integer determinant over GF. 
532  670  Given an n x n (with n=400) matrix A over GF with random entries 
533  671  compute det(A). 
 672  
 673  EXAMPLES:: 
 674  
 675  sage: import sage.matrix.benchmark as b 
 676  sage: ts = b.det_GF(1000) 
 677  sage: tm = b.det_GF(1000, system='magma') # optional  magma 
534  678  """ 
535  679  if system == 'sage': 
536  680  A = random_matrix(GF(p), n, n) 
… 
… 

562  706  def hilbert_matrix(n): 
563  707  """ 
564  708  Returns the Hilbert matrix of size n over rationals. 
 709  
 710  EXAMPLES:: 
 711  
 712  sage: import sage.matrix.benchmark as b 
 713  sage: b.hilbert_matrix(3) 
 714  [ 1 1/2 1/3] 
 715  [1/2 1/3 1/4] 
 716  [1/3 1/4 1/5] 
565  717  """ 
566  718  A = Matrix(QQ,n,n) 
567  719  for i in range(A.nrows()): 
… 
… 

575  727  """ 
576  728  Given a n x (2*n) (with n=100) matrix over QQ with random integer entries 
577  729  between min=0 and max=9, compute the reduced row echelon form. 
 730  
 731  EXAMPLES:: 
 732  
 733  sage: import sage.matrix.benchmark as b 
 734  sage: ts = b.echelon_QQ(100) 
 735  sage: tm = b.echelon_QQ(100, system='magma') # optional  magma 
578  736  """ 
579  737  if system == 'sage': 
580  738  A = random_matrix(ZZ, n, 2*n, x=min, y=max+1).change_ring(QQ) 
… 
… 

601  759  """ 
602  760  Given a n x n (with n=100) matrix over QQ with random integer entries 
603  761  between min=0 and max=9, compute the reduced row echelon form. 
 762  
 763  EXAMPLES:: 
 764  
 765  sage: import sage.matrix.benchmark as b 
 766  sage: ts = b.inverse_QQ(100) 
 767  sage: tm = b.inverse_QQ(100, system='magma') # optional  magma 
604  768  """ 
605  769  if system == 'sage': 
606  770  A = random_matrix(ZZ, n, n, x=min, y=max+1).change_ring(QQ) 
… 
… 

628  792  Given an n x n (with n=100) matrix A over QQ with random entries 
629  793  whose numerators and denominators are bounded by b, compute A * 
630  794  (A+1). 
 795  
 796  EXAMPLES:: 
 797  
 798  sage: import sage.matrix.benchmark as b 
 799  sage: ts = b.matrix_multiply_QQ(100) 
 800  sage: tm = b.matrix_multiply_QQ(100, system='magma') # optional  magma 
631  801  """ 
632  802  if system == 'sage': 
633  803  A = random_matrix(QQ, n, n, num_bound=bnd, den_bound=bnd) 
… 
… 

660  830  """ 
661  831  Runs the benchmark for calculating the determinant of the hilbert 
662  832  matrix over rationals of dimension n. 
 833  
 834  
 835  EXAMPLES:: 
 836  
 837  sage: import sage.matrix.benchmark as b 
 838  sage: ts = b.det_hilbert_QQ(50) 
 839  sage: tm = b.det_hilbert_QQ(50, system='magma') # optional  magma 
663  840  """ 
664  841  if system == 'sage': 
665  842  A = hilbert_matrix(n) 
… 
… 

683  860  """ 
684  861  Runs the benchmark for calculating the inverse of the hilbert 
685  862  matrix over rationals of dimension n. 
 863  
 864  EXAMPLES:: 
 865  
 866  sage: import sage.matrix.benchmark as b 
 867  sage: ts = b.invert_hilbert_QQ(30) 
 868  sage: tm = b.invert_hilbert_QQ(30, system='magma') # optional  magma 
686  869  """ 
687  870  if system == 'sage': 
688  871  A = hilbert_matrix(n) 
… 
… 

702  885  return float(magma.eval('s')) 
703  886  
704  887  def MatrixVector_QQ(n=1000,h=100,system='sage',times=1): 
 888  """ 
 889  Compute product of square n matrix by random vector with num and 
 890  denom bounded by 100 the given number of times. 
 891  
 892  EXAMPLES:: 
 893  
 894  sage: import sage.matrix.benchmark as b 
 895  sage: ts = b.MatrixVector_QQ(500) 
 896  sage: tm = b.MatrixVector_QQ(500, system='magma') # optional  magma 
 897  """ 
705  898  if system=='sage': 
706  899  V=QQ**n 
707  900  v=V.random_element(h) 
… 
… 

743  936  Nullspace over RR: 
744  937  Given a n+1 x n (with n=300) matrix over RR with random entries 
745  938  between min=0 and max=10, compute the nullspace. 
 939  
 940  EXAMPLES:: 
 941  
 942  sage: import sage.matrix.benchmark as b 
 943  sage: ts = b.nullspace_RR(100) 
 944  sage: tm = b.nullspace_RR(100, system='magma') # optional  magma 
746  945  """ 
747  946  if system == 'sage': 
748  947  A = random_matrix(ZZ, n+1, n, x=min, y=max+1).change_ring(RR) 
… 
… 

764  963  raise ValueError, 'unknown system "%s"'%system 
765  964  
766  965  
 966  def nullspace_RDF(n=300, min=0, max=10, system='sage'): 
 967  """ 
 968  Nullspace over RDF: 
 969  Given a n+1 x n (with n=300) matrix over RDF with random entries 
 970  between min=0 and max=10, compute the nullspace. 
 971  
 972  EXAMPLES:: 
 973  
 974  sage: import sage.matrix.benchmark as b 
 975  sage: ts = b.nullspace_RDF(100) 
 976  sage: tm = b.nullspace_RDF(100, system='magma') # optional  magma 
 977  """ 
 978  if system == 'sage': 
 979  A = random_matrix(ZZ, n+1, n, x=min, y=max+1).change_ring(RDF) 
 980  t = cputime() 
 981  v = A.kernel() 
 982  return cputime(t) 
 983  elif system == 'magma': 
 984  code = """ 
 985  n := %s; 
 986  A := RMatrixSpace(RealField(16), n+1,n)![Random(%s,%s) : i in [1..n*(n+1)]]; 
 987  t := Cputime(); 
 988  K := Kernel(A); 
 989  s := Cputime(t); 
 990  """%(n,min,max) 
 991  if verbose: print code 
 992  magma.eval(code) 
 993  return float(magma.eval('s')) 
 994  else: 
 995  raise ValueError, 'unknown system "%s"'%system 
 996  
 997  