1import numpy as np 2 3# Model A only. 4# Uses least squares regression to find the solution 5# when there is one unknown variable. 6def lstsq_solution(A, B): 7 A_inv = np.linalg.pinv(A) 8 x = np.matmul(A_inv, B) 9 return x[0][0] 10 11# Model B only. 12# Uses the pseudoinverse matrix to find the solution 13# when there are two unknown variables. 14def pinv_solution(A, mv, B): 15 new_A = np.concatenate((A, mv), axis=1) 16 new_A_inv = np.linalg.pinv(new_A) 17 new_x = np.matmul(new_A_inv, B) 18 print("pinv solution:", new_x[0][0], new_x[1][0]) 19 return (new_x[0][0], new_x[1][0]) 20 21# Model A only. 22# Finds the coefficient to multiply A by to minimize 23# the percentage error between A and B. 24def minimize_percentage_error_model_a(A, B): 25 R = np.divide(A, B) 26 num = 0 27 den = 0 28 best_x = 0 29 best_error = 100 30 for r_i in R: 31 num += r_i 32 den += r_i**2 33 if den == 0: 34 return 0 35 return (num/den)[0] 36 37# Model B only. 38# Finds the coefficients to multiply to the frame bitrate 39# and the motion vector bitrate to minimize the percent error. 40def minimize_percentage_error_model_b(r_e, r_m, r_f): 41 r_ef = np.divide(r_e, r_f) 42 r_mf = np.divide(r_m, r_f) 43 sum_ef = np.sum(r_ef) 44 sum_ef_sq = np.sum(np.square(r_ef)) 45 sum_mf = np.sum(r_mf) 46 sum_mf_sq = np.sum(np.square(r_mf)) 47 sum_ef_mf = np.sum(np.multiply(r_ef, r_mf)) 48 # Divides x by y. If y is zero, returns 0. 49 divide = lambda x, y : 0 if y == 0 else x / y 50 # Set up and solve the matrix equation 51 A = np.array([[1, divide(sum_ef_mf, sum_ef_sq)],[divide(sum_ef_mf, sum_mf_sq), 1]]) 52 B = np.array([divide(sum_ef, sum_ef_sq), divide(sum_mf, sum_mf_sq)]) 53 A_inv = np.linalg.pinv(A) 54 x = np.matmul(A_inv, B) 55 return x 56 57# Model A only. 58# Calculates the least squares error between A and B 59# using coefficients in X. 60def average_lstsq_error(A, B, x): 61 error = 0 62 n = 0 63 for i, a in enumerate(A): 64 a = a[0] 65 b = B[i][0] 66 if b == 0: 67 continue 68 n += 1 69 error += (b - x*a)**2 70 if n == 0: 71 return None 72 error /= n 73 return error 74 75# Model A only. 76# Calculates the average percentage error between A and B. 77def average_percent_error_model_a(A, B, x): 78 error = 0 79 n = 0 80 for i, a in enumerate(A): 81 a = a[0] 82 b = B[i][0] 83 if b == 0: 84 continue 85 n += 1 86 error_i = (abs(x*a-b)/b)*100 87 error += error_i 88 error /= n 89 return error 90 91# Model B only. 92# Calculates the average percentage error between A and B. 93def average_percent_error_model_b(A, M, B, x): 94 error = 0 95 for i, a in enumerate(A): 96 a = a[0] 97 mv = M[i] 98 b = B[i][0] 99 if b == 0: 100 continue 101 estimate = x[0]*a 102 estimate += x[1]*mv 103 error += abs(estimate - b) / b 104 error *= 100 105 error /= A.shape[0] 106 return error 107 108def average_squared_error_model_a(A, B, x): 109 error = 0 110 n = 0 111 for i, a in enumerate(A): 112 a = a[0] 113 b = B[i][0] 114 if b == 0: 115 continue 116 n += 1 117 error_i = (1 - x*(a/b))**2 118 error += error_i 119 error /= n 120 error = error**0.5 121 return error * 100 122 123def average_squared_error_model_b(A, M, B, x): 124 error = 0 125 n = 0 126 for i, a in enumerate(A): 127 a = a[0] 128 b = B[i][0] 129 mv = M[i] 130 if b == 0: 131 continue 132 n += 1 133 error_i = 1 - ((x[0]*a + x[1]*mv)/b) 134 error_i = error_i**2 135 error += error_i 136 error /= n 137 error = error**0.5 138 return error * 100 139 140# Traverses the data and prints out one value for 141# each update type. 142def print_solutions(file_path): 143 data = np.genfromtxt(file_path, delimiter="\t") 144 prev_update = 0 145 split_list_indices = list() 146 for i, val in enumerate(data): 147 if prev_update != val[3]: 148 split_list_indices.append(i) 149 prev_update = val[3] 150 split = np.split(data, split_list_indices) 151 for array in split: 152 A, mv, B, update = np.hsplit(array, 4) 153 z = np.where(B == 0)[0] 154 r_e = np.delete(A, z, axis=0) 155 r_m = np.delete(mv, z, axis=0) 156 r_f = np.delete(B, z, axis=0) 157 A = r_e 158 mv = r_m 159 B = r_f 160 all_zeros = not A.any() 161 if all_zeros: 162 continue 163 print("update type:", update[0][0]) 164 x_ls = lstsq_solution(A, B) 165 x_a = minimize_percentage_error_model_a(A, B) 166 x_b = minimize_percentage_error_model_b(A, mv, B) 167 percent_error_a = average_percent_error_model_a(A, B, x_a) 168 percent_error_b = average_percent_error_model_b(A, mv, B, x_b)[0] 169 baseline_percent_error_a = average_percent_error_model_a(A, B, 1) 170 baseline_percent_error_b = average_percent_error_model_b(A, mv, B, [1, 1])[0] 171 172 squared_error_a = average_squared_error_model_a(A, B, x_a) 173 squared_error_b = average_squared_error_model_b(A, mv, B, x_b)[0] 174 baseline_squared_error_a = average_squared_error_model_a(A, B, 1) 175 baseline_squared_error_b = average_squared_error_model_b(A, mv, B, [1, 1])[0] 176 177 print("model,\tframe_coeff,\tmv_coeff,\terror,\tbaseline_error") 178 print("Model A %_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(percent_error_a) + ",\t" + str(baseline_percent_error_a)) 179 print("Model A sq_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(squared_error_a) + ",\t" + str(baseline_squared_error_a)) 180 print("Model B %_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(percent_error_b) + ",\t" + str(baseline_percent_error_b)) 181 print("Model B sq_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(squared_error_b) + ",\t" + str(baseline_squared_error_b)) 182 print() 183 184if __name__ == "__main__": 185 print_solutions("data2/all_lowres_target_lt600_data.txt") 186