From 61b06fc1f0bd80f96472fba85a31b34d20f4d055 Mon Sep 17 00:00:00 2001 From: Nicolas Mounet Date: Wed, 2 Jun 2021 12:43:10 +0200 Subject: [PATCH] Adding LogCustomKernel sampleable distribution (curve is vs. a log variable) --- cara/monte_carlo/sampleable.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cara/monte_carlo/sampleable.py b/cara/monte_carlo/sampleable.py index 95374370..4333c93f 100644 --- a/cara/monte_carlo/sampleable.py +++ b/cara/monte_carlo/sampleable.py @@ -94,6 +94,30 @@ class CustomKernel(SampleableDistribution): return kde_model.sample(n_samples=size)[:, 0] +class LogCustomKernel(SampleableDistribution): + """ + Defines a distribution which follows a custom curve vs. the log + (in base 10) of the random variable. Uses a Gaussian kernel density + fit. This is more appropriate for a noisy distribution function. + """ + def __init__(self, log_variable: float_array_size_n, + frequencies: float_array_size_n, + kernel_bandwidth: float): + # these are resp. the log of the random variable, the distribution + # frequencies at these values, and the bandwidth of the Gaussian + # kernel + self.log_variable = log_variable + self.frequencies = frequencies + self.kernel_bandwidth = kernel_bandwidth + + def generate_samples(self, size: int) -> float_array_size_n: + kde_model = KernelDensity(kernel='gaussian', + bandwidth=self.kernel_bandwidth) + kde_model.fit(self.log_variable.reshape(-1, 1), + sample_weight=self.frequencies) + return 10 ** kde_model.sample(n_samples=size)[:, 0] + + _VectorisedFloatOrSampleable = typing.Union[ SampleableDistribution, cara.models._VectorisedFloat, ]