Verfasst am: 17.11.2014, 20:24
Titel: Fit beschleunigen
Liebe Matlab-Experten,
Ich kämpfe mit folgendem Problem: Ich habe 4 Stapel von MR-Bildern, die zur verschiedenen Echozeiten "TE" gemessen wurden und exponentiell abfallende Intensitäten "I" zeigen. Ich versuche nun jedes Element meiner 4 Bilder-Matrizen mit einer speziellen exponentiellen Funktion zu fitten, einen der Fit-Koeffizienten zu extrahieren und in eine neue Matrix (derselben Größe wie die ursprünglichen Bilderstapel) zu schreiben.
Nachdem meine Matrizen relativ groß sind (256 x 256 x 40), dauert die Prozedur ewig (hab nach etwa 1 h Wartezeit den Prozess abgebrochen). Wie könnte ich Code ähnlich dem u.a. Beispiel beschleunigen (auf meinem nicht allzu modernen Rechner derzeit ~122 s)?
% Perform fit tic for i = 1:size(I1,1) for j = 1:size(I1,2) for k = 1:size(I1,3)
y = [I1(1,j,k) I2(i,j,k) I3(i,j,k) I4(i,j,k)];
y = sort(y,'descend'); % Real data show exponential decrease [xFit,yFit] = prepareCurveData(x,y);
% Define fit (T2_star is variable of interest)
ft = fittype('I0*exp(-TE/T2_star)','independent','TE',...
'dependent','I');
opts = fitoptions('Method','NonLinearLeastSquares');
opts.Display = 'Off';
% Start points for coefficients
opts.StartPoint = [y(1)0.5];
[fitresult,gof] = fit(xFit,yFit,ft,opts);
% Extract coefficient of interest
coeffs = coeffvalues(fitresult);
T2_star(i,j,k) = coeffs(2);
end end end toc
ich würde es mal mit lsqcurvefit versuchen. Die vorliegende Funktion wird bei jedem Durchlauf erstmal die Funktion analysieren müssen, was alleine schon dauern wird. Das sollte schon deutlich schneller gehen.
Wenn die Bilder nacheinander aufgenommen sind, könnte man zudem versuchen, die Koeffizienten des einen Bildes als Startwert für das nächste zu nehmen.
Ein weiterer Gedanke: man kann die Fit-Gleichung auf beiden Seiten logarithmieren und so ein lineares Gleichungssystem daraus machen, was sich sehr schnell lösen lassen sollte. Man muss sich allerdings darüber im klaren sein, dass die Abweichungen dabei mittransformiert wurden, was zu leicht anderen Ergebnissen führt. Wenn man das zurückrechnet, wird nämlich quasi der relative Fehler minimiert, nicht der absolute. Es liegt an dir zu entscheiden, ob das nicht akzeptabel, egal, oder vielleicht sogar hilfreich ist.
Vielen Dank für den Vorschlag. Ich hab jetzt versucht, lsqcurvefit anstelle von fit zu verwenden. Mit folgendem Code läuft der Fit nun in ~15s durch:
Code:
tic
F = @(a,TE)a(1)*exp(-TE/a(2)); % a(1) = I0; a(2) = T2_star; for i = 1:length(I1)
y = [I1(i) I2(i) I3(i) I4(i)];
y = sort(y,'descend'); % Real data show exponential decrease
a0 = [y(1)3];
opts = optimset('Display','off');
a(i,:) = lsqcurvefit(F,a0,TE,y,[],[],opts);
end toc
Wie Du siehst, habe ich auch die Eingangs-Matrizen in einen Spaltenvektor geschrieben, um keine 3-fach Schleife laufen lassen zu müssen. Liege ich recht in der Annahme, dass auch das der Beschleunigung dient?
Danke nochmals für die Hilfe,
Robert
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.