我有一套帶有峯值的頻率數據,我需要擬合一個高斯曲線,然後從中獲得半峯全寬。 FWHM的一部分我可以做,我已經有了一個代碼,但我無法編寫代碼來適應高斯。如何在matlab/octave中擬合高斯數據?
有沒有人知道任何功能,會爲我做這個或將能夠指出我在正確的方向嗎? (我可以做線和多項式的最小二乘擬合,但我不能讓它適用於高斯)
如果它與Octave和Matlab兼容,這是有幫助的,因爲我現在有Octave,但不會直到下週才能訪問Matlab。
任何幫助將不勝感激!
我有一套帶有峯值的頻率數據,我需要擬合一個高斯曲線,然後從中獲得半峯全寬。 FWHM的一部分我可以做,我已經有了一個代碼,但我無法編寫代碼來適應高斯。如何在matlab/octave中擬合高斯數據?
有沒有人知道任何功能,會爲我做這個或將能夠指出我在正確的方向嗎? (我可以做線和多項式的最小二乘擬合,但我不能讓它適用於高斯)
如果它與Octave和Matlab兼容,這是有幫助的,因爲我現在有Octave,但不會直到下週才能訪問Matlab。
任何幫助將不勝感激!
直接擬合單維高斯是一個非線性擬合問題。你會發現現成的實現here,或here,或者here for 2D,或here(如果你有統計工具箱)(你有沒有聽說過谷歌的?:)
無論如何,有可能是一個簡單的解決方案。如果你確信你的數據y
將由高斯很好的描述,併合理地分佈在整個x
-range,可以線性化問題(這些方程,不是語句):
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
,您可以交叉檢查(應該只有小差異)。
非常感謝。我只能通過谷歌找到第一個鏈接,但沒有與我的數據一起工作,第二個雖然工作。 也感謝您的解釋/方程式。 :D – user1806676
@ user1806676:我還沒有嘗試線性化方法,但至少數學是正確的。你應該在那裏做一些實驗和驗證。 –
試過了線性化的方法。效果很好。 –
也許這有你正在尋找的東西?不知道兼容性: 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.
更適合作爲評論,不是嗎? –
儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的基本部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/評論/低質量帖/ 13114204) –
@ScottHoltzman感謝您的高擡頭,我已經包括了相關的描述。 –
我有類似的問題。 這是谷歌的第一個結果,這裏鏈接的一些腳本使我的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)
請注意,'fit'不是內置的;它是曲線擬合工具箱的一部分 –
我發現MATLAB「適合」的功能緩慢,並用「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')
你有一個單峯(僅1高斯)?還是多個高峯(多重重疊的高加索人)? –
這只是每個文件的單個峯值。 – user1806676
如果它只是一個峯值,則取數值的均值和標準值,並定義您的樣本正態分佈。你嘗試過嗎?否則,如果您有統計工具箱,請使用normfit()。 – Justin