Curve fitting using lsqcurvefit

3 visualizzazioni (ultimi 30 giorni)
Hi currently i am trying to fit my measured data to a model. I have followed this example https://au.mathworks.com/matlabcentral/answers/478835-lsqcurvefit-initial-values-stays-the-same#answer_391692 . I am also attaching the code from the example. i want to know what parameters do i need to change to fit my measured data to the model and extract the values from it. Any help is appreicated. I am also attaching my data.
T = readtable('cole.xlsx');
x = T{:,1}; %freq
y = T{:,2}; %real
%Transpose
freq = x.';
e_real = y.';
options = optimset('MaxFunEvals',10000);
options=optimset(options,'MaxIter',10000);
guess = 4.5;
UB = guess + 1;
LB = guess - 1;
lb = [];
ub = [];
x0 = [6,guess,2.5,0.6,0.09];
x = lsqcurvefit(@flsq,x0,freq,e_real,lb,ub,options)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x =
4.8828 - 0.0885i 5.0695 - 0.1843i 1.2278 -92.9851i -1.0163 - 9.3958i -0.0126 - 0.0739i
e_f = x(1);
e_del = x(2)*1e2;
tau1 = x(3)*1e-12;
alf1 = x(4);
sig = x(5);
yfit = real(flsq(x,freq));
%plot e_real against freq
plot(freq,e_real,'k.',freq,yfit,'b-')
legend('Data','Fitted')
title('Data and Fitted Curve')
function y = flsq(x,freq)
x(3)=x(3)*1e-12;
y = x(1) + (x(2)-x(1))./(1 + ((1j*2*pi.*freq*x(3)).^(1-x(4))))+x(5)./(1j*2*pi*freq*8.854e-12);
end
  7 Commenti
Walter Roberson
Walter Roberson il 8 Mar 2022
lsqcurvefit() and fmincon() both do iterative automatic ways to update values to provide best fits.
Walter Roberson
Walter Roberson il 8 Mar 2022
If this has physical significance, then are there any constraints on the parameters of the model? Any that have to be real-valued? Any that have to be positive?

Accedi per commentare.

Risposta accettata

Walter Roberson
Walter Roberson il 7 Mar 2022
You can get a better fit by either telling lsqcurvefit() a better starting point, or by using a different optimizer.
But... remember that "better fit" mathematically does not necessarily mean "follows the curve more closely"
format long g
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/917874/cole.xlsx';
T = readtable(filename);
x = T{:,1}; %freq
y = T{:,2}; %real
%Transpose
freq = x.';
e_real = y.';
options = optimset('MaxFunEvals',10000);
options=optimset(options,'MaxIter',10000);
guess = 4.5;
UB = guess + 1;
LB = guess - 1;
lb = [];
ub = [];
x0 = [6,guess,2.5,0.6,0.09];
[x, fval] = lsqcurvefit(@flsq,x0,freq,e_real,lb,ub,options)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x =
4.88278441116842 - 0.0884918454761463i 5.06952748610154 - 0.184297340006755i 1.22778921925455 - 92.9851457164006i -1.01629693596011 - 9.39581846397004i -0.0126281060006031 - 0.073855580530327i
fval =
2.50307155416643
e_f = x(1);
e_del = x(2)*1e2;
tau1 = x(3)*1e-12;
alf1 = x(4);
sig = x(5);
yfit = real(flsq(x,freq));
%plot e_real against freq
plot(freq,e_real,'k.',freq,yfit,'b-')
legend('Data','Fitted')
title('Data and Fitted Curve -- lsqcurvefit')
Residue = @(x) norm(flsq(x,freq) - e_real);
options = optimset('MaxFunEvals', 1E5);
options = optimset(options, 'MaxIter', 1E5);
options = optimset(options, 'Display', 'none');
for K = 2 : 50
guess = x0 + randn(1,5);
[x(K,:), fval(K)] = fmincon(Residue, guess, [], [], [], [], [], [], [], options);
end
[~, idx] = min(abs(fval));
disp('original -- lsqcurvefit')
original -- lsqcurvefit
disp([fval(1), x(1,:)])
Columns 1 through 4 2.50307155416643 + 0i 4.88278441116842 - 0.0884918454761463i 5.06952748610154 - 0.184297340006755i 1.22778921925455 - 92.9851457164006i Columns 5 through 6 -1.01629693596011 - 9.39581846397004i -0.0126281060006031 - 0.073855580530327i
disp('best found in several tries of fmincon')
best found in several tries of fmincon
disp([fval(idx), x(idx,:)])
1.82932684842456 4.25784166349341 -638714.651612716 5141.92675473731 -3.02543789002661 0.000633983073703346
e_f = x(idx,1);
e_del = x(idx,2)*1e2;
tau1 = x(idx,3)*1e-12;
alf1 = x(idx,4);
sig = x(idx,5);
yfit = real(flsq(x(idx,:),freq));
%plot e_real against freq
plot(freq, e_real, 'k.', freq, yfit, 'b-')
legend('Data','Fitted')
title('Data and Fitted Curve -- fmincon')
function y = flsq(x,freq)
x(3)=x(3)*1e-12;
y = x(1) + (x(2)-x(1))./(1 + ((1j*2*pi.*freq*x(3)).^(1-x(4))))+x(5)./(1j*2*pi*freq*8.854e-12);
end
  5 Commenti
