我有一组带有峰值的频率数据,我需要将其拟合成高斯曲线,然后从中获得半峰全宽。我可以做的 FWHM 部分,我已经有一个代码,但是我在编写代码以适应高斯时遇到了麻烦。
有谁知道任何可以为我做这件事或能够为我指明正确方向的功能?(我可以做最小二乘拟合线和多项式,但我不能让它为高斯工作)
如果它与 Octave 和 Matlab 兼容也会很有帮助,因为我现在有 Octave,但要到下周才能访问 Matlab。
任何帮助将不胜感激!
我有一组带有峰值的频率数据,我需要将其拟合成高斯曲线,然后从中获得半峰全宽。我可以做的 FWHM 部分,我已经有一个代码,但是我在编写代码以适应高斯时遇到了麻烦。
有谁知道任何可以为我做这件事或能够为我指明正确方向的功能?(我可以做最小二乘拟合线和多项式,但我不能让它为高斯工作)
如果它与 Octave 和 Matlab 兼容也会很有帮助,因为我现在有 Octave,但要到下周才能访问 Matlab。
任何帮助将不胜感激!
直接拟合单个一维高斯是一个非线性拟合问题。你会在这里找到现成的实现,或者这里,或者这里2D,或者这里(如果你有统计工具箱)(你听说过谷歌吗?:)
无论如何,可能有一个更简单的解决方案。如果您确定您的数据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π)) ) - ½(μ/σ)²
已经做出来了。现在,求解线性系统Ax=b
(这些是 Matlab 语句):
% 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
(应该只有很小的差异)。
也许这有你正在寻找的东西?不确定兼容性: 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.
我有类似的问题。这是谷歌上的第一个结果,这里链接的一些脚本让我的 matlab 崩溃了。
最后我在这里发现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)
我发现 MATLAB 的“fit”函数很慢,并且使用了带有内联高斯函数的“lsqcurvefit”。这是为了拟合高斯函数,如果您只想将数据拟合到正态分布,请使用“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')