2012-11-08 17 views
8

Mam zestaw danych częstotliwości ze szczytami, do których muszę dopasować krzywą Gaussa, a następnie uzyskać maksymalną połowę maksymalnej szerokości od. Część FWHM, którą mogę zrobić, mam już kod, ale mam problem z wpisaniem kodu pasującego do Gaussa.Jak dopasować Gaussa do danych w Matlab/oktawę?

Czy ktoś wie o funkcjach, które zrobią to za mnie lub będą w stanie wskazać mi właściwy kierunek? (Mogę wykonać najmniejsze kwadraty pasujące do linii i wielomianów, ale nie mogę go uruchomić dla gaussów)

Również byłoby pomocne, gdyby był zgodny zarówno z Octave, jak i Matlabem, ponieważ mam w tej chwili Octave ale don dostęp do Matlaba do następnego tygodnia.

Każda pomoc będzie bardzo ceniona!

+0

Czy masz pojedynczy pik (tylko 1 Gaussa)? Lub wielokrotne szczyty (wielokrotne, zachodzące na siebie guassian)? –

+0

To tylko jeden szczyt na plik. – user1806676

+1

Jeśli jest to tylko jeden pik, weź średnią i standardową liczbę liczb, która określa normalną dystrybucję próbki. Czy próbowałeś tego? W przeciwnym razie, jeśli masz przybornik statystyk, użyj funkcji normfit(). – Justin

Odpowiedz

19

zamontowanie jednego 1D bezpośrednio Gaussa jest nieliniowa problemem montażu. Znajdziesz gotowe realizacje here lub here lub here for 2D lub here (jeśli masz zestaw narzędzi statystycznych) (słyszałeś od Google? :)

W każdym razie, nie może być prostsze rozwiązanie. Jeśli wiesz na pewno dane y będzie dobrze opisane przez Gaussa, i jest dość dobrze rozmieszczone na całej swojej x -range można zlinearyzować problemu (są to równania, a nie sprawozdanie)

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

, w którym dokonano podstawieniaTeraz rozwiązanie dla układu liniowego Ax=b z (są oświadczenia 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;      

Wektor x znalazłeś ten sposób będzie równa

x == [P Q R] 

które następnie trzeba odwrócić inżynier, aby znaleźć myśli | j, a średnia odchylenie Ď:

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

które można kontrole krzyżowe z x(3) == R (nie powinno być tylko małe różnice).

+0

Dziękuję bardzo. Byłem w stanie znaleźć tylko pierwszy z linków za pośrednictwem google i to nie działało z moimi danymi, drugi jednak działa. Dziękuję również za wyjaśnienie/równania. : D – user1806676

+0

@ user1806676: Nie próbowałem linearyzowanego podejścia, ale przynajmniej matematyka jest poprawna. Powinieneś tam eksperymentować i sprawdzać poprawność. –

+0

Próbowano zlinearyzowane podejście. Działa dobrze. –

2

Być może ma to coś, czego szukasz? Nie jestem pewien kompatybilności: http://www.mathworks.com/matlabcentral/fileexchange/11733-gaussian-curve-fit

Z dokumentacji:

[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. 
+0

Lepiej nadaje się jako komentarz, nie? –

+0

Podczas gdy ten link może odpowiedzieć na pytanie, lepiej umieścić w nim istotne części odpowiedzi i podać link do odsyłacza. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. - [Z recenzji] (/ recenzja/niskiej jakości-posts/13114204) –

+1

@ScottHoltzman Dzięki za opinie, dołączyłem odpowiedni opis. –

1

miałem podobny problem. był to pierwszy wynik w Google, a niektóre ze skradzionych skryptów spowodowały awarię mojego matlaba.

Wreszcie znalazłem here, że Matlab ma wbudowaną funkcję dopasowania, która może pasować również do Gaussians.

to wyglądać tak:

>> 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) 
+1

Pamiętaj, że 'fit' nie jest wbudowany; to część zestawu narzędzi do dopasowywania krzywych –

0

okazało się, że MATLAB "fit" funkcja była powolna i używane "lsqcurvefit" z funkcją Gaussa inline.Ma to na celu dopasowanie funkcji Gaussa, jeśli chcesz dopasować dane do rozkładu normalnego, użyj "normfit".

Sprawdź to

% % 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') 
Powiązane problemy