11
votes

I'm fairly new to Python and trying to create a function to multiply a vector by a matrix (of any column size). e.g.:

multiply([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])

[1, 1]

Here is my code:

def multiply(v, G):
    result = []
    total = 0
    for i in range(len(G)):
        r = G[i]
        for j in range(len(v)):
            total += r[j] * v[j]
        result.append(total)
    return result  

The problem is that when I try to select the first row of each column in the matrix (r[j]) the error 'list index out of range' is shown. Is there any other way of completing the multiplication without using NumPy?

7

7 Answers

10
votes

The Numpythonic approach: (using numpy.dot in order to get the dot product of two matrices)

In [1]: import numpy as np

In [3]: np.dot([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])
Out[3]: array([1, 1])

The Pythonic approach:

The length of your second for loop is len(v) and you attempt to indexing v based on that so you got index Error . As a more pythonic way you can use zip function to get the columns of a list then use starmap and mul within a list comprehension:

In [13]: first,second=[1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]

In [14]: from itertools import starmap

In [15]: from operator import mul

In [16]: [sum(starmap(mul, zip(first, col))) for col in zip(*second)]
Out[16]: [1, 1]
4
votes

I think the problem with your code was that you loop through the rows of the matrix rather than by the columns. Also you don't reset your 'total' variable after each vector*matrix column calculation. This is what you want:

def multiply(v, G):
    result = []
    for i in range(len(G[0])): #this loops through columns of the matrix
        total = 0
        for j in range(len(v)): #this loops through vector coordinates & rows of matrix
            total += v[j] * G[j][i]
        result.append(total)
    return result
3
votes

i have attached a code for matrix multiplication do follow the example format for one dimensional multiplication (lists of list)

def MM(a,b):
c = []
for i in range(0,len(a)):
    temp=[]
    for j in range(0,len(b[0])):
        s = 0
        for k in range(0,len(a[0])):
            s += a[i][k]*b[k][j]
        temp.append(s)
    c.append(temp)

return c
a=[[1,2]]
b=[[1],[2]]
print(MM(a,b))

result is [[5]]

2
votes

r is an element from G so it's a row which only has two elements. That means you can't use index j to get a value from r because j goes from 0 till the length of v, which is 6 in your example.

2
votes

I needed solution where the first matrix could be 2-dimensional. Extending the solution from @Kasramvd to accept a two dimensional first matrix. Posted here for reference:

>>> first,second=[[1,0,0,1,0,0],[0,1,1,1,0,0]], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
>>> from itertools import starmap
>>> from operator import mul
>>> [[sum(starmap(mul, zip(row, col))) for col in zip(*second)] for row in first]
[[1, 1], [3, 1]]
0
votes

There is a code that help u to multiply two matrix:

A=[[1,2,3],[4,5,6],[7,8,9]]
B=[[1,2,3],[4,5,6],[7,8,9]]
matrix=[]

def multiplicationLineColumn(line,column):
    try:
        sizeLine=len(line)
        sizeColumn=len(column)
        if(sizeLine!=sizeColumn):
            raise ValueError("Exception")
        res = sum([line[i] * column[i] for i in range(sizeLine)])
        return res
    except ValueError:
        print("sould have the same len line & column")

def  getColumn(matrix,numColumn):
    size=len(matrix)
    column= [matrix[i][numColumn] for i in range(size)]
    return column

def getLine(matrix,numLine):
    line = matrix[numLine]
    return line

for i in range(len(A)):
    matrix.append([])
    for j in range(len(B)):
        matrix[i].append(multiplicationLineColumn(getLine(A,i),getColumn(B,j)))

print(matrix)
0
votes
# check matrices
A = [[1,2],[3,4]]
B = [[1,4],[5,6],[7,8],[9,6]]

def custom_mm(A,B):    
    if len(A[0]) == len(B): -- condition to check if matrix multiplication is valid or not. Making sure matrix is nXm and mXy
        result = [] -- final matrix
        for i in range(0,len(A)): -- loop through each row of first matrix
            temp = [] -- temporary list to hold output of each row of the output matrix where number of elements will be column of second matrix
            for j in range(0,len(B[0])): -- loop through each column of second matrix
                total = 0 
                l = 0 -- dummy index to switch row of second matrix 
                for k in range(0,len(A[0])):
                    total += A[i][k]*B[l][j]
                    l = l+1
                temp.append(total)
            result.append(temp)                
        return result
    else:
        return (print("not possible"))

print(custom_mm(A,B))