| import numpy as np | 
 |  | 
 | # Model A only. | 
 | # Uses least squares regression to find the solution | 
 | # when there is one unknown variable. | 
 | def lstsq_solution(A, B): | 
 |     A_inv = np.linalg.pinv(A) | 
 |     x = np.matmul(A_inv, B) | 
 |     return x[0][0] | 
 |  | 
 | # Model B only. | 
 | # Uses the pseudoinverse matrix to find the solution | 
 | # when there are two unknown variables. | 
 | def pinv_solution(A, mv, B): | 
 |     new_A = np.concatenate((A, mv), axis=1) | 
 |     new_A_inv = np.linalg.pinv(new_A) | 
 |     new_x = np.matmul(new_A_inv, B) | 
 |     print("pinv solution:", new_x[0][0], new_x[1][0]) | 
 |     return (new_x[0][0], new_x[1][0]) | 
 |  | 
 | # Model A only. | 
 | # Finds the coefficient to multiply A by to minimize | 
 | # the percentage error between A and B. | 
 | def minimize_percentage_error_model_a(A, B): | 
 |     R = np.divide(A, B) | 
 |     num = 0 | 
 |     den = 0 | 
 |     best_x = 0 | 
 |     best_error = 100 | 
 |     for r_i in R: | 
 |         num += r_i | 
 |         den += r_i**2 | 
 |     if den == 0: | 
 |         return 0 | 
 |     return (num/den)[0] | 
 |  | 
 | # Model B only. | 
 | # Finds the coefficients to multiply to the frame bitrate | 
 | # and the motion vector bitrate to minimize the percent error. | 
 | def minimize_percentage_error_model_b(r_e, r_m, r_f): | 
 |     r_ef = np.divide(r_e, r_f) | 
 |     r_mf = np.divide(r_m, r_f) | 
 |     sum_ef = np.sum(r_ef) | 
 |     sum_ef_sq = np.sum(np.square(r_ef)) | 
 |     sum_mf = np.sum(r_mf) | 
 |     sum_mf_sq = np.sum(np.square(r_mf)) | 
 |     sum_ef_mf = np.sum(np.multiply(r_ef, r_mf)) | 
 |     # Divides x by y. If y is zero, returns 0. | 
 |     divide = lambda x, y : 0 if y == 0 else x / y | 
 |     # Set up and solve the matrix equation | 
 |     A = np.array([[1, divide(sum_ef_mf, sum_ef_sq)],[divide(sum_ef_mf, sum_mf_sq), 1]]) | 
 |     B = np.array([divide(sum_ef, sum_ef_sq), divide(sum_mf, sum_mf_sq)]) | 
 |     A_inv = np.linalg.pinv(A) | 
 |     x = np.matmul(A_inv, B) | 
 |     return x | 
 |  | 
 | # Model A only. | 
 | # Calculates the least squares error between A and B | 
 | # using coefficients in X. | 
 | def average_lstsq_error(A, B, x): | 
 |     error = 0 | 
 |     n = 0 | 
 |     for i, a in enumerate(A): | 
 |         a = a[0] | 
 |         b = B[i][0] | 
 |         if b == 0: | 
 |             continue | 
 |         n += 1 | 
 |         error += (b - x*a)**2 | 
 |     if n == 0: | 
 |         return None | 
 |     error /= n | 
 |     return error | 
 |  | 
 | # Model A only. | 
 | # Calculates the average percentage error between A and B. | 
 | def average_percent_error_model_a(A, B, x): | 
 |     error = 0 | 
 |     n = 0 | 
 |     for i, a in enumerate(A): | 
 |         a = a[0] | 
 |         b = B[i][0] | 
 |         if b == 0: | 
 |             continue | 
 |         n += 1 | 
 |         error_i = (abs(x*a-b)/b)*100 | 
 |         error += error_i | 
 |     error /= n | 
 |     return error | 
 |  | 
 | # Model B only. | 
 | # Calculates the average percentage error between A and B. | 
 | def average_percent_error_model_b(A, M, B, x): | 
 |     error = 0 | 
 |     for i, a in enumerate(A): | 
 |         a = a[0] | 
 |         mv = M[i] | 
 |         b = B[i][0] | 
 |         if b == 0: | 
 |             continue | 
 |         estimate = x[0]*a | 
 |         estimate += x[1]*mv | 
 |         error += abs(estimate - b) / b | 
 |     error *= 100 | 
 |     error /= A.shape[0] | 
 |     return error | 
 |  | 
 | def average_squared_error_model_a(A, B, x): | 
 |     error = 0 | 
 |     n = 0 | 
 |     for i, a in enumerate(A): | 
 |         a = a[0] | 
 |         b = B[i][0] | 
 |         if b == 0: | 
 |             continue | 
 |         n += 1 | 
 |         error_i = (1 - x*(a/b))**2 | 
 |         error += error_i | 
 |     error /= n | 
 |     error = error**0.5 | 
 |     return error * 100 | 
 |  | 
 | def average_squared_error_model_b(A, M, B, x): | 
 |     error = 0 | 
 |     n = 0 | 
 |     for i, a in enumerate(A): | 
 |         a = a[0] | 
 |         b = B[i][0] | 
 |         mv = M[i] | 
 |         if b == 0: | 
 |             continue | 
 |         n += 1 | 
 |         error_i = 1 - ((x[0]*a + x[1]*mv)/b) | 
 |         error_i = error_i**2 | 
 |         error += error_i | 
 |     error /= n | 
 |     error = error**0.5 | 
 |     return error * 100 | 
 |  | 
 | # Traverses the data and prints out one value for | 
 | # each update type. | 
 | def print_solutions(file_path): | 
 |     data = np.genfromtxt(file_path, delimiter="\t") | 
 |     prev_update = 0 | 
 |     split_list_indices = list() | 
 |     for i, val in enumerate(data): | 
 |         if prev_update != val[3]: | 
 |             split_list_indices.append(i) | 
 |             prev_update = val[3] | 
 |     split = np.split(data, split_list_indices) | 
 |     for array in split: | 
 |         A, mv, B, update = np.hsplit(array, 4) | 
 |         z = np.where(B == 0)[0] | 
 |         r_e = np.delete(A, z, axis=0) | 
 |         r_m = np.delete(mv, z, axis=0) | 
 |         r_f = np.delete(B, z, axis=0) | 
 |         A = r_e | 
 |         mv = r_m | 
 |         B = r_f | 
 |         all_zeros = not A.any() | 
 |         if all_zeros: | 
 |             continue | 
 |         print("update type:", update[0][0]) | 
 |         x_ls = lstsq_solution(A, B) | 
 |         x_a = minimize_percentage_error_model_a(A, B) | 
 |         x_b = minimize_percentage_error_model_b(A, mv, B) | 
 |         percent_error_a = average_percent_error_model_a(A, B, x_a) | 
 |         percent_error_b = average_percent_error_model_b(A, mv, B, x_b)[0] | 
 |         baseline_percent_error_a = average_percent_error_model_a(A, B, 1) | 
 |         baseline_percent_error_b = average_percent_error_model_b(A, mv, B, [1, 1])[0] | 
 |  | 
 |         squared_error_a = average_squared_error_model_a(A, B, x_a) | 
 |         squared_error_b = average_squared_error_model_b(A, mv, B, x_b)[0] | 
 |         baseline_squared_error_a = average_squared_error_model_a(A, B, 1) | 
 |         baseline_squared_error_b = average_squared_error_model_b(A, mv, B, [1, 1])[0] | 
 |  | 
 |         print("model,\tframe_coeff,\tmv_coeff,\terror,\tbaseline_error") | 
 |         print("Model A %_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(percent_error_a) + ",\t" + str(baseline_percent_error_a)) | 
 |         print("Model A sq_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(squared_error_a) + ",\t" + str(baseline_squared_error_a)) | 
 |         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)) | 
 |         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)) | 
 |         print() | 
 |  | 
 | if __name__ == "__main__": | 
 |     print_solutions("data2/all_lowres_target_lt600_data.txt") |