nonlinear curve fit: how to optimize?

I have a custom model which I want to fit to my data. The model works manually, i.e. when I know approximately the fit paramaters. But now I need to optimize this solution, so that it works for similar curves (the one that I will give here is only a perfect noise free data), so please consider this problem in a general case.
The fit model is:
function [x,errorfitted] = fit1d_ABCpara(q,psd1d)
x0 = [2e-10,6e-4, 2.4];
lb = [1e-11, 3e-04,2];
ub = [Inf,3e-3,3];
fun = @(x,xdata)0.5e14 * x(1) .* (1+((x(2).*q).^2)).^-((x(3)/2));
[x,errorfitted] = lsqcurvefit(fun,x0,q,psd1d,lb,ub);
This is the curve for original data points:
This is the fit I get from the code above for my data in log-log space:
But this is what I want and I could get the fit by manually changing my fit parameters:
How can I optimize my 3 parameters?
Thanks in advance!

6 Comments

Try what happens if you multiply your ydata and your function by a factor of, say, 1e14.
Best wishes
Torsten.
Thanks a lot! It helped a little bit, but didn't fix the problem. Now, I can get some kind of fit, but it's not optimizing! I edited the question and now added further explanation.
To get the curve you want, you will have to introduce different weights for different data points. Deviances between data and model for data with high x-values must be weighted more than deviances between data and model for data with low x-values.
Use lsqnonlin instead of lsqcurvefit, define the F_i as
F_i = (y_func(xdata(i))-ydata(i))/ydata(i)
and see what you get.
Best wishes
Torsten.
Dear Torsen, Thank you very much! I got the idea but sorry to say that I can't implement it! I didn't get where to apply F_i? (F_i is the weight, isn't it?)
Could you please give me some step-wise structure how to proceed and when/where to apply the weighting in the lsqnonlin? Thanks!
function [x,errorfitted] = fit1d_ABCpara(q,psd1d)
x0 = [2e-10,6e-4, 2.4];
lb = [1e-11, 3e-04,2];
ub = [Inf,3e-3,3];
fun=@(x)(0.5 * x(1) .* (1+((x(2).*q).^2)).^-((x(3)/2))-psd1d)./psd1d;
[x,errorfitted]=lsqnonlin(fun,x0,lb,ub);
Best wishes
Torsten.
Dear Torsen, Thank you so much! Weighting solved the problem!! I would really appreciate if you could rewrite your comment as a separate answer, so that I can accept your answer and close this trend. Thanks for the help again!

Sign in to comment.

 Accepted Answer

To get the curve you want, you will have to introduce different weights for different data points. Deviances between data and model for data with high x-values must be weighted more than deviances between data and model for data with low x-values.
Here is a suggestion on how to modify your code:
function [x,errorfitted] = fit1d_ABCpara(q,psd1d)
x0 = [2e-10,6e-4, 2.4];
lb = [1e-11, 3e-04,2];
ub = [Inf,3e-3,3];
fun=@(x)(0.5 * x(1) .* (1+((x(2).*q).^2)).^-((x(3)/2))-psd1d)./psd1d;
[x,errorfitted]=lsqnonlin(fun,x0,lb,ub);
Best wishes
Torsten.
P.S. Nice to hear that it worked :-)

More Answers (0)

Community Treasure Hunt

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

Start Hunting!