Skip to content

Instantly share code, notes, and snippets.

@ksandric
Last active July 28, 2024 07:33
Show Gist options
  • Save ksandric/e91860143f1dd378645c01d518ddf013 to your computer and use it in GitHub Desktop.
Save ksandric/e91860143f1dd378645c01d518ddf013 to your computer and use it in GitHub Desktop.
C# Works like ksdensity in mathlab. KDE performs kernel density estimation (KDE)on one - dimensional data. Probability density function (PDF) signal analysis.
public static double[,] KernelDensityEstimation(double[] data, double sigma, int nsteps)
{
// probability density function (PDF) signal analysis
// Works like ksdensity in mathlab.
// KDE performs kernel density estimation (KDE)on one - dimensional data
// http://en.wikipedia.org/wiki/Kernel_density_estimation
// Input: -data: input data, one-dimensional
// -sigma: bandwidth(sometimes called "h")
// -nsteps: optional number of abscis points.If nsteps is an
// array, the abscis points will be taken directly from it. (default 100)
// Output: -x: equispaced abscis points
// -y: estimates of p(x)
// This function is part of the Kernel Methods Toolbox(KMBOX) for MATLAB.
// http://sourceforge.net/p/kmbox
// Converted to C# code by ksandric
double[,] result = new double[nsteps, 2];
double[] x = new double[nsteps], y = new double[nsteps];
double MAX = Double.MinValue, MIN = Double.MaxValue;
int N = data.Length; // number of data points
// Find MIN MAX values in data
for (int i = 0; i < N; i++)
{
if (MAX < data[i])
{
MAX = data[i];
}
if (MIN > data[i])
{
MIN = data[i];
}
}
// Like MATLAB linspace(MIN, MAX, nsteps);
x[0] = MIN;
for (int i = 1; i < nsteps; i++)
{
x[i] = x[i - 1] + ((MAX - MIN) / nsteps);
}
// kernel density estimation
double c = 1.0 / (Math.Sqrt(2 * Math.PI * sigma * sigma));
for (int i = 0; i < N; i++)
{
for (int j = 0; j < nsteps; j++)
{
y[j] = y[j] + 1.0 / N * c * Math.Exp(-(data[i] - x[j]) * (data[i] - x[j]) / (2 * sigma * sigma));
}
}
// compilation of the X,Y to result. Good for creating plot(x, y)
for (int i = 0; i < nsteps; i++)
{
result[i, 0] = x[i];
result[i, 1] = y[i];
}
return result;
}
@ksandric
Copy link
Author

plot

@citystrawman
Copy link

Hi, here's matlab ksdensity funciton, but the input parameters are not exactly one-to-one matched. May I know how can I call [f,xi] = ksdensity(x,pts) using this C# function?

@ksandric
Copy link
Author

double sigma, int nsteps - These are optional parameters. try it: nsteps = 100, sigma = 0.009

@citystrawman
Copy link

citystrawman commented Jul 26, 2024

double sigma, int nsteps - These are optional parameters. try it: nsteps = 100, sigma = 0.009

Sorry, not quite understand. I want to find a C# version for matlab [f,xi] = ksdensity(x,pts) where in this function by setting pts as a range, I can get the density value on that specific range.

For example, in Matlab's documentation:
ksdensity1

if I set pts as a range from 0 to 6, I can have the ksdensity value from 0 to 6:
ksdensity2

I know using your function could still make it by padding or removing some range, but is there a function that perfectly simulate [f,xi] = ksdensity(x,pts)?

@ksandric
Copy link
Author

This function does not have such functionality. But it can be added by working with the result of the function double[,] result

To do this, you need to refine the function. Add an input parameter indicating the interval. And implement the logic, for example, the one you use "by padding or removing some range". Or take this functionality out into a separate function. This seems like a simple action.

@citystrawman
Copy link

citystrawman commented Jul 28, 2024

This function does not have such functionality. But it can be added by working with the result of the function double[,] result

To do this, you need to refine the function. Add an input parameter indicating the interval. And implement the logic, for example, the one you use "by padding or removing some range". Or take this functionality out into a separate function. This seems like a simple action.

Thanks. I just tried your KernelDensityEstimation and compared it with the matlab ksdensity, I used same input data but the result seems to be very different:
use C# KernelDensityEstimation
The above picture is plot from KernelDensityEstimation result

use matlab
The above picture is plot from matlab result

I used same data for both of the two, and the code is as follows:

static void Main()
{
    // Sample data
    double[] x = new double[60] {0.5377,1.8339,-2.2588,0.8622,0.3188,-1.3077,-0.4336,0.3426,3.5784,2.7694,
                                -1.3499,3.0349,0.7254,-0.0631,0.7147,-0.205,-0.1241,1.4897,1.409,1.4172,
                                0.6715,-1.2075,0.7172,1.6302,0.4889,1.0347,0.7269,-0.3034,0.2939,-0.7873,
                                5.8884,3.8529,3.9311,4.1905,2.0557,6.4384,5.3252,4.2451,6.3703,3.2885,
                                4.8978,4.7586,5.3192,5.3129,4.1351,4.9699,4.8351,5.6277,6.0933,6.1093,4.1363,
                                5.0774,3.7859,3.8865,4.9932,6.5326,4.2303,5.3714,4.7744,6.1174};
    double[,] doubles = KernelDensityEstimation(x, 0.9, 128);  \\I firstly use 0.09 but it seems that 0.09 is too sensitive

    using (StreamWriter sw = new StreamWriter(@"D:\\Downloads\\data1.txt"))
    {
        int num = doubles.GetLength(0);
        for (int i = 0; i < num; i++)
        {
            sw.WriteLine(doubles[i, 0].ToString() + "," + doubles[i, 1].ToString());  \\write out and plot it using excel
        }
}
}
x = [0.5377;1.8339;-2.2588;0.8622;0.3188;-1.3077;-0.4336;0.3426;3.5784;2.7694;
-1.3499;3.0349;0.7254;-0.0631;0.7147;-0.205;-0.1241;1.4897;1.409;1.4172;
0.6715;-1.2075;0.7172;1.6302;0.4889;1.0347;0.7269;-0.3034;0.2939;-0.7873;
5.8884;3.8529;3.9311;4.1905;2.0557;6.4384;5.3252;4.2451;6.3703;3.2885;
4.8978;4.7586;5.3192;5.3129;4.1351;4.9699;4.8351;5.6277;6.0933;6.1093;4.1363;
5.0774;3.7859;3.8865;4.9932;6.5326;4.2303;5.3714;4.7744;6.1174];
num_pts = 128;
pts = 0:(6-0)/(num_pts-1):6;
[f,xi] = ksdensity(x, pts); 
figure
plot(xi,f);

I dont know what makes the result so different. Is it because sigma ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment