set parameters of nlinfit function
Show older comments
Hi
I’m beginner in MATLAB. I have some experimental points and I used nlinfit function to solve my problem and find the best LS curve fitting result. When I use the nlinfit, it pass MSE= 1.5873e+07 and the result is not very good. I attached my data, please check output of nlinfit function to see the output.
Note: I want to find the best curve fitting based on spherical model, soI use: fun = @(p,X) p(1)*(1.5*X/p(2)-0.5*(X/p(2)).^3);
How I should set function’s arguments to reach the best results? Please help me to solve my problem.
Best regards
Accepted Answer
More Answers (1)
Mani Ahmadian
on 2 Oct 2014
Edited: Mani Ahmadian
on 2 Oct 2014
0 votes
12 Comments
Star Strider
on 2 Oct 2014
I would estimate it only for h <= a0, since that estimates c0 as well.
Defining the parameters as:
% b(1) = c0, b(2) = a0
gam2 = @(b,h) b(1).*(1.5*h./b(2) - 0.5*(h./b(2)).^3);
with the function ‘gam2’ being the function you would use as your objective function for nlinfit.
Mani Ahmadian
on 2 Oct 2014
Star Strider
on 2 Oct 2014
I continue to suggest that you fit only the values for h <= a0 because of the discontinuity at h = a0. The fitting functions must be continuously differentiable, since nlinfit uses a Levenberg-Marquardt gradient descent algorithm, and they are not at such discontinuities. You can estimate c0=b(1) as well as b(2)=a0 on the continuous portion of the curve.
Mani Ahmadian
on 13 Oct 2014
Star Strider
on 13 Oct 2014
You cannot fit a continuous and continuously-differentiable function across a discontinuity such as you describe. You have to fit each region of the discontinuous function separately, possibly with a different function describing each continuous region.
That is just how the maths work. It is beyond my power to change them!
Mani Ahmadian
on 13 Oct 2014
Star Strider
on 13 Oct 2014
It is best to fit all of the data at once.
You set a threshold of h<=a0 but haven’t defined what ‘a0’ is. Fitting it then is simply a matter of using only those (h,gamma) data.
What is ‘a0’?
Mani Ahmadian
on 13 Oct 2014
Mani Ahmadian
on 13 Oct 2014
Star Strider
on 14 Oct 2014
Edited: Star Strider
on 14 Oct 2014
Truncating the x and y values so that x<=a0 for successive values of ‘a0’, both parameter values converge to essentially stable values, although those values are a function of ‘a0’.
The following code (for the spherical model) loops, calculating ‘a0’ at each step and truncating the (x,y) arrays to accommodate x<=a0 in the subsequent step, estimating the parameters with the new data set, and repeating for 25 iterations:
fidi = fopen('nlinfit_Data.txt');
D = textscan(fidi, '%f %f', 'HeaderLines',1);
x = D{1};
y = D{2};
% b(1) = c0, b(2) = a0
gam2 = @(b,h) b(1).*(1.5*h./b(2) - 0.5*(h./b(2)).^3);
B(:,1) = [1E+4; x(length(x))];
Lxy(1) = length(x);
for k1 = 2:25
B(:,k1) = nlinfit(x(x<=(B(2,k1-1))),y(x<=(B(2,k1-1))),gam2, B(:,k1-1));
Lxy(k1) = length(x(x<=(B(2,k1-1))));
end
figure(1)
semilogy(1:25, B(1,:), 1:25, B(2,:))
legend('c_0', 'a_0')
xlabel('Iteration #')
ylabel('Parameter Value')
The ‘B’ matrix contains the parameter values for each iteration, and the ‘Lxy’ vector (length of the data vectors at each step) demonstrates that the data are indeed being truncated. The preceding parameter values are used as the initial estimates for the subsequent estimation. The results are yours to interpret.
To plot the estimated y-values for a particular index of parameter values, you can use this code:
Lidx = 9; % Choose Parameter Set By Index
xv = linspace(min(x),x(Lidx)); % Create x-Vector
yfit = gam2(B(:,Lidx), xv); % Calculate Estimated Fit
figure(2)
plot(x(1:Lidx), y(1:Lidx), '+')
hold on
plot(xv, yfit, '-r')
hold off
grid
xlabel('\ith\rm')
ylabel('\gamma_{2}(\ith\rm)')
Have fun with it!
Mani Ahmadian
on 15 Oct 2014
Star Strider
on 15 Oct 2014
My pleasure!
You too!
Categories
Find more on Nonlinear Regression 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!



