Ticket #655: sparsegfp.patch
| File sparsegfp.patch, 12.8 KB (added by malb, 2 years ago) |
|---|
-
sage/libs/linbox/linbox.pxd
# HG changeset patch # User Martin Albrecht <malb@informatik.uni-bremen.de> # Date 1189866063 -3600 # Node ID faf211fd9c6707064e1649a7eb1fb7e374d9654e # Parent 2cce131bce328a2ca283d5fb590b7aa8ddab5200 first steps towards faster sparse linear algerba over GF(p) diff -r 2cce131bce32 -r faf211fd9c67 sage/libs/linbox/linbox.pxd
a b 1 1 include "../../ext/cdefs.pxi" 2 2 3 cdef extern from "../libs/m4ri/packedmatrix.h": 4 ctypedef struct packedmatrix 3 include '../../modules/vector_modn_sparse_h.pxi' 5 4 6 5 ctypedef size_t mod_int 7 6 … … 18 17 size_t B_nr, size_t B_nc) 19 18 cdef unsigned long rank(self) except -1 20 19 20 cdef class Linbox_modn_sparse: 21 cdef c_vector_modint *rows 22 cdef size_t nrows 23 cdef size_t ncols 24 cdef unsigned int modulus 21 25 22 ## cdef class Linbox_mod2_dense: 23 ## cdef packedmatrix *matrix 24 25 ## cdef set(self, packedmatrix *matrix) 26 ## cdef int echelonize(self) 27 ## cdef matrix_matrix_multiply(self, packedmatrix *ans, packedmatrix *B) 28 ## cdef unsigned long rank(self) except -1 26 cdef set(self, int modulus, size_t nrows, size_t ncols, c_vector_modint *rows) 27 cdef object rank(self, int reorder) 28 #cdef void solve(self, void *x, void *b) 29 29 30 30 31 cdef class Linbox_integer_dense: 31 32 cdef mpz_t** matrix -
sage/libs/linbox/linbox.pyx
diff -r 2cce131bce32 -r faf211fd9c67 sage/libs/linbox/linbox.pyx
a b 87 87 r = linbox_modn_dense_rank(self.n, self.matrix, self.nrows, self.ncols) 88 88 return r 89 89 90 91 92 93 94 95 ########################################################################## 96 ## Dense matrices GF(2) 97 ########################################################################## 98 99 ## cdef extern from "linbox_wrap.h": 100 ## ctypedef struct packedmatrix 101 102 ## cdef int linbox_mod2_dense_echelonize(packedmatrix *m) 103 104 ## cdef void linbox_mod2_dense_minpoly(mod_int **mp, size_t* degree, packedmatrix *matrix, int do_minpoly) 105 106 ## cdef int linbox_mod2_dense_matrix_matrix_multiply(packedmatrix *ans, packedmatrix *A, packedmatrix *B) 107 108 ## cdef int linbox_mod2_dense_rank(packedmatrix *m) 109 110 ## cdef class Linbox_mod2_dense: 111 ## cdef set(self, packedmatrix *matrix): 112 ## self.matrix = matrix 113 114 ## cdef int echelonize(self): 115 ## cdef int r 116 ## r = linbox_mod2_dense_echelonize(self.matrix) 117 ## return r 118 119 ## def minpoly(self): 120 ## return self._poly(True) 121 122 ## def charpoly(self): 123 ## return self._poly(False) 124 125 ## def _poly(self, minpoly): 90 ########################################################################## 91 ## Sparse matices modulo p. 92 ########################################################################## 93 94 cdef extern from "linbox_wrap.h": 95 int linbox_modn_sparse_matrix_rank(unsigned long modulus, size_t nrows, size_t ncols, void* rows, int reorder) #, int **pivots) 96 void linbox_modn_sparse_matrix_solve(unsigned long modulus, size_t numrows, size_t numcols, void **x, void *a, void *b) 97 98 cdef class Linbox_modn_sparse: 99 cdef set(self, int modulus, size_t nrows, size_t ncols, c_vector_modint *rows): 100 self.rows = rows 101 self.nrows = nrows 102 self.ncols = ncols 103 self.modulus = modulus 104 105 cdef object rank(self, int reorder): 106 #cdef int *_pivots 107 cdef int r 108 r = linbox_modn_sparse_matrix_rank(self.modulus, self.nrows, self.ncols, self.rows, reorder) 109 110 #pivots = [_pivots[i] for i in range(r)] 111 #free(_pivots) 112 return r#, pivots 113 114 ## cdef void solve(self, void *x, void *b): 126 115 ## """ 127 ## INPUT:128 ## as given129 130 ## OUTPUT:131 ## coefficients of charpoly or minpoly as a Python list132 116 ## """ 133 ## cdef mod_int *f 134 ## cdef size_t degree 135 ## linbox_mod2_dense_minpoly(&f, °ree, self.matrix, minpoly) 136 137 ## v = [] 138 ## cdef Py_ssize_t i 139 ## for i from 0 <= i <= degree: 140 ## v.append(f[i]) 141 ## linbox_modn_dense_delete_array(f) 142 ## return v 143 144 ## cdef matrix_matrix_multiply(self, 145 ## packedmatrix *ans, 146 ## packedmatrix *B): 147 ## cdef int e 148 149 ## e = linbox_mod2_dense_matrix_matrix_multiply(ans, self.matrix, B) 150 ## if e: 151 ## raise RuntimeError, "error doing matrix matrix multiply mod2 using linbox" 152 153 ## cdef unsigned long rank(self) except -1: 154 ## cdef unsigned long r 155 ## r = linbox_mod2_dense_rank(self.matrix) 156 ## return r 157 158 159 ########################################################################## 160 ## Sparse matices modulo p. 161 ########################################################################## 162 cdef class Linbox_modn_sparse: 163 pass 164 165 117 ## linbox_modn_sparse_matrix_solve(self.modulus, self.nrows, self.ncols, &x, self.rows, b) 118 166 119 ########################################################################## 167 120 ## Sparse matrices over ZZ 168 121 ########################################################################## -
sage/matrix/matrix_modn_sparse.pxd
diff -r 2cce131bce32 -r faf211fd9c67 sage/matrix/matrix_modn_sparse.pxd
a b 6 6 cdef c_vector_modint* rows 7 7 cdef public int p 8 8 cdef swap_rows_c(self, Py_ssize_t n1, Py_ssize_t n2) 9 10 cdef _init_linbox(self) -
sage/matrix/matrix_modn_sparse.pyx
diff -r 2cce131bce32 -r faf211fd9c67 sage/matrix/matrix_modn_sparse.pyx
a b 79 79 80 80 from sage.misc.misc import verbose, get_verbose, graphics_filename 81 81 82 from sage.rings.integer import Integer 83 84 from sage.matrix.matrix0 import Matrix as Matrix0 85 from sage.rings.arith import is_prime 86 87 from sage.structure.element import is_Vector 88 82 89 ################ 83 90 # TODO: change this to use extern cdef's methods. 84 91 from sage.ext.arith cimport arith_int … … 88 95 89 96 import sage.ext.multi_modular 90 97 MAX_MODULUS = sage.ext.multi_modular.MAX_MODULUS 98 99 from sage.libs.linbox.linbox cimport Linbox_modn_sparse 100 cdef Linbox_modn_sparse linbox 101 linbox = Linbox_modn_sparse() 91 102 92 103 cdef class Matrix_modn_sparse(matrix_sparse.Matrix_sparse): 93 104 … … 462 473 for j from 0 <= j < self.rows[i].num_nonzero: 463 474 k+=1 464 475 return QQ(k)/QQ(self.nrows()*self.ncols()) 476 477 cdef _init_linbox(self): 478 _sig_on 479 linbox.set(self.p, self._nrows, self._ncols, self.rows) 480 _sig_off 481 482 def _rank_linbox(self): 483 """ 484 See self.rank(). 485 """ 486 if is_prime(self.p): 487 x = self.fetch('rank') 488 if not x is None: 489 return x 490 self._init_linbox() 491 _sig_on 492 # the returend pivots list is currently wrong 493 #r, pivots = linbox.rank(1) 494 r = linbox.rank(1) 495 r = Integer(r) 496 _sig_off 497 self.cache('rank', r) 498 return r 499 else: 500 raise TypeError, "only GF(p) supported via LinBox" 501 502 def rank(self, gauss=False): 503 """ 504 Compute the rank of self. 505 506 INPUT: 507 gauss -- if True Gaussian elimination is used. If False 508 'Symbolic Reordering' as implemented in LinBox 509 is used. (default: False) 510 511 EXAMPLE: 512 sage: A = random_matrix(GF(127),200,200,density=0.01,sparse=True) 513 sage: r1 = A.rank(gauss=False) 514 sage: r2 = A.rank(gauss=True) 515 sage: r1 == r2 516 True 517 518 ALGORITHM: Uses LinBox or native implementation. 519 520 REFERENCES: Jean-Guillaume Dumas and Gilles Villars. 'Computing the 521 Rank of Large Sparse Matrices over Finite Fields'. Proc. CASC'2002, 522 The Fifth International Workshop on Computer Algebra in Scientific Computing, 523 Big Yalta, Crimea, Ukraine, 22-27 sept. 2002, Springer-Verlag, 524 http://perso.ens-lyon.fr/gilles.villard/BIBLIOGRAPHIE/POSTSCRIPT/rankjgd.ps 525 526 NOTE: 527 For very sparse matrices Gaussian elimination is faster because 528 it barly has anything to do. If the fill in needs to be considered, 529 'Symbolic Reordering' is usually much faster. 530 """ 531 x = self.fetch('rank') 532 if not x is None: return x 533 534 if is_prime(self.p) and not gauss: 535 return self._rank_linbox() 536 else: 537 return Matrix0.rank(self) 538 539 def transpose(self): 540 """ 541 Return the transpose of self. 542 543 EXAMPLE: 544 sage: A = matrix(GF(127),3,3,[0,1,0,2,0,0,3,0,0],sparse=True) 545 sage: A 546 [0 1 0] 547 [2 0 0] 548 [3 0 0] 549 sage: A.transpose() 550 [0 2 3] 551 [1 0 0] 552 [0 0 0] 553 """ 554 cdef int i, j 555 cdef c_vector_modint row 556 cdef Matrix_modn_sparse B 557 558 B = self.new_matrix(nrows = self.ncols(), ncols = self.nrows()) 559 for i from 0 <= i < self._nrows: 560 row = self.rows[i] 561 for j from 0 <= j < row.num_nonzero: 562 set_entry(&B.rows[row.positions[j]], i, row.entries[j]) 563 return B 564 565 def matrix_from_rows(self, rows): 566 """ 567 Return the matrix constructed from self using rows with indices 568 in the rows list. 569 570 INPUT: 571 rows -- list or tuple of row indices 572 573 EXAMPLE: 574 sage: M = MatrixSpace(GF(127),3,3,sparse=True) 575 sage: A = M(range(9)); A 576 [0 1 2] 577 [3 4 5] 578 [6 7 8] 579 sage: A.matrix_from_rows([2,1]) 580 [6 7 8] 581 [3 4 5] 582 """ 583 cdef int i,k 584 cdef Matrix_modn_sparse A 585 cdef c_vector_modint row 586 587 if not isinstance(rows, (list, tuple)): 588 raise TypeError, "rows must be a list of integers" 589 590 591 A = self.new_matrix(nrows = len(rows)) 592 593 k = 0 594 for ii in rows: 595 i = ii 596 if i < 0 or i >= self.nrows(): 597 raise IndexError, "row %s out of range"%i 598 599 row = self.rows[i] 600 for j from 0 <= j < row.num_nonzero: 601 set_entry(&A.rows[k], row.positions[j], row.entries[j]) 602 k += 1 603 return A 604 605 606 def matrix_from_columns(self, cols): 607 """ 608 Return the matrix constructed from self using columns with 609 indices in the columns list. 610 611 EXAMPLES: 612 sage: M = MatrixSpace(GF(127),3,3,sparse=True) 613 sage: A = M(range(9)); A 614 [0 1 2] 615 [3 4 5] 616 [6 7 8] 617 sage: A.matrix_from_columns([2,1]) 618 [2 1] 619 [5 4] 620 [8 7] 621 """ 622 cdef int i,j 623 cdef Matrix_modn_sparse A 624 cdef c_vector_modint row 625 626 if not isinstance(cols, (list, tuple)): 627 raise TypeError, "rows must be a list of integers" 628 629 A = self.new_matrix(ncols = len(cols)) 630 631 cols = dict(zip([int(e) for e in cols],range(len(cols)))) 632 633 for i from 0 <= i < self.nrows(): 634 row = self.rows[i] 635 for j from 0 <= j < row.num_nonzero: 636 if int(row.positions[j]) in cols: 637 set_entry(&A.rows[i], cols[int(row.positions[j])], row.entries[j]) 638 return A 639 640 ## def _solve(self, Matrix_modn_sparse B): 641 ## """ 642 ## """ 643 ## cdef c_vector_modint *X 644 645 ## cdef Matrix_modn_sparse C 646 647 ## if not self.is_square(): 648 ## raise NotImplementedError, "input matrix must be square" 649 650 ## if self.rank() != self.nrows(): 651 ## raise ValueError, "input matrix must have full rank but it doesn't" 652 653 ## self._init_linbox() 654 655 ## matrix = True 656 ## if is_Vector(B): 657 ## matrix = False 658 ## C = self.matrix_space(1,self.nrows())(B.list()) 659 660 ## #_sig_on 661 ## linbox.solve(&X, C.rows) 662 ## #_sig_off 663 664 ## ## X = None 665 ## ## if not matrix: 666 ## ## # Convert back to a vector 667 ## ## return (X.base_ring() ** X.nrows())(X.list()) 668 ## ## else: 669 ## ## return X
