In [11]:
import numpy as np
import time


For this exercise you will be provided with a problem and and asked to construct two solutions. The first solution should be without numpy and the second with numpy. The vectorized forms with numpy should perform magnitudes more quickly.

In [12]:
arg_length = 10000000
arg_vector = np.arange(arg_length)  # An example vector argument.
print(f"Vector argument: {arg_vector}")

num_rows, num_cols = 200, 100
arg_matrix = np.array([[i + j for j in range(num_cols)] for i in range(num_rows)])  # An example matrix argument.
print(f"Matrix argument: {arg_matrix}")

Vector argument: [      0       1       2 ... 9999997 9999998 9999999]
Matrix argument: [[  0   1   2 ...  97  98  99]
[  1   2   3 ...  98  99 100]
[  2   3   4 ...  99 100 101]
...
[197 198 199 ... 294 295 296]
[198 199 200 ... 295 296 297]
[199 200 201 ... 296 297 298]]


Problem 1: Construct a function which takes a vector, and returns an vector with each element doubled.

In [ ]:
def doubler(x):
"""Take an array and return an array with each element doubled.  This version does not use numpy.

:param x: An array of numbers.
:return: An array of doubled numbers.
"""
raise NotImplementedError

start_time = time.time()
print(doubler(arg_vector)[:5])
print(f"Runtime: {time.time() - start_time}")

In [ ]:
def doubler_numpy(x):
"""Take an array and return an array with each element doubled.  This version uses numpy.

:param x: An array of numbers.
:return: An array of doubled numbers.
"""
raise NotImplementedError

start_time = time.time()
print(doubler_numpy(arg_vector)[:5])
print(f"Runtime: {time.time() - start_time}")


Problem 2: Construct a function which takes two vectors and returns the elementwise summation.

In [ ]:
def adder(a, b):
"""Take two arrays and return an array with their elementwise addition.  This version does not use numpy.

:param a: An array of numbers.
:param b: An array of numbers.
:return: An array of the elementwise addition of a and b.
"""
raise NotImplementedError

start_time = time.time()
print(f"Runtime: {time.time() - start_time}")

In [ ]:
def adder_numpy(a, b):
"""Take two arrays and return an array with their elementwise addition.  This version uses numpy.

:param a: An array of numbers.
:param b: An array of numbers.
:return: An array of the elementwise addition of a and b.
"""
raise NotImplementedError

start_time = time.time()
print(f"Runtime: {time.time() - start_time}")


Problem 3: Construct a function which takes a matrix and returns the tranpose.

In [ ]:
def transposer(A):
"""Take an mxn matrix (with m,n > 0) and return a nxm matrix with the transpose.

:param A: A mxn matrix.
:return: A nxm matrix.
"""
raise NotImplementedError

start_time = time.time()
print(transposer(arg_matrix)[0][:5])
print(f"Runtime: {time.time() - start_time}")

In [ ]:
def transposer_numpy(A):
"""Take an mxn matrix (with m,n > 0) and return a nxm matrix with the transpose.

:param A: A mxn matrix.
:return: A nxm matrix.
"""
raise NotImplementedError

start_time = time.time()
print(transposer_numpy(arg_matrix)[0][:5])
print(f"Runtime: {time.time() - start_time}")


Problem 4: Construct a function which takes two matrices and returns their dot product.

In [ ]:
def dot(A, B):
"""Take an mxn matrix and a nxk (with m,n, k > 0) and return a mxr matrix with the transpose.

:param A: A mxn matrix.
:param B: A nxp matrix.
:return: A mxp matrix.
"""
raise NotImplementedError

start_time = time.time()
print(dot(arg_matrix, arg_matrix.T)[0][:5])
print(f"Runtime: {time.time() - start_time}")

In [ ]:
def dot_numpy(A, B):
"""Take an mxn matrix and a nxk (with m,n, k > 0) and return a mxr matrix with the transpose.

:param A: A mxn matrix.
:param B: A nxr matrix.
:return: A nxr matrix.
"""
raise NotImplementedError

start_time = time.time()
print(dot_numpy(arg_matrix, arg_matrix.T)[0][:5])
print(f"Runtime: {time.time() - start_time}")

In [ ]: