10

ガウス曲線に適合させてから半値全幅を取得する必要があるピークを持つ周波数データのセットがあります。私ができるFWHMの部分、私はすでにそのためのコードを持っていますが、ガウスに合うようにコードを書くのに苦労しています。

誰かが私のためにこれを行う、または私を正しい方向に向けることができる機能を知っていますか?(直線と多項式の最小二乗フィッティングはできますが、ガウス分布では機能しません)

また、私は現在Octaveを持っていますが、来週までMatlabにアクセスできないので、OctaveとMatlabの両方と互換性があると便利です。

どんな助けでも大歓迎です!

4

4 に答える 4

20

単一の1Dガウス分布を直接近似することは、非線形近似の問題です。既製の実装は、ここ、またはここ、または2Dの場合はここ、またはここ(統計ツールボックスがある場合)にあります(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π)) ) - ½(μ/σ)²

作ったことがある。ここで、線形システムを次のように解きます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違いがあるはずです)。

于 2012-11-08T14:23:28.820 に答える
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.
于 2012-11-08T14:22:37.060 に答える
1

私も同様の問題を抱えていました。これはグーグルでの最初の結果であり、ここにリンクされているスクリプトのいくつかが私のmatlabをクラッシュさせました。

最後に、matlabにはガウス関数にも適合できるfit関数が組み込まれていることがわかりました。

それはそのように見えます:

>> 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)
于 2014-11-05T20:57:21.890 に答える
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')
于 2015-07-07T21:03:17.673 に答える