I have a data set that has two peaks close together. I'd like to fit these peaks with gaussians so that I come up with a new data set that replicates the original one. To this end, I am using MATLAB's "findpeaks" function, and using the heights and widths of the peaks in order to come up with the appropriate number of gaussians, and then add those gaussians together. However, because the peaks are so close together, the result looks like the following (with the original data set in blue and the replicated one in red):
Is there a better method to replicate the data with gaussian peaks?
Gaussian function are defined by two variable, mean and variance. The two peak would give you the means of the two gaussians and by the look of the figure the same variance for them both (If some data has gone through a Gaussian process the variance would be the same, I can not think of a physical process where that would not be the case, unless it is just an arbitrary plot). So you only have to find one variable. As for the peaks that would just be the normalization so that the area under the curve sums up to 1. A gaussian sums up to 1 by default, if the sum under the plot you are trying to fit is 2 you do not need to do anything, otherwise scale accordingly.
My guess is something like this (pseudo code):
f = 0.5*gauss(-3,var)+0.5*gauss(3,var)
If you know more about the process that created the plot, then you can actually do better.
Related
I have a a bunch of data that I'd like to use to find an unknown parameter in a physical equation.
I'm trying to find a parameter k to characterise the output of a hall effect sensor as a function on input voltage and distance between the sensor and the magnet. However, I've found this function to be inversely proportional to the square of the distance.
I asked my professor about how to use MATLAB to find the unknown parameter, and he told me I could try to fit it by taking the logarithm of both sides of the equation and plotting that, seen as that would make the relationship linear and thus easier to plot.
I'd have to do this in MATLAB and I'm assuming the values I measured would have to be converted by hand before being able to perform any sort of curve fitting on them.
I was wondering if doing that was worth it, and if there is a faster way of doing this.
Thanks :)
In order to easily identify the relationship, for a set input voltage, I had to take the logarithm of the measured distance and the logarithm of the respective output voltages and plot those. Fitting a line through those points then enabled me to see that the coefficient was close enough to -2, confirming the inverse square relationship.
I then did the same for different input voltages and added everything together on the same plot.
I have about 10000 floating point data, and have read them into a single row matrix.
Now I would like to plot them and show their distribution, would there be some simple functions to do that?
plot() actually plots value with respect to data number...which is not what I want
bar() is similar to what I want, but actually I would like to lower the sample rate and merge neighbor bars which are close enough (e.g. one bar for 0.50-0.55, and one bar for 0.55-0.60, etc) instead of having one single bar for every single data sample.
would there be a function to calculate this distribution by dividing the range into small steps, and outputting the prob density in each step?
Thank you!
hist() would be best. It plots a histogram, with a lot of options which you can see by doc hist, or by checking the Matlab website. Options include a specified number of bins, or a range of bins. This will plot a histogram of 1000 normally random points, with 50 bins.
hist(randn(1000,1),50)
I have an array named Area, which contains a set of values.
The histogram of the array looks like this
The bin width is 60 in this case. I'd like to fit two gaussians to the two peaks here (even if it won't be a great fit).
So I used:
options = statset('Display','final');
obj = gmdistribution.fit(area,2,'Options',options);
gausspdf = pdf(obj, xaxis);
A = sum(gausspdf);
gausspdf = gausspdf/A;
But when I try to plot the two fitted Gaussians, the resulting curve looks like this:
I'm quite confused, as there should be two peaks appearing in the plot?
The gmdistribution.fit method fits data according to maximum-likelihood criterion; that is, it tries to find parameters which maximize the likelihood given the data. It will not necessarily fit what you see or expect visually. Still, there is the possibility that the algorithm converged to a "bad" local minimum. You can try and set the initial conditions according to what you want to get, practically 'helping' the algorithm to converge to the desired result. You do this using the Start option to the fit method, which enables you to give it either an initial guess, in which case you should try and estimate the parameters from the histogram, or an initial component index for each data sample. See the documentation for more details.
I think that your peaks are too close and the function can't distinguish them. so maybe you should change the options for gmdistribution or apply a non-linear function to your data first to get more separate peaks in histogram.
this is my problem:
I have the next data "A", which looks like:
As you can see, I have drawn with red circles the apparently peaks, the most defined are 2 and 7, I say that they are defined because its standard deviation is low in comparison with the other peaks (especially the second one).
What I need is a way (anyway) to get the values and the standard deviation of n peaks in a numeric array.
I have tried with "clusters", but I got no good results:
First of all, I used "kmeans" MATLAB function, and I realize that this algorithm doesn't group peaks as I need. As you can see in the picture above, in the red circle, that cluster has at less 3 or 4 peaks. And kmeans need that you set the number of clusters, and I need to identify it automatically.
I hope that anyone can give me some ideas, or a way to get better results, thanks.
Pd: I leave the data "A" in the next link.
https://drive.google.com/file/d/0B4WGV21GqSL5a2EyQ2l0SHZURzA/edit?usp=sharing
The problem is that your axes have very different meaning.
K-means optimizes variance. But variance in X is something entirely different than variance in Y, isn't it? Furthermore, each of these methods will split your data in both X and Y, whereas I assume you want the data to be partitioned on the X axis only.
I suggest the following: consider the Y axis to be a weight, and X axis to be a position.
Then perform weighted density estimation, and look for low density to separate your clusters.
I can't help you with MATLAB. I don't use it.
Mathematically, what you want to do is place a Gaussian at each point, with area Y and center X. Then find minima and maxima on the sum of these Gaussians. See Wikipedia, Kernel Density Estimation for details; except that you want to use the Y axis as weights. You could maybe also use 1/Y as standard deviation, if you don't want to use weights.
I was given this task, I am a noob and need some pointers to get started with centroid calculation in Matlab:
Instead of an image first I was asked to simulate a Gaussian distribution(2 dimensional), add noise(random noise) and plot the intensities, now the position of the centroid changes due to noise and I need to bring it back to its original position by
-clipping level to get rid of the noise, noise reduction by clipping or smoothing, sliding average (lpf) (averaging filter 3-5 samples ), calculating the means or using Convolution filter kernel - which does matrix operations which represent the 2-D images
Since you are a noob, even if we wrote down the answer verbatim you probably won't understand how it works. So instead I'll do what you asked, give you pointers and you'll have to read the related documentation :
a) to produce a 2-d Gaussian use meshgrid or ndgrid
b) to add noise to the image look into rand ,randn or randi, depending what exactly you need.
c) to plot the intensities use imagesc
d) to find the centroid there are several ways, try to further search SO, you'll find many discussions. Also you can check TMW File exchange for different implementations for that.