-1

I have written the algorithm for multiplying two matrix of 2x3 and 3x2 respectively. The algorithm is behaving perfectly. The problem is that how to save the results into resultant matrix of 2x2?

Below is the code

from numpy import *

m1 = matrix('1 2 3; 4 5 6')
m2 = matrix('7 8; 9 10; 11 12')
m4 = matrix('')

for k in range(len(m1)):
    for i in range(len(m1)):
        m3 = 0
        for j in range(len(m2)):
            m3 = m3 + m1[k, j] * m2[j, i]
        print(m3)


hurat
  • 19
  • 1
  • 4
  • https://stackoverflow.com/questions/10508021/matrix-multiplication-in-python – Drako Apr 23 '19 at 07:57
  • 1
    The [official doc](https://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.html) says _"It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays. The class may be removed in the future."_ — [Andras Deak](https://stackoverflow.com/users/5067311/andras-deak) said "[\[`numpy.matrix`\] was originally meant for convenient use in computations involving linear algebra, but there are both limitations and surprising differences in how they behave compared to instances of the more general array class.](https://stackoverflow.com/a/53254739/2749397)" – gboffi Apr 23 '19 at 21:25

2 Answers2

0

We can use the same algorithm for matrix multiplication using list of lists and Numpy arrays

In [30]: l1 = [[1,2,3],[4,5,6]] ; l2 = [[7,8],[9,10],[11,12]]                                                                         
In [31]: l3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*l2)] for row in l1]                    
In [32]: a1 = np.array(l1) ; a2 = np.array(l2)                                                               
In [33]: a3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*a2)] for row in a1]                    
In [34]: a3                                                                                                  
Out[34]: [[58, 64], [139, 154]]
In [35]: l3                                                                                                  
Out[35]: [[58, 64], [139, 154]]

and, for a check, let's use @, the builtin matrix multiplication operator

In [36]: a1@a2                                                                                               
Out[36]: 
array([[ 58,  64],
       [139, 154]])

Now, let's see if we can use the same matrix multiplication algorithm if our data is wrapped in a matrix class

In [37]: m1 = np.matrix(l1) ; m2 = np.matrix(l2)                                                             
In [38]: m3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*m2)] for row in m1]                    
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-38-2cd8454aa248> in <module>
----> 1 m3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*m2)] for row in m1]
<ipython-input-38-2cd8454aa248> in <listcomp>(.0)
----> 1 m3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*m2)] for row in m1]
<ipython-input-38-2cd8454aa248> in <listcomp>(.0)
----> 1 m3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*m2)] for row in m1]
<ipython-input-38-2cd8454aa248> in <genexpr>(.0)
----> 1 m3 = [[sum(e1*e2 for e1, e2 in zip(row,col)) for col in zip(*m2)] for row in m1]
~/lib/miniconda3/lib/python3.7/site-packages/numpy/matrixlib/defmatrix.py in __mul__(self, other)
    218         if isinstance(other, (N.ndarray, list, tuple)) :
    219             # This promotes 1-D vectors to row vectors
--> 220             return N.dot(self, asmatrix(other))
    221         if isscalar(other) or not hasattr(other, '__rmul__') :
    222             return N.dot(self, other)

ValueError: shapes (1,3) and (1,2) not aligned: 3 (dim 1) != 1 (dim 0)

Why we have this error? the dimensions are the same as before, why we have different shapes?

Here it is the reason, when we look at an element of m1 we have not a 1D array or a non-nested list, we have still another matrix

In [39]: m1[0]                                                                                               
Out[39]: matrix([[1, 2, 3]])

Moral of this tale?

The matrix class has an inherent stickyness that leads to this particular unexpected behaviour and to other, different, unexpected behaviours.

If one doesn't know exactly all the issues associated with using np.matrix(), the best choice is to use 2D arrays instantiated using np.array.

On the other hand, if one knows exactly all the issues associated with using np.matrix(), usually they do not want to use np.matrix.

gboffi
  • 22,939
  • 8
  • 54
  • 85
-1

from numpy import *

m1 = matrix('1 2 3; 4 5 6')
m2 = matrix('7 8; 9 10; 11 12')

m1_Row_Col = m1.shape
m2_Row_Col = m2.shape

m3 = [[0 for row in range(m2_Row_Col[1])] for col in range(m1_Row_Col[0])]

for k in range(len(m1)):
    for i in range(m2_Row_Col[1]):
        out = 0
        for j in range(len(m2)):
            out = out + m1[k, j] * m2[j, i]
        m3[k][i] = out
print(m3)
hurat
  • 19
  • 1
  • 4