Ticket #10734: trac_10734-dense_matrix_and_submatrix-folded.patch

File trac_10734-dense_matrix_and_submatrix-folded.patch, 12.1 KB (added by David Loeffler, 11 years ago)

Apply only this patch. Patch against 5.0.beta7

  • module_list.py

    # HG changeset patch
    # User Gonzalo Tornaría <tornaria@cmat.edu.uy>
    # Date 1296612000 7200
    # Node ID e489ec9e4b02003a4e75eb31c01701513eee7490
    # Parent  68e89260148df131fec1708338ceba3ea964b2bb
    #10734: Matrix_modn_sparse speed improvements
    Implement optimized versions of submatrix(), dense_matrix(), add methods
    dense_submatrix() and set_block_unsafe()
    
    diff --git a/module_list.py b/module_list.py
    a b  
    966966              libraries = ['gmp', 'linbox', 'givaro', BLAS, BLAS2],
    967967              extra_compile_args = ['-DDISABLE_COMMENTATOR']),
    968968
     969    Extension('sage.matrix.matrix_mod_dense',
     970              sources = ['sage/matrix/matrix_mod_dense.pyx']),
     971
    969972    Extension('sage.matrix.matrix_modn_sparse',
    970973              sources = ['sage/matrix/matrix_modn_sparse.pyx'],
    971974              libraries = ['gmp']),
  • sage/matrix/matrix_mod2_dense.pxd

    diff --git a/sage/matrix/matrix_mod2_dense.pxd b/sage/matrix/matrix_mod2_dense.pxd
    a b  
    11# choose: dense or sparse
    22
    3 cimport matrix_dense
     3from matrix_mod_dense cimport Matrix_mod_dense
    44
    55from sage.libs.m4ri cimport *
    66
    7 cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense):
     7cdef class Matrix_mod2_dense(Matrix_mod_dense):
    88    cdef mzd_t *_entries
    99    cdef object _one
    1010    cdef object _zero
    1111
    12     cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value)
    13 
    1412    cpdef Matrix_mod2_dense _multiply_m4rm(Matrix_mod2_dense self, Matrix_mod2_dense right, int k)
    1513    cpdef Matrix_mod2_dense _multiply_strassen(Matrix_mod2_dense self, Matrix_mod2_dense right, int cutoff)
    1614
  • sage/matrix/matrix_mod2_dense.pyx

    diff --git a/sage/matrix/matrix_mod2_dense.pyx b/sage/matrix/matrix_mod2_dense.pyx
    a b  
    149149
    150150   
    151151
    152 cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense):   # dense or sparse
     152cdef class Matrix_mod2_dense(Matrix_mod_dense):
    153153    """
    154154    Dense matrix over GF(2).
    155155    """
     
    431431    cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, value):
    432432        mzd_write_bit(self._entries, i, j, int(value))
    433433
     434    # this exists for compatibility with matrix_modn_dense
     435    cdef int get_unsafe_int(self, Py_ssize_t i, Py_ssize_t j):
     436        """
     437        Get the (i,j) entry of self as an int.
     438        """
     439        if mzd_read_bit(self._entries, i, j):
     440            return 1
     441        else:
     442            return 0
     443
    434444    cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
    435445        if mzd_read_bit(self._entries, i, j):
    436446            return self._one
  • new file sage/matrix/matrix_mod_dense.pxd

    diff --git a/sage/matrix/matrix_mod_dense.pxd b/sage/matrix/matrix_mod_dense.pxd
    new file mode 100644
    - +  
     1cimport matrix_dense
     2
     3cdef class Matrix_mod_dense(matrix_dense.Matrix_dense):
     4    cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value)
     5    cdef int get_unsafe_int(self, Py_ssize_t i, Py_ssize_t j)
     6
     7
  • new file sage/matrix/matrix_mod_dense.pyx

    diff --git a/sage/matrix/matrix_mod_dense.pyx b/sage/matrix/matrix_mod_dense.pyx
    new file mode 100644
    - +  
     1cdef class Matrix_mod_dense(matrix_dense.Matrix_dense):
     2    cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value):
     3        raise NotImplementedError
     4
     5    cdef int get_unsafe_int(self, Py_ssize_t i, Py_ssize_t j):
     6        raise NotImplementedError
  • sage/matrix/matrix_modn_dense.pxd

    diff --git a/sage/matrix/matrix_modn_dense.pxd b/sage/matrix/matrix_modn_dense.pxd
    a b  
    11cimport matrix_dense
     2from matrix_mod_dense cimport Matrix_mod_dense
    23
    34cdef extern from "../ext/multi_modular.h":
    45    ctypedef unsigned long mod_int
    56    mod_int MOD_INT_OVERFLOW
    67
    7 cdef class Matrix_modn_dense(matrix_dense.Matrix_dense):
     8cdef class Matrix_modn_dense(Matrix_mod_dense):
    89    cdef mod_int **_matrix
    910    cdef mod_int *_entries
    1011    cdef mod_int p
     
    1314    #cdef set_matrix(Matrix_modn_dense self, mod_int **m)
    1415    #cdef mod_int **get_matrix(Matrix_modn_dense self)
    1516    #cdef mod_int entry(self, mod_int i, mod_int j)
    16     cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value)
    1717    cdef _rescale_row_c(self, Py_ssize_t row, mod_int multiple, Py_ssize_t start_col)
    1818    cdef _rescale_col_c(self, Py_ssize_t col, mod_int multiple, Py_ssize_t start_row)   
    1919    cdef _add_multiple_of_row_c(self,  Py_ssize_t row_to, Py_ssize_t row_from,
  • sage/matrix/matrix_modn_dense.pyx

    diff --git a/sage/matrix/matrix_modn_dense.pyx b/sage/matrix/matrix_modn_dense.pyx
    a b  
    165165#                  http://www.gnu.org/licenses/
    166166##############################################################################
    167167
    168 cdef class Matrix_modn_dense(matrix_dense.Matrix_dense): 
     168cdef class Matrix_modn_dense(Matrix_mod_dense):
    169169    ########################################################################
    170170    # LEVEL 1 functionality
    171171    # x * __cinit__ 
     
    361361        """       
    362362        self._matrix[i][j] = (<IntegerMod_int> value).ivalue
    363363
     364    cdef int get_unsafe_int(self, Py_ssize_t i, Py_ssize_t j):
     365        """
     366        Get the (i,j) entry of self as an int value, no checks.
     367        """
     368        return self._matrix[i][j]
     369
    364370    cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
    365371        cdef IntegerMod_int n
    366372        n =  IntegerMod_int.__new__(IntegerMod_int)
  • sage/matrix/matrix_modn_sparse.pxd

    diff --git a/sage/matrix/matrix_modn_sparse.pxd b/sage/matrix/matrix_modn_sparse.pxd
    a b  
     1include '../modules/vector_modn_sparse_h.pxi'
     2
    13cimport matrix_sparse
     4cimport matrix_dense
    25
    3 include '../modules/vector_modn_sparse_h.pxi'
     6from matrix_mod_dense cimport Matrix_mod_dense
     7
     8
    49
    510cdef class Matrix_modn_sparse(matrix_sparse.Matrix_sparse):   
    611    cdef c_vector_modint* rows
    712    cdef public int p
    813    cdef swap_rows_c(self, Py_ssize_t n1, Py_ssize_t n2)
     14    cdef set_block_unsafe(self, Py_ssize_t row, Py_ssize_t col, Matrix_mod_dense block)
    915
    1016    cdef _init_linbox(self)
  • sage/matrix/matrix_modn_sparse.pyx

    diff --git a/sage/matrix/matrix_modn_sparse.pyx b/sage/matrix/matrix_modn_sparse.pyx
    a b  
    8080include '../modules/vector_modn_sparse_c.pxi'
    8181
    8282cimport matrix
    83 cimport matrix_sparse
    84 cimport matrix_dense
    8583from sage.rings.finite_rings.integer_mod cimport IntegerMod_int, IntegerMod_abstract
    8684
    8785from sage.misc.misc import verbose, get_verbose, graphics_filename
     
    9492from sage.structure.element import is_Vector
    9593
    9694cimport sage.structure.element
    97 from matrix_modn_dense cimport Matrix_modn_dense
    9895
    9996include '../modules/binary_search.pxi'
    10097include '../modules/vector_integer_sparse_h.pxi'
     
    528525        self.cache('pivots',tuple(pivots))
    529526        self.cache('in_echelon_form',True)
    530527
     528    def submatrix(self, Py_ssize_t row=0, Py_ssize_t col=0,
     529                        Py_ssize_t nrows=-1, Py_ssize_t ncols=-1):
     530        """
     531        Return the matrix constructed from self using the specified
     532        range of rows and columns.
     533
     534        INPUT:
     535
     536        - ``row``, ``col`` - index of the starting row and column.
     537          Indices start at zero.
     538
     539        - ``nrows``, ``ncols`` - (optional) number of rows and columns to
     540          take. If not provided, take all rows below and all columns to
     541          the right of the starting entry.
     542
     543        SEE ALSO:
     544
     545        The functions :func:`matrix_from_rows`,
     546        :func:`matrix_from_columns`, and
     547        :func:`matrix_from_rows_and_columns` allow one to select
     548        arbitrary subsets of rows and/or columns.
     549
     550        EXAMPLES:
     551
     552        Take a `3 \\times 3` submatrix of a sparse matrix::
     553
     554            sage: A = matrix(Integers(7), 100, 100, sparse=True)
     555            sage: A[25,25] = 1 ; A[26,24] = 2 ; A[24,26] = 3
     556            sage: A.submatrix(24,24,3,3)
     557            [0 0 3]
     558            [0 1 0]
     559            [2 0 0]
     560
     561        Note that the result is a sparse matrix::
     562
     563            sage: parent(A.submatrix(20,20,50,50))
     564            Full MatrixSpace of 50 by 50 sparse matrices over Ring of integers modulo 7
     565        """
     566        cdef Py_ssize_t i, j, pos
     567        cdef Matrix_modn_sparse M
     568
     569        if nrows == -1:
     570           nrows = self._nrows - row
     571        if ncols == -1:
     572           ncols = self._ncols - col
     573
     574        M = self.new_matrix(nrows, ncols)
     575        for i from 0 <= i < nrows:
     576            for j from 0 <= j < self.rows[row+i].num_nonzero:
     577                pos = self.rows[row+i].positions[j] - col
     578                if 0 <= pos < ncols:
     579                    set_entry(&M.rows[i], pos, self.rows[row+i].entries[j])
     580        return M
     581
     582    def dense_matrix(self):
     583        """
     584        If this matrix is sparse, return a dense matrix with the same
     585        entries. If this matrix is dense, return this matrix (not a copy).
     586
     587        .. note::
     588
     589           The definition of "dense" and "sparse" in Sage have nothing to
     590           do with the number of nonzero entries. Sparse and dense are
     591           properties of the underlying representation of the matrix.
     592
     593        EXAMPLES::
     594
     595            sage: A = matrix(Integers(7), 4, [1..16], sparse=True)
     596            sage: A.is_sparse()
     597            True
     598            sage: B = A.dense_matrix()
     599            sage: parent(A)
     600            Full MatrixSpace of 4 by 4 sparse matrices over Ring of integers modulo 7
     601            sage: parent(B)
     602            Full MatrixSpace of 4 by 4 dense matrices over Ring of integers modulo 7
     603        """
     604        cdef Py_ssize_t i, j
     605        cdef Matrix_mod_dense M
     606
     607        M = self.new_matrix(self._nrows, self._ncols, sparse=False)
     608        for i from 0 <= i < self._nrows:
     609            for j from 0 <= j < self.rows[i].num_nonzero:
     610                M.set_unsafe_int(i, self.rows[i].positions[j], self.rows[i].entries[j])
     611        M.subdivide(self.get_subdivisions())
     612        return M
     613
     614    def dense_submatrix(self, Py_ssize_t row=0, Py_ssize_t col=0,
     615                              Py_ssize_t nrows=-1, Py_ssize_t ncols=-1):
     616        """
     617        Return the matrix constructed from self using the specified
     618        range of rows and columns, as a dense matrix.
     619
     620        INPUT:
     621
     622        - ``row``, ``col`` - index of the starting row and column.
     623          Indices start at zero.
     624
     625        - ``nrows``, ``ncols`` - (optional) number of rows and columns to
     626          take. If not provided, take all rows below and all columns to
     627          the right of the starting entry.
     628
     629        EXAMPLES::
     630
     631        Take a `3 \\times 3` submatrix of a sparse matrix::
     632
     633            sage: A = matrix(Integers(7), 100, 100, sparse=True)
     634            sage: A[25,25] = 1 ; A[26,24] = 2 ; A[24,26] = 3
     635            sage: A.dense_submatrix(24,24,3,3)
     636            [0 0 3]
     637            [0 1 0]
     638            [2 0 0]
     639
     640        Note that the result is a dense matrix::
     641
     642            sage: parent(A.dense_submatrix(20,20,50,50))
     643            Full MatrixSpace of 50 by 50 dense matrices over Ring of integers modulo 7
     644            sage: A.dense_submatrix(20,20,50,50) == A.submatrix(20,20,50,50)
     645            True
     646        """
     647        cdef Py_ssize_t i, j, pos
     648        cdef Matrix_mod_dense M
     649
     650        if nrows == -1:
     651            nrows = self._nrows - row
     652        if ncols == -1:
     653            ncols = self._ncols - col
     654
     655        M = self.new_matrix(nrows, ncols, sparse=False)
     656        for i from 0 <= i < nrows:
     657            for j from 0 <= j < self.rows[row+i].num_nonzero:
     658                pos = self.rows[row+i].positions[j] - col
     659                if 0 <= pos < ncols:
     660                    M.set_unsafe_int(i, pos, self.rows[row+i].entries[j])
     661        return M
     662
     663    cdef set_block_unsafe(self, Py_ssize_t row, Py_ssize_t col, Matrix_mod_dense block):
     664        """
     665        Sets the sub-matrix of self, with upper left corner given by row,
     666        col to block. No checks.
     667        """
     668        cdef Py_ssize_t i, j
     669        for i from 0 <= i < block.nrows():
     670            for j from 0 <= j < block.ncols():
     671                set_entry(&self.rows[row+i], col+j, block.get_unsafe_int(i,j))
     672
    531673    def _nonzero_positions_by_row(self, copy=True):
    532674        """
    533675        Returns the list of pairs (i,j) such that self[i,j] != 0.