# Displaying matrices with . instead of 0

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

[ [  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 close merge delete

Sort by » oldest newest most voted

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
more

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?

more

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.

( 2011-01-12 15:37:15 -0600 )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.

( 2011-01-12 20:17:56 -0600 )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.

( 2011-01-13 03:37:36 -0600 )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 "-"?

( 2011-01-13 06:03:14 -0600 )edit

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

( 2011-01-13 06:32:47 -0600 )edit

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.

more