Azzera filtri
Azzera filtri

Is there an appropriate fitting methods for data that as orders of magnitude differences

34 visualizzazioni (ultimi 30 giorni)
Hi I want to fit my data to a nonlinear equation that I have. This is to extract the equation parameters. I tried to use lsqcurvefit but didn't got very good results. The problem is that the data spans over money orders of magnitudes, from ~1e-10 to ~1 (diode IV curve of both forward and reverse bias). I suspect it gives more weight to the larger values and therefore doesn't fit well at the other parts. Is there more appropriate fitting methods or options that can help in this situation?Thanks
  5 Commenti

Accedi per commentare.

Risposte (1)

John D'Errico
John D'Errico il 3 Feb 2022
Modificato: John D'Errico il 3 Feb 2022
You do NOT want to use a simple least squares on suh a problem. What will happen is the points that are very large will dominate the fit. Think about it. You have two numbers, one is one the order of 1e-10. Your other data point is around 1.
Then what would an error of 1e-2 mean in context of the second point? It seems pretty close.
But how about that really tiny point? An error of 1e-2, on a point at 1e-10 is HUGE.
So what do you do? This is almost always the case where proportional error is what makes sense anyway. The way to deal with that is to log your data. That is, take the logs of all those y values. Now any errors on each point are treated as equally important.
Implicitly, this assumes your noise is a proportional, lognormally distributed noise. And much of the time, this is exactly what you wanted. In terms of your model, this also often works out well. For example, suppose this is my data:
x = 1:10;
y = exp(2.3*x)*17.*lognrnd(0,1,[1 10]) % that is pretty large noise in context!
y = 1×10
1.0e+11 * 0.0000 0.0000 0.0000 0.0000 0.0001 0.0001 0.0057 0.0092 0.0633 5.5667
plot(x,y,'o')
As you can see, the plot is pretty much useless to visualize the data. But a semi-logy plot works quite well.
semilogy(x,y,'o')
We can fit the data simply enough. I'll use a natural log.
ylog = log(y);
But what happens when we log the equation a*exp(b*x)? We will get log(a) + b*x. And now we can use polyfit to fit the data.
coef = polyfit(x,ylog,1)
coef = 1×2
2.3338 2.7103
a = exp(coef(2))
a = 15.0342
b = coef(1)
b = 2.3338
And those coeffcients are actually pretty close to the original values. Again, remember the noise was actually pretty large.
semilogy(x,y,'bo')
hold on
semilogy(x,a*exp(b*x),'r-')
If the model cannot be logged as easily (so you have a sum of terms) you can still use a nonlinear least squares. Just be careful and do so on the logged data.

Categorie

Scopri di più su Get Started with Curve Fitting 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