如何将高斯拟合到matlab / octave中的数据?

时间:2012-11-08 14:04:25

标签: matlab octave curve-fitting gaussian

我有一组带有峰值的频率数据,我需要将这些峰值拟合成高斯曲线,然后从中得到半峰全宽。我可以做的FWHM部分,我已经有了一个代码,但我在编写代码以适应高斯时遇到了麻烦。

有没有人知道任何能为我这样做的功能,或者能够指出我正确的方向? (我可以对线和多项式进行最小二乘拟合,但我不能让它适用于高斯人)

如果它与Octave和Matlab兼容,那么它会有所帮助,因为我现在有Octave,但直到下周才能访问Matlab。

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:19)

直接拟合单个1D高斯是一个非线性拟合问题。您会找到现成的实施hereherehere for 2Dhere(如果您有统计工具箱)(您是否听说过Google?): )

无论如何,可能有一个更简单的解决方案。如果您确定数据y将由高斯描述得很好,并且在整个x范围内分布得相当均匀,那么您可以将问题线性化(这些是方程式,而不是语句):

   y = 1/(σ·√(2π)) · exp( -½ ( (x-μ)/σ )² )
ln y = ln( 1/(σ·√(2π)) ) - ½ ( (x-μ)/σ )²
     = Px² + Qx + R         

替换

P = -1/(2σ²)
Q = +2μ/(2σ²)    
R = ln( 1/(σ·√(2π)) ) - ½(μ/σ)²

已经制作完成。现在,用(这些是Matlab语句)求解线性系统Ax=b

% design matrix for least squares fit
xdata = xdata(:);
A = [xdata.^2,  xdata,  ones(size(xdata))]; 

% log of your data 
b = log(y(:));                  

% least-squares solution for x
x = A\b;                    

您通过这种方式找到的向量x将等于

x == [P Q R]

然后您必须进行逆向工程以找到平均值μ和标准偏差σ:

mu    = -x(2)/x(1)/2;
sigma = sqrt( -1/2/x(1) );

您可以与x(3) == R进行交叉核对(应该只有差异)。

答案 1 :(得分:2)

也许这有你想要的东西?不确定兼容性: http://www.mathworks.com/matlabcentral/fileexchange/11733-gaussian-curve-fit

从其文档:

[sigma,mu,A]=mygaussfit(x,y) 
[sigma,mu,A]=mygaussfit(x,y,h)

this function is doing fit to the function 
y=A * exp( -(x-mu)^2 / (2*sigma^2) )

the fitting is been done by a polyfit 
the lan of the data.

h is the threshold which is the fraction 
from the maximum y height that the data 
is been taken from. 
h should be a number between 0-1. 
if h have not been taken it is set to be 0.2 
as default.

答案 2 :(得分:1)

我有类似的问题。 这是谷歌的第一个结果,这里链接的一些脚本使我的matlab崩溃。

最后我找到了here matlab内置拟合函数,也适合高斯人。

它看起来像那样:

>> v=-30:30;
>> fit(v', exp(-v.^2)', 'gauss1')

ans = 

   General model Gauss1:
   ans(x) =  a1*exp(-((x-b1)/c1)^2)
   Coefficients (with 95% confidence bounds):
      a1 =           1  (1, 1)
      b1 =  -8.489e-17  (-3.638e-12, 3.638e-12)
      c1 =           1  (1, 1)

答案 3 :(得分:0)

我发现MATLAB"适合"功能很慢,并使用" lsqcurvefit"具有内联高斯函数。这是为了拟合Gaussian FUNCTION,如果你只想将数据拟合到Normal分布,请使用" normfit。"

检查

% % Generate synthetic data (for example) % % %

    nPoints = 200;  binSize = 1/nPoints ; 
    fauxMean = 47 ;fauxStd = 8;
    faux = fauxStd.*randn(1,nPoints) + fauxMean; % REPLACE WITH YOUR ACTUAL DATA
    xaxis = 1:length(faux) ;fauxData = histc(faux,xaxis);

    yourData = fauxData; % replace with your actual distribution
    xAxis = 1:length(yourData) ; 

    gausFun = @(hms,x) hms(1) .* exp (-(x-hms(2)).^2 ./ (2*hms(3)^2)) ; % Gaussian FUNCTION

% % Provide estimates for initial conditions (for lsqcurvefit) % % 

    height_est = max(fauxData)*rand ; mean_est = fauxMean*rand; std_est=fauxStd*rand;
    x0 = [height_est;mean_est; std_est]; % parameters need to be in a single variable

    options=optimset('Display','off'); % avoid pesky messages from lsqcurvefit (optional)
    [params]=lsqcurvefit(gausFun,x0,xAxis,yourData,[],[],options); % meat and potatoes

    lsq_mean = params(2); lsq_std = params(3) ; % what you want

% % % Plot data with fit % % % 
    myFit = gausFun(params,xAxis);
    figure;hold on;plot(xAxis,yourData./sum(yourData),'k');
    plot(xAxis,myFit./sum(myFit),'r','linewidth',3) % normalization optional
    xlabel('Value');ylabel('Probability');legend('Data','Fit')