1

How can this be done elegantly (Pythonic way)

You have two matrices A and B represented each by a list of lists.

You would like to calculate the overall sum over the matrix of element-wise product of A and B.

sample code:

sum = 0
nrows = len(A)
ncols = len(A[0])
for i in range(nrows):
    for j in range(ncols):
        sum += A[i][j]*B[i][j]

# interested finally in the value of sum
# return sum

for example if

A=[[1,2,3],[3,4,5]]

and

B=[[3,2,2],[1,1,1]]

the result is :

1*3 + 2*2 + 3*2 + 3*1 + 4*1 + 5*1 = 25

user1780424
  • 403
  • 1
  • 6
  • 12
  • 1
    That is not the same as a dot product of two matrices in the general case. – Mad Physicist Dec 08 '17 at 03:56
  • Flatten each matrix with `sum()` or `reduce()`, `zip()` the items into pairs, multiply each pair and `sum()` the results. Could be a one liner all together, but then it would not be beautiful. – Klaus D. Dec 08 '17 at 04:05
  • True, it's not the same as dot product of two matrices, but I didn't know what to call this operation and I though dot-product conveys the meaning. – user1780424 Dec 08 '17 at 04:14

4 Answers4

4

If the matrices are always 2D, you could do

sum(sum(a * b for a, b in zip(*rows)) for rows in zip(A, B))

IDEOne Link

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
3

You could also try something like this (assuming matrices are 2D):

import itertools

A=[[1,2,3],[3,4,5]]
B=[[3,2,2],[1,1,1]]

def flatten(lst):
    return itertools.chain.from_iterable(lst)

>>> print(sum(x * y for x, y in zip(flatten(A), flatten(B))))
25

Or even:

>>> print(sum(x * y for x, y in zip(sum(A, []), sum(B, []))))
25
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
  • 1
    The second method is beautiful, on how you flatten it. It actually outperforms, time-wise, the other method given by 'Mad Physicist' above. – user1780424 Dec 08 '17 at 04:38
  • 1
    @user1780424 yeah, glad you liked it. If you lists get really big, the first method will outperform the rest, have a look at the 4th answer [here](https://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python). Using `itertools.chain.from_iterable` to flatten lists is very efficient. – RoadRunner Dec 08 '17 at 04:41
2

Here is a flat version of @MadPhysicist's generator expr.

sum(a*b for ab in zip(A, B) for a, b in zip(*ab))
# 25
Paul Panzer
  • 51,835
  • 3
  • 54
  • 99
1
import itertools

A = [[1,2,3],[3,4,5]]
B = [[3,2,2],[1,1,1]]

# flatten list A => [1,2,3,3,4,5]]
A_flat = itertools.chain.from_iterable(A)

# flatten list B = > [3,2,2,1,1,1]]
B_flat = itertools.chain.from_iterable(B)

# making sum of 1+3 , 2+2 , 3+2 result=> [4, 4, 5, 4, 5, 6]
pair_sum = [ sum(pair) for pair in zip(A_flat,B_flat)]

# total
print('Total : ', sum(pair_sum))


############

import itertools

A = [[1,2,3],[3,4,5]]
B = [[3,2,2],[1,1,1]]
A_flat = itertools.chain.from_iterable(A)
B_flat = itertools.chain.from_iterable(B)
total = sum(sum(pair) for pair in zip(A_flat,B_flat))
print(total)
Fuji Komalan
  • 1,979
  • 16
  • 25