Page 1 of 1

Numpy exercise

Posted: Thu Feb 18, 2021 12:49 am
by klayperson
I didn't see a post about this exercise and I wanted to compare with others to see if I made the right approach.
I appended the values from the randomly generated array in order to make my lists.
From my result, using the array dot function is about 34-39 times faster than doing matrix multiplication using lists.
This ratio increases linearly with the increase in input size (i.e. 2x inputs = 2x dt1/dt2)

Let me know what y'all got. And any feedback on my code would be great!

Code: Select all

from datetime import datetime
a = np.random.randn(100)
b = np.random.randn(100)
T = 100000

L1=[]
L2=[]

for e, f in zip(a, b):
  L1.append(e)
  L2.append(f)

def slow_matrix_multiplication(L1, L2):
  result = 0
  for i in range(len(L1)):
    result += L1[i]*L2[i]
  return result

t0 = datetime.now()
for t in range(T):
  slow_matrix_multiplication(L1, L2)
dt1 = datetime.now() - t0

t0 = datetime.now()
for t in range(T):
  a.dot(b)
dt2 = datetime.now() - t0

print("dt1 / dt2: ", dt1.total_seconds() / dt2.total_seconds())

Re: Numpy exercise

Posted: Sat Apr 03, 2021 1:07 pm
by BabaKirtos
Hello, there seems to be some logical problem with your code, the exercise is about comparing matrix multiplication using lists and numpy dot operator. Your code seems to be multiplying randomly generated 1D arrays, using for loop then the dot operator.
I wasn't able to generate random lists, so I used pre initialized lists, you can look at my code below. I observed that the numpy dot operator is around 2-3 times faster than using 3 for loops.

Code: Select all

# DLP - Numpy - Exercise

import numpy as np
from datetime import datetime  

def matrix_mul_list(L1,L2):
  result = 0
  R = []
  A = []
  for l in  range(len(L1)):
    for m in range(len(L2[0])):
      for n in range(len(L2)):
        result += L1[l][n]*L2[n][m]
      R.append(result)
      result = 0  
    A.append(R)   
    R = [] 
  return A

L1 = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
L2 = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]

N1 = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
N2 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

t0 = datetime.now()
print(matrix_mul_list(L1,L2))
dt1 = datetime.now() - t0

print(' ')

t0 = datetime.now()
print(N1.dot(N2))
dt2 = datetime.now() - t0

print(' ')

print('Matrix multiplication is ' + str(dt2/dt1) + ' times faster.')

Re: Numpy exercise

Posted: Fri Nov 26, 2021 4:20 pm
by ohmy
Thanks for your example.
Very useful.

str(dt2/dt1)
should be:
str(dt1/dt2)

Re: Numpy exercise

Posted: Thu Mar 17, 2022 6:30 pm
by krb
Here's another approach that seems to work. Let me know what you think!

import numpy as np
from datetime import datetime

a = np.random.random((10000000))
b = np.random.random((10000000))

t0fast = datetime.now()
fast = a.dot(b)
print(fast)
t1fast = datetime.now() - t0fast
print("Fast method: " + str(t1fast))

t0slow = datetime.now()
c = 0
for i in range(len(a)):
c += a * b
print(c)
t1slow = datetime.now() - t0slow
print("Slow method: " + str(t1slow))

Re: Numpy exercise

Posted: Sun Aug 21, 2022 10:45 pm
by CrappyProgrammer
a = np.random.random((5,10))
b = np.random.random((10,5))
a_list = a.tolist()
b_list = b.T.tolist()
T = 100

solution_list = []

def slow_dot_product(a, b):
result = 0
for e, f in zip(a,b):
result += e*f
return result

def slow_matrix_mult(A,B):
for row_index in range(len(A)):
solution_row = []
for column_index in range(len(B)):
solution_row.append(slow_dot_product(A[row_index],B[column_index]))
solution_list.append(solution_row)

t0 = datetime.now()
for t in range(T):
numpy_solution = np.matmul(a,b)
dt1 = datetime.now() - t0
print('numpy solution in ', dt1.total_seconds(), 'seconds')

t0 = datetime.now()
for t in range(T):
slow_matrix_mult(a_list,b_list)
dt2 = datetime.now() - t0
print('list solution in ', dt2.total_seconds(), 'seconds')

if(dt2.total_seconds() > dt1.total_seconds()):
print('Numpy multiplication is', dt2.total_seconds()/dt1.total_seconds(), 'times faster than list multiplication')
else:
print('List multiplication is', dt1.total_seconds()/dt2.total_seconds(), 'times faster than Numpy multiplication')

Re: Numpy exercise

Posted: Sun Aug 21, 2022 10:55 pm
by CrappyProgrammer

Code: Select all

a = np.random.random((5,10))
b = np.random.random((10,5))
a_list = a.tolist()
b_list = b.T.tolist()
T = 100

solution_list = []

def slow_dot_product(a, b):
  result = 0
  for e, f in zip(a,b):
    result += e*f
  return result

def slow_matrix_mult(A,B):
  for row_index in range(len(A)):
    solution_row = []
    for column_index in range(len(B)):
      solution_row.append(slow_dot_product(A[row_index],B[column_index]))
    solution_list.append(solution_row)

t0 = datetime.now()
for t in range(T):
   numpy_solution = np.matmul(a,b)
dt1 = datetime.now() - t0
print('numpy solution in ', dt1.total_seconds(), 'seconds')

t0 = datetime.now()
for t in range(T):
  slow_matrix_mult(a_list,b_list)
dt2 = datetime.now() - t0
print('list solution in ', dt2.total_seconds(), 'seconds')

if(dt2.total_seconds() > dt1.total_seconds()):
  print('Numpy multiplication is', dt2.total_seconds()/dt1.total_seconds(), 'times faster than list multiplication')
else:
  print('List multiplication is', dt1.total_seconds()/dt2.total_seconds(), 'times faster than Numpy multiplication')

Re: Numpy exercise

Posted: Thu Sep 22, 2022 2:18 pm
by Jack
Hi all,

I've just completed the Numpy exercise. I'm an inexperienced programmer, I'd appreciate any input/feedback/corrections to my code!

Of note, the A.dot(B) calculation is approx 24x faster for a 1000x1000 array. This decreases as the size of the array increases.

Thanks in advance.

Jack

Code: Select all

from datetime import datetime

n=2000

A = np.random.random((n,n))
B = np.random.random((n,n))

product = np.zeros((n,n))

def slowmultiplication(A,B):
  for i in range(len(A)):       # iterating by rows in A
    for j in range(len(B[0])):  # iterating by columns in B
      for k in range(2):        # iterating by rows in B
        product[i,j] += A[i,k]*B[k,j]
  return product

# See how long this calculation takes
t0 = datetime.now()
slowmultiplication(A,B)
t1 = datetime.now()
print(t1-t0)

# See how long the calculation takes with numpy matrix multiplication
t2 = datetime.now()
A.dot(B)
t3 = datetime.now()
print(t3-t2)
print((t1-t0)/(t3-t2))