# Element-wise product of matrices

I am trying to calculate Hadamard product of two matrices.


def elementwise(M, N):
assert(M.parent() == N.parent())
nc, nr = M.ncols(), M.nrows()
A = copy(M.parent().zero_element())
for r in xrange(nr):
for c in xrange(nc):
A[r,c] = M[r,c] * N[r,c]
return A ring = PolynomialRing(QQ, 1, 'x')
T = Matrix(ring, [
[1,-x,-x,0],
[-x,1,0,-x],
[0,-x,1,0],
[-x,0,0,1]]) R = Matrix(QQ, [
[1,1,0,1],
[1,1,1,0],
[1,0,0,1],
[0,1,1,0]]) B = ~T
elementwise(B,R)

I get a following mistake

Error in lines 21-21
Traceback (most recent call last):
File "/projects/sage/sage-7.5/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 982, in execute
exec compile(block+'\n', '', 'single') in namespace, locals
File "", line 1, in <module>
File "", line 2, in elementwise
AssertionError

Although elementwise(B,R) does not work, the program calculates elementwise(B,B) and elementwise(R,R) without any mistakes. Probably that's because matrices B and R have different types (B is a dense matrix over general ring and R is a rational dense matrix). What should I do?

edit retag close merge delete

Sort by ยป oldest newest most voted

The assertion error comes from the line

assert(M.parent() == N.parent())


because:

sage: B.parent()
Full MatrixSpace of 4 by 4 dense matrices over Fraction Field of Multivariate Polynomial Ring in x over Rational Field
sage: R.parent()
Full MatrixSpace of 4 by 4 dense matrices over Rational Field


Just remove that line and you will get:

sage: elementwise(B,R)    # with the assertion removed
[        (-1)/(x^4 + 2*x^3 + x^2 - 1)   (-x^2 - x)/(x^4 + 2*x^3 + x^2 - 1)                                    0 (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)]
[  (-x^2 - x)/(x^4 + 2*x^3 + x^2 - 1)         (-1)/(x^4 + 2*x^3 + x^2 - 1) (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0]
[(-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0                                    0       (-x^2)/(x^4 + 2*x^3 + x^2 - 1)]
[                                   0 (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)       (-x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0]


Alternatively, if you want to keep your function intact, you can define both matrices on the same ring:

sage: elementwise(B,R.change_ring(B.base_ring()))   # without removing the assertion
[        (-1)/(x^4 + 2*x^3 + x^2 - 1)   (-x^2 - x)/(x^4 + 2*x^3 + x^2 - 1)                                    0 (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)]
[  (-x^2 - x)/(x^4 + 2*x^3 + x^2 - 1)         (-1)/(x^4 + 2*x^3 + x^2 - 1) (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0]
[(-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0                                    0       (-x^2)/(x^4 + 2*x^3 + x^2 - 1)]
[                                   0 (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)       (-x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0]


Alternatively, the elementwise_product method doesthe job, see R.elementwise_product? for the documentation:

sage: R.elementwise_product(B)
[        (-1)/(x^4 + 2*x^3 + x^2 - 1)   (-x^2 - x)/(x^4 + 2*x^3 + x^2 - 1)                                    0 (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)]
[  (-x^2 - x)/(x^4 + 2*x^3 + x^2 - 1)         (-1)/(x^4 + 2*x^3 + x^2 - 1) (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0]
[(-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0                                    0       (-x^2)/(x^4 + 2*x^3 + x^2 - 1)]
[                                   0 (-x^3 - x^2)/(x^4 + 2*x^3 + x^2 - 1)       (-x^2)/(x^4 + 2*x^3 + x^2 - 1)                                    0]

more

The following works:

def elementwise( M, N ):
print "M parent is: %s" % M.parent()
print "N parent is: %s" % N.parent()

assert( M.parent() == N.parent() )

nc, nr = M.ncols(), M.nrows()
A = copy( M.parent().zero() )

for r in xrange(nr):
for c in xrange(nc):
A[r,c] = M[r,c] * N[r,c]
return A

ring  = PolynomialRing( QQ, 1, 'x' )
field = ring.fraction_field()

T = Matrix( ring, [
[ 1, -x, -x,  0] ,
[-x,  1,  0, -x] ,
[ 0, -x,  1,  0] ,
[-x,  0,  0,  1] ] )

R = Matrix( field, [
[ 1, 1, 0, 1 ] ,
[ 1, 1, 1, 0 ] ,
[ 1, 0, 0, 1 ] ,
[ 0, 1, 1, 0 ] ] )

B = ~T

elementwise( B, R )


(I only took care that the assertion does not fail. So i replaced the definition ring / field QQ from R, made it the field of fraction of the polynomial ring ring. While computing B, its parent is no longer the ring, as in T, but the field.)

more