Ticket #4492: 4492_block_matrix.patch

File 4492_block_matrix.patch, 26.4 KB (added by wjp, 11 years ago)

block_matrix rewrite. Replaces all previous patches.

  • sage/combinat/designs/incidence_structures.py

    # HG changeset patch
    # User Willem Jan Palenstijn <wjp@usecode.org>
    # Date 1294869358 -3600
    # Node ID 6c8a4e251d968b53f2b3ae7c3b0e495c56d7274f
    # Parent  c58f82863c75b2e53662e08cd550bb398653174c
    #4492: rewrite block_matrix constructor
    
    It is now much more consistent with Matrix(),
    and will deduce dimensions automatically in more cases.
    
    diff -r c58f82863c75 -r 6c8a4e251d96 sage/combinat/designs/incidence_structures.py
    a b  
    463463            sage: BD.incidence_graph()
    464464            Bipartite graph on 14 vertices
    465465            sage: A = BD.incidence_matrix()
    466             sage: Graph(block_matrix([A*0,A,A.transpose(),A*0])) == BD.incidence_graph()
     466            sage: Graph(block_matrix([[A*0,A],[A.transpose(),A*0]])) == BD.incidence_graph()
    467467            True
    468468       
    469469        REFERENCE:
     
    473473        from sage.graphs.bipartite_graph import BipartiteGraph
    474474        A = self.incidence_matrix()
    475475        return BipartiteGraph(A)
    476         #same as return Graph(block_matrix([A*0,A,A.transpose(),A*0]))
     476        #same as return Graph(block_matrix([[A*0,A],[A.transpose(),A*0]]))
    477477
    478478    def is_block_design(self):
    479479        """
  • sage/combinat/matrices/hadamard_matrix.py

    diff -r c58f82863c75 -r 6c8a4e251d96 sage/combinat/matrices/hadamard_matrix.py
    a b  
    114114    else:
    115115        raise ValueError, "The order %s is not covered by the Paley type II construction."%n
    116116    S = matrix(ZZ,[[H2(i,j,p) for i in range(N)] for j in range(N)])
    117     return block_matrix([S+1,S-1,S-1,-S-1])
     117    return block_matrix([[S+1,S-1],[S-1,-S-1]])
    118118
    119119def hadamard_matrix(n):
    120120    """
  • sage/crypto/lattice.py

    diff -r c58f82863c75 -r 6c8a4e251d96 sage/crypto/lattice.py
    a b  
    199199    A_prime = A[n:m].lift().apply_map(minrep)
    200200
    201201    if not dual:
    202         B = block_matrix([ZZ(q), ZZ.zero() , A_prime, ZZ.one() ], 2, 2, \
    203                          False)
     202        B = block_matrix([[ZZ(q), ZZ.zero()], [A_prime, ZZ.one()] ], \
     203                         subdivide=False)
    204204    else:
    205         B = block_matrix([ZZ.one(), -A_prime.transpose(), ZZ.zero(), \
    206                          ZZ(q)], 2 , 2 , False)
     205        B = block_matrix([[ZZ.one(), -A_prime.transpose()], [ZZ.zero(), \
     206                         ZZ(q)]], subdivide=False)
    207207        for i in range(m//2): B.swap_rows(i,m-i-1)
    208208
    209209    if not ntl:
  • sage/matrix/constructor.py

    diff -r c58f82863c75 -r 6c8a4e251d96 sage/matrix/constructor.py
    a b  
    13811381        nents = nrows*ncols
    13821382    return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix([1]*nents)
    13831383
    1384 
    1385 def block_matrix(sub_matrices, nrows=None, ncols=None, subdivide=True):
     1384def _determine_block_matrix_grid(sub_matrices):
    13861385    """
    1387     Returns a larger matrix made by concatenating the sub_matrices
     1386    For internal use. This tries to determine the dimensions
     1387    of rows/columns when assembling the matrices in sub_matrices in a
     1388    rectangular grid. It returns a pair of lists containing
     1389    respectively the sizes of rows and columns.
     1390
     1391    sub_matrices must be a list of lists of matrices. All sublists
     1392    are expected to be the same size.
     1393
     1394    Non-zero scalars are considered to be square matrices of any size,
     1395    and zeroes are considered to be zero matrices of any size.
     1396
     1397    A ValueError is raised if there is insufficient or
     1398    conflicting information.
     1399
     1400    TESTS::
     1401
     1402        sage: from sage.matrix.constructor import _determine_block_matrix_grid
     1403        sage: A = matrix(QQ, 2, 2, [3,9,6,10])
     1404        sage: _determine_block_matrix_grid([[A, A], [A, A]])
     1405        ([2, 2], [2, 2])
     1406
     1407        sage: B = matrix(QQ, 1, 1, [ 1 ] )
     1408        sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )
     1409        sage: _determine_block_matrix_grid([[B, 0], [0, C]])
     1410        ([1, 2], [1, 2])
     1411    """
     1412
     1413    nrows = len(sub_matrices)
     1414    if nrows == 0:
     1415        return ([], [])
     1416    ncols = len(sub_matrices[0])
     1417
     1418    if ncols == 0:
     1419        return ([0] * nrows, [])
     1420
     1421    row_heights = [None] * nrows
     1422    col_widths = [None] * ncols
     1423
     1424    changing = True
     1425    while changing:
     1426        changing = False
     1427        for i in range(nrows):
     1428            for j in range(ncols):
     1429                M = sub_matrices[i][j]
     1430                sub_width = None
     1431                sub_height = None
     1432                if is_Matrix(M):
     1433                    sub_width = M.ncols()
     1434                    sub_height = M.nrows()
     1435                elif M: # non-zero scalar is interpreted as a square matrix
     1436                    if row_heights[i] is None:
     1437                        sub_width = col_widths[j]
     1438                    else:
     1439                        sub_width = row_heights[i]
     1440                    sub_height = sub_width
     1441                if sub_width is not None:
     1442                    if col_widths[j] is None:
     1443                        changing = True
     1444                        col_widths[j] = sub_width
     1445                    elif col_widths[j] != sub_width:
     1446                        raise ValueError, "Incompatible submatrix widths"
     1447                if sub_height is not None:
     1448                    if row_heights[i] is None:
     1449                        changing = True
     1450                        row_heights[i] = sub_height
     1451                    elif row_heights[i] != sub_height:
     1452                        raise ValueError, "Incompatible submatrix heights"
     1453   
     1454    if None in row_heights or None in col_widths:
     1455        if None in row_heights or None in col_widths:
     1456            raise ValueError, "Insufficient information to determine dimensions."
     1457
     1458    return (row_heights, col_widths)
     1459
     1460def _determine_block_matrix_rows(sub_matrices):
     1461    """
     1462    For internal use. This tests if the matrices in sub_matrices
     1463    fit in a rectangular matrix when assembled a row at a time.
     1464
     1465    sub_matrices must be a list of lists of matrices.
     1466
     1467    It returns a pair (row_heights, zero_widths, width) where
     1468    row_heights is the list of row heights, zero_widths is the
     1469    total width filled up by zero matrices per row, and width
     1470    is the total width of the resulting matrix.
     1471
     1472    Non-zero scalars are considered to be square matrices of any size,
     1473    and zeroes are considered to be zero matrices of any size.
     1474
     1475    A ValueError is raised if there is insufficient or
     1476    conflicting information.
     1477
     1478    TESTS::
     1479
     1480        sage: from sage.matrix.constructor import _determine_block_matrix_rows
     1481        sage: A = Matrix(ZZ, 1, 4, [1, 2, 3, 4])
     1482        sage: _determine_block_matrix_rows([ [1, 1], [ A ] ])
     1483        ([2, 1], [0, 0], 4)
     1484
     1485        sage: B = Matrix(ZZ, 2, 2, [1, 2, 3, 4])
     1486        sage: _determine_block_matrix_rows([ [B, B], [B, 1] ])
     1487        ([2, 2], [0, 0], 4)
     1488    """
     1489
     1490    total_height = 0
     1491    total_width = None
     1492
     1493    row_heights = [ None ] * len(sub_matrices)
     1494    zero_widths = [ 0 ] * len(sub_matrices)
     1495
     1496    # We first do a pass to see if we can determine the width
     1497    unknowns = False
     1498    for i in range(len(sub_matrices)):
     1499        R = sub_matrices[i]
     1500        height = None
     1501        # We first do a pass to see if we can determine the height
     1502        # of this row
     1503        found_zeroes = False
     1504        for M in R:
     1505            if is_Matrix(M):
     1506                if height is None:
     1507                    height = M.nrows()
     1508                elif height != M.nrows():
     1509                    raise ValueError, "Incompatible submatrix heights"
     1510            elif not M:
     1511                found_zeroes = True
     1512        if len(R) == 0:
     1513            height = 0
     1514
     1515        # If we have a height, then we know the dimensions of any
     1516        # non-zero scalars, and can maybe compute the width
     1517        if height is not None and not found_zeroes:
     1518            width = 0
     1519            for M in R:
     1520                if is_Matrix(M):
     1521                    width += M.ncols()
     1522                else:
     1523                    # non-zero scalar
     1524                    width += height
     1525            if total_width is None:
     1526                total_width = width
     1527            elif total_width != width:
     1528                raise ValueError, "Incompatible submatrix widths"
     1529            row_heights[i] = height
     1530        else:
     1531            # We don't set height here even if we know it,
     1532            # to signal this row hasn't been fit yet.
     1533            unknowns = True
     1534
     1535    if total_width is None:
     1536        raise ValueError, "Insufficient information to determine submatrix widths"
     1537
     1538    if unknowns:
     1539        # Do a second pass and see if the remaining rows can be
     1540        # determined now that we know the width of the matrix.
     1541        for i in range(len(sub_matrices)):
     1542            if row_heights[i] is not None:
     1543                continue
     1544            R = sub_matrices[i]
     1545            zero_state = 0
     1546            # 0: no zeroes found
     1547            # 1: consecutive zeroes found
     1548            # 2: consecutive zeroes followed by non-zero found
     1549            # 3: non-consecutive zeroes found
     1550            scalars = 0
     1551            width = 0
     1552            height = None
     1553            for j in range(len(R)):
     1554                M = R[j]
     1555                if is_Matrix(M):
     1556                    height = M.nrows()
     1557                    width += M.ncols()
     1558                    if zero_state == 1:
     1559                        zero_state = 2
     1560                elif not M:
     1561                    if zero_state == 0:
     1562                        zero_state = 1
     1563                    elif zero_state == 2:
     1564                        zero_state = 3
     1565                else:
     1566                     scalars += 1
     1567
     1568            remaining_width = total_width - width
     1569            # This remaining width has to be split over the
     1570            # zeroes and (non-zero) scalars
     1571
     1572            if height is not None:
     1573                remaining_width -= scalars * height
     1574                if remaining_width < 0:
     1575                    raise ValueError, "Incompatible submatrix widths"
     1576                if remaining_width > 0 and zero_state == 3:
     1577                    raise ValueError, "Insufficient information to determine submatrix widths"
     1578                if remaining_width > 0 and zero_state == 0:
     1579                    raise ValueError, "Incompatible submatrix widths"
     1580                # otherwise, things fit
     1581                row_heights[i] = height
     1582                zero_widths[i] = remaining_width
     1583            elif zero_state != 0:
     1584                # if we don't know the height, and there are zeroes,
     1585                # we can't determine the height
     1586                raise ValueError, "Insufficient information to determine submatrix heights"
     1587            elif total_width % len(R) != 0:
     1588                raise ValueError, "Incompatible submatrix widths"
     1589            else:
     1590                height = int(total_width / len(R))
     1591                row_heights[i] = height
     1592
     1593    # If we got this far, then everything fits
     1594    return (row_heights, zero_widths, total_width)
     1595
     1596def block_matrix(*args, **kwds): #sub_matrices, nrows=None, ncols=None, subdivide=True):
     1597    """
     1598    Returns a larger matrix made by concatenating submatrices
    13881599    (rows first, then columns). For example, the matrix
    13891600
    13901601    ::
     
    13941605   
    13951606    is made up of submatrices A, B, C, and D.
    13961607   
    1397     INPUT:
     1608    INPUT: The block_matrix command takes a list of submatrices to add
     1609    as blocks, optionally preceded by a ring and the number of block rows
     1610    and block columns, and returns a matrix.
     1611
     1612    The submatrices can be specified as a list of matrices (using
     1613    ``nrows`` and ``ncols`` to determine their layout), or a list
     1614    of lists of matrices, where each list forms a row.
     1615
     1616    -  ``ring`` - the base ring
     1617       
     1618    -  ``nrows`` - the number of block rows
    13981619   
    1399    
    1400     -  ``sub_matrices`` - matrices (must be of the correct
    1401        size, or constants)
    1402    
    1403     -  ``nrows`` - (optional) the number of block rows
    1404    
    1405     -  ``ncols`` - (optional) the number of block cols
     1620    -  ``ncols`` - the number of block cols
     1621
     1622    -  ``sub_matrices`` - matrices (see below for syntax)
    14061623   
    14071624    -  ``subdivide`` - boolean, whether or not to add
    14081625       subdivision information to the matrix
    1409    
     1626
     1627    -  ``sparse`` - boolean, whether to make the resulting matrix sparse
     1628 
    14101629   
    14111630    EXAMPLES::
    14121631   
    14131632        sage: A = matrix(QQ, 2, 2, [3,9,6,10])
    1414         sage: block_matrix([A, -A, ~A, 100*A])
     1633        sage: block_matrix([ [A, -A], [~A, 100*A] ])
    14151634        [    3     9|   -3    -9]
    14161635        [    6    10|   -6   -10]
    14171636        [-----------+-----------]
    14181637        [-5/12   3/8|  300   900]
    14191638        [  1/4  -1/8|  600  1000]
     1639
     1640    If the number of submatrices in each row is the same,
     1641    you can specify the submatrices as a single list too::
     1642
     1643        sage: block_matrix(2, 2, [ A, A, A, A ])
     1644        [ 3  9| 3  9]
     1645        [ 6 10| 6 10]
     1646        [-----+-----]
     1647        [ 3  9| 3  9]
     1648        [ 6 10| 6 10]
     1649
    14201650   
    14211651    One can use constant entries::
    14221652   
    1423         sage: block_matrix([1, A, 0, 1])
     1653        sage: block_matrix([ [1, A], [0, 1] ])
    14241654        [ 1  0| 3  9]
    14251655        [ 0  1| 6 10]
    14261656        [-----+-----]
     
    14311661
    14321662        sage: B = matrix(QQ, 1, 1, [ 1 ] )
    14331663        sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )
    1434         sage: block_matrix([B, 0, 0, C])
     1664        sage: block_matrix([ [B, 0], [0, C] ])
    14351665        [1|0 0]
    14361666        [-+---]
    14371667        [0|2 3]
    14381668        [0|4 5]
    14391669   
    1440     One can specify the number of rows or columns (optional for square
    1441     number of matrices)::
     1670    One can specify the number of rows or columns as keywords too::
    14421671   
    14431672        sage: block_matrix([A, -A, ~A, 100*A], ncols=4)
    14441673        [    3     9|   -3    -9|-5/12   3/8|  300   900]
     
    14501679        [    3     9|   -3    -9|-5/12   3/8|  300   900]
    14511680        [    6    10|   -6   -10|  1/4  -1/8|  600  1000]
    14521681   
    1453     It handle base rings nicely too::
     1682    It handles base rings nicely too::
    14541683   
    14551684        sage: R.<x> = ZZ['x']
    1456         sage: block_matrix([1/2, A, 0, x-1])
     1685        sage: block_matrix(2, 2, [1/2, A, 0, x-1])
    14571686        [  1/2     0|    3     9]
    14581687        [    0   1/2|    6    10]
    14591688        [-----------+-----------]
    14601689        [    0     0|x - 1     0]
    14611690        [    0     0|    0 x - 1]
    1462         sage: block_matrix([1/2, A, 0, x-1]).parent()
     1691        sage: block_matrix(2, 2, [1/2, A, 0, x-1]).parent()
    14631692        Full MatrixSpace of 4 by 4 dense matrices over Univariate Polynomial Ring in x over Rational Field
    14641693   
    1465     Subdivisions are optional::
     1694    Subdivisions are optional. If they are disabled, the columns need not line up::
    14661695   
    14671696        sage: B = matrix(QQ, 2, 3, range(6))
    1468         sage: block_matrix([~A, B, B, ~A], subdivide=False)
     1697        sage: block_matrix([ [~A, B], [B, ~A] ], subdivide=False)
    14691698        [-5/12   3/8     0     1     2]
    14701699        [  1/4  -1/8     3     4     5]
    14711700        [    0     1     2 -5/12   3/8]
    14721701        [    3     4     5   1/4  -1/8]
     1702
     1703    Without subdivisions it also deduces dimensions for scalars if possible::
     1704
     1705        sage: C = matrix(ZZ, 1, 2, range(2))
     1706        sage: block_matrix([ [ C, 0 ], [ 3, 4 ], [ 5, 6, C ] ], subdivide=False )
     1707        [0 1 0 0]
     1708        [3 0 4 0]
     1709        [0 3 0 4]
     1710        [5 6 0 1]
     1711
     1712    If all submatrices are sparse (unless there are none at all), the result
     1713    will be a sparse matrix. Otherwise it will be dense by default. The
     1714    ``sparse`` keyword can be used to override this::
     1715
     1716        sage: A = Matrix(ZZ, 2, 2, [0, 1, 0, 0], sparse=True)
     1717        sage: block_matrix([ [ A ], [ A ] ]).parent()
     1718        Full MatrixSpace of 4 by 2 sparse matrices over Integer Ring
     1719        sage: block_matrix([ [ A ], [ A ] ], sparse=False).parent()
     1720        Full MatrixSpace of 4 by 2 dense matrices over Integer Ring
     1721
    14731722    """
    1474     # determine the block dimensions
    1475     n = ZZ(len(sub_matrices))
    1476     if nrows is None:
    1477         if ncols is None:
    1478             if n.is_square():
    1479                 nrows = ncols = n.sqrt()
     1723    args = list(args)
     1724    sparse = kwds.get('sparse',None)
     1725
     1726    if len(args) == 0:
     1727        if sparse is not None:
     1728            return matrix_space.MatrixSpace(rings.ZZ, 0, 0, sparse=sparse)([])
     1729        else:
     1730            return matrix_space.MatrixSpace(rings.ZZ, 0, 0)([])
     1731
     1732    if len(args) >= 1 and rings.is_Ring(args[0]):
     1733        # A ring is specified
     1734        if kwds.get('ring', args[0]) != args[0]:
     1735            raise ValueError, "Specified rings are not the same"
     1736        ring = args[0]
     1737        args.pop(0)
     1738    else:
     1739        ring = kwds.get('ring', None)
     1740
     1741    if len(args) >= 1:
     1742        try:
     1743            nrows = int(args[0])
     1744            args.pop(0)
     1745            if kwds.get('nrows', nrows) != nrows:
     1746                raise ValueError, "Number of rows specified in two places and they are not the same"
     1747        except TypeError:
     1748            nrows = kwds.get('nrows', None)
     1749    else:
     1750        nrows = kwds.get('nrows', None)
     1751
     1752    if len(args) >= 1:
     1753        # check to see if additionally, the number of columns is specified
     1754        try:
     1755            ncols = int(args[0])
     1756            args.pop(0)
     1757            if kwds.get('ncols', ncols) != ncols:
     1758                raise ValueError, "Number of columns specified in two places and they are not the same"
     1759        except TypeError:
     1760            ncols = kwds.get('ncols', None)
     1761    else:
     1762        ncols = kwds.get('ncols', None)
     1763
     1764    # Now we've taken care of initial ring, nrows, and ncols arguments.
     1765   
     1766    # Now the rest of the arguments are a list of rows, a flat list of
     1767    # matrices, or a single value.
     1768
     1769    if len(args) == 0:
     1770        args = [[]]
     1771    if len(args) > 1:
     1772        print args
     1773        raise TypeError, "Invalid block_matrix invocation"
     1774
     1775    sub_matrices = args[0]
     1776
     1777    if is_Matrix(sub_matrices):
     1778        # a single matrix (check nrows/ncols/ring)
     1779        if (nrows is not None and nrows != 1) or \
     1780           (ncols is not None and ncols != 1):
     1781            raise ValueError, "Invalid nrows/ncols passed to block_matrix"
     1782        if ring is not None:
     1783            M = M.change_ring(ring)
     1784        if sparse is not None and M.is_sparse() != sparse:
     1785            M = M.sparse_matrix() if sparse else M.dense_matrix()
     1786        return M
     1787
     1788    if not isinstance(sub_matrices, (list, tuple)):
     1789        raise TypeError, "Invalid block_matrix invocation"
     1790
     1791    subdivide = kwds.get('subdivide', True)
     1792
     1793    # Will we try to place the matrices in a rectangular grid?
     1794    try_grid = True
     1795
     1796
     1797    if len(sub_matrices) == 0:
     1798        if (nrows is not None and nrows != 0) or \
     1799           (ncols is not None and ncols != 0):
     1800            raise ValueError, "Invalid nrows/ncols passed to block_matrix"
     1801    elif isinstance(sub_matrices[0], (list, tuple)):
     1802        # A list of lists: verify all elements are lists, and if
     1803        # ncols is set, the lengths match.
     1804        if nrows is not None and len(sub_matrices) != nrows:
     1805            raise ValueError, "Invalid nrows passed to block_matrix"
     1806        first_len = len(sub_matrices[0])
     1807        if ncols is not None and first_len != ncols:
     1808            raise ValueError, "Invalid ncols passed to block_matrix"
     1809        same_length = all(isinstance(v, (list, tuple)) and len(v) == first_len for v in sub_matrices)
     1810        if subdivide and not same_length:
     1811            raise ValueError, "List of rows is not valid (rows are wrong types or lengths)"
     1812        try_grid = same_length
     1813    else:
     1814        # A flat list
     1815        # determine the block dimensions
     1816        n = ZZ(len(sub_matrices))
     1817        if nrows is None:
     1818            if ncols is None:
     1819                if n.is_square():
     1820                    import warnings
     1821                    warnings.warn("This invocation of block_matrix is deprecated. See its documentation for details.", DeprecationWarning, stacklevel=2)
     1822                    nrows = ncols = n.sqrt()
     1823                else:
     1824                    raise ValueError, "Must specify nrows or ncols for non-square block matrix."
    14801825            else:
    1481                 raise ValueError, "Must specify rows or cols for non-square block matrix."
    1482         else:
    1483             nrows = int(n/ncols)
    1484     elif ncols is None:
    1485         ncols = int(n/nrows)
    1486     if nrows * ncols != n:
    1487         raise ValueError, "Given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n)
    1488 
    1489     # empty matrix
    1490     if n == 0:
    1491       ans = Matrix(ZZ,0,0,[])
    1492       if subdivide:
    1493         ans.subdivide([0]*(nrows-1),[0]*(ncols-1))
    1494       return ans
    1495    
    1496     # determine the sub-block dimensions
    1497     row_heights = [None] * nrows
    1498     col_widths = [None] * ncols
    1499     for i in range(nrows):
    1500         for j in range(0, ncols):
    1501             M = sub_matrices[i*ncols+j]
     1826                nrows = int(n/ncols)
     1827        elif ncols is None:
     1828            ncols = int(n/nrows)
     1829        if nrows * ncols != n:
     1830            raise ValueError, "Given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n)
     1831        # Now create a list of lists from this
     1832        sub_matrices = [ sub_matrices[i*ncols : (i+1)*ncols] for i in range(nrows) ]
     1833
     1834    # At this point sub_matrices is a list of lists
     1835
     1836    # determine the base ring and sparsity
     1837    if ring is None:
     1838        ring = ZZ
     1839        for row in sub_matrices:
     1840            for M in row:
     1841                R = M.base_ring() if is_Matrix(M) else M.parent()
     1842                if R is not ZZ:
     1843                    ring = sage.categories.pushout.pushout(ring, R)
     1844
     1845    if sparse is None:
     1846        sparse = True
     1847        for row in sub_matrices:
     1848            for M in row:
     1849                if sparse and is_Matrix(M) and not M.is_sparse():
     1850                    sparse = False
     1851
     1852    row_heights = None
     1853    col_widths = None
     1854    zero_widths = None
     1855    total_width = None
     1856 
     1857    # We first try to place the matrices in a rectangular grid
     1858    if try_grid:
     1859        try:
     1860            (row_heights, col_widths) = _determine_block_matrix_grid(sub_matrices)
     1861        except ValueError as e:
     1862            if subdivide:
     1863                raise ValueError, e
     1864
     1865
     1866    if col_widths is None:
     1867        # Try placing the matrices in rows instead
     1868        # (Only if subdivide is False)
     1869        (row_heights, zero_widths, total_width) = _determine_block_matrix_rows(sub_matrices)
     1870
     1871
     1872    # Success, so assemble the final matrix
     1873
     1874    big = None
     1875    for i in range(len(sub_matrices)):
     1876        R = sub_matrices[i]
     1877        row = None
     1878        for j in range(len(R)):
     1879            M = R[j]
     1880
    15021881            if is_Matrix(M):
    1503                 if row_heights[i] is None:
    1504                     row_heights[i] = M.nrows()
    1505                 if col_widths[j] is None:
    1506                     col_widths[j] = M.ncols()
    1507    
    1508     if None in row_heights or None in col_widths:
    1509         for i in range(nrows):
    1510             for j in range(0, ncols):
    1511                 x = sub_matrices[i*ncols+j]
    1512                 if not is_Matrix(x) and x: # must be square matrix
    1513                     if row_heights[i] is None:
    1514                         row_heights[i] = col_widths[j]
    1515                     if col_widths[j] is None:
    1516                         col_widths[j] = row_heights[i]
    1517                        
    1518         if None in row_heights or None in col_widths:
    1519             raise ValueError, "Insufficient information to determine dimensions."
    1520 
    1521     # determine the base ring
    1522     base = ZZ
    1523     for M in sub_matrices:
    1524         R = M.base_ring() if is_Matrix(M) else M.parent()
    1525         if R is not ZZ:
    1526             base = sage.categories.pushout.pushout(base, R)
    1527        
    1528     # finally concatenate
    1529     for i in range(nrows):
    1530         for j in range(ncols):
    1531             # coerce
    1532             M = sub_matrices[i*ncols+j]
    1533             if is_Matrix(M):
    1534                 if M.base_ring() is not base:
    1535                     M = M.change_ring(base)
     1882                if M.base_ring() is not ring:
     1883                    M = M.change_ring(ring)
     1884                if M.is_sparse() != sparse:
     1885                    M = M.sparse_matrix() if sparse else M.dense_matrix()
     1886            elif not M and zero_widths is not None:
     1887                if zero_widths[i] > 0:
     1888                    M = matrix(ring, row_heights[i], zero_widths[i], 0, sparse=sparse)
     1889                    zero_widths[i] = 0
     1890                else:
     1891                    continue # zero-width matrix
    15361892            else:
    1537                 M = matrix(base, row_heights[i], col_widths[j], M)
    1538             # append
    1539             if j == 0:
     1893                if zero_widths is not None:
     1894                    M = matrix(ring, row_heights[i], row_heights[i], M, sparse=sparse)
     1895                else:
     1896                    M = matrix(ring, row_heights[i], col_widths[j], M, sparse=sparse)
     1897
     1898            # append M to this row
     1899            if row is None:
    15401900                row = M
    15411901            else:
    15421902                row = row.augment(M)
    1543         if i == 0:
     1903
     1904        # append row to final matrix
     1905        if big is None:
    15441906            big = row
    15451907        else:
    15461908            big = big.stack(row)
    1547            
     1909
     1910    if big is None:
     1911        if ring is None:
     1912            ring = ZZ
     1913        big = Matrix(ring, 0, 0)
     1914
    15481915    if subdivide:
    15491916        big.subdivide(running_total(row_heights[:-1]),
    15501917                      running_total(col_widths[:-1]))
    1551        
     1918
    15521919    return big
    15531920
    15541921def block_diagonal_matrix(*sub_matrices, **kwds):
     
    15841951    entries = [ZZ.zero_element()] * n**2
    15851952    for i in range(n):
    15861953        entries[n*i+i] = sub_matrices[i]
    1587     return block_matrix(entries, **kwds)
     1954    return block_matrix(n, n, entries, **kwds)
    15881955
    15891956def jordan_block(eigenvalue, size, sparse=False):
    15901957    r"""
  • sage/matrix/matrix2.pyx

    diff -r c58f82863c75 -r 6c8a4e251d96 sage/matrix/matrix2.pyx
    a b  
    51905190        """
    51915191        if not isinstance(Y,Matrix):
    51925192            raise TypeError, "second argument must be a matrix"
    5193         return sage.matrix.constructor.block_matrix([x*Y for x in self.list()],self.nrows(),self.ncols())
     5193        return sage.matrix.constructor.block_matrix(self.nrows(),self.ncols(),[x*Y for x in self.list()])
    51945194
    51955195    def randomize(self, density=1, nonzero=False, *args, **kwds):
    51965196        """
  • sage/matrix/matrix_mod2_dense.pyx

    diff -r c58f82863c75 -r 6c8a4e251d96 sage/matrix/matrix_mod2_dense.pyx
    a b  
    442442            [0 1 0]
    443443            [0 1 1]
    444444            [0 0 0]
    445             sage: block_matrix([B, 1, 0, B])
     445            sage: block_matrix([[B, 1], [0, B]])
    446446            [0 1 0|1 0 0]
    447447            [0 1 1|0 1 0]
    448448            [0 0 0|0 0 1]