Reputation: 97
I have an array of data which, when plotted, looks wave.I need to determine the best fitting (linear and exponential) for these data and find the value of lambda 1,lambda 2 and tau in this function ((L=lambda 1*t+lambda 2*(1-exp(-t/tau). Some friends advice my to use((polyfit)) but I couldn't understanding the applicability of the command after reading the help file and searching in Google. Any help would be greatly appreciated. I will be grateful to you.
my attempt was as following:
%% data 1
file1 = dlmread('outfile_rate_add0.5_depGDP_GTP0.1.txt');
t1 = file1 (:,1);
d1 = file1 (:,2);
% Then call plot()
plot(t1, d1, 'b*-', 'LineWidth', 2, 'MarkerSize', 15);
% Then get a fit
coeffs1 = polyfit(t1, d1, 1)
% Get fitted values
fittedX1 = linspace(min(t1), max(t1), 1001);
fittedY1 = polyval(coeffs1, fittedX1);
% Plot the fitted line
hold on;
plot(fittedX1, fittedY1, 'r-', 'LineWidth', 3);
hold off
hleg = legend('Data','lam*t + c','Location','northEast');
grid on;
title('Line fitting ','fontsize',13,'fontweight','b','color','k')
xlabel('Time ms','fontsize',13,'fontweight','b','color','k');
ylabel('Averge length','fontsize',13,'fontweight','b','color','k');
Upvotes: 1
Views: 1458
Reputation: 4311
If you have access to the Optimization toolbox, you can formulate this problem, such that it can be solved with fminsearch(). Here is how it can be done: The parameter to optimize (lambda1, lambda2 and tau) are stored in one parameter-vector, which will be used by the fit_function, which is the function that you proposed.
function main
% some data
t = sort(rand(50,1)*10);
lambda1 = 0.5;
lambda2 = 1;
tau = 2.0;
par = [lambda1, lambda2, tau];
y = fit_function(t, par) + (rand(size(t))-0.5)*0.2;
par0 = [1,2,3]; % initial guess
par_fit = fminsearch(@objFun, par0);
% nested objective function, this one will be minimized
function e = objFun(par)
yfitted = fit_function(t, par);
e = sum((yfitted-y).^2);
end
% plotting some results
figure
plot(t,fit_function(t,par),'k-')
hold on
plot(t,y,'ko')
plot(t,fit_function(t,par_fit),'rx-')
legend('original','noisy','optimization')
par
par_fit
end
function yfitted = fit_function(t, par)
% y = lambda1*t + lambda2*(1-exp(-t/tau))
lambda1 = par(1);
lambda2 = par(2);
tau = par(3);
yfitted = lambda1*t + lambda2*(1-exp(-t/tau));
end
The result looks like this: The parameters i used for the unnoisy data and the parameters which came out of the optimization are like this
par =
0.5000 1.0000 2.0000
par_fit =
0.4949 1.0433 2.1792
Best, Nras.
Update for your use-case
function main
%% ----- DATA -----
file1 = dlmread('outfile_rate_add0.5_depGDP_GTP0.1.txt');
t = file1(:,1);
y = file1(:,2);
%% ----- OPTIMIZATION -----
par0 = [1,2,3]; % initial guess <--- Here you have to make a good guess
par_fit = fminsearch(@objFun, par0);
%% ----- OBJECTIVE FUNCTION (will be minimized) -----
function e = objFun(par)
yfitted = fit_function(t, par); % result of model function with current parameter
e = sum((yfitted-y).^2); % minimize squared distance between model and observation
end
%% ----- VSIUALIZING RESULTS ----- %
figure
plot(t,y,'ko')
hold on
plot(t,fit_function(t,par_fit),'rx-')
legend('original','optimization')
end
%% ----- MODEL FUNCTION ----- %
function yfitted = fit_function(t, par)
% the model function reads as: y = lambda1*t + lambda2*(1-exp(-t/tau))
lambda1 = par(1);
lambda2 = par(2);
tau = par(3);
yfitted = lambda1*t + lambda2*(1-exp(-t/tau));
end
Upvotes: 3