Ticket #10627: trac_10627-pretty-matrices.patch

File trac_10627-pretty-matrices.patch, 7.0 KB (added by iandrus, 10 years ago)
  • sage/matrix/matrix0.pyx

    # HG changeset patch
    # User Ivan Andrus <darthandrus@gmail.com>
    # Date 1295629988 -3600
    # Node ID 1cdd36d237744ded4cc6c162cc4f189fff33b9d6
    # Parent  777e700394384024109c7f3114b68d1e6d810554
    #10627 Make Matrix.str able to override the representations of elements
    
    diff --git a/sage/matrix/matrix0.pyx b/sage/matrix/matrix0.pyx
    a b  
    16051605        if not isinstance(name, str):
    16061606            name = "obj"
    16071607        return rep + " (type 'print %s.str()' to see all of the entries)" % name
    1608        
    1609     def str(self):
     1608
     1609    def str(self, rep_mapping=None, zero=None, plus_one=None, minus_one=None):
    16101610        r"""
     1611        Return a nice string representation of the matrix.
     1612
     1613        INPUT:
     1614
     1615        - ``rep_mapping`` - a dictionary or callable used to override
     1616          the usual representation of elements.
     1617
     1618          If ``rep_mapping`` is a dictionary then keys should be
     1619          elements of the base ring and values the desired string
     1620          representation.  Values sent in via the other keyword
     1621          arguments will override values in the dictionary.
     1622
     1623          If ``rep_mapping`` is callable then it will be called with
     1624          elements of the matrix and must return a string.  Simply
     1625          call :func:`repr` on elements which should have the default
     1626          representation.
     1627
     1628        - ``zero`` - string (default: ``None``); if not ``None`` use
     1629          the value of ``zero`` as the representation of the zero
     1630          element.
     1631
     1632        - ``plus_one`` - string (default: ``None``); if not ``None``
     1633          use the value of ``plus_one`` as the representation of the
     1634          one element.
     1635
     1636        - ``minus_one`` - string (default: ``None``); if not ``None``
     1637          use the value of ``minus_one`` as the representation of the
     1638          negative of the one element.
     1639
    16111640        EXAMPLES::
    1612        
     1641
    16131642            sage: R = PolynomialRing(QQ,6,'z')
    16141643            sage: a = matrix(2,3, R.gens())
    16151644            sage: a.__repr__()
    16161645            '[z0 z1 z2]\n[z3 z4 z5]'
     1646
     1647            sage: M = matrix([[1,0],[2,-1]])
     1648            sage: M.str()
     1649            '[ 1  0]\n[ 2 -1]'
     1650            sage: M.str(plus_one='+',minus_one='-',zero='.')
     1651            '[+ .]\n[2 -]'
     1652            sage: M.str({1:"not this one",2:"II"},minus_one="*",plus_one="I")
     1653            '[ I  0]\n[II  *]'
     1654
     1655            sage: def print_entry(x):
     1656            ...     if x>0:
     1657            ...         return '+'
     1658            ...     elif x<0:
     1659            ...         return '-'
     1660            ...     else: return '.'
     1661            ...
     1662            sage: M.str(print_entry)
     1663            '[+ .]\n[+ -]'
     1664            sage: M.str(repr)
     1665            '[ 1  0]\n[ 2 -1]'
    16171666        """
    16181667        #x = self.fetch('repr')  # too confusing!!
    16191668        #if not x is None: return x
     
    16261675
    16271676        row_divs, col_divs = self.get_subdivisions()
    16281677
     1678        # Set the mapping based on keyword arguments
     1679        if rep_mapping is None:
     1680            rep_mapping = {}
     1681        if isinstance(rep_mapping, dict):
     1682            if zero is not None:
     1683                rep_mapping[self.base_ring().zero()] = zero
     1684            if plus_one is not None:
     1685                rep_mapping[self.base_ring().one()] = plus_one
     1686            if minus_one is not None:
     1687                rep_mapping[-self.base_ring().one()] = minus_one
     1688
    16291689        # compute column widths
    16301690        S = []
    16311691        for x in self.list():
    1632             S.append(repr(x))
     1692            # Override the usual representations with those specified
     1693            if callable(rep_mapping):
     1694                rep = rep_mapping(x)
     1695            elif rep_mapping.has_key(x):
     1696                rep = rep_mapping.get(x)
     1697            else:
     1698                rep = repr(x)
     1699            S.append(rep)
    16331700
    16341701        tmp = []
    16351702        for x in S:
    16361703            tmp.append(len(x))
    1637        
     1704
    16381705        width = max(tmp)
    16391706        rows = []
    16401707        m = 0
    1641        
     1708
    16421709        left_bracket = "["
    16431710        right_bracket = "]"
    16441711        while nc in col_divs:
  • sage/matrix/matrix_mod2_dense.pyx

    diff --git a/sage/matrix/matrix_mod2_dense.pyx b/sage/matrix/matrix_mod2_dense.pyx
    a b  
    433433            return self._zero
    434434
    435435
    436     def str(self):
     436    def str(self, rep_mapping=None, zero=None, plus_one=None, minus_one=None):
    437437        """
     438        Return a nice string representation of the matrix.
     439
     440        INPUT:
     441
     442        - ``rep_mapping`` - a dictionary or callable used to override
     443          the usual representation of elements.  For a dictionary,
     444          keys should be elements of the base ring and values the
     445          desired string representation.
     446
     447        - ``zero`` - string (default: ``None``); if not ``None`` use
     448          the value of ``zero`` as the representation of the zero
     449          element.
     450
     451        - ``plus_one`` - string (default: ``None``); if not ``None``
     452          use the value of ``plus_one`` as the representation of the
     453          one element.
     454
     455        - ``minus_one`` - Ignored.  Only for compatibility with
     456          generic matrices.
     457
    438458        EXAMPLE::
    439459
    440             sage: B = random_matrix(GF(2),3,3)       
     460            sage: B = random_matrix(GF(2),3,3)
    441461            sage: B # indirect doctest
    442462            [0 1 0]
    443463            [0 1 1]
     
    450470            [0 0 0|0 1 0]
    451471            [0 0 0|0 1 1]
    452472            [0 0 0|0 0 0]
     473            sage: B.str(zero='.')
     474            '[. 1 .]\n[. 1 1]\n[. . .]'
    453475        """
    454476        if self._nrows ==0 or self._ncols == 0:
    455477            return "[]"
    456            
     478
    457479        cdef int i,j, last_i
    458480        cdef list s = []
    459481        empty_row = " "*(self._ncols*2-1)
    460482        cdef char *row_s
    461483        cdef char *div_s
    462484
     485        # Set the mapping based on keyword arguments
     486        # We ignore minus_one (it's only there for compatibility with Matrix)
     487        if rep_mapping is not None or zero is not None or plus_one is not None:
     488        # Shunt mappings off to the generic code since they might not be single characters
     489            return matrix_dense.Matrix_dense.str(self, rep_mapping=rep_mapping, zero=zero, plus_one=plus_one)
     490
    463491        cdef list row_div, col_div
    464492        if self.subdivisions is not None:
    465493            row_s = empty_row
     
    469497            for i in col_div:
    470498                if i == last_i or i == self._ncols:
    471499                    # Adjacent column divisions messy, use generic code
    472                     return matrix_dense.Matrix_dense.str(self)
     500                    return matrix_dense.Matrix_dense.str(self, rep_mapping)
    473501                row_s[2*i-1] = '|'
    474502                div_s[2*i] = '+'
    475503                last_i = i
    476            
     504
    477505        for i from 0 <= i < self._nrows:
    478506            row_s = row = b"[%s]" % empty_row
    479507            for j from 0 <= j < self._ncols:
    480508                row_s[1+2*j] = c'0' + mzd_read_bit(self._entries,i,j)
    481509            s.append(row)
    482        
     510
    483511        if self.subdivisions is not None:
    484512            for i in reversed(row_div):
    485513                s.insert(i, row_divider)
    486        
     514
    487515        return "\n".join(s)
    488516
    489517    def row(self, Py_ssize_t i, from_list=False):