Ticket #4492: 4492_block_matrix_rebased.patch

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

rebased to 4.6.2.alpha1

  • sage/combinat/designs/incidence_structures.py

    # HG changeset patch
    # User Willem Jan Palenstijn <wjp@usecode.org>
    # Date 1294869358 -3600
    # Node ID 36e38f2524aa3edb7d60312865cb89cf8e59313c
    # Parent  b4b5dc9a3ffdec878f793354f7e9a35cf7213570
    #4492: rewrite block_matrix constructor
    
    It is now much more consistent with Matrix(),
    and will deduce dimensions automatically in more cases.
    
    diff -r b4b5dc9a3ffd -r 36e38f2524aa 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 b4b5dc9a3ffd -r 36e38f2524aa 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 b4b5dc9a3ffd -r 36e38f2524aa 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 b4b5dc9a3ffd -r 36e38f2524aa sage/matrix/constructor.py
    a b  
    14371437    one = ring(1)
    14381438    return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix([one]*nents)
    14391439
    1440 def block_matrix(sub_matrices, nrows=None, ncols=None, subdivide=True):
     1440def _determine_block_matrix_grid(sub_matrices):
    14411441    """
    1442     Returns a larger matrix made by concatenating the sub_matrices
     1442    For internal use. This tries to determine the dimensions
     1443    of rows/columns when assembling the matrices in sub_matrices in a
     1444    rectangular grid. It returns a pair of lists containing
     1445    respectively the sizes of rows and columns.
     1446
     1447    sub_matrices must be a list of lists of matrices. All sublists
     1448    are expected to be the same size.
     1449
     1450    Non-zero scalars are considered to be square matrices of any size,
     1451    and zeroes are considered to be zero matrices of any size.
     1452
     1453    A ValueError is raised if there is insufficient or
     1454    conflicting information.
     1455
     1456    TESTS::
     1457
     1458        sage: from sage.matrix.constructor import _determine_block_matrix_grid
     1459        sage: A = matrix(QQ, 2, 2, [3,9,6,10])
     1460        sage: _determine_block_matrix_grid([[A, A], [A, A]])
     1461        ([2, 2], [2, 2])
     1462
     1463        sage: B = matrix(QQ, 1, 1, [ 1 ] )
     1464        sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )
     1465        sage: _determine_block_matrix_grid([[B, 0], [0, C]])
     1466        ([1, 2], [1, 2])
     1467    """
     1468
     1469    nrows = len(sub_matrices)
     1470    if nrows == 0:
     1471        return ([], [])
     1472    ncols = len(sub_matrices[0])
     1473
     1474    if ncols == 0:
     1475        return ([0] * nrows, [])
     1476
     1477    row_heights = [None] * nrows
     1478    col_widths = [None] * ncols
     1479
     1480    changing = True
     1481    while changing:
     1482        changing = False
     1483        for i in range(nrows):
     1484            for j in range(ncols):
     1485                M = sub_matrices[i][j]
     1486                sub_width = None
     1487                sub_height = None
     1488                if is_Matrix(M):
     1489                    sub_width = M.ncols()
     1490                    sub_height = M.nrows()
     1491                elif M: # non-zero scalar is interpreted as a square matrix
     1492                    if row_heights[i] is None:
     1493                        sub_width = col_widths[j]
     1494                    else:
     1495                        sub_width = row_heights[i]
     1496                    sub_height = sub_width
     1497                if sub_width is not None:
     1498                    if col_widths[j] is None:
     1499                        changing = True
     1500                        col_widths[j] = sub_width
     1501                    elif col_widths[j] != sub_width:
     1502                        raise ValueError, "Incompatible submatrix widths"
     1503                if sub_height is not None:
     1504                    if row_heights[i] is None:
     1505                        changing = True
     1506                        row_heights[i] = sub_height
     1507                    elif row_heights[i] != sub_height:
     1508                        raise ValueError, "Incompatible submatrix heights"
     1509   
     1510    if None in row_heights or None in col_widths:
     1511        if None in row_heights or None in col_widths:
     1512            raise ValueError, "Insufficient information to determine dimensions."
     1513
     1514    return (row_heights, col_widths)
     1515
     1516def _determine_block_matrix_rows(sub_matrices):
     1517    """
     1518    For internal use. This tests if the matrices in sub_matrices
     1519    fit in a rectangular matrix when assembled a row at a time.
     1520
     1521    sub_matrices must be a list of lists of matrices.
     1522
     1523    It returns a pair (row_heights, zero_widths, width) where
     1524    row_heights is the list of row heights, zero_widths is the
     1525    total width filled up by zero matrices per row, and width
     1526    is the total width of the resulting matrix.
     1527
     1528    Non-zero scalars are considered to be square matrices of any size,
     1529    and zeroes are considered to be zero matrices of any size.
     1530
     1531    A ValueError is raised if there is insufficient or
     1532    conflicting information.
     1533
     1534    TESTS::
     1535
     1536        sage: from sage.matrix.constructor import _determine_block_matrix_rows
     1537        sage: A = Matrix(ZZ, 1, 4, [1, 2, 3, 4])
     1538        sage: _determine_block_matrix_rows([ [1, 1], [ A ] ])
     1539        ([2, 1], [0, 0], 4)
     1540
     1541        sage: B = Matrix(ZZ, 2, 2, [1, 2, 3, 4])
     1542        sage: _determine_block_matrix_rows([ [B, B], [B, 1] ])
     1543        ([2, 2], [0, 0], 4)
     1544    """
     1545
     1546    total_height = 0
     1547    total_width = None
     1548
     1549    row_heights = [ None ] * len(sub_matrices)
     1550    zero_widths = [ 0 ] * len(sub_matrices)
     1551
     1552    # We first do a pass to see if we can determine the width
     1553    unknowns = False
     1554    for i in range(len(sub_matrices)):
     1555        R = sub_matrices[i]
     1556        height = None
     1557        # We first do a pass to see if we can determine the height
     1558        # of this row
     1559        found_zeroes = False
     1560        for M in R:
     1561            if is_Matrix(M):
     1562                if height is None:
     1563                    height = M.nrows()
     1564                elif height != M.nrows():
     1565                    raise ValueError, "Incompatible submatrix heights"
     1566            elif not M:
     1567                found_zeroes = True
     1568        if len(R) == 0:
     1569            height = 0
     1570
     1571        # If we have a height, then we know the dimensions of any
     1572        # non-zero scalars, and can maybe compute the width
     1573        if height is not None and not found_zeroes:
     1574            width = 0
     1575            for M in R:
     1576                if is_Matrix(M):
     1577                    width += M.ncols()
     1578                else:
     1579                    # non-zero scalar
     1580                    width += height
     1581            if total_width is None:
     1582                total_width = width
     1583            elif total_width != width:
     1584                raise ValueError, "Incompatible submatrix widths"
     1585            row_heights[i] = height
     1586        else:
     1587            # We don't set height here even if we know it,
     1588            # to signal this row hasn't been fit yet.
     1589            unknowns = True
     1590
     1591    if total_width is None:
     1592        raise ValueError, "Insufficient information to determine submatrix widths"
     1593
     1594    if unknowns:
     1595        # Do a second pass and see if the remaining rows can be
     1596        # determined now that we know the width of the matrix.
     1597        for i in range(len(sub_matrices)):
     1598            if row_heights[i] is not None:
     1599                continue
     1600            R = sub_matrices[i]
     1601            zero_state = 0
     1602            # 0: no zeroes found
     1603            # 1: consecutive zeroes found
     1604            # 2: consecutive zeroes followed by non-zero found
     1605            # 3: non-consecutive zeroes found
     1606            scalars = 0
     1607            width = 0
     1608            height = None
     1609            for j in range(len(R)):
     1610                M = R[j]
     1611                if is_Matrix(M):
     1612                    height = M.nrows()
     1613                    width += M.ncols()
     1614                    if zero_state == 1:
     1615                        zero_state = 2
     1616                elif not M:
     1617                    if zero_state == 0:
     1618                        zero_state = 1
     1619                    elif zero_state == 2:
     1620                        zero_state = 3
     1621                else:
     1622                     scalars += 1
     1623
     1624            remaining_width = total_width - width
     1625            # This remaining width has to be split over the
     1626            # zeroes and (non-zero) scalars
     1627
     1628            if height is not None:
     1629                remaining_width -= scalars * height
     1630                if remaining_width < 0:
     1631                    raise ValueError, "Incompatible submatrix widths"
     1632                if remaining_width > 0 and zero_state == 3:
     1633                    raise ValueError, "Insufficient information to determine submatrix widths"
     1634                if remaining_width > 0 and zero_state == 0:
     1635                    raise ValueError, "Incompatible submatrix widths"
     1636                # otherwise, things fit
     1637                row_heights[i] = height
     1638                zero_widths[i] = remaining_width
     1639            elif zero_state != 0:
     1640                # if we don't know the height, and there are zeroes,
     1641                # we can't determine the height
     1642                raise ValueError, "Insufficient information to determine submatrix heights"
     1643            elif total_width % len(R) != 0:
     1644                raise ValueError, "Incompatible submatrix widths"
     1645            else:
     1646                height = int(total_width / len(R))
     1647                row_heights[i] = height
     1648
     1649    # If we got this far, then everything fits
     1650    return (row_heights, zero_widths, total_width)
     1651
     1652def block_matrix(*args, **kwds): #sub_matrices, nrows=None, ncols=None, subdivide=True):
     1653    """
     1654    Returns a larger matrix made by concatenating submatrices
    14431655    (rows first, then columns). For example, the matrix
    14441656
    14451657    ::
     
    14491661   
    14501662    is made up of submatrices A, B, C, and D.
    14511663   
    1452     INPUT:
     1664    INPUT: The block_matrix command takes a list of submatrices to add
     1665    as blocks, optionally preceded by a ring and the number of block rows
     1666    and block columns, and returns a matrix.
     1667
     1668    The submatrices can be specified as a list of matrices (using
     1669    ``nrows`` and ``ncols`` to determine their layout), or a list
     1670    of lists of matrices, where each list forms a row.
     1671
     1672    -  ``ring`` - the base ring
     1673       
     1674    -  ``nrows`` - the number of block rows
    14531675   
    1454    
    1455     -  ``sub_matrices`` - matrices (must be of the correct
    1456        size, or constants)
    1457    
    1458     -  ``nrows`` - (optional) the number of block rows
    1459    
    1460     -  ``ncols`` - (optional) the number of block cols
     1676    -  ``ncols`` - the number of block cols
     1677
     1678    -  ``sub_matrices`` - matrices (see below for syntax)
    14611679   
    14621680    -  ``subdivide`` - boolean, whether or not to add
    14631681       subdivision information to the matrix
    1464    
     1682
     1683    -  ``sparse`` - boolean, whether to make the resulting matrix sparse
     1684 
    14651685   
    14661686    EXAMPLES::
    14671687   
    14681688        sage: A = matrix(QQ, 2, 2, [3,9,6,10])
    1469         sage: block_matrix([A, -A, ~A, 100*A])
     1689        sage: block_matrix([ [A, -A], [~A, 100*A] ])
    14701690        [    3     9|   -3    -9]
    14711691        [    6    10|   -6   -10]
    14721692        [-----------+-----------]
    14731693        [-5/12   3/8|  300   900]
    14741694        [  1/4  -1/8|  600  1000]
     1695
     1696    If the number of submatrices in each row is the same,
     1697    you can specify the submatrices as a single list too::
     1698
     1699        sage: block_matrix(2, 2, [ A, A, A, A ])
     1700        [ 3  9| 3  9]
     1701        [ 6 10| 6 10]
     1702        [-----+-----]
     1703        [ 3  9| 3  9]
     1704        [ 6 10| 6 10]
     1705
    14751706   
    14761707    One can use constant entries::
    14771708   
    1478         sage: block_matrix([1, A, 0, 1])
     1709        sage: block_matrix([ [1, A], [0, 1] ])
    14791710        [ 1  0| 3  9]
    14801711        [ 0  1| 6 10]
    14811712        [-----+-----]
     
    14861717
    14871718        sage: B = matrix(QQ, 1, 1, [ 1 ] )
    14881719        sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )
    1489         sage: block_matrix([B, 0, 0, C])
     1720        sage: block_matrix([ [B, 0], [0, C] ])
    14901721        [1|0 0]
    14911722        [-+---]
    14921723        [0|2 3]
    14931724        [0|4 5]
    14941725   
    1495     One can specify the number of rows or columns (optional for square
    1496     number of matrices)::
     1726    One can specify the number of rows or columns as keywords too::
    14971727   
    14981728        sage: block_matrix([A, -A, ~A, 100*A], ncols=4)
    14991729        [    3     9|   -3    -9|-5/12   3/8|  300   900]
     
    15051735        [    3     9|   -3    -9|-5/12   3/8|  300   900]
    15061736        [    6    10|   -6   -10|  1/4  -1/8|  600  1000]
    15071737   
    1508     It handle base rings nicely too::
     1738    It handles base rings nicely too::
    15091739   
    15101740        sage: R.<x> = ZZ['x']
    1511         sage: block_matrix([1/2, A, 0, x-1])
     1741        sage: block_matrix(2, 2, [1/2, A, 0, x-1])
    15121742        [  1/2     0|    3     9]
    15131743        [    0   1/2|    6    10]
    15141744        [-----------+-----------]
    15151745        [    0     0|x - 1     0]
    15161746        [    0     0|    0 x - 1]
    1517         sage: block_matrix([1/2, A, 0, x-1]).parent()
     1747        sage: block_matrix(2, 2, [1/2, A, 0, x-1]).parent()
    15181748        Full MatrixSpace of 4 by 4 dense matrices over Univariate Polynomial Ring in x over Rational Field
    15191749   
    1520     Subdivisions are optional::
     1750    Subdivisions are optional. If they are disabled, the columns need not line up::
    15211751   
    15221752        sage: B = matrix(QQ, 2, 3, range(6))
    1523         sage: block_matrix([~A, B, B, ~A], subdivide=False)
     1753        sage: block_matrix([ [~A, B], [B, ~A] ], subdivide=False)
    15241754        [-5/12   3/8     0     1     2]
    15251755        [  1/4  -1/8     3     4     5]
    15261756        [    0     1     2 -5/12   3/8]
    15271757        [    3     4     5   1/4  -1/8]
     1758
     1759    Without subdivisions it also deduces dimensions for scalars if possible::
     1760
     1761        sage: C = matrix(ZZ, 1, 2, range(2))
     1762        sage: block_matrix([ [ C, 0 ], [ 3, 4 ], [ 5, 6, C ] ], subdivide=False )
     1763        [0 1 0 0]
     1764        [3 0 4 0]
     1765        [0 3 0 4]
     1766        [5 6 0 1]
     1767
     1768    If all submatrices are sparse (unless there are none at all), the result
     1769    will be a sparse matrix. Otherwise it will be dense by default. The
     1770    ``sparse`` keyword can be used to override this::
     1771
     1772        sage: A = Matrix(ZZ, 2, 2, [0, 1, 0, 0], sparse=True)
     1773        sage: block_matrix([ [ A ], [ A ] ]).parent()
     1774        Full MatrixSpace of 4 by 2 sparse matrices over Integer Ring
     1775        sage: block_matrix([ [ A ], [ A ] ], sparse=False).parent()
     1776        Full MatrixSpace of 4 by 2 dense matrices over Integer Ring
     1777
    15281778    """
    1529     # determine the block dimensions
    1530     n = ZZ(len(sub_matrices))
    1531     if nrows is None:
    1532         if ncols is None:
    1533             if n.is_square():
    1534                 nrows = ncols = n.sqrt()
     1779    args = list(args)
     1780    sparse = kwds.get('sparse',None)
     1781
     1782    if len(args) == 0:
     1783        if sparse is not None:
     1784            return matrix_space.MatrixSpace(rings.ZZ, 0, 0, sparse=sparse)([])
     1785        else:
     1786            return matrix_space.MatrixSpace(rings.ZZ, 0, 0)([])
     1787
     1788    if len(args) >= 1 and rings.is_Ring(args[0]):
     1789        # A ring is specified
     1790        if kwds.get('ring', args[0]) != args[0]:
     1791            raise ValueError, "Specified rings are not the same"
     1792        ring = args[0]
     1793        args.pop(0)
     1794    else:
     1795        ring = kwds.get('ring', None)
     1796
     1797    if len(args) >= 1:
     1798        try:
     1799            nrows = int(args[0])
     1800            args.pop(0)
     1801            if kwds.get('nrows', nrows) != nrows:
     1802                raise ValueError, "Number of rows specified in two places and they are not the same"
     1803        except TypeError:
     1804            nrows = kwds.get('nrows', None)
     1805    else:
     1806        nrows = kwds.get('nrows', None)
     1807
     1808    if len(args) >= 1:
     1809        # check to see if additionally, the number of columns is specified
     1810        try:
     1811            ncols = int(args[0])
     1812            args.pop(0)
     1813            if kwds.get('ncols', ncols) != ncols:
     1814                raise ValueError, "Number of columns specified in two places and they are not the same"
     1815        except TypeError:
     1816            ncols = kwds.get('ncols', None)
     1817    else:
     1818        ncols = kwds.get('ncols', None)
     1819
     1820    # Now we've taken care of initial ring, nrows, and ncols arguments.
     1821   
     1822    # Now the rest of the arguments are a list of rows, a flat list of
     1823    # matrices, or a single value.
     1824
     1825    if len(args) == 0:
     1826        args = [[]]
     1827    if len(args) > 1:
     1828        print args
     1829        raise TypeError, "Invalid block_matrix invocation"
     1830
     1831    sub_matrices = args[0]
     1832
     1833    if is_Matrix(sub_matrices):
     1834        # a single matrix (check nrows/ncols/ring)
     1835        if (nrows is not None and nrows != 1) or \
     1836           (ncols is not None and ncols != 1):
     1837            raise ValueError, "Invalid nrows/ncols passed to block_matrix"
     1838        if ring is not None:
     1839            M = M.change_ring(ring)
     1840        if sparse is not None and M.is_sparse() != sparse:
     1841            M = M.sparse_matrix() if sparse else M.dense_matrix()
     1842        return M
     1843
     1844    if not isinstance(sub_matrices, (list, tuple)):
     1845        raise TypeError, "Invalid block_matrix invocation"
     1846
     1847    subdivide = kwds.get('subdivide', True)
     1848
     1849    # Will we try to place the matrices in a rectangular grid?
     1850    try_grid = True
     1851
     1852
     1853    if len(sub_matrices) == 0:
     1854        if (nrows is not None and nrows != 0) or \
     1855           (ncols is not None and ncols != 0):
     1856            raise ValueError, "Invalid nrows/ncols passed to block_matrix"
     1857    elif isinstance(sub_matrices[0], (list, tuple)):
     1858        # A list of lists: verify all elements are lists, and if
     1859        # ncols is set, the lengths match.
     1860        if nrows is not None and len(sub_matrices) != nrows:
     1861            raise ValueError, "Invalid nrows passed to block_matrix"
     1862        first_len = len(sub_matrices[0])
     1863        if ncols is not None and first_len != ncols:
     1864            raise ValueError, "Invalid ncols passed to block_matrix"
     1865        same_length = all(isinstance(v, (list, tuple)) and len(v) == first_len for v in sub_matrices)
     1866        if subdivide and not same_length:
     1867            raise ValueError, "List of rows is not valid (rows are wrong types or lengths)"
     1868        try_grid = same_length
     1869    else:
     1870        # A flat list
     1871        # determine the block dimensions
     1872        n = ZZ(len(sub_matrices))
     1873        if nrows is None:
     1874            if ncols is None:
     1875                if n.is_square():
     1876                    import warnings
     1877                    warnings.warn("This invocation of block_matrix is deprecated. See its documentation for details.", DeprecationWarning, stacklevel=2)
     1878                    nrows = ncols = n.sqrt()
     1879                else:
     1880                    raise ValueError, "Must specify nrows or ncols for non-square block matrix."
    15351881            else:
    1536                 raise ValueError, "Must specify rows or cols for non-square block matrix."
    1537         else:
    1538             nrows = int(n/ncols)
    1539     elif ncols is None:
    1540         ncols = int(n/nrows)
    1541     if nrows * ncols != n:
    1542         raise ValueError, "Given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n)
    1543 
    1544     # empty matrix
    1545     if n == 0:
    1546       ans = Matrix(ZZ,0,0,[])
    1547       if subdivide:
    1548         ans.subdivide([0]*(nrows-1),[0]*(ncols-1))
    1549       return ans
    1550    
    1551     # determine the sub-block dimensions
    1552     row_heights = [None] * nrows
    1553     col_widths = [None] * ncols
    1554     for i in range(nrows):
    1555         for j in range(0, ncols):
    1556             M = sub_matrices[i*ncols+j]
     1882                nrows = int(n/ncols)
     1883        elif ncols is None:
     1884            ncols = int(n/nrows)
     1885        if nrows * ncols != n:
     1886            raise ValueError, "Given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n)
     1887        # Now create a list of lists from this
     1888        sub_matrices = [ sub_matrices[i*ncols : (i+1)*ncols] for i in range(nrows) ]
     1889
     1890    # At this point sub_matrices is a list of lists
     1891
     1892    # determine the base ring and sparsity
     1893    if ring is None:
     1894        ring = ZZ
     1895        for row in sub_matrices:
     1896            for M in row:
     1897                R = M.base_ring() if is_Matrix(M) else M.parent()
     1898                if R is not ZZ:
     1899                    ring = sage.categories.pushout.pushout(ring, R)
     1900
     1901    if sparse is None:
     1902        sparse = True
     1903        for row in sub_matrices:
     1904            for M in row:
     1905                if sparse and is_Matrix(M) and not M.is_sparse():
     1906                    sparse = False
     1907
     1908    row_heights = None
     1909    col_widths = None
     1910    zero_widths = None
     1911    total_width = None
     1912 
     1913    # We first try to place the matrices in a rectangular grid
     1914    if try_grid:
     1915        try:
     1916            (row_heights, col_widths) = _determine_block_matrix_grid(sub_matrices)
     1917        except ValueError as e:
     1918            if subdivide:
     1919                raise ValueError, e
     1920
     1921
     1922    if col_widths is None:
     1923        # Try placing the matrices in rows instead
     1924        # (Only if subdivide is False)
     1925        (row_heights, zero_widths, total_width) = _determine_block_matrix_rows(sub_matrices)
     1926
     1927
     1928    # Success, so assemble the final matrix
     1929
     1930    big = None
     1931    for i in range(len(sub_matrices)):
     1932        R = sub_matrices[i]
     1933        row = None
     1934        for j in range(len(R)):
     1935            M = R[j]
     1936
    15571937            if is_Matrix(M):
    1558                 if row_heights[i] is None:
    1559                     row_heights[i] = M.nrows()
    1560                 if col_widths[j] is None:
    1561                     col_widths[j] = M.ncols()
    1562    
    1563     if None in row_heights or None in col_widths:
    1564         for i in range(nrows):
    1565             for j in range(0, ncols):
    1566                 x = sub_matrices[i*ncols+j]
    1567                 if not is_Matrix(x) and x: # must be square matrix
    1568                     if row_heights[i] is None:
    1569                         row_heights[i] = col_widths[j]
    1570                     if col_widths[j] is None:
    1571                         col_widths[j] = row_heights[i]
    1572                        
    1573         if None in row_heights or None in col_widths:
    1574             raise ValueError, "Insufficient information to determine dimensions."
    1575 
    1576     # determine the base ring
    1577     base = ZZ
    1578     for M in sub_matrices:
    1579         R = M.base_ring() if is_Matrix(M) else M.parent()
    1580         if R is not ZZ:
    1581             base = sage.categories.pushout.pushout(base, R)
    1582        
    1583     # finally concatenate
    1584     for i in range(nrows):
    1585         for j in range(ncols):
    1586             # coerce
    1587             M = sub_matrices[i*ncols+j]
    1588             if is_Matrix(M):
    1589                 if M.base_ring() is not base:
    1590                     M = M.change_ring(base)
     1938                if M.base_ring() is not ring:
     1939                    M = M.change_ring(ring)
     1940                if M.is_sparse() != sparse:
     1941                    M = M.sparse_matrix() if sparse else M.dense_matrix()
     1942            elif not M and zero_widths is not None:
     1943                if zero_widths[i] > 0:
     1944                    M = matrix(ring, row_heights[i], zero_widths[i], 0, sparse=sparse)
     1945                    zero_widths[i] = 0
     1946                else:
     1947                    continue # zero-width matrix
    15911948            else:
    1592                 M = matrix(base, row_heights[i], col_widths[j], M)
    1593             # append
    1594             if j == 0:
     1949                if zero_widths is not None:
     1950                    M = matrix(ring, row_heights[i], row_heights[i], M, sparse=sparse)
     1951                else:
     1952                    M = matrix(ring, row_heights[i], col_widths[j], M, sparse=sparse)
     1953
     1954            # append M to this row
     1955            if row is None:
    15951956                row = M
    15961957            else:
    15971958                row = row.augment(M)
    1598         if i == 0:
     1959
     1960        # append row to final matrix
     1961        if big is None:
    15991962            big = row
    16001963        else:
    16011964            big = big.stack(row)
    1602            
     1965
     1966    if big is None:
     1967        if ring is None:
     1968            ring = ZZ
     1969        big = Matrix(ring, 0, 0)
     1970
    16031971    if subdivide:
    16041972        big.subdivide(running_total(row_heights[:-1]),
    16051973                      running_total(col_widths[:-1]))
    1606        
     1974
    16071975    return big
    16081976
    16091977def block_diagonal_matrix(*sub_matrices, **kwds):
     
    16392007    entries = [ZZ.zero_element()] * n**2
    16402008    for i in range(n):
    16412009        entries[n*i+i] = sub_matrices[i]
    1642     return block_matrix(entries, **kwds)
     2010    return block_matrix(n, n, entries, **kwds)
    16432011
    16442012def jordan_block(eigenvalue, size, sparse=False):
    16452013    r"""
  • sage/matrix/matrix2.pyx

    diff -r b4b5dc9a3ffd -r 36e38f2524aa sage/matrix/matrix2.pyx
    a b  
    52095209        """
    52105210        if not isinstance(Y,Matrix):
    52115211            raise TypeError, "second argument must be a matrix"
    5212         return sage.matrix.constructor.block_matrix([x*Y for x in self.list()],self.nrows(),self.ncols())
     5212        return sage.matrix.constructor.block_matrix(self.nrows(),self.ncols(),[x*Y for x in self.list()])
    52135213
    52145214    def randomize(self, density=1, nonzero=False, *args, **kwds):
    52155215        """
  • sage/matrix/matrix_mod2_dense.pyx

    diff -r b4b5dc9a3ffd -r 36e38f2524aa 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]