I'm trying to write a function that adds two matrices to pass the following doctests:
>>> a = [[1, 2], [3, 4]]
>>> b = [[2, 2], [2, 2]]
>>> add_matrices(a, b)
[[3, 4], [5, 6]]
>>> c = [[8, 2], [3, 4], [5, 7]]
>>> d = [[3, 2], [9, 2], [10, 12]]
>>> add_matrices(c, d)
[[11, 4], [12, 6], [15, 19]]
So I wrote a function:
def add(x, y):
return x + y
And then I wrote the following function:
def add_matrices(c, d):
for i in range(len(c)):
print map(add, c[i], d[i])
And I sort of get the right answer.
Algorithm. Step1: input two matrix. Step 2: nested for loops only to iterate through each row and columns. Step 3: At each iterationshall add the corresponding elements from two matrices and shall store the result.
In Python, we can implement a matrix as a nested list (list inside a list). We can treat each element as a row of the matrix. For example X = [[1, 2], [4, 5], [3, 6]] would represent a 3x2 matrix. First row can be selected as X[0] and the element in first row, first column can be selected as X[0][0] .
A matrix can only be added to (or subtracted from) another matrix if the two matrices have the same dimensions . To add two matrices, just add the corresponding entries, and place this sum in the corresponding position in the matrix which results.
add() function is used when we want to compute the addition of two array. It add arguments element-wise. If shape of two arrays are not same, that is arr1.
You can use the numpy
module, which has support for this.
>>> import numpy as np
>>> a = np.matrix([[1, 2], [3, 4]])
>>> b = np.matrix([[2, 2], [2, 2]])
>>> a+b
matrix([[3, 4],
[5, 6]])
Assuming you wanted to implement it yourself, you'd set up the following machinery, which would let you define arbitrary pairwise operations:
from pprint import pformat as pf
class Matrix(object):
def __init__(self, arrayOfRows=None, rows=None, cols=None):
if arrayOfRows:
self.data = arrayOfRows
else:
self.data = [[0 for c in range(cols)] for r in range(rows)]
self.rows = len(self.data)
self.cols = len(self.data[0])
@property
def shape(self): # myMatrix.shape -> (4,3)
return (self.rows, self.cols)
def __getitem__(self, i): # lets you do myMatrix[row][col
return self.data[i]
def __str__(self): # pretty string formatting
return pf(self.data)
@classmethod
def map(cls, func, *matrices):
assert len(set(m.shape for m in matrices))==1, 'Not all matrices same shape'
rows,cols = matrices[0].shape
new = Matrix(rows=rows, cols=cols)
for r in range(rows):
for c in range(cols):
new[r][c] = func(*[m[r][c] for m in matrices], r=r, c=c)
return new
Now adding pairwise methods is as easy as pie:
def __add__(self, other):
return Matrix.map(lambda a,b,**kw:a+b, self, other)
def __sub__(self, other):
return Matrix.map(lambda a,b,**kw:a-b, self, other)
Example:
>>> a = Matrix([[1, 2], [3, 4]])
>>> b = Matrix([[2, 2], [2, 2]])
>>> b = Matrix([[0, 0], [0, 0]])
>>> print(a+b)
[[3, 4], [5, 6]]
>>> print(a-b)
[[-1, 0], [1, 2]]
You can even add pairwise exponentiation, negation, binary operations, etc. I do not demonstrate it here, because it's probably best to leave * and ** for matrix multiplication and matrix exponentiation.
If you just want a really simple way to map an operation over only two nested-list matrices, you can do this:
def listmatrixMap(f, *matrices):
return \
[
[
f(*values)
for c,values in enumerate(zip(*rows))
]
for r,rows in enumerate(zip(*matrices))
]
Demo:
>>> listmatrixMap(operator.add, a, b, c))
[[3, 4], [5, 6]]
With an additional if-else and keyword argument, you can use indices in your lambda. Below is an example of how to write a matrix row-order enumerate
function. The if-else and keyword were omitted above for clarity.
>>> listmatrixMap(lambda val,r,c:((r,c),val), a, indices=True)
[[((0, 0), 1), ((0, 1), 2)], [((1, 0), 3), ((1, 1), 4)]]
edit
So we could write the above add_matrices
function like so:
def add_matrices(a,b):
return listmatrixMap(add, a, b)
Demo:
>>> add_matrices(c, d)
[[11, 4], [12, 6], [15, 19]]
def addM(a, b):
res = []
for i in range(len(a)):
row = []
for j in range(len(a[0])):
row.append(a[i][j]+b[i][j])
res.append(row)
return res
One more solution:
map(lambda i: map(lambda x,y: x + y, matr_a[i], matr_b[i]), xrange(len(matr_a)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With