result = [] # final result
for i in range(len(A)):
row = [] # the new row in new matrix
for j in range(len(B[0])):
product = 0 # the new element in the new row
for v in range(len(A[i])):
product += A[i][v] * B[v][j]
row.append(product) # append sum of product into the new row
result.append(row) # append the new row into the final result
print(result)
Answer from Aaron Shen on Stack Overflowresult = [] # final result
for i in range(len(A)):
row = [] # the new row in new matrix
for j in range(len(B[0])):
product = 0 # the new element in the new row
for v in range(len(A[i])):
product += A[i][v] * B[v][j]
row.append(product) # append sum of product into the new row
result.append(row) # append the new row into the final result
print(result)
Break it down. Before you try to write a function that multiplies matrices, write one that multiplies vectors. If you can do that, multiplying two matrices is just a matter of multiplying row i and column j for every element i,j of the resultant matrix.
python - Multiplication of any two matrices using lists and for in loop - Code Review Stack Exchange
Understanding nested matrix multiplication loops in Python
Python Matrix multiplication using for loop - Stack Overflow
Python - Nested Loop Multiplication Matrix - Stack Overflow
I have basically two comments:
- Naming.
- Use functions to follow the single responsibility principle.
Naming
Python has an official style-guide, PEP8. Some of its recommendations are:
- Using
lower_casefor variables and functions,PascalCasefor classes andALL_CAPSfor global constants. - To limit your line length to 80 (or at the most 120) characters
Your names which you use to iterate through the rows and columns are not clear at all. Why vc and vr (I guess the c and r stand for column and row, but what does the v stand for?)? Instead I would use rows and columns for the number of rows and columns and use i and j to iterate over them, because that is the convention used in mathematics when describing matrices.
Single responsibility principle
As for your actual code, you basically have four major responsibilities:
- Asking the user for input
- Creating a matrix
- Calculating the matrix product
- Printing a matrix scheme
I would make this into four functions:
def ask_user(message):
while True:
try:
return int(input(message))
except TypeError:
pass
This function will ask the user the message until he inputs something that can be cast to an int.
def matrix_from_user():
rows = ask_user("Number of rows?: ")
columns = ask_user("Number of columns?: ")
matrix = [[0] * columns for _ in range(rows)]
for i in range(rows):
for j in range(columns):
matrix[i][j] = ask_user("M{}{}: ".format(i+1, j+1))
return matrix
Here I used str.format to make the construction of the string easier.
def matrix_mul(matrix1, matrix2):
rows, columns = len(matrix1), len(matrix2[0])
matrix = [[0] * columns for _ in range(rows)]
for i in range(rows):
for j in range(columns):
matrix[i][j] = sum(matrix1[i][k] * matrix2[k][j]
for k in range(len(matrix2)))
return matrix
This is a straightforward implementation of the formula \ for two matrices \
and \
. It uses the built-in
sum function that takes an iterable to sum. This iterable is a generator comprehension here.
def matrix_print(matrix):
print('\nElements of matrix:')
rows, columns = len(matrix), len(matrix[0])
for i in range(rows):
row = ' '.join('M{}{}'.format(i + 1, j + 1) for j in range(columns))
print('|', row, '|')
Here I used str.join to easily join an iterable of strings with a given delimiter (' ' here).
Your main program becomes then simply:
if __name__ == "__main__":
matrix1 = matrix_from_user()
matrix_print(matrix1)
matrix2 = matrix_from_user()
product = matrix_mul(matrix1, matrix2)
print('Matrix1: ', matrix1)
print('Matrix2: ', matrix2)
print('Result of Matrix Multiplication:', product)
This code I put under an if __name__ == "__main__": guard which allows you to import this script from another script without this part of the code being run (so you get access to the functions).
For learning reason, you can create 2d array in one row like:
matrix2 = [[vc + v*10*vr for vc in range(0, v)] for vr in range(0, r)]
Since python is a funcational language, for learning reason, you can define a map/ reduce over matrix like:
def map(matrix, r,c, fn,summ):
for vr in range(0, r):
for vc in range(0, c):
fn(matrix[r][c],summ)
or with additional map-reduce over the row:
def map(matrix, r,c, fn,fnRow,startVal,summ):
for vr in range(0, r):
summRow = startVal
for vc in range(0, c):
fn(matrix[r][c],summRow)
fnRow(summRow, summ)
for learning reason you could implement Strassen matrix multiplication algorithm (google please), not naive one. I doubt you learn something like that.
For doing real project, use Numpy for initiations, not for high-performance operations.
Hi,
I have a problem in understanding nested python loops for matrix addition. For example:
X=[[1, 2, 3],[4, 5, 6], [7, 8, 9]]
for I in range(len(X)):
for j in range (len(X[0])):
r[i][j] = X[i][j] + Y[i][j]I am able to understand length of X and that it represents the length of row but can't understand X[0]. Somebody please guide me.
Zulfi
The issue is in this array indexing: M[i,j]. Built-in nested (not truly multi-dimensional) python arrays cannot be accessed in this way, you must index the dimensions one at a time: M[i][j].
You may see python code that does use this indexing, but that is with 3rd party libraries such as numpy.
To access an inner array, you use this syntax:
sum = sum + M[i][j] * b[j]
You could use a list (or a dictionary) to hold your matrices:
matrices = []
for i in range(len(node2)):
if (sOrP[i] == 'S'):
#print('series connection')
matrixTemplate = numpy.array([[1.0, 0.0],[0.0, 1.0]]) #Got to put 1.0 else it doesnt work
matrixTemplate[0][1] = frequenciesList[0][i]
matrices.append(matrixTemplate)
#print(matrixTemplate)
elif (sOrP[i] == 'P'):
#print('parallel connection')
matrixTemplate = numpy.array([[1.0, 0.0],[0.0, 1.0]])
matrixTemplate[1][0] = 1/frequenciesList[0][i]
matrices.append(matrixTemplate)
#print(matrixTemplate)
And then use reduce and numpy.matmul to compute your total matrix product:
from functools import reduce
Ty = reduce(numpy.matmul, matrices)
You can use either a loop or a numpy function.
Loop implementation:
matrixes = [M1, M2, ..., Mn]
A = matrixes[0]
for i in range(1, len(matrixes)):
B = matrixes[i]
A = np.dot(A, B)
First iteration: A = M1, B = M2; M1.M2
Second iteration: A = M1.M2, B = M3; M1.M2.M3
...
Numpy function: numpy.linalg.multi_dot(matrixes)