def __init__(self, dist): # This should be a normal class attribute so that that residual # can compute the percent point function, but we don't not want # to force a scipy dependency if the normal distribution is not # needed. if not hasattr(Distribution, "N"): Distribution.N = normal_distribution(0,1) self.dist = dist
def simulate_2D_radial(f_func, n_particles, n_steps, D, dt, dt_sim, initial_radius=6): x, y = np.empty((2, n_steps, n_particles)) # random numbers in circle of radius 6 x0 = np.random.random( n_particles * 2) * (initial_radius * 2) - initial_radius y0 = np.random.random( n_particles * 2) * (initial_radius * 2) - initial_radius mask = x0**2 + y0**2 < initial_radius**2 x[0] = x0[mask][:n_particles] y[0] = y0[mask][:n_particles] # this simulation is valid when F and D are constant locally dilution = int(dt // dt_sim) n_steps_sim = n_steps * dilution rv = normal_distribution(loc=0., scale=(2 * D * dt_sim)**0.5) x_curr = x[0].copy() y_curr = y[0].copy() for i in range(1, n_steps_sim): r_curr = np.sqrt(x_curr**2 + y_curr**2) force = f_func(r_curr) force_x = force * (x_curr / r_curr) force_x[~np.isfinite(force_x)] = 0. force_y = force * (y_curr / r_curr) force_y[~np.isfinite(force_y)] = 0. dx, dy = rv.rvs((2, n_particles)) # the mean of the distribution displaces by gamma * F * dt # F is in units of kT/um, so gamma = D / kT = D x_curr += dx + force_x * D * dt_sim y_curr += dy + force_y * D * dt_sim if i % dilution == 0: x[i // dilution] = x_curr y[i // dilution] = y_curr return x, y
def simulate_1D(f_func, n_particles, n_steps, D, dt, dt_sim, force=0., kT=1.): # this simulation is valid when F and D are constant locally # that is (2*D*dt_sim)**0.5 << length at which force varies x = np.empty((n_steps, n_particles)) x[0] = np.random.random(n_particles) * 10 - 5 dilution = int(dt // dt_sim) n_steps_sim = n_steps * dilution gamma = D / kT rv = normal_distribution(loc=force * dt_sim * gamma, scale=(2 * D * dt_sim)**0.5) x_curr = x[0].copy() for i in range(1, n_steps_sim): force = f_func(x_curr) dx = rv.rvs(n_particles) # the mean of the distribution displaces by gamma * F * dt # F is in units of kT/um, so gamma = D / kT = D x_curr += dx + force * D * dt_sim if i % dilution == 0: x[i // dilution] = x_curr return x
def __init__(self, mean=0, std=1): self.dist = normal_distribution(mean, std) self._nllf_scale = log(sqrt(2*pi*std**2))
def __init__(self, dist): if not hasattr(Distribution, "N"): Distribution.N = normal_distribution(0,1) self.dist = dist
# for n in range(N_REALISATIONS): # plt.plot(x, np.log(plot_realisations[n] / x0), color=r_colors[n]) plt.xlabel('t') plt.ylabel(r'log(x(t)/$x_{0}$)') plt.legend() # Compute Distributions n_bins = 50 # Analytical xT_mean = np.exp(all_realisations_log_mean[-1]) xT_std = np.exp(all_realisations_log_std[-1]) print( f"For the Analytical Solution, mean={xT_mean} (log:{np.log(xT_mean)}), std={xT_std} (log:{np.log(xT_std)})" ) norm = normal_distribution(loc=np.log(xT_mean), scale=np.log(xT_std)) plt.figure() count, bins, ignored = plt.hist(all_realisations_log[:, -1], n_bins, color='grey') plt.plot(bins, norm.pdf(bins), color='black') plt.axvline(x=all_realisations_log_mean[-1] + (1.96 * all_realisations_log_std[-1]), color='darkmagenta') plt.axvline(x=all_realisations_log_mean[-1] - (1.96 * all_realisations_log_std[-1]), color='darkmagenta') # Explicit-Explicit xT_mean_ee = np.exp(all_realisations_ee_log_mean[-1]) xT_std_ee = np.exp(all_realisations_ee_log_std[-1])
def __init__(self, mean=0, std=1): Distribution.__init__(self, normal_distribution(mean, std)) self._nllf_scale = log(sqrt(2 * pi * std ** 2))