least square fit "lsqcurvefit" not good enough?

2 views (last 30 days)
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))

Accepted Answer

Mathieu NOE
Mathieu NOE on 5 Jul 2023
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 Comments
Mathieu NOE
Mathieu NOE on 5 Jul 2023
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');

Sign in to comment.

More Answers (0)

Categories

Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!