-
-
Save ksandric/e91860143f1dd378645c01d518ddf013 to your computer and use it in GitHub Desktop.
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
commented
Jul 11, 2018
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?
double sigma, int nsteps - These are optional parameters. try it: nsteps = 100, sigma = 0.009
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:
if I set pts as a range from 0 to 6, I can have the ksdensity value from 0 to 6:
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)
?
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.
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:
The above picture is plot from KernelDensityEstimation result
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 ?