Ticket #4492: trac_4492blockmatrixreviewer.patch
File trac_4492blockmatrixreviewer.patch, 13.0 KB (added by , 11 years ago) 


sage/matrix/constructor.py
# HG changeset patch # User Rob Beezer <beezer@ups.edu> # Date 1294899948 28800 # Node ID 14c4ac8842b826f252d961ffe56e9ca6742507c9 # Parent 373a94ced8192f81f04b0448f95cc66e72953dbb 4492: block matrix constructor, reviewer edits diff r 373a94ced819 r 14c4ac8842b8 sage/matrix/constructor.py
a b 1382 1382 return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix([1]*nents) 1383 1383 1384 1384 def _determine_block_matrix_grid(sub_matrices): 1385 """1385 r""" 1386 1386 For internal use. This tries to determine the dimensions 1387 1387 of rows/columns when assembling the matrices in sub_matrices in a 1388 1388 rectangular grid. It returns a pair of lists containing … … 1443 1443 changing = True 1444 1444 col_widths[j] = sub_width 1445 1445 elif col_widths[j] != sub_width: 1446 raise ValueError , "Incompatible submatrix widths"1446 raise ValueError("incompatible submatrix widths") 1447 1447 if sub_height is not None: 1448 1448 if row_heights[i] is None: 1449 1449 changing = True 1450 1450 row_heights[i] = sub_height 1451 1451 elif row_heights[i] != sub_height: 1452 raise ValueError , "Incompatible submatrix heights"1452 raise ValueError("ncompatible submatrix heights") 1453 1453 1454 1454 if None in row_heights or None in col_widths: 1455 1455 if None in row_heights or None in col_widths: 1456 raise ValueError , "Insufficient information to determine dimensions."1456 raise ValueError("insufficient information to determine dimensions.") 1457 1457 1458 1458 return (row_heights, col_widths) 1459 1459 … … 1506 1506 if height is None: 1507 1507 height = M.nrows() 1508 1508 elif height != M.nrows(): 1509 raise ValueError , "Incompatible submatrix heights"1509 raise ValueError("incompatible submatrix heights") 1510 1510 elif not M: 1511 1511 found_zeroes = True 1512 1512 if len(R) == 0: … … 1525 1525 if total_width is None: 1526 1526 total_width = width 1527 1527 elif total_width != width: 1528 raise ValueError , "Incompatible submatrix widths"1528 raise ValueError("incompatible submatrix widths") 1529 1529 row_heights[i] = height 1530 1530 else: 1531 1531 # We don't set height here even if we know it, … … 1533 1533 unknowns = True 1534 1534 1535 1535 if total_width is None: 1536 raise ValueError , "Insufficient information to determine submatrix widths"1536 raise ValueError("insufficient information to determine submatrix widths") 1537 1537 1538 1538 if unknowns: 1539 1539 # Do a second pass and see if the remaining rows can be … … 1572 1572 if height is not None: 1573 1573 remaining_width = scalars * height 1574 1574 if remaining_width < 0: 1575 raise ValueError , "Incompatible submatrix widths"1575 raise ValueError("incompatible submatrix widths") 1576 1576 if remaining_width > 0 and zero_state == 3: 1577 raise ValueError , "Insufficient information to determine submatrix widths"1577 raise ValueError("insufficient information to determine submatrix widths") 1578 1578 if remaining_width > 0 and zero_state == 0: 1579 raise ValueError , "Incompatible submatrix widths"1579 raise ValueError("ncompatible submatrix widths") 1580 1580 # otherwise, things fit 1581 1581 row_heights[i] = height 1582 1582 zero_widths[i] = remaining_width 1583 1583 elif zero_state != 0: 1584 1584 # if we don't know the height, and there are zeroes, 1585 1585 # we can't determine the height 1586 raise ValueError , "Insufficient information to determine submatrix heights"1586 raise ValueError("insufficient information to determine submatrix heights") 1587 1587 elif total_width % len(R) != 0: 1588 raise ValueError , "Incompatible submatrix widths"1588 raise ValueError("incompatible submatrix widths") 1589 1589 else: 1590 1590 height = int(total_width / len(R)) 1591 1591 row_heights[i] = height … … 1593 1593 # If we got this far, then everything fits 1594 1594 return (row_heights, zero_widths, total_width) 1595 1595 1596 def block_matrix(*args, **kwds): #sub_matrices, nrows=None, ncols=None, subdivide=True):1597 """1596 def block_matrix(*args, **kwds): 1597 r""" 1598 1598 Returns a larger matrix made by concatenating submatrices 1599 1599 (rows first, then columns). For example, the matrix 1600 1600 … … 1605 1605 1606 1606 is made up of submatrices A, B, C, and D. 1607 1607 1608 INPUT: The block_matrix command takes a list of submatrices to add 1608 INPUT: 1609 1610 The block_matrix command takes a list of submatrices to add 1609 1611 as blocks, optionally preceded by a ring and the number of block rows 1610 1612 and block columns, and returns a matrix. 1611 1613 … … 1673 1675 [ 3 9 3 95/12 3/8 300 900] 1674 1676 [ 6 10 6 10 1/4 1/8 600 1000] 1675 1677 1676 ::1677 1678 1678 sage: block_matrix([A, A, ~A, 100*A], nrows=1) 1679 1679 [ 3 9 3 95/12 3/8 300 900] 1680 1680 [ 6 10 6 10 1/4 1/8 600 1000] … … 1688 1688 [+] 1689 1689 [ 0 0x  1 0] 1690 1690 [ 0 0 0 x  1] 1691 1691 1692 sage: block_matrix(2, 2, [1/2, A, 0, x1]).parent() 1692 1693 Full MatrixSpace of 4 by 4 dense matrices over Univariate Polynomial Ring in x over Rational Field 1693 1694 … … 1719 1720 sage: block_matrix([ [ A ], [ A ] ], sparse=False).parent() 1720 1721 Full MatrixSpace of 4 by 2 dense matrices over Integer Ring 1721 1722 1723 Consecutive zero submatrices are consolidated. :: 1724 1725 sage: B = matrix(2, range(4)) 1726 sage: C = matrix(2, 8, range(16)) 1727 sage: block_matrix(2, [[B,0,0,B],[C]], subdivide=False) 1728 [ 0 1 0 0 0 0 0 1] 1729 [ 2 3 0 0 0 0 2 3] 1730 [ 0 1 2 3 4 5 6 7] 1731 [ 8 9 10 11 12 13 14 15] 1732 1733 Ambiguity is not tolerated. :: 1734 1735 sage: B = matrix(2, range(4)) 1736 sage: C = matrix(2, 8, range(16)) 1737 sage: block_matrix(2, [[B,0,B,0],[C]], subdivide=False) 1738 Traceback (most recent call last): 1739 ... 1740 ValueError: insufficient information to determine submatrix widths 1741 1742 Historically, giving only a flat list of submatrices, whose number 1743 was a perfect square, would create a new matrix by laying out the submatrices 1744 in a square grid. This behavior is now deprecated. :: 1745 1746 sage: A = matrix(2, 3, range(6)) 1747 sage: B = matrix(3, 3, range(9)) 1748 sage: block_matrix([A, A, B, B]) 1749 doctest:...: DeprecationWarning: invocation of block_matrix with just a list whose length is a perfect square is deprecated. See the documentation for details. 1750 [0 1 20 1 2] 1751 [3 4 53 4 5] 1752 [+] 1753 [0 1 20 1 2] 1754 [3 4 53 4 5] 1755 [6 7 86 7 8] 1756 1757 Historically, a flat list of matrices whose number is not a perfect square, 1758 with no specification of the number of rows or columns, would raise an error. 1759 This behavior continues, but could be removed when the deprecation above is 1760 completed. :: 1761 1762 sage: A = matrix(2, 3, range(6)) 1763 sage: B = matrix(3, 3, range(9)) 1764 sage: block_matrix([A, A, A, B, B, B]) 1765 Traceback (most recent call last): 1766 ... 1767 ValueError: must specify nrows or ncols for nonsquare block matrix. 1722 1768 """ 1723 1769 args = list(args) 1724 1770 sparse = kwds.get('sparse',None) … … 1732 1778 if len(args) >= 1 and rings.is_Ring(args[0]): 1733 1779 # A ring is specified 1734 1780 if kwds.get('ring', args[0]) != args[0]: 1735 raise ValueError , "Specified rings are not the same"1781 raise ValueError("base ring specified twice and they are different") 1736 1782 ring = args[0] 1737 1783 args.pop(0) 1738 1784 else: … … 1743 1789 nrows = int(args[0]) 1744 1790 args.pop(0) 1745 1791 if kwds.get('nrows', nrows) != nrows: 1746 raise ValueError , "Number of rows specified in two places and they are not the same"1792 raise ValueError("number of rows specified twice and they are different") 1747 1793 except TypeError: 1748 1794 nrows = kwds.get('nrows', None) 1749 1795 else: … … 1755 1801 ncols = int(args[0]) 1756 1802 args.pop(0) 1757 1803 if kwds.get('ncols', ncols) != ncols: 1758 raise ValueError , "Number of columns specified in two places and they are not the same"1804 raise ValueError("number of columns specified twice and they are different") 1759 1805 except TypeError: 1760 1806 ncols = kwds.get('ncols', None) 1761 1807 else: … … 1770 1816 args = [[]] 1771 1817 if len(args) > 1: 1772 1818 print args 1773 raise TypeError , "Invalid block_matrix invocation"1819 raise TypeError("invalid block_matrix invocation") 1774 1820 1775 1821 sub_matrices = args[0] 1776 1822 … … 1778 1824 # a single matrix (check nrows/ncols/ring) 1779 1825 if (nrows is not None and nrows != 1) or \ 1780 1826 (ncols is not None and ncols != 1): 1781 raise ValueError , "Invalid nrows/ncols passed to block_matrix"1827 raise ValueError("invalid nrows/ncols passed to block_matrix") 1782 1828 if ring is not None: 1783 1829 M = M.change_ring(ring) 1784 1830 if sparse is not None and M.is_sparse() != sparse: … … 1786 1832 return M 1787 1833 1788 1834 if not isinstance(sub_matrices, (list, tuple)): 1789 raise TypeError , "Invalid block_matrix invocation"1835 raise TypeError("invalid block_matrix invocation") 1790 1836 1791 1837 subdivide = kwds.get('subdivide', True) 1792 1838 … … 1797 1843 if len(sub_matrices) == 0: 1798 1844 if (nrows is not None and nrows != 0) or \ 1799 1845 (ncols is not None and ncols != 0): 1800 raise ValueError , "Invalid nrows/ncols passed to block_matrix"1846 raise ValueError("invalid nrows/ncols passed to block_matrix") 1801 1847 elif isinstance(sub_matrices[0], (list, tuple)): 1802 1848 # A list of lists: verify all elements are lists, and if 1803 1849 # ncols is set, the lengths match. 1804 1850 if nrows is not None and len(sub_matrices) != nrows: 1805 raise ValueError , "Invalid nrows passed to block_matrix"1851 raise ValueError("invalid nrows passed to block_matrix") 1806 1852 first_len = len(sub_matrices[0]) 1807 1853 if ncols is not None and first_len != ncols: 1808 raise ValueError , "Invalid ncols passed to block_matrix"1854 raise ValueError("invalid ncols passed to block_matrix") 1809 1855 same_length = all(isinstance(v, (list, tuple)) and len(v) == first_len for v in sub_matrices) 1810 1856 if subdivide and not same_length: 1811 raise ValueError , "List of rows is not valid (rows are wrong types or lengths)"1857 raise ValueError("list of rows is not valid (rows are wrong types or lengths)") 1812 1858 try_grid = same_length 1813 1859 else: 1814 1860 # A flat list … … 1818 1864 if ncols is None: 1819 1865 if n.is_square(): 1820 1866 import warnings 1821 warnings.warn(" This invocation of block_matrix is deprecated. See itsdocumentation for details.", DeprecationWarning, stacklevel=2)1867 warnings.warn("invocation of block_matrix with just a list whose length is a perfect square is deprecated. See the documentation for details.", DeprecationWarning, stacklevel=2) 1822 1868 nrows = ncols = n.sqrt() 1823 1869 else: 1824 raise ValueError, "Must specify nrows or ncols for nonsquare block matrix." 1870 # this form (ie just a flat list) could be allowed once deprecated invocation (above) goes away 1871 raise ValueError("must specify nrows or ncols for nonsquare block matrix.") 1825 1872 else: 1826 1873 nrows = int(n/ncols) 1827 1874 elif ncols is None: 1828 1875 ncols = int(n/nrows) 1829 1876 if nrows * ncols != n: 1830 raise ValueError , "Given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n)1877 raise ValueError("given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n)) 1831 1878 # Now create a list of lists from this 1832 1879 sub_matrices = [ sub_matrices[i*ncols : (i+1)*ncols] for i in range(nrows) ] 1833 1880 … … 1860 1907 (row_heights, col_widths) = _determine_block_matrix_grid(sub_matrices) 1861 1908 except ValueError as e: 1862 1909 if subdivide: 1863 raise ValueError , e1910 raise ValueError(e) 1864 1911 1865 1912 1866 1913 if col_widths is None: … … 1923 1970 Create a block matrix whose diagonal block entries are given by 1924 1971 sub_matrices, with zero elsewhere. 1925 1972 1926 See also ``block_matrix``.1973 See also :meth:`block_matrix`. 1927 1974 1928 1975 EXAMPLES:: 1929 1976