least square fit "lsqcurvefit" not good enough?

1 次查看(过去 30 天)
Hi All,
Trying to solve "K_a" by least square fitting an equation "func" to a dataset "backgroundImpIm". Bu when I plot them together, the fit doesn't seem good. I have tried to tweak FunctionTolerance and StepTolerance but the fit doesn't improve. Anyone have answers?
Thanks,
clc
close all
clear
background = csvread('0SM.CSV',3,0,[3,0,1603,2]);
backgroundImpIm = background(:,3);
f = background(:,1);
freq = f(1:100);
x0 = [1];
h = 5E-3;
a = 5E-5;
m_e = 9.1E-31;
q = 1.6E-19;
c = 3E8;
omega = 2*pi*freq;
k_0 = omega/c;
beta = k_0;
epsilon_real = 1;
epsilon_im = 0;
x = epsilon_im./epsilon_real;
func = @(K_a,freq)(-K_a./(tan(2*pi*freq*h.*(1 + 0.19./((K_a/60 +1) - 0.81))/c)));
%options = optimoptions(@lsqcurvefit,'FunctionTolerance',1e-100)
K_a = lsqcurvefit(func,x0,freq,backgroundImpIm(1:100))
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.
K_a = 5.6540
plot(freq,backgroundImpIm(1:100))
hold on
plot(freq,func(K_a,freq))

采纳的回答

Mathieu NOE
Mathieu NOE 2023-7-5
hello
you can get better results if you start the fit not at index 1 , but a bit above, as your first sample seems a bit off and your data lack some resolution in the lower freq range
this appears more clearly also if you plot the results with a x log spacing
also I am limited to the use of fminsearch as I don't have the optimization toolbox , but you can easily swith back to your original code
Result :
K_a = 50.0846
background = csvread('0SM.CSV',3,0,[3,0,1603,2]);
backgroundImpIm = background(:,3);
f = background(:,1);
ind = (2:100); % <= HERE , start at 2 at lowest , discard 1st sample
freq = f(ind);
x0 = [1];
h = 5E-3;
a = 5E-5;
m_e = 9.1E-31;
q = 1.6E-19;
c = 3E8;
omega = 2*pi*freq;
k_0 = omega/c;
beta = k_0;
epsilon_real = 1;
epsilon_im = 0;
x = epsilon_im./epsilon_real;
func = @(K_a,freq)(-K_a./(tan(2*pi*freq*h.*(1 + 0.19./((K_a/60 +1) - 0.81))/c)));
%options = optimoptions(@lsqcurvefit,'FunctionTolerance',1e-100)
% K_a = lsqcurvefit(func,x0,freq,backgroundImpIm(1:100))
K_a = fminsearch(@(x) norm(func(x,freq)-backgroundImpIm(ind)),x0)
semilogx(freq,backgroundImpIm(ind),'*-r',freq,func(K_a,freq),'b')
legend('raw data,','fit');
  2 个评论
Mathieu NOE
Mathieu NOE 2023-7-5
Another way to demonstrate that your fit shoud not include the first data point
background = csvread('0SM.CSV',3,0,[3,0,1603,2]);
backgroundImpIm = background(:,3);
f = background(:,1);
ind = (2:1600); % <= HERE , start at 2 at lowest , discard 1st sample
freq = f(ind);
x0 = [1];
h = 5E-3;
a = 5E-5;
m_e = 9.1E-31;
q = 1.6E-19;
c = 3E8;
omega = 2*pi*freq;
k_0 = omega/c;
beta = k_0;
epsilon_real = 1;
epsilon_im = 0;
x = epsilon_im./epsilon_real;
func = @(K_a,freq)(-K_a./(tan(2*pi*freq*h.*(1 + 0.19./((K_a/60 +1) - 0.81))/c)));
%options = optimoptions(@lsqcurvefit,'FunctionTolerance',1e-100)
% K_a = lsqcurvefit(func,x0,freq,backgroundImpIm(1:100))
K_a = fminsearch(@(x) norm(func(x,freq)-backgroundImpIm(ind)),x0)
% semilogx(freq,backgroundImpIm(ind),'*-r',freq,func(K_a,freq),'b')
semilogx(f,backgroundImpIm,'*-r',freq,func(K_a,freq),'b')
legend('raw data,','fit');

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Nonlinear Least Squares (Curve Fitting) 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by