Ticket #3376: m4ri_strassen_standard.patch

File m4ri_strassen_standard.patch, 16.6 KB (added by malb, 11 years ago)
  • sage/matrix/matrix_mod2_dense.pxd

    diff -r 446f71aa25cb sage/matrix/matrix_mod2_dense.pxd
    a b cdef extern from "m4ri/m4ri.h": 
    1010        int width
    1111        int *rowswap
    1212
     13    ctypedef struct permutation:
     14        int *values
     15        int size
    1316
    1417    ctypedef int BIT
    1518
    cdef extern from "m4ri/m4ri.h": 
    6366    # set BIT
    6467    cdef void mzd_write_bit( packedmatrix *m, int row, int col, BIT value)
    6568
     69    cdef void mzd_write_zeroed_bits(packedmatrix *m, int x, int y, int n, word values)
     70     
     71    cdef void mzd_clear_bits(packedmatrix *m, int x, int y, int n)
     72
    6673    # get BIT
    6774    cdef BIT mzd_read_bit( packedmatrix *m, int row, int col )
     75
     76    # get BITs (n<=64)
     77    cdef word mzd_read_bits( packedmatrix *m, int row, int col, int n)
     78   
    6879
    6980    ######################
    7081    # Low-Level Arithmetic
    cdef extern from "m4ri/m4ri.h": 
    7788    cdef void mzd_row_clear_offset(packedmatrix *m, int, int)
    7889
    7990    cdef void mzd_row_add_offset(packedmatrix *m, int, int, int)
     91
     92    cdef permutation *mzd_col_block_rotate(packedmatrix *M, int ,int, int, int, permutation *)
    8093
    8194    ############
    8295    # Arithmetic
    cdef extern from "m4ri/m4ri.h": 
    98111    cdef packedmatrix *mzd_addmul_m4rm(packedmatrix *, packedmatrix *, packedmatrix *, int k)
    99112
    100113    # matrix multiplication via Strassen's formula
    101     cdef packedmatrix *mzd_mul_strassen(packedmatrix *, packedmatrix *, packedmatrix *, int cutoff)
     114    cdef packedmatrix *mzd_mul(packedmatrix *, packedmatrix *, packedmatrix *, int cutoff)
    102115
    103116    # C = C + AB via Strassen's formula
    104     cdef packedmatrix *mzd_addmul_strassen(packedmatrix *, packedmatrix *, packedmatrix *, int cutoff)
     117    cdef packedmatrix *mzd_addmul(packedmatrix *, packedmatrix *, packedmatrix *, int cutoff)
    105118
    106119    # equality testing
    107120    cdef int mzd_equal(packedmatrix *, packedmatrix *)
    cdef class Matrix_mod2_dense(matrix_dens 
    133146    cdef object _zero
    134147
    135148
    136     cdef Matrix_mod2_dense _multiply_m4rm_c(Matrix_mod2_dense self, Matrix_mod2_dense right, int k)
     149    cpdef Matrix_mod2_dense _multiply_m4rm(Matrix_mod2_dense self, Matrix_mod2_dense right, int k)
     150    cpdef Matrix_mod2_dense _multiply_strassen(Matrix_mod2_dense self, Matrix_mod2_dense right, int cutoff)
  • sage/matrix/matrix_mod2_dense.pyx

    diff -r 446f71aa25cb sage/matrix/matrix_mod2_dense.pyx
    a b cdef class Matrix_mod2_dense(matrix_dens 
    391391            verbose('matrix multiply of %s x %s matrix by %s x %s matrix'%(
    392392                self._nrows, self._ncols, right._nrows, right._ncols))
    393393
    394         cdef int n = self._ncols
    395         return self._multiply_m4rm_c(right,0)
     394        return self._multiply_strassen(right, 0)
    396395
    397     def _multiply_m4rm(Matrix_mod2_dense self, Matrix_mod2_dense right, k=0, transpose=False):
     396    cpdef Matrix_mod2_dense _multiply_m4rm(Matrix_mod2_dense self, Matrix_mod2_dense right, int k):
    398397        """
    399398        Multiply matrices using the 'Method of the Four Russians
    400399        Multiplication' (M4RM) or Konrod's method.
    cdef class Matrix_mod2_dense(matrix_dens 
    422421              [0 0 1 0]
    423422              [1 0 0 1]
    424423              [1 1 0 0]
    425               sage: A._multiply_m4rm(B)
     424              sage: A._multiply_m4rm(B, 0)
    426425              [0 0 0 0]
    427426              [1 0 0 1]
    428427              [0 1 0 1]
    429428              [1 1 0 0]
     429
     430        TESTS:
     431            sage: A = random_matrix(GF(2),0,0)
     432            sage: B = random_matrix(GF(2),0,0)
     433            sage: A._multiply_m4rm(B, 0)
     434            []
     435            sage: A = random_matrix(GF(2),3,0)
     436            sage: B = random_matrix(GF(2),0,3)
     437            sage: A._multiply_m4rm(B, 0)
     438            [0 0 0]
     439            [0 0 0]
     440            [0 0 0]
     441            sage: A = random_matrix(GF(2),0,3)
     442            sage: B = random_matrix(GF(2),3,0)
     443            sage: A._multiply_m4rm(B, 0)
     444            []
    430445
    431446        ALGORITHM: Uses the 'Method of the Four Russians'
    432447        multiplication as implemented in the M4RI library.
    cdef class Matrix_mod2_dense(matrix_dens 
    452467        if self._ncols != right._nrows:
    453468            raise ArithmeticError, "left ncols must match right nrows"
    454469
    455         return self._multiply_m4rm_c(right, 0)
    456        
    457     cdef Matrix_mod2_dense _multiply_m4rm_c(Matrix_mod2_dense self, Matrix_mod2_dense right, int k):
    458         """
    459         TESTS:
    460             sage: A = random_matrix(GF(2),0,0)
    461             sage: B = random_matrix(GF(2),0,0)
    462             sage: A._multiply_m4rm(B)
    463             []
    464             sage: A = random_matrix(GF(2),3,0)
    465             sage: B = random_matrix(GF(2),0,3)
    466             sage: A._multiply_m4rm(B)
    467             [0 0 0]
    468             [0 0 0]
    469             [0 0 0]
    470             sage: A = random_matrix(GF(2),0,3)
    471             sage: B = random_matrix(GF(2),3,0)
    472             sage: A._multiply_m4rm(B)
    473             []
    474         """
    475470        if get_verbose() >= 2:
    476471            verbose('m4rm multiply of %s x %s matrix by %s x %s matrix'%(
    477472                self._nrows, self._ncols, right._nrows, right._ncols))
    cdef class Matrix_mod2_dense(matrix_dens 
    485480        ans._entries = mzd_mul_m4rm(ans._entries, self._entries, right._entries, k)
    486481        _sig_off
    487482        return ans
    488 
    489483
    490484    def _multiply_classical(Matrix_mod2_dense self, Matrix_mod2_dense right):
    491485        r"""
    cdef class Matrix_mod2_dense(matrix_dens 
    536530        A._entries = mzd_mul_naiv(A._entries, self._entries,(<Matrix_mod2_dense>right)._entries)
    537531        return A
    538532
    539     def _multiply_strassen(self, Matrix_mod2_dense right, cutoff=2048):
     533    cpdef Matrix_mod2_dense _multiply_strassen(Matrix_mod2_dense self, Matrix_mod2_dense right, int cutoff):
    540534        """
    541535        Strassen-Winograd $O(n^{2.807})$ multiplication [Str69].
    542536
    cdef class Matrix_mod2_dense(matrix_dens 
    554548        INPUT:
    555549            right -- a matrix of matching dimensions.
    556550            cutoff -- matrix dimension where M4RM should be used
    557                       instead of Strassen (default: 2048)
     551                      instead of Strassen (default: let M4RI decide)
    558552
    559553        EXAMPLE:
    560554              sage: A = Matrix(GF(2), 4, 3, [0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1] )
    cdef class Matrix_mod2_dense(matrix_dens 
    568562              [0 0 1 0]
    569563              [1 0 0 1]
    570564              [1 1 0 0]
    571               sage: A._multiply_strassen(B)
     565              sage: A._multiply_strassen(B, 0)
    572566              [0 0 0 0]
    573567              [1 0 0 1]
    574568              [0 1 0 1]
    575569              [1 1 0 0]
    576570              sage: A = random_matrix(GF(2),2701,3000)
    577571              sage: B = random_matrix(GF(2),3000,3172)
    578               sage: A._multiply_strassen(B, cutoff=1024) == A._multiply_m4rm(B)
     572              sage: A._multiply_strassen(B, 256) == A._multiply_m4rm(B, 0)
    579573              True
    580574
    581575        TESTS:
    582576            sage: A = random_matrix(GF(2),0,0)
    583577            sage: B = random_matrix(GF(2),0,0)
    584             sage: A._multiply_strassen(B)
     578            sage: A._multiply_strassen(B, 0)
    585579            []
    586580            sage: A = random_matrix(GF(2),3,0)
    587581            sage: B = random_matrix(GF(2),0,3)
    588             sage: A._multiply_strassen(B)
     582            sage: A._multiply_strassen(B, 0)
    589583            [0 0 0]
    590584            [0 0 0]
    591585            [0 0 0]
    592586            sage: A = random_matrix(GF(2),0,3)
    593587            sage: B = random_matrix(GF(2),3,0)
    594             sage: A._multiply_strassen(B)
     588            sage: A._multiply_strassen(B, 0)
    595589            []
    596590
    597591        ALGORITHM: Uses Strassen-Winograd matrix multiplication with
    cdef class Matrix_mod2_dense(matrix_dens 
    616610        ans = self.new_matrix(nrows = self.nrows(), ncols = right.ncols())
    617611        if self._nrows == 0 or self._ncols == 0 or right._ncols == 0:
    618612            return ans
     613
    619614        _sig_on
    620         ans._entries = mzd_mul_strassen(ans._entries, self._entries, right._entries, cutoff)
     615        ans._entries = mzd_mul(ans._entries, self._entries, right._entries, cutoff)
    621616        _sig_off
    622617        return ans
    623618
    cdef class Matrix_mod2_dense(matrix_dens 
    10071002            [0 1 1]
    10081003            [0 0 0]
    10091004            sage: A.swap_columns(0,1); A
     1005            [1 0 0]
     1006            [1 0 1]
     1007            [0 0 0]
    10101008        """
    10111009        mzd_col_swap(self._entries, col1, col2)
    10121010   
    def to_png(Matrix_mod2_dense A, filename 
    13941392    gdImagePng(im, out)
    13951393    gdImageDestroy(im)
    13961394    fclose(out)
     1395
     1396
     1397
     1398
     1399# This is basically test code, do not call it will break Sage's
     1400# assumptions about matrices (malb).
     1401
     1402def _read_bits(Matrix_mod2_dense A, int x, int y, int n):
     1403    return mzd_read_bits(A._entries, x, y, n)
     1404
     1405def _write_zeroed_bits(Matrix_mod2_dense A, int x, int y, int n, unsigned long values):
     1406    """
     1407    EXAMPLE:
     1408        sage: A = matrix(GF(2),4,66)
     1409        sage: sage.matrix.matrix_mod2_dense._write_zeroed_bits(A,0,0,4,13)
     1410        sage: print A.str()
     1411        [1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1412        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1413        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1414        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1415        sage: ZZ(sage.matrix.matrix_mod2_dense._read_bits(A,0,0,4))
     1416        13
     1417
     1418        sage: sage.matrix.matrix_mod2_dense._write_zeroed_bits(A,1,1,4,13)
     1419        sage: print A.str()
     1420        [1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1421        [0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1422        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1423        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1424        sage: ZZ(sage.matrix.matrix_mod2_dense._read_bits(A,1,1,4))
     1425        13
     1426
     1427        sage: sage.matrix.matrix_mod2_dense._write_zeroed_bits(A,2,0,64,2^63 + 2^62 + 1)
     1428        sage: print A.str()
     1429        [1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1430        [0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1431        [1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0]
     1432        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1433        sage: ZZ(sage.matrix.matrix_mod2_dense._read_bits(A,2,0,64))
     1434        13835058055282163713
     1435
     1436        sage: sage.matrix.matrix_mod2_dense._write_zeroed_bits(A,3,1,64,2^63 + 2^62 + 1)
     1437        sage: print A.str()
     1438        [1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1439        [0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     1440        [1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0]
     1441        [0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0]
     1442        sage: ZZ(sage.matrix.matrix_mod2_dense._read_bits(A,3,1,64))
     1443        13835058055282163713
     1444    """
     1445    mzd_write_zeroed_bits(A._entries, x, y, n, values)
     1446
     1447def _clear_bits(Matrix_mod2_dense A, int x, int y, int n):
     1448    """
     1449    EXAMPLE:
     1450        sage: A = matrix(GF(2),3,66)
     1451        sage: for i in range(A.nrows()):
     1452        ...      for j in range(A.ncols()):
     1453        ...          A[i,j] = 1
     1454
     1455        sage: print A.str()
     1456        [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1457        [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1458        [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1459
     1460        sage: sage.matrix.matrix_mod2_dense._clear_bits(A,0,0,3)
     1461        sage: sage.matrix.matrix_mod2_dense._clear_bits(A,1,1,3)
     1462        sage: print A.str()
     1463        [0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1464        [1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1465        [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1466
     1467        sage: sage.matrix.matrix_mod2_dense._clear_bits(A,0,0,64)
     1468        sage: sage.matrix.matrix_mod2_dense._clear_bits(A,1,1,64)
     1469        sage: print A.str()
     1470        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1]
     1471        [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
     1472        [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
     1473    """
     1474    mzd_clear_bits(A._entries, x, y, n)
     1475
     1476   
     1477def _addmul(Matrix_mod2_dense C, Matrix_mod2_dense A, Matrix_mod2_dense B, int cutoff):
     1478    """
     1479    EXAMPLE:
     1480        sage: def check_addmul(m,k,n, cutoff):
     1481        ...     A = random_matrix(GF(2),m, k)
     1482        ...     B = random_matrix(GF(2),k, n)
     1483        ...     C = random_matrix(GF(2),m, n)
     1484        ...     D1 = C + A*B
     1485        ...     D2 = sage.matrix.matrix_mod2_dense._addmul(C,A,B, cutoff=cutoff)
     1486        ...     if D1 != D2:
     1487        ...      return False
     1488        ...     else:
     1489        ...      return True
     1490       
     1491        sage: check_addmul(1000,1000,1000, 256)
     1492        True
     1493        sage: check_addmul(1000,10,20, 64)
     1494        True
     1495        sage: check_addmul(1710,1290,1000, 256)
     1496        True
     1497        sage: check_addmul(1290, 1710, 200, 64)
     1498        True
     1499        sage: check_addmul(1290, 1710, 2000, 256)
     1500        True
     1501        sage: check_addmul(1290, 1290, 2000, 64)
     1502        True
     1503    """
     1504    cdef Matrix_mod2_dense D = <Matrix_mod2_dense>C.copy()
     1505    mzd_addmul(D._entries, A._entries, B._entries, cutoff)
     1506    return D
     1507
     1508def _col_block_rotate(Matrix_mod2_dense A, int zs, int ze, int de):
     1509    """
     1510    EXAMPLE:
     1511       sage: A = matrix(GF(2), 10, 128)
     1512       sage: for i in range(10):
     1513       ...     A[i,i+10] = 1
     1514       ...     for j in range(20,A.ncols()):
     1515       ...       A[i,j] = 1
     1516       ...
     1517
     1518       sage: sage.matrix.matrix_mod2_dense._col_block_rotate(A, 0, 10, A.ncols())
     1519       sage: A.submatrix(0,0,10,10)
     1520       [1 0 0 0 0 0 0 0 0 0]
     1521       [0 1 0 0 0 0 0 0 0 0]
     1522       [0 0 1 0 0 0 0 0 0 0]
     1523       [0 0 0 1 0 0 0 0 0 0]
     1524       [0 0 0 0 1 0 0 0 0 0]
     1525       [0 0 0 0 0 1 0 0 0 0]
     1526       [0 0 0 0 0 0 1 0 0 0]
     1527       [0 0 0 0 0 0 0 1 0 0]
     1528       [0 0 0 0 0 0 0 0 1 0]
     1529       [0 0 0 0 0 0 0 0 0 1]
     1530
     1531       sage: A.submatrix(0,10,10,10)
     1532       [1 1 1 1 1 1 1 1 1 1]
     1533       [1 1 1 1 1 1 1 1 1 1]
     1534       [1 1 1 1 1 1 1 1 1 1]
     1535       [1 1 1 1 1 1 1 1 1 1]
     1536       [1 1 1 1 1 1 1 1 1 1]
     1537       [1 1 1 1 1 1 1 1 1 1]
     1538       [1 1 1 1 1 1 1 1 1 1]
     1539       [1 1 1 1 1 1 1 1 1 1]
     1540       [1 1 1 1 1 1 1 1 1 1]
     1541       [1 1 1 1 1 1 1 1 1 1]
     1542
     1543       sage: A.submatrix(0,100,10,28)
     1544       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1545       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1546       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1547       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1548       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1549       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1550       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1551       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1552       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1553       [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
     1554    """
     1555    mzd_col_block_rotate(A._entries, zs, ze, de, 1, NULL)