def plot_img_conv_mse(img_path): """Plot the error due to converting to SC bitstreams and back plots against bitstream length, on log scale""" img = img_io.load_img(img_path, gs=True) def mse_trace(rng, func, correlated, color, label): #Helper function - produces a single MSE trace xvals = np.linspace(16, 512, num=20, dtype=np.uint16) yvals = np.zeros(20) for idx, bs_len in enumerate(xvals): for _ in range(5): img_bs = img_io.img_to_bs(img, func, bs_len=bs_len, correlated=correlated) img_recon = img_io.bs_to_img(img_bs, bs.bs_mean) yvals[idx] += img_io.img_mse(img_recon, img) rng.reset() yvals[idx] /= 5 print([xvals, yvals]) plt.plot(xvals, yvals, color=color, label=label) rng = bs.SC_RNG() mse_trace(rng, rng.bs_uniform, False, color='blue', label="Uniform rand, SCC= 0") mse_trace(rng, rng.bs_uniform, True, color='red', label="Uniform, SCC= +1") mse_trace(rng, rng.bs_lfsr, True, color='green', label="LFSR, SCC= +1") plt.legend() plt.xlabel("SC bitstream length") plt.ylabel("MSE") plt.title("Image to SC conversion MSE test") plt.show()
def plot_variance(func, ideal_sc_func, uniform_func, hyper_func, N, samps): xy_vals = np.array([a / N for a in range(N + 1)]) s = xy_vals.size var_vals_hyper = np.zeros((s, s)) var_vals_lfsr = np.zeros((s, s)) var_vals_uniform = np.zeros((s, s)) rng = bs.SC_RNG() for idx, x in enumerate(xy_vals): print("{} out of {}".format(idx, s)) for idy, y in enumerate(xy_vals): var_vals_uniform[idx][idy] = uniform_func( x, y, N) #Ideal bernoulli variance var_vals_hyper[idx][idy] = hyper_func( x, y, N) #Ideal hypergeometric variance lfsr_array = np.zeros(samps) #uniform_array = np.zeros(samps) for i in range(samps): bsx_lfsr = rng.bs_lfsr(N, x, keep_rng=False) bsy_lfsr = rng.bs_lfsr(N, y, keep_rng=False) #bsx_uniform = rng.bs_uniform(N, x, keep_rng=False) #bsy_uniform = rng.bs_uniform(N, y, keep_rng=False) #bit-wise output variance #var_vals_lfsr[idx][idy] += np.sqrt(bs.bs_var(func(bsx_lfsr, bsy_lfsr), bs_len=N)) #var_vals_uniform[idx][idy] += bs.bs_var(func(bsx_uniform, bsy_uniform), bs_len=N) #stream-wise output variance lfsr_array[i] = bs.bs_mean(func(bsx_lfsr, bsy_lfsr), bs_len=N) #uniform_array[i] = bs.bs_mean(func(bsx_uniform, bsy_uniform), bs_len=N) #Bit-wise output variance #var_vals_lfsr[idx][idy] /= samps #var_vals_uniform[idx][idy] /= samps #Stream-wise output variance var_vals_lfsr[idx][idy] = np.sqrt( np.sum((lfsr_array - ideal_sc_func(x, y))**2) / samps) #var_vals_uniform[idx][idy] = np.sqrt(np.sum((uniform_array - ideal_sc_func(x, y)) ** 2) / samps) X, Y = np.meshgrid(xy_vals, xy_vals) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') surf = ax.plot_surface(X, Y, var_vals_lfsr, color='r') surf2 = ax.plot_surface(X, Y, var_vals_uniform, color='y') surf3 = ax.plot_surface(X, Y, var_vals_hyper, color='b') ax.set_xlabel('X Input Value') ax.set_ylabel('Y Input Value') ax.set_zlabel('Std Deviation') maxval = np.maximum(np.max(var_vals_lfsr), np.max(var_vals_uniform)) ax.set_zlim(0, maxval) #fig.colorbar(surf , shrink=0.5, aspect=5) plt.title("Std Deviation vs. Input X and Y Values") plt.show()
def cnn_kernel_3x3(img, kernel, N): """Unipolar kernel convolve -> AND gates Bipolar kernel convolve -> XNOR gates""" is_bp = np.any(kernel < 0) h, w = img.shape rng = bs.SC_RNG() rng_type = rng.bs_bp_uniform if is_bp else rng.bs_uniform img_bs = img_io.img_to_bs(img, rng_type, bs_len=N) #Correlated at +1 img_bs = torch.from_numpy(img_bs).to(device) rng.reset() kernel_bs = img_io.img_to_bs(kernel, rng_type, bs_len=N, scale=False) kernel_bs = torch.from_numpy(kernel_bs).to(device) nb = N>>3 rc_mat = torch.cuda.ByteTensor(h-2, w-2, nb).fill_(0) m = torch.cuda.ByteTensor(3, 3, nb).fill_(0) z = torch.cuda.ByteTensor(nb).fill_(0) for i in range(h-2): for j in range(w-2): for k in range(3): for l in range(3): if is_bp: m[k][l] = torch.bitwise_not(torch.bitwise_xor(img_bs[i + k][j + l], kernel_bs[k][l])) else: m[k][l] = torch.bitwise_and(img_bs[i + k][j + l], kernel_bs[k][l]) #mux sum tree l1_1 = mux_p_cuda(m[0][0], m[0][1], 0.5) l1_2 = mux_p_cuda(m[0][2], m[1][0], 0.5) l1_3 = mux_p_cuda(m[1][1], m[1][2], 0.5) l1_4 = mux_p_cuda(m[2][0], m[2][1], 0.5) l2_1 = mux_p_cuda(l1_1, l1_2, 0.5) l2_2 = mux_p_cuda(l1_3, l1_4, 0.5) l3 = mux_p_cuda(l2_1, l2_2, 0.5) rc_mat[i][j] = mux_p_cuda(l3, mux_p_cuda(m[2][2], z, 1.0/8.0), 1.0/9.0) #mean_type = bs.bs_mean_bp if is_bp else bs.bs_mean #rc_mat = rc_mat.to(cpu) #img_io.disp_img(img_io.bs_to_img(rc_mat, mean_type, scaling=9)) return bs.get_corr_mat_cuda(rc_mat.view((h-2)*(w-2), nb)).to(cpu).numpy()
def test_hyper_vin(N, samps): rng = bs.SC_RNG() err = 0.0 for i in range(samps): print("{} out of {}".format(i, samps)) px = np.random.randint(0, N + 1) / N py = np.random.randint(0, N + 1) / N pz = np.random.randint(0, N + 1) / N #Get vin from lfsr-generated input bitstreams bsx = rng.bs_lfsr(N, px, keep_rng=False, pack=False) * 1 bsy = rng.bs_lfsr(N, py, keep_rng=False, pack=False) * 1 bsz = rng.bs_lfsr(N, pz, keep_rng=False, pack=False) * 1 actual_vin = pm.get_actual_vin(np.array([bsx, bsy, bsz])) #Get ideal vin ideal_vin = pm.get_vin_mc0(np.array([px, py, pz])) #Compare the two - probably different err += np.abs(actual_vin - ideal_vin) return np.mean(err / samps)
def lfsr_corr_mat_compare(func, num_inputs, num_outputs, p_arr, N, eq_predicted_cov=None): """Compare the actual output covariance matrix for a set of lfsr-generated input bitstreams to the theoretical one predicted based on the computed input covariance matrix""" Mf = pm.get_func_mat(func, num_inputs, num_outputs) rng = bs.SC_RNG() bs_mat = np.zeros((num_inputs, N), dtype=np.uint8) vin = pm.get_vin_mc0(p_arr) #Generate a set of independent bitstreams - Used to compare against ideal results for i in range(num_inputs): #bs_mat[j, :] = rng.bs_lfsr(N, p_arr[j], keep_rng=False, pack=False) bs_mat[i, :] = rng.bs_uniform(N, p_arr[i], keep_rng=False, pack=False) bs_mat_out = np.vstack( func(*np.split(bs_mat, bs_mat.shape[0], axis=0))[::-1]) #Assert that we get the correct p_arr back out (just a test) #assert np.all(np.isclose(p_arr, pm.B_mat(num_inputs).T @ vins[i, :])) in_corr_actual = bs.get_corr_mat_np(bs_mat) in_corr_ideal = pm.ptm_input_corr_mat(vin) np.set_printoptions(linewidth=np.inf) print( "Ideal in corr: \n {}".format(in_corr_ideal) ) #--> Variances match, and covariances are even closer to 0 (more exact) print("Actual in corr: \n {}".format(in_corr_actual) ) #--> About 0 (all entries) for independent bitstreams, as expected out_corr_actual = bs.get_corr_mat_np(bs_mat_out) out_corr_ideal = pm.ptm_output_corr_mat(vin, Mf) print("Ideal out corr: \n {}".format(out_corr_ideal)) print("Actual out corr: \n {}".format(out_corr_actual)) if eq_predicted_cov is not None: print("Eq-predicted cov: \n {}".format(eq_predicted_cov(*p_arr, N)**2))