Ticket #10974: trac_10974_stack-augment-special.patch

File trac_10974_stack-augment-special.patch, 33.0 KB (added by rbeezer, 9 years ago)
  • sage/matrix/matrix1.pyx

    # HG changeset patch
    # User Rob Beezer <beezer@ups.edu>
    # Date 1300742683 25200
    # Node ID 3e5d5cf530345e0b020c54f296160d93f7953812
    # Parent  cc0a175bb6a0b06d7a2d3f114cc433585aa93d2f
    10974: Overhaul matrix stack, augment for specialized classes
    
    diff -r cc0a175bb6a0 -r 3e5d5cf53034 sage/matrix/matrix1.pyx
    a b  
    12131213
    12141214        return Z
    12151215
     1216    def augment(self, right, subdivide=False):
     1217        r"""
     1218        Returns a new matrix formed by appending the matrix
     1219        (or vector) ``right`` on the right side of ``self``.
     1220
     1221        INPUT:
     1222
     1223        - ``right`` - a matrix, vector or free module element, whose
     1224          dimensions are compatible with ``self``.
     1225
     1226        - ``subdivide`` - default: ``False`` - request the resulting
     1227          matrix to have a new subdivision, separating ``self`` from ``right``.
     1228
     1229        OUTPUT:
     1230
     1231        A new matrix formed by appending ``right`` onto the right side of ``self``.
     1232        If ``right`` is a vector (or free module element) then in this context
     1233        it is appropriate to consider it as a column vector.  (The code first
     1234        converts a vector to a 1-column matrix.)
     1235
     1236        If ``subdivide`` is ``True`` then any column subdivisions for
     1237        the two matrices are preserved, and a new subdivision is added
     1238        between ``self`` and ``right``.  If the row divisions are
     1239        identical, then they are preserved, otherwise they are discarded.
     1240        When ``subdivide`` is ``False`` there is no subdivision information
     1241        in the result.
     1242
     1243        .. warning::
     1244            If ``subdivide`` is ``True`` then unequal row subdivisions
     1245            will be discarded, since it would be ambiguous how to interpret
     1246            them.  If the subdivision behavior is not what you need,
     1247            you can manage subdivisions yourself with methods like
     1248            :meth:`~sage.matrix.matrix2.Matrix.get_subdivisions`
     1249            and
     1250            :meth:`~sage.matrix.matrix2.Matrix.subdivide`.
     1251            You might also find :func:`~sage.matrix.constructor.block_matrix`
     1252            or
     1253            :func:`~sage.matrix.constructor.block_diagonal_matrix`
     1254            useful and simpler in some instances.
     1255
     1256
     1257        EXAMPLES:
     1258
     1259        Augmenting with a matrix. ::
     1260
     1261            sage: A = matrix(QQ, 3, range(12))
     1262            sage: B = matrix(QQ, 3, range(9))
     1263            sage: A.augment(B)
     1264            [ 0  1  2  3  0  1  2]
     1265            [ 4  5  6  7  3  4  5]
     1266            [ 8  9 10 11  6  7  8]
     1267
     1268        Augmenting with a vector. ::
     1269
     1270            sage: A = matrix(QQ, 2, [0, 2, 4, 6, 8, 10])
     1271            sage: v = vector(QQ, 2, [100, 200])
     1272            sage: A.augment(v)
     1273            [  0   2   4 100]
     1274            [  6   8  10 200]
     1275
     1276        Errors are raised if the sizes are incompatible. ::
     1277
     1278            sage: A = matrix(RR, [[1, 2],[3, 4]])
     1279            sage: B = matrix(RR, [[10, 20], [30, 40], [50, 60]])
     1280            sage: A.augment(B)
     1281            Traceback (most recent call last):
     1282            ...
     1283            TypeError: number of rows must be the same, 2 != 3
     1284
     1285            sage: v = vector(RR, [100, 200, 300])
     1286            sage: A.augment(v)
     1287            Traceback (most recent call last):
     1288            ...
     1289            TypeError: number of rows must be the same, 2 != 3
     1290
     1291        Setting ``subdivide`` to ``True`` will, in its simplest form,
     1292        add a subdivision between ``self`` and ``right``. ::
     1293
     1294            sage: A = matrix(QQ, 3, range(12))
     1295            sage: B = matrix(QQ, 3, range(15))
     1296            sage: A.augment(B, subdivide=True)
     1297            [ 0  1  2  3| 0  1  2  3  4]
     1298            [ 4  5  6  7| 5  6  7  8  9]
     1299            [ 8  9 10 11|10 11 12 13 14]
     1300
     1301        Column subdivisions are preserved by augmentation, and enriched,
     1302        if subdivisions are requested.  (So multiple augmentations can
     1303        be recorded.) ::
     1304
     1305            sage: A = matrix(QQ, 3, range(6))
     1306            sage: A.subdivide(None, [1])
     1307            sage: B = matrix(QQ, 3, range(9))
     1308            sage: B.subdivide(None, [2])
     1309            sage: A.augment(B, subdivide=True)
     1310            [0|1|0 1|2]
     1311            [2|3|3 4|5]
     1312            [4|5|6 7|8]
     1313
     1314        Row subdivisions can be preserved, but only if they are identical.
     1315        Otherwise, this information is discarded and must be managed
     1316        separately. ::
     1317
     1318            sage: A = matrix(QQ, 3, range(6))
     1319            sage: A.subdivide([1,3], None)
     1320            sage: B = matrix(QQ, 3, range(9))
     1321            sage: B.subdivide([1,3], None)
     1322            sage: A.augment(B, subdivide=True)
     1323            [0 1|0 1 2]
     1324            [---+-----]
     1325            [2 3|3 4 5]
     1326            [4 5|6 7 8]
     1327            [---+-----]
     1328
     1329            sage: A.subdivide([1,2], None)
     1330            sage: A.augment(B, subdivide=True)
     1331            [0 1|0 1 2]
     1332            [2 3|3 4 5]
     1333            [4 5|6 7 8]
     1334
     1335        The result retains the base ring of ``self`` by coercing
     1336        the elements of ``right`` into the base ring of ``self``. ::
     1337
     1338            sage: A = matrix(QQ, 2, [1,2])
     1339            sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)])
     1340            sage: C = A.augment(B); C
     1341            [                  1 183017397/205358938]
     1342            [                  2 106580492/131825561]
     1343            sage: C.parent()
     1344            Full MatrixSpace of 2 by 2 dense matrices over Rational Field
     1345
     1346            sage: D = B.augment(A); D
     1347            [0.89120736006...  1.00000000000000]
     1348            [0.80849640381...  2.00000000000000]
     1349            sage: D.parent()
     1350            Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision
     1351
     1352        Sometimes it is not possible to coerce into the base ring
     1353        of ``self``.  A solution is to change the base ring of ``self``
     1354        to a more expansive ring.  Here we mix the rationals with
     1355        a ring of polynomials with rational coefficients.  ::
     1356
     1357            sage: R = PolynomialRing(QQ, 'y')
     1358            sage: A = matrix(QQ, 1, [1,2])
     1359            sage: B = matrix(R, 1, ['y', 'y^2'])
     1360
     1361            sage: C = B.augment(A); C
     1362            [  y y^2   1   2]
     1363            sage: C.parent()
     1364            Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field
     1365
     1366            sage: D = A.augment(B)
     1367            Traceback (most recent call last):
     1368            ...
     1369            TypeError: not a constant polynomial
     1370
     1371            sage: E = A.change_ring(R)
     1372            sage: F = E.augment(B); F
     1373            [  1   2   y y^2]
     1374            sage: F.parent()
     1375            Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field
     1376
     1377        AUTHORS:
     1378
     1379        - Naqi Jaffery (2006-01-24): examples
     1380        - Rob Beezer (2010-12-07): vector argument, docstring, subdivisions
     1381        """
     1382        from sage.matrix.constructor import matrix
     1383
     1384        if hasattr(right, '_vector_'):
     1385            right = right.column()
     1386        if not isinstance(right, sage.matrix.matrix1.Matrix):
     1387            raise TypeError("a matrix must be augmented with another matrix, or a vector")
     1388
     1389        cdef Matrix other
     1390        other = right
     1391
     1392        if self._nrows != other._nrows:
     1393            raise TypeError('number of rows must be the same, {0} != {1}'.format(self._nrows, other._nrows))
     1394        if not (self._base_ring is other.base_ring()):
     1395            other = other.change_ring(self._base_ring)
     1396
     1397        cdef Matrix Z
     1398        Z = self.new_matrix(ncols = self._ncols + other._ncols)
     1399
     1400        cdef Py_ssize_t r, c
     1401        for r from 0 <= r < self._nrows:
     1402            for c from 0 <= c < self._ncols:
     1403                Z.set_unsafe(r,c, self.get_unsafe(r,c))
     1404        nc = self.ncols()
     1405
     1406        for r from 0 <= r < other._nrows:
     1407            for c from 0 <= c < other._ncols:
     1408                Z.set_unsafe(r, c+nc, other.get_unsafe(r,c))
     1409
     1410        if subdivide:
     1411            Z._subdivide_on_augment(self, other)
     1412
     1413        return Z
    12161414
    12171415    def matrix_from_columns(self, columns):
    12181416        """
     
    16681866        """
    16691867        return self.matrix_space(nrows, ncols, sparse=sparse)(entries=entries,
    16701868                                             coerce=coerce, copy=copy)
    1671 
    1672     def augment(self, right, subdivide=False):
    1673         r"""
    1674         Returns a new matrix formed by appending the matrix
    1675         (or vector) ``right`` on the right side of ``self``.
    1676 
    1677         INPUT:
    1678 
    1679         - ``right`` - a matrix, vector or free module element, whose
    1680           dimensions are compatible with ``self``.
    1681 
    1682         - ``subdivide`` - default: ``False`` - request the resulting
    1683           matrix to have a new subdivision, separating ``self`` from ``right``.
    1684 
    1685         OUTPUT:
    1686 
    1687         A new matrix formed by appending ``right`` onto the right side of ``self``.
    1688         If ``right`` is a vector (or free module element) then in this context
    1689         it is appropriate to consider it as a column vector.  (The code first
    1690         converts a vector to a 1-column matrix.)
    1691 
    1692         If ``subdivide`` is ``True`` then any column subdivisions for
    1693         the two matrices are preserved, and a new subdivision is added
    1694         between ``self`` and ``right``.  If the row divisions are
    1695         identical, then they are preserved, otherwise they are discarded.
    1696         When ``subdivide`` is ``False`` there is no subdivision information
    1697         in the result.
    1698 
    1699         .. warning::
    1700             If ``subdivide`` is ``True`` then unequal row subdivisions
    1701             will be discarded, since it would be ambiguous how to interpret
    1702             them.  If the subdivision behavior is not what you need,
    1703             you can manage subdivisions yourself with methods like
    1704             :meth:`~sage.matrix.matrix2.Matrix.get_subdivisions`
    1705             and
    1706             :meth:`~sage.matrix.matrix2.Matrix.subdivide`.
    1707             You might also find :func:`~sage.matrix.constructor.block_matrix`
    1708             or
    1709             :func:`~sage.matrix.constructor.block_diagonal_matrix`
    1710             useful and simpler in some instances.
    1711 
    1712 
    1713         EXAMPLES:
    1714 
    1715         Augmenting with a matrix. ::
    1716 
    1717             sage: A = matrix(QQ, 3, range(12))
    1718             sage: B = matrix(QQ, 3, range(9))
    1719             sage: A.augment(B)
    1720             [ 0  1  2  3  0  1  2]
    1721             [ 4  5  6  7  3  4  5]
    1722             [ 8  9 10 11  6  7  8]
    1723 
    1724         Augmenting with a vector. ::
    1725 
    1726             sage: A = matrix(QQ, 2, [0, 2, 4, 6, 8, 10])
    1727             sage: v = vector(QQ, 2, [100, 200])
    1728             sage: A.augment(v)
    1729             [  0   2   4 100]
    1730             [  6   8  10 200]
    1731 
    1732         Errors are raised if the sizes are incompatible. ::
    1733 
    1734             sage: A = matrix(RR, [[1, 2],[3, 4]])
    1735             sage: B = matrix(RR, [[10, 20], [30, 40], [50, 60]])
    1736             sage: A.augment(B)
    1737             Traceback (most recent call last):
    1738             ...
    1739             TypeError: number of rows must be the same, 2 != 3
    1740 
    1741             sage: v = vector(RR, [100, 200, 300])
    1742             sage: A.augment(v)
    1743             Traceback (most recent call last):
    1744             ...
    1745             TypeError: number of rows must be the same, 2 != 3
    1746 
    1747         Setting ``subdivide`` to ``True`` will, in its simplest form,
    1748         add a subdivision between ``self`` and ``right``. ::
    1749 
    1750             sage: A = matrix(QQ, 3, range(12))
    1751             sage: B = matrix(QQ, 3, range(15))
    1752             sage: A.augment(B, subdivide=True)
    1753             [ 0  1  2  3| 0  1  2  3  4]
    1754             [ 4  5  6  7| 5  6  7  8  9]
    1755             [ 8  9 10 11|10 11 12 13 14]
    1756 
    1757         Column subdivisions are preserved by augmentation, and enriched,
    1758         if subdivisions are requested.  (So multiple augmentations can
    1759         be recorded.) ::
    1760 
    1761             sage: A = matrix(QQ, 3, range(6))
    1762             sage: A.subdivide(None, [1])
    1763             sage: B = matrix(QQ, 3, range(9))
    1764             sage: B.subdivide(None, [2])
    1765             sage: A.augment(B, subdivide=True)
    1766             [0|1|0 1|2]
    1767             [2|3|3 4|5]
    1768             [4|5|6 7|8]
    1769 
    1770         Row subdivisions can be preserved, but only if they are identical.
    1771         Otherwise, this information is discarded and must be managed
    1772         separately. ::
    1773 
    1774             sage: A = matrix(QQ, 3, range(6))
    1775             sage: A.subdivide([1,3], None)
    1776             sage: B = matrix(QQ, 3, range(9))
    1777             sage: B.subdivide([1,3], None)
    1778             sage: A.augment(B, subdivide=True)
    1779             [0 1|0 1 2]
    1780             [---+-----]
    1781             [2 3|3 4 5]
    1782             [4 5|6 7 8]
    1783             [---+-----]
    1784 
    1785             sage: A.subdivide([1,2], None)
    1786             sage: A.augment(B, subdivide=True)
    1787             [0 1|0 1 2]
    1788             [2 3|3 4 5]
    1789             [4 5|6 7 8]
    1790 
    1791         The result retains the base ring of ``self`` by coercing
    1792         the elements of ``right`` into the base ring of ``self``. ::
    1793 
    1794             sage: A = matrix(QQ, 2, [1,2])
    1795             sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)])
    1796             sage: C = A.augment(B); C
    1797             [                  1 183017397/205358938]
    1798             [                  2 106580492/131825561]
    1799             sage: C.parent()
    1800             Full MatrixSpace of 2 by 2 dense matrices over Rational Field
    1801 
    1802             sage: D = B.augment(A); D
    1803             [0.89120736006...  1.00000000000000]
    1804             [0.80849640381...  2.00000000000000]
    1805             sage: D.parent()
    1806             Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision
    1807 
    1808         Sometimes it is not possible to coerce into the base ring
    1809         of ``self``.  A solution is to change the base ring of ``self``
    1810         to a more expansive ring.  Here we mix the rationals with
    1811         a ring of polynomials with rational coefficients.  ::
    1812 
    1813             sage: R = PolynomialRing(QQ, 'y')
    1814             sage: A = matrix(QQ, 1, [1,2])
    1815             sage: B = matrix(R, 1, ['y', 'y^2'])
    1816 
    1817             sage: C = B.augment(A); C
    1818             [  y y^2   1   2]
    1819             sage: C.parent()
    1820             Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field
    1821 
    1822             sage: D = A.augment(B)
    1823             Traceback (most recent call last):
    1824             ...
    1825             TypeError: not a constant polynomial
    1826 
    1827             sage: E = A.change_ring(R)
    1828             sage: F = E.augment(B); F
    1829             [  1   2   y y^2]
    1830             sage: F.parent()
    1831             Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field
    1832 
    1833         AUTHORS:
    1834 
    1835         - Naqi Jaffery (2006-01-24): examples
    1836         - Rob Beezer (2010-12-07): vector argument, docstring, subdivisions
    1837         """
    1838         from sage.matrix.constructor import matrix
    1839 
    1840         if hasattr(right, '_vector_'):
    1841             right = right.column()
    1842         if not isinstance(right, sage.matrix.matrix1.Matrix):
    1843             raise TypeError("a matrix must be augmented with another matrix, or a vector")
    1844 
    1845         cdef Matrix other
    1846         other = right
    1847 
    1848         if self._nrows != other._nrows:
    1849             raise TypeError('number of rows must be the same, {0} != {1}'.format(self._nrows, other._nrows))
    1850         if not (self._base_ring is other.base_ring()):
    1851             other = other.change_ring(self._base_ring)
    1852 
    1853         cdef Matrix Z
    1854         Z = self.new_matrix(ncols = self._ncols + other._ncols)
    1855 
    1856         cdef Py_ssize_t r, c
    1857         for r from 0 <= r < self._nrows:
    1858             for c from 0 <= c < self._ncols:
    1859                 Z.set_unsafe(r,c, self.get_unsafe(r,c))
    1860         nc = self.ncols()
    1861 
    1862         for r from 0 <= r < other._nrows:
    1863             for c from 0 <= c < other._ncols:
    1864                 Z.set_unsafe(r, c+nc, other.get_unsafe(r,c))
    1865 
    1866         if subdivide:
    1867             Z._subdivide_on_augment(self, other)
    1868 
    1869         return Z
    1870 
    18711869    def block_sum(self, Matrix other):
    18721870        """
    18731871        Return the block matrix that has self and other on the diagonal::
  • sage/matrix/matrix_integer_dense.pyx

    diff -r cc0a175bb6a0 -r 3e5d5cf53034 sage/matrix/matrix_integer_dense.pyx
    a b  
    44064406    #####################################################################################
    44074407    # operations with matrices
    44084408    #####################################################################################
    4409     def stack(self, other):
    4410         """
    4411         Return the matrix self on top of other: [ self ] [ other ]
    4412        
     4409    def stack(self, bottom, subdivide=False):
     4410        r"""
     4411        Return the matrix self on top of bottom: [ self ] [ bottom ]
     4412
    44134413        EXAMPLES::
    4414        
     4414
    44154415            sage: M = Matrix(ZZ, 2, 3, range(6))
    44164416            sage: N = Matrix(ZZ, 1, 3, [10,11,12])
    44174417            sage: M.stack(N)
     
    44194419            [ 3  4  5]
    44204420            [10 11 12]
    44214421
     4422        A vector may be stacked below a matrix. ::
     4423
     4424            sage: A = matrix(ZZ, 2, 4, range(8))
     4425            sage: v = vector(ZZ, 4, range(4))
     4426            sage: A.stack(v)
     4427            [0 1 2 3]
     4428            [4 5 6 7]
     4429            [0 1 2 3]
     4430
     4431        The ``subdivide`` option will add a natural subdivision between
     4432        ``self`` and ``bottom``.  For more details about how subdivisions
     4433        are managed when stacking, see 
     4434        :meth:`sage.matrix.matrix1.Matrix.stack`.  ::
     4435
     4436            sage: A = matrix(ZZ, 3, 4, range(12))
     4437            sage: B = matrix(ZZ, 2, 4, range(8))
     4438            sage: A.stack(B, subdivide=True)
     4439            [ 0  1  2  3]
     4440            [ 4  5  6  7]
     4441            [ 8  9 10 11]
     4442            [-----------]
     4443            [ 0  1  2  3]
     4444            [ 4  5  6  7]
     4445
    44224446        TESTS:
    44234447
    44244448        Stacking a dense matrix atop a sparse one should work::
     
    44384462            sage: P.is_sparse()
    44394463            False
    44404464        """
    4441         if self._ncols != other.ncols():
     4465        if hasattr(bottom, '_vector_'):
     4466            bottom = bottom.row()
     4467        if self._ncols != bottom.ncols():
    44424468            raise TypeError("number of columns must be the same")
    4443         if not (self._base_ring is other.base_ring()):
    4444             other = other.change_ring(self._base_ring)
    4445         cdef Matrix_integer_dense A = other.dense_matrix()
     4469        if not (self._base_ring is bottom.base_ring()):
     4470            bottom = bottom.change_ring(self._base_ring)
     4471        cdef Matrix_integer_dense other = bottom.dense_matrix()
    44464472        cdef Matrix_integer_dense M
    4447         M = self.new_matrix(nrows = self._nrows + A._nrows, ncols = self.ncols())
     4473        M = self.new_matrix(nrows = self._nrows + other._nrows, ncols = self.ncols())
    44484474        cdef Py_ssize_t i, k
    44494475        k = self._nrows * self._ncols
    44504476        for i from 0 <= i < k:
    44514477            mpz_set(M._entries[i], self._entries[i])
    4452         for i from 0 <= i < A._nrows * A._ncols:
    4453             mpz_set(M._entries[k + i], A._entries[i])
     4478        for i from 0 <= i < other._nrows * other._ncols:
     4479            mpz_set(M._entries[k + i], other._entries[i])
     4480        if subdivide:
     4481            M._subdivide_on_stack(self, other)
    44544482        return M
    44554483
     4484    def augment(self, right, subdivide=False):
     4485        r"""
     4486        Returns a new matrix formed by appending the matrix
     4487        (or vector) ``right`` on the right side of ``self``.
     4488
     4489        INPUT:
     4490
     4491        - ``right`` - a matrix, vector or free module element, whose
     4492          dimensions are compatible with ``self``.
     4493
     4494        - ``subdivide`` - default: ``False`` - request the resulting
     4495          matrix to have a new subdivision, separating ``self`` from ``right``.
     4496
     4497        OUTPUT:
     4498
     4499        A new matrix formed by appending ``right`` onto the right side of ``self``.
     4500        If ``right`` is a vector (or free module element) then in this context
     4501        it is appropriate to consider it as a column vector.  (The code first
     4502        converts a vector to a 1-column matrix.)
     4503
     4504        EXAMPLES::
     4505
     4506            sage: A = matrix(ZZ, 4, 5, range(20))
     4507            sage: B = matrix(ZZ, 4, 3, range(12))
     4508            sage: A.augment(B)
     4509            [ 0  1  2  3  4  0  1  2]
     4510            [ 5  6  7  8  9  3  4  5]
     4511            [10 11 12 13 14  6  7  8]
     4512            [15 16 17 18 19  9 10 11]
     4513
     4514        A vector may be augmented to a matrix. ::
     4515
     4516            sage: A = matrix(ZZ, 3, 5, range(15))
     4517            sage: v = vector(ZZ, 3, range(3))
     4518            sage: A.augment(v)
     4519            [ 0  1  2  3  4  0]
     4520            [ 5  6  7  8  9  1]
     4521            [10 11 12 13 14  2]
     4522
     4523        The ``subdivide`` option will add a natural subdivision between
     4524        ``self`` and ``right``.  For more details about how subdivisions
     4525        are managed when augmenting, see
     4526        :meth:`sage.matrix.matrix1.Matrix.augment`.  ::
     4527
     4528            sage: A = matrix(ZZ, 3, 5, range(15))
     4529            sage: B = matrix(ZZ, 3, 3, range(9))
     4530            sage: A.augment(B, subdivide=True)
     4531            [ 0  1  2  3  4| 0  1  2]
     4532            [ 5  6  7  8  9| 3  4  5]
     4533            [10 11 12 13 14| 6  7  8]
     4534
     4535        Errors are raised if the sizes are incompatible. ::
     4536
     4537            sage: A = matrix(ZZ, [[1, 2],[3, 4]])
     4538            sage: B = matrix(ZZ, [[10, 20], [30, 40], [50, 60]])
     4539            sage: A.augment(B)
     4540            Traceback (most recent call last):
     4541            ...
     4542            TypeError: number of rows must be the same, not 2 != 3
     4543        """
     4544        if hasattr(right, '_vector_'):
     4545            right = right.column()
     4546        if self._nrows != right.nrows():
     4547            raise TypeError('number of rows must be the same, not {0} != {1}'.format(self._nrows, right.nrows()))
     4548        if not (self._base_ring is right.base_ring()):
     4549            right = right.change_ring(self._base_ring)
     4550
     4551        cdef Matrix_integer_dense other = right.dense_matrix()
     4552        m = self._nrows
     4553        ns, na = self._ncols, other._ncols
     4554        n = ns + na
     4555
     4556        cdef Matrix_integer_dense Z
     4557        Z = self.new_matrix(nrows = m, ncols = n)
     4558        cdef Py_ssize_t i, j, p, qs, qa
     4559        p, qs, qa = 0, 0, 0
     4560        for i from 0 <= i < m:
     4561          for j from 0 <= j < ns:
     4562            mpz_set(Z._entries[p], self._entries[qs])
     4563            p = p + 1
     4564            qs = qs + 1
     4565          for j from 0 <= j < na:
     4566            mpz_set(Z._entries[p], other._entries[qa])
     4567            p = p + 1
     4568            qa = qa + 1           
     4569        if subdivide:
     4570          Z._subdivide_on_augment(self, other)
     4571        return Z
     4572
    44564573    def insert_row(self, Py_ssize_t index, row):
    44574574        """
    44584575        Create a new matrix from self with.
     
    46504767        else:
    46514768            raise NotImplementedError
    46524769           
    4653 ##     def augment(self, other):
    4654 ##         """
    4655 ##         """
    4656 ##         if self._nrows != other.nrows():
    4657 ##             raise TypeError, "number of rows must be the same"
    4658 ##         if not (self._base_ring is other.base_ring()):
    4659 ##             other = other.change_ring(self._base_ring)
    4660 ##         cdef Matrix_integer_dense A = other
    4661 ##         cdef Matrix_integer_dense M
    4662 ##         M = self.new_matrix(nrows = self._nrows, ncols = self._ncols + A._ncols)
    4663 ##         cdef Py_ssize_t i, k
    4664 ##         k = self._nrows * self._ncols
    4665 ##         for i from 0 <= i < k:
    4666 ##             mpz_set(M._entries[i], self._entries[i])
    4667 ##         for i from 0 <= i < A._nrows * A._ncols:
    4668 ##             mpz_set(M._entries[k + i], A._entries[i])
    4669 ##         return M
    4670 
    46714770    def _singular_(self, singular=None):
    46724771        r"""
    46734772        Return Singular representation of this integer matrix.
  • sage/matrix/matrix_mod2_dense.pyx

    diff -r cc0a175bb6a0 -r 3e5d5cf53034 sage/matrix/matrix_mod2_dense.pyx
    a b  
    14601460        return mzd_cmp(self._entries, (<Matrix_mod2_dense>right)._entries)
    14611461
    14621462
    1463     def augment(self, Matrix_mod2_dense right):
    1464         """
     1463    def augment(self, right, subdivide=False):
     1464        r"""
    14651465        Augments ``self`` with ``right``.
    14661466
    14671467        EXAMPLE::
     
    14881488            sage: C*A == MS(1)
    14891489            True
    14901490
     1491        A vector may be augmented to a matrix. ::
     1492
     1493            sage: A = matrix(GF(2), 3, 4, range(12))
     1494            sage: v = vector(GF(2), 3, range(3))
     1495            sage: A.augment(v)
     1496            [0 1 0 1 0]
     1497            [0 1 0 1 1]
     1498            [0 1 0 1 0]
     1499
     1500        The ``subdivide`` option will add a natural subdivision between
     1501        ``self`` and ``right``.  For more details about how subdivisions
     1502        are managed when augmenting, see
     1503        :meth:`sage.matrix.matrix1.Matrix.augment`.  ::
     1504
     1505            sage: A = matrix(GF(2), 3, 5, range(15))
     1506            sage: B = matrix(GF(2), 3, 3, range(9))
     1507            sage: A.augment(B, subdivide=True)
     1508            [0 1 0 1 0|0 1 0]
     1509            [1 0 1 0 1|1 0 1]
     1510            [0 1 0 1 0|0 1 0]
     1511
    14911512        TESTS::
    14921513
    14931514            sage: A = random_matrix(GF(2),2,3)
     
    14951516            sage: A.augment(B)
    14961517            [0 1 0]
    14971518            [0 1 1]
    1498            
     1519
    14991520            sage: B.augment(A)
    15001521            [0 1 0]
    15011522            [0 1 1]
     
    15101531            sage: M.augment(N)
    15111532            []
    15121533        """
    1513         cdef Matrix_mod2_dense A
     1534        if hasattr(right, '_vector_'):
     1535            right = right.column()
    15141536
    1515         if self._nrows != right._nrows:
     1537        cdef Matrix_mod2_dense other = right
     1538
     1539        if self._nrows != other._nrows:
    15161540            raise TypeError("Both numbers of rows must match.")
    15171541
    15181542        if self._ncols == 0:
    1519             return right.__copy__()
    1520         if right._ncols == 0:
     1543            return other.__copy__()
     1544        if other._ncols == 0:
    15211545            return self.__copy__()
    15221546
    1523         A = self.new_matrix(ncols = self._ncols + right._ncols)
     1547        cdef Matrix_mod2_dense Z
     1548        Z = self.new_matrix(ncols = self._ncols + other._ncols)
    15241549        if self._nrows == 0:
    1525             return A
    1526         A._entries = mzd_concat(A._entries, self._entries, right._entries)
    1527         return A
     1550            return Z
     1551        Z._entries = mzd_concat(Z._entries, self._entries, other._entries)
     1552        if subdivide:
     1553            Z._subdivide_on_augment(self, other)
     1554        return Z
    15281555
    1529     def stack(self, Matrix_mod2_dense other):
    1530         """
    1531         Stack ``self`` on top of ``other``.
     1556    def stack(self, bottom, subdivide=False):
     1557        r"""
     1558        Stack ``self`` on top of ``bottom``.
    15321559
    15331560        EXAMPLE::
    15341561
     
    15451572            [1 0]
    15461573            [0 1]
    15471574
     1575        A vector may be stacked below a matrix. ::
     1576
     1577            sage: A = matrix(GF(2), 2, 5, range(10))
     1578            sage: v = vector(GF(2), 5, range(5))
     1579            sage: A.stack(v)
     1580            [0 1 0 1 0]
     1581            [1 0 1 0 1]
     1582            [0 1 0 1 0]
     1583
     1584        The ``subdivide`` option will add a natural subdivision between
     1585        ``self`` and ``bottom``.  For more details about how subdivisions
     1586        are managed when stacking, see
     1587        :meth:`sage.matrix.matrix1.Matrix.stack`.  ::
     1588
     1589            sage: A = matrix(GF(2), 3, 5, range(15))
     1590            sage: B = matrix(GF(2), 1, 5, range(5))
     1591            sage: A.stack(B, subdivide=True)
     1592            [0 1 0 1 0]
     1593            [1 0 1 0 1]
     1594            [0 1 0 1 0]
     1595            [---------]
     1596            [0 1 0 1 0]
     1597
    15481598        TESTS::
    15491599
    15501600            sage: A = random_matrix(GF(2),0,3)
     
    15691619            sage: M.stack(N)
    15701620            []
    15711621        """
     1622        if hasattr(bottom, '_vector_'):
     1623            bottom = bottom.row()
     1624        cdef Matrix_mod2_dense other = bottom
     1625
    15721626        if self._ncols != other._ncols:
    15731627            raise TypeError("Both numbers of columns must match.")
    15741628
     
    15771631        if other._nrows == 0:
    15781632            return self.__copy__()
    15791633
    1580         cdef Matrix_mod2_dense A
    1581         A = self.new_matrix(nrows = self._nrows + other._nrows)
     1634        cdef Matrix_mod2_dense Z
     1635        Z = self.new_matrix(nrows = self._nrows + other._nrows)
    15821636        if self._ncols == 0:
    1583             return A
    1584         A._entries = mzd_stack(A._entries, self._entries, other._entries)
    1585         return A
     1637            return Z
     1638        Z._entries = mzd_stack(Z._entries, self._entries, other._entries)
     1639        if subdivide:
     1640            Z._subdivide_on_stack(self, other)
     1641        return Z
    15861642
    15871643    def submatrix(self, lowr, lowc, nrows , ncols):
    15881644        """
  • sage/matrix/matrix_sparse.pyx

    diff -r cc0a175bb6a0 -r 3e5d5cf53034 sage/matrix/matrix_sparse.pyx
    a b  
    800800                        A.set_unsafe(new_row, new_col, entry)
    801801        return A
    802802
    803     def stack(self, other):
    804         """
    805         Return the augmented matrix self on top of other:
     803    def stack(self, bottom, subdivide=False):
     804        r"""
     805        Stack ``self`` on top of ``bottom``.
    806806
    807807            [ self  ]
    808             [ other ]
     808            [ bottom ]
    809809
    810810        EXAMPLES::
    811811
     
    815815            [ 0  1  2]
    816816            [ 3  4  5]
    817817            [10 11 12]
     818
     819        A vector may be stacked below a matrix. ::
     820
     821            sage: A = matrix(QQ, 2, 5, range(10), sparse=True)
     822            sage: v = vector(QQ, 5, range(5), sparse=True)
     823            sage: A.stack(v)
     824            [0 1 2 3 4]
     825            [5 6 7 8 9]
     826            [0 1 2 3 4]
     827
     828        The ``subdivide`` option will add a natural subdivision between
     829        ``self`` and ``other``.  For more details about how subdivisions
     830        are managed when stacking, see
     831        :meth:`sage.matrix.matrix1.Matrix.stack`.  ::
     832
     833            sage: A = matrix(ZZ, 3, 4, range(12), sparse=True)
     834            sage: B = matrix(ZZ, 2, 4, range(8), sparse=True)
     835            sage: A.stack(B, subdivide=True)
     836            [ 0  1  2  3]
     837            [ 4  5  6  7]
     838            [ 8  9 10 11]
     839            [-----------]
     840            [ 0  1  2  3]
     841            [ 4  5  6  7]
    818842        """
    819         if not isinstance(other, matrix.Matrix):
     843        if hasattr(bottom, '_vector_'):
     844            bottom = bottom.row()
     845        if not isinstance(bottom, matrix.Matrix):
    820846            raise TypeError, "other must be a matrix"
    821847
    822         if self._ncols != other.ncols():
     848        cdef Matrix_sparse other = bottom.sparse_matrix()
     849
     850        if self._ncols != other._ncols:
    823851            raise TypeError, "number of columns must be the same"
    824852
    825853        if not (self._base_ring is other.base_ring()):
     
    831859        for i, j in self.nonzero_positions(copy=False):
    832860            Z.set_unsafe(i, j, self.get_unsafe(i,j))
    833861        for i, j in other.nonzero_positions(copy=False):
    834             Z.set_unsafe(i + self._nrows, j, (<matrix.Matrix>other).get_unsafe(i,j))
     862            Z.set_unsafe(i + self._nrows, j, other.get_unsafe(i,j))
     863        if subdivide:
     864            Z._subdivide_on_stack(self, other)
    835865        return Z
    836866
    837     def augment(self, other):
    838         """
     867    def augment(self, right, subdivide=False):
     868        r"""
    839869        Return the augmented matrix of the form::
    840870
    841             [self | other].
     871            [self | right].
    842872
    843873        EXAMPLES::
    844874
     
    858888            sage: B.augment(A)
    859889            [9 1 2]
    860890            [8 3 4]
     891
     892        A vector may be augmented to a matrix. ::
     893
     894            sage: A = matrix(QQ, 3, 4, range(12), sparse=True)
     895            sage: v = vector(QQ, 3, range(3), sparse=True)
     896            sage: A.augment(v)
     897            [ 0  1  2  3  0]
     898            [ 4  5  6  7  1]
     899            [ 8  9 10 11  2]
     900
     901        The ``subdivide`` option will add a natural subdivision between
     902        ``self`` and ``right``.  For more details about how subdivisions
     903        are managed when augmenting, see
     904        :meth:`sage.matrix.matrix1.Matrix.augment`.  ::
     905
     906            sage: A = matrix(QQ, 3, 5, range(15), sparse=True)
     907            sage: B = matrix(QQ, 3, 3, range(9), sparse=True)
     908            sage: A.augment(B, subdivide=True)
     909            [ 0  1  2  3  4| 0  1  2]
     910            [ 5  6  7  8  9| 3  4  5]
     911            [10 11 12 13 14| 6  7  8]
    861912        """
    862         if not isinstance(other, matrix.Matrix):
    863             raise TypeError, "other must be a matrix"
     913        if hasattr(right, '_vector_'):
     914            right = right.column()
     915        if not isinstance(right, matrix.Matrix):
     916            raise TypeError, "right must be a matrix"
    864917
    865         if self._nrows != other.nrows():
     918        cdef Matrix_sparse other = right.sparse_matrix()
     919
     920        if self._nrows != other._nrows:
    866921            raise TypeError, "number of rows must be the same"
    867922
    868         if not (self._base_ring is other.base_ring()):
    869             other = other.change_ring(self._base_ring)
     923        if not (self._base_ring is right.base_ring()):
     924            right = right.change_ring(self._base_ring)
    870925
    871926        cdef Matrix_sparse Z
    872         Z = self.new_matrix(ncols = self._ncols + other.ncols())
    873 
     927        Z = self.new_matrix(ncols = self._ncols + other._ncols)
    874928        for i, j in self.nonzero_positions(copy=False):
    875929            Z.set_unsafe(i, j, self.get_unsafe(i,j))
    876         for i, j in other.nonzero_positions(copy=False):
    877             Z.set_unsafe(i, j + self._ncols, (<matrix.Matrix>other).get_unsafe(i,j))
     930        for i, j in right.nonzero_positions(copy=False):
     931            Z.set_unsafe(i, j + self._ncols, other.get_unsafe(i,j))
     932        if subdivide:
     933            Z._subdivide_on_augment(self, other)
    878934        return Z
    879935
    880936    cdef Vector _vector_times_matrix_(self, Vector v):