Lsqcurvefit / Lsqnonlin to electrical model. Bad fit problem
3 views (last 30 days)
I have experimental data (Impedance (ohms) and frequency (Hz)) from a given material. From this experimental data, I am trying to build an electrical model that explains the electrical behaviour of the material. This electrical model contains 3 Parameters: two resistors and one capacitor whose values I have "closely" approximated and plotted. I wanted to use a least square curve fit in order to find better values that fit my model to my real data. The fact is that the function is giving me way worse results than my calculated values. I think I'm messing up the x0 value (since I don't properly understand what are the initial points that the function requires).
Here is the code:
%% My initial Parameters
R1 = 2800;
R2 = Zabs(1)-R1; %Zabs is a vector with experimental data
fc = 10^(2.5);
C = 1/(2*pi*fc*R2);
w = 2*pi*frequencies';
Zc = -1./(1i*C.*w);
myModel = R1 + (((-1./(1i*C.*w))*R2)./((-1./(1i*C.*w))+R2)); %The following calculates the model with my input values
%% Trying to perform optimization
xdata = frequencies; %experimental data
ydata = Zabs; %experimental data
fun = @(x) x(1) + (((-1./(1i*x(3).*w))*x(2))./((-1./(1i*x(3).*w))+x(2)));
x0 = [2000; 20000; 10^-7];
options.Algorithm = 'levenberg-marquardt';
[x,resnorm,residual,exitflag,output] = lsqnonlin(fun,x0,,,options)
The fact is that the function gives me worse values and that do not have real-life meaning. I also tried with lsqcurvefit but I was also not successful.
If you have any tips I would be for ever grateful :). Thank you in advance.
Ameer Hamza on 26 May 2018
You are not defining the loss function properly, therefore lsqnonlin() is not able to provide correct minimum. Try to define it like this
fun = @(x) x(1) + (((-1./(1i*x(3).*xdata))*x(2))./((-1./(1i*x(3).*xdata))+x(2))) - ydata;
Also, I would suggest using lsqcurvefit() for such problems since it provides an easy interface for defining the fitting function. For example, the following will work
fun = @(x, xData) x(1) + (((-1./(1i*x(3).*xData))*x(2))./((-1./(1i*x(3).*xData))+x(2)));
solution = lsqcurvefit(fun, x0, xdata, ydata)
As far as x0 is concerned, it is the initial guess for the values of R1, R2 and C. These numerical algorithm needs a starting point to start estimating the correct values. If you still face some problem, then attach a sample dataset and your code so that it will be easy to spot error.