diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py b/third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py new file mode 100644 index 0000000000..2a5da6a794 --- /dev/null +++ b/third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py @@ -0,0 +1,185 @@ +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") |