Lsqcurvefit / Lsqnonlin to electrical model. Bad fit problem

3 views (last 30 days)
Pedro Dias
Pedro Dias on 26 May 2018
Answered: Alex Sha on 12 Oct 2019
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.

Accepted Answer

Ameer Hamza
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.
  2 Comments
Ameer Hamza
Ameer Hamza on 26 May 2018
I could not exactly figure out the issue but I think that the problem might be happening because your objective function produces complex values. To avoid complex values, it is better to create two separate real-values objective functions for real part and the complex part of the objective function. And then add them together to create a single real-valued objective function. In that case, you might need to use fmincon(). You can refer to my comment on another question dealing with complex values functions problem. It might help you to figure out the issue. Note in that comment I used symbolic toolbox to separate the real and imaginary part of the objective function, you might want to avoid that and separate the real and imaginary parts on a paper first and then use that method.

Sign in to comment.

More Answers (1)

Alex Sha
Alex Sha on 12 Oct 2019
Have a try with the results as below:
Parameter Best Estimate
-------------------- -------------
x1 30060.9228551244
x2 361360.209800656
x3 -7.86513179934713E-10

Community Treasure Hunt

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

Start Hunting!