from KDEpy import FFTKDE
from KDEpy.bw_selection import silvermans_rule, improved_sheather_jones

# Get the standard deviation of the kernel functions
data = np.array([3.1, 5.2, 6.9, 7.9, 8.5, 11.3, 11.5, 11.5, 11.5, 15.5])
# Silverman assumes normality of data - use ISJ with much data instead
kernel_std = silvermans_rule(data.reshape(-1, 1))  # Shape (obs, dims)

# (1) First resample original data, then (2) add noise from kernel
size = 50
resampled_data = np.random.choice(data, size=size, replace=True)
resampled_data = resampled_data + np.random.randn(size) * kernel_std

# Plot the results
plt.scatter(data, np.zeros_like(data), marker='|', label="Original data")
plt.scatter(resampled_data, np.ones_like(resampled_data) * 0.01,
            marker='|', label="Resampled from KDE")
x, y = FFTKDE(kernel="gaussian", bw="silverman").fit(data).evaluate()
plt.plot(x, y, label="FFTKDE with Silverman's rule")
plt.title('Weighted and unweighted KDE')
plt.tight_layout(); plt.legend(loc='upper left');