Loading [MathJax]/jax/output/HTML-CSS/jax.js
Ask Your Question
3

Displaying matrices with . instead of 0

asked 14 years ago

Ivan Andrus gravatar image

updated 13 years ago

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 ] ]
Preview: (hide)

3 Answers

Sort by » oldest newest most voted
1

answered 13 years ago

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
Preview: (hide)
link
1

answered 14 years ago

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?

Preview: (hide)
link

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 ( 14 years ago )

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 ( 14 years ago )

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 ( 14 years ago )

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 ( 14 years ago )

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 ( 14 years ago )
0

answered 14 years ago

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.

Preview: (hide)
link

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: 14 years ago

Seen: 1,030 times

Last updated: Feb 03 '12