tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bitrate_accuracy.py (5844B)


      1 import numpy as np
      2 
      3 # Model A only.
      4 # Uses least squares regression to find the solution
      5 # when there is one unknown variable.
      6 def 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.
     14 def 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.
     24 def 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.
     40 def 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.
     60 def 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.
     77 def 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.
     93 def 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 
    108 def 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 
    123 def 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.
    142 def 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 
    184 if __name__ == "__main__":
    185    print_solutions("data2/all_lowres_target_lt600_data.txt")