Walter Roberson
Walter Roberson il 8 Mar 2022
ga() is another iterative means for improving fit, but it does not help much. In one of my earlier runs, I got better than the below display, but it was still worse than fmincon() so I am not going to bother to show it.
format long g
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/917874/cole.xlsx';
T = readtable(filename);
x = T{:,1}; %freq
y = T{:,2}; %real
%Transpose
freq = x.';
e_real = y.';
options = optimset('MaxFunEvals',10000);
options=optimset(options,'MaxIter',10000);
guess = 4.5;
UB = guess + 1;
LB = guess - 1;
lb = [];
ub = [];
x0 = [6,guess,2.5,0.6,0.09];
[x, fval] = lsqcurvefit(@flsq,x0,freq,e_real,lb,ub,options)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x =
4.88278441116842 - 0.0884918454761463i 5.06952748610154 - 0.184297340006755i 1.22778921925455 - 92.9851457164006i -1.01629693596011 - 9.39581846397004i -0.0126281060006031 - 0.073855580530327i
fval =
2.50307155416643
e_f = x(1);
e_del = x(2)*1e2;
tau1 = x(3)*1e-12;
alf1 = x(4);
sig = x(5);
yfit = real(flsq(x,freq));
%plot e_real against freq
plot(freq,e_real,'k.',freq,yfit,'b-')
legend('Data','Fitted')
title('Data and Fitted Curve -- lsqcurvefit')
Residue = @(x) norm(flsq(x,freq) - e_real);
options = optimset('MaxFunEvals', 1E5);
options = optimset(options, 'MaxIter', 1E5);
options = optimset(options, 'Display', 'none');
tic
for K = 2 : 200
[x(K,:), fval(K)] = ga(Residue, 5, [], [], [], [], [], [], [], options);
end
toc
Elapsed time is 38.143890 seconds.
[~, idx] = min(abs(fval));
disp('original -- lsqcurvefit')
original -- lsqcurvefit
disp([fval(1), x(1,:)])
Columns 1 through 4 2.50307155416643 + 0i 4.88278441116842 - 0.0884918454761463i 5.06952748610154 - 0.184297340006755i 1.22778921925455 - 92.9851457164006i Columns 5 through 6 -1.01629693596011 - 9.39581846397004i -0.0126281060006031 - 0.073855580530327i
disp('best found in several tries of ga')
best found in several tries of ga
disp([fval(idx), x(idx,:)])
2.0261188723609 4.23046723004257 3.35326686725843 153.911545598562 -0.327809240216987 0.0453959038185919
e_f = x(idx,1);
e_del = x(idx,2)*1e2;
tau1 = x(idx,3)*1e-12;
alf1 = x(idx,4);
sig = x(idx,5);
yfit = real(flsq(x(idx,:),freq));
%plot e_real against freq
plot(freq, e_real, 'k.', freq, yfit, 'b-')
legend('Data','Fitted')
title('Data and Fitted Curve -- ga')
function y = flsq(x,freq)
x(3)=x(3)*1e-12;
y = x(1) + (x(2)-x(1))./(1 + ((1j*2*pi.*freq*x(3)).^(1-x(4))))+x(5)./(1j*2*pi*freq*8.854e-12);
end
Kabit Kishore
Kabit Kishore il 8 Mar 2022
Thank you @Walter Roberson. Much appreciated.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Get Started with Optimization Toolbox in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by