Ask Your Question
3

Displaying matrices with . instead of 0

asked 2011-01-12 08:57:06 +0100

Ivan Andrus gravatar image

updated 2011-05-12 16:31:10 +0100

Kelvin Li gravatar image

In GAP it is possible (at least in some circumstances) to display a matrix with . instead of 0 and without brackets. This makes the structure of the matrix much easier to see. Is there a way to do this in Sage?

e.g. to show

   1   3   3   .   9
   1   1   1   2   5
   1   1   3   2   3
   1   3   1   .   3
   1   1   1   .   5
   1   .   .   1   3
   1   1   3   .   3
   1   3   1   .   3
   1   1   1   .   3
   1   3   .   .   .
   1   .   1   .   2

instead of

[ [  1,  3,  3,  0,  9 ],
  [  1,  1,  1,  2,  5 ],
  [  1,  1,  3,  2,  3 ],
  [  1,  3,  1,  0,  3 ],
  [  1,  1,  1,  0,  5 ],
  [  1,  0,  0,  1,  3 ],
  [  1,  1,  3,  0,  3 ],
  [  1,  3,  1,  0,  3 ],
  [  1,  1,  1,  0,  3 ],
  [  1,  3,  0,  0,  0 ],
  [  1,  0,  1,  0,  2 ] ]
edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2012-02-03 06:49:15 +0100

Ivan Andrus gravatar image

Below is what I currently have in my init.sage to mimic GAP printing. It works great if there are few different values or they are all related, but not well at all if there are many different unrelated values.

def increment_string(s):
    """
    Magically increment a string a la perl

    Arguments:
    - `str`:
    """
    if s == "":
        return "A"
    elif s[-1] == 'Z':
        return increment_string(s[:-1]) + 'A'
    else:
        return s[:-1] + chr(ord(s[-1]) + 1)


def pretty_print(M,maxlen=5,suppress_legend=False):

    elements = [x for x in Set(M.list()) if len(repr(x)) > maxlen]
    specials={M.base_ring().zero():'.'}

    if len(elements) == 0:
        print M.str(specials)
        return

    cur_label=""
    for x in elements:
        if specials.has_key(-x):
            specials[x]='-'+specials[-x]
        elif specials.has_key(conjugate(x)):
            specials[x]='/'+specials[conjugate(x)]
        elif specials.has_key(-conjugate(x)):
            specials[x]='-/'+specials[-conjugate(x)]
        else:
            cur_label = increment_string(cur_label)
            specials[x] = cur_label

    s = M.str(specials)
    if not suppress_legend:
        # "Sort by value"
        from operator import itemgetter
        for key,val in sorted(specials.iteritems(), key=itemgetter(1)):
            k = val[0]
            if k != '-' and k != '/' and k != '.':
                s += "\n"+val+" = "+repr(key)
    print s

pp = pretty_print
edit flag offensive delete link more
1

answered 2011-01-12 14:49:03 +0100

How about

m = matrix([[0,0,1], [1,0,0]])
print m.str().replace(' 0', ' .').replace('[0', '[.')

Should we add a method to the matrix class which does something like this? What should it be called?

edit flag offensive delete link more

Comments

Maybe m.print_with_dots()? zeros_are_dots()? Not sure... Then one followup would be whether we should enable this only for finite field matrices as in GAP (at least as I understand it in GAP). And whether we should enable blank spaces in sparse matrices. Etc.

kcrisman gravatar imagekcrisman ( 2011-01-12 22:37:15 +0100 )edit

Considering that sometimes I convert a matrix to one over a finite field just so that I can display it like this, I would prefer if the method worked for any matrix.

Ivan Andrus gravatar imageIvan Andrus ( 2011-01-13 03:17:56 +0100 )edit

Sounds like you need to open a ticket :) Open source is driven by developer interest, as you know. But in that case I vote for an option to leave zero spots blank as well, so it doesn't look so much like a Nethack screen.

kcrisman gravatar imagekcrisman ( 2011-01-13 10:37:36 +0100 )edit

We can add some optional arguments to the "str" method, to be used like mat.str(zero="."), for example. What sort of replacements might we want? Replace "0" with something else? Replace "1" with "+" and "-1" with "-"?

John Palmieri gravatar imageJohn Palmieri ( 2011-01-13 13:03:14 +0100 )edit

Ooh, I like this direction. Can you open a ticket? Ivan is on Trac, and you should copy Jason Grout on it too.

kcrisman gravatar imagekcrisman ( 2011-01-13 13:32:47 +0100 )edit
0

answered 2011-01-12 10:14:36 +0100

kcrisman gravatar image

Huh, that's a great question. I don't believe so. However, you could $\LaTeX$ it...

sage: M = matrix([[1,2,3]])
sage: latex(M)
\left(\begin{array}{rrr}
1 & 2 & 3
\end{array}\right)

Though that's not what you want in terms of the dots. Here it is in Sage, straight from some examples in the GAP reference manual:

sage: G = gap([[1,-1,1],[2,0,-1],[1,1,1]])
sage: G
[ [ 1, -1, 1 ], [ 2, 0, -1 ], [ 1, 1, 1 ] ]
sage: type(G)
<class 'sage.interfaces.gap.GapElement'>
sage: G.Display()
[ [   1,  -1,   1 ],
  [   2,   0,  -1 ],
  [   1,   1,   1 ] ]
sage: H = gap('[[1,-1,1],[2,0,-1],[1,1,1]]*One(GF(5))')
sage: H
[ [ Z(5)^0, Z(5)^2, Z(5)^0 ], [ Z(5), 0*Z(5), Z(5)^2 ], 
  [ Z(5)^0, Z(5)^0, Z(5)^0 ] ]
sage: H.Display()
1 4 1
 2 . 4
 1 1 1

You'll note that this only happens in the finite field case, where of course 0 isn't in the group of units and so it's appropriate to display it differently. So I don't know whether we would want to do this.

For sparse Sage matrices, like (from Sage matrix?),

 sage: m=matrix(QQ,2,3,{(1,1): 2}); m
 [0 0 0]
 [0 2 0]

I could imagine something of the kind as an optional way of doing it. But I don't use them, so you'd want to ask on sage-devel about that.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2011-01-12 08:57:06 +0100

Seen: 996 times

Last updated: Feb 03 '12