# Keeping zeros after matrix multiplication

Hello, Sage Community!

Suppose I do the following:

var('x y z')
u = vector([0, 1, 1])
v = vector([x, y, z])
u * v


The result is obviously y+z. I would like to keep the zeros after the multiplication, in order to have 0x+y+z as my result. Is it possible?

edit retag close merge delete

Sort by » oldest newest most voted

(Edited to address the follow-up question posted as a comment to an earlier version of this answer).

Obtain a complete expression using string formatting:

sage: x, y, z = SR.var('x y z')
sage: u = vector([0, 1, 1])
sage: uu = vector([1, 2, -1])
sage: v = vector([x, y, z])
sage: print(' + '.join('({})*({})'.format(a, b) for a, b in zip(u, v)))
(0)*(x) + (1)*(y) + (1)*(z)
sage: print(' + '.join('({})*({})'.format(a, b) for a, b in zip(uu, v)))
(1)*(x) + (2)*(y) + (-1)*(z)


The parentheses are maybe not so nice but they take care of keeping things clean whether coefficients are positive, negative or zero.

If one wants to push the "pretty-printing" effort a little, one should probably write a function. For example:

def axbycz(u):
r"""
Return a custom string for the scalar product of
this vector with the vector (x, y, z), keeping zeros.

EXAMPLES::

sage: axbycz(vector([0, 1, 1]))
'0x + y + z'
sage: axbycz(vector([1, 2, -1]))
'x + 2y - z'
sage: print(axbycz(vector([0, 1, 1])))
0x + y + z
sage: print(axbycz(vector([1, 2, -1])))
x + 2y - z
"""
aa = lambda c: '' if c == 1 else '-' if c == -1 else c
bc = lambda c: '+ {}'.format(aa(c)) if c >=0 else '- {}'.format(aa(-c))
a, b, c = u
return '{}x {}y {}z'.format(aa(a), bc(b), bc(c))


where the output will be as in the examples included in the function's documentation.

One could instead decide to have the function print a result rather than return a string.

def print_axbycz(u):
r"""
Print a custom string for the scalar product of
this vector with the vector (x, y, z), keeping zeros.

EXAMPLES::

sage: print_axbycz(vector([0, 1, 1]))
0x + y + z
sage: print_axbycz(vector([1, 2, -1]))
x + 2y - z
"""
aa = lambda c: '' if c == 1 else '-' if c == -1 else c
bc = lambda c: '+ {}'.format(aa(c)) if c >=0 else '- {}'.format(aa(-c))
a, b, c = u
print('{}x {}y {}z'.format(aa(a), bc(b), bc(c)))

more

Hello, @slelievre. Sorry for not answering before; I was really busy. Yes, that solves the particular example that I posed. However, it cannot handle negative coefficients. For example, by changing to u = vector([1, 2, -1]), and then doing u * v, I was hoping to get x+0y-z

( 2019-12-23 18:22:50 +0200 )edit

( 2019-12-24 05:27:25 +0200 )edit

Awesome! Thank you very much!

( 2019-12-24 15:53:58 +0200 )edit