|
| 1 | +# advanced_numpy.py |
| 2 | +"""Python Essentials: Advanced NumPy. |
| 3 | +<Name> |
| 4 | +<Class> |
| 5 | +<Date> |
| 6 | +""" |
| 7 | +import numpy as np |
| 8 | +from sympy import isprime |
| 9 | +from matplotlib import pyplot as plt |
| 10 | + |
| 11 | + |
| 12 | +def prob1(A): |
| 13 | + """Make a copy of 'A' and set all negative entries of the copy to 0. |
| 14 | + Return the copy. |
| 15 | +
|
| 16 | + Example: |
| 17 | + >>> A = np.array([-3,-1,3]) |
| 18 | + >>> prob4(A) |
| 19 | + array([0, 0, 3]) |
| 20 | + """ |
| 21 | + raise NotImplementedError("Problem 1 Incomplete") |
| 22 | + |
| 23 | + |
| 24 | +def prob2(arr_list): |
| 25 | + """return all arrays in arr_list as one 3-dimensional array |
| 26 | + where the arrays are padded with zeros appropriately.""" |
| 27 | + raise NotImplementedError("Problem 2 Incomplete") |
| 28 | + |
| 29 | + |
| 30 | +def prob3(func, A): |
| 31 | + """Time how long it takes to run func on the array A in two different ways, |
| 32 | + where func is a universal function. |
| 33 | + First, use array broadcasting to operate on the entire array element-wise. |
| 34 | + Second, use a nested for loop, operating on each element individually. |
| 35 | + Return the ratio showing how many times faster array broadcasting is than |
| 36 | + using a nested for loop, averaged over 10 trials. |
| 37 | +
|
| 38 | + Parameters: |
| 39 | + func -- array broadcast-able numpy function |
| 40 | + A -- nxn array to operate on |
| 41 | + Returns: |
| 42 | + num_times_faster -- float |
| 43 | + """ |
| 44 | + raise NotImplementedError("Problem 3 Incomplete") |
| 45 | + |
| 46 | + |
| 47 | +def prob4(A): |
| 48 | + """Divide each row of 'A' by the row sum and return the resulting array. |
| 49 | +
|
| 50 | + Example: |
| 51 | + >>> A = np.array([[1,1,0],[0,1,0],[1,1,1]]) |
| 52 | + >>> prob6(A) |
| 53 | + array([[ 0.5 , 0.5 , 0. ], |
| 54 | + [ 0. , 1. , 0. ], |
| 55 | + [ 0.33333333, 0.33333333, 0.33333333]]) |
| 56 | + """ |
| 57 | + raise NotImplementedError("Problem 4 Incomplete") |
| 58 | + |
| 59 | + |
| 60 | +# this is provided for problem 5 |
| 61 | +def LargestPrime(x, show_factorization=False): |
| 62 | + # account for edge cases. |
| 63 | + if x == 0 or x == 1: |
| 64 | + return np.nan |
| 65 | + |
| 66 | + # create needed variables |
| 67 | + forced_break = False |
| 68 | + prime_factors = [] # place to store factors of number |
| 69 | + factor_test_arr = np.arange(1, 11) |
| 70 | + |
| 71 | + while True: |
| 72 | + # a factor is never more than half the number |
| 73 | + if np.min(factor_test_arr) > (x // 2) + 1: |
| 74 | + forced_break = True |
| 75 | + break |
| 76 | + if isprime(x): # if the checked number is prime itself, stop |
| 77 | + prime_factors.append(x) |
| 78 | + break |
| 79 | + |
| 80 | + # check if anythin gin the factor_test_arr are factors |
| 81 | + div_arr = x / factor_test_arr |
| 82 | + factor_mask = div_arr - div_arr.astype(int) == 0 |
| 83 | + divisors = factor_test_arr[factor_mask] |
| 84 | + if divisors.size > 0: # if divisors exist... |
| 85 | + if ( |
| 86 | + divisors[0] == 1 and divisors.size > 1 |
| 87 | + ): # make sure not to select 1 |
| 88 | + i = 1 |
| 89 | + elif ( |
| 90 | + divisors[0] == 1 and divisors.size == 1 |
| 91 | + ): # if one is the only one don't pick it |
| 92 | + factor_test_arr = factor_test_arr + 10 |
| 93 | + continue |
| 94 | + else: # othewise take the smallest divisor |
| 95 | + i = 0 |
| 96 | + |
| 97 | + # if divisor was found divide number by it and |
| 98 | + # repeat the process |
| 99 | + x = int(x / divisors[i]) |
| 100 | + prime_factors.append(divisors[i]) |
| 101 | + factor_test_arr = np.arange(1, 11) |
| 102 | + else: # if no number was found increase the test_arr |
| 103 | + # and keep looking for factors |
| 104 | + factor_test_arr = factor_test_arr + 10 |
| 105 | + continue |
| 106 | + |
| 107 | + if show_factorization: # show entire factorization if desired |
| 108 | + print(prime_factors) |
| 109 | + if forced_break: # if too many iterations break |
| 110 | + print(f"Something wrong, exceeded iteration threshold for value: {x}") |
| 111 | + return 0 |
| 112 | + return max(prime_factors) |
| 113 | + |
| 114 | + |
| 115 | +def prob5(arr, naive=False): |
| 116 | + """Return an array where every number is replaced be the largest prime |
| 117 | + in its factorization. Implement two methods. Switching between the two |
| 118 | + is determined by a bool. |
| 119 | +
|
| 120 | + Example: |
| 121 | + >>> A = np.array([15, 41, 49, 1077]) |
| 122 | + >>> prob4(A) |
| 123 | + array([5,41,7,359]) |
| 124 | + """ |
| 125 | + raise NotImplementedError("Problem 5 Incomplete") |
| 126 | + |
| 127 | + |
| 128 | +def prob6(x, y, z, A, optimize=False, split=True): |
| 129 | + """takes three vectors and a matrix and performs |
| 130 | + (np.outer(x,y)*z.reshape(-1,1))@A on them using einsum.""" |
| 131 | + raise NotImplementedError("Problem 6 part 1 Incomplete") |
| 132 | + |
| 133 | + |
| 134 | +def naive6(x, y, z, A): |
| 135 | + """uses normal numpy functions to do what prob5 does""" |
| 136 | + raise NotImplementedError("Problem 6 part 2 Incomplete") |
| 137 | + |
| 138 | + |
| 139 | +def prob7(): |
| 140 | + """Times and creates plots that generate the difference in |
| 141 | + speeds between einsum and normal numpy functions |
| 142 | + """ |
| 143 | + raise NotImplementedError("Problem 7 Incomplete") |
0 commit comments