Using fitnlm is causing my coefficients and fit to become unstable, even after a few iterations. How can I create the fit to be more stable?

27 views (last 30 days)
I am using fitnlm to fit a best fit line to a set of data in order to find three coeffiecients that are in the model function. Even after 2 or 3 interatiosn, the fit becomes unstable and the coefficients go wild. I have somewhat of an idea of what they should be i.e positive, magnitude. How to edit the fitnlm and optimset options to create the fit to be more stable. I am working with very low numbers here.
F = @(b,mu)((mu.^((2*b(2))-1)).*exp(4*b(1)*((log(mu)).^2) + b(3)));
mu is between 0 and 1
b1 is unknown
b2 is between 0 and 1
b3 is unknown but positive
ydata is of order of magnitude 1e-8

Answers (1)

Drew
Drew on 7 Feb 2024
If you are facing instability in your nonlinear regression using fitnlm, you can try to stabilize the fitting process by setting better initial guesses for your parameters and by constraining the parameter space. Since you have an idea of the expected range of your parameters, you can use this information to set bounds and initial values for the fitting algorithm. fitnlm does not directly support parameter bounds, but you can transform your problem into an optimization problem using lsqcurvefit or fmincon which do support bounds.
Here's an example of how you can use lsqcurvefit to fit your nonlinear model with bounds:
% Define your model function
F = @(b,mu) ((mu.^((2*b(2))-1)).*exp(4*b(1)*((log(mu)).^2) + b(3)));
% Define your data (mu and ydata)
mu = ...; % your mu data
ydata = ...; % your ydata
% Set initial guesses for your parameters
b0 = [0.1, 0.5, 0.1]; % Example initial guesses (b1, b2, b3)
% Set lower and upper bounds for the parameters
lb = [-Inf, 0, 0]; % Lower bounds (b1 can be anything, b2 >= 0, b3 >= 0)
ub = [Inf, 1, Inf]; % Upper bounds (b1 can be anything, b2 <= 1, b3 can be anything)
% Set options for lsqcurvefit
options = optimoptions('lsqcurvefit', 'Algorithm', 'trust-region-reflective', ...
'Display', 'iter', 'MaxIterations', 400, ...
'FunctionTolerance', 1e-9, 'StepTolerance', 1e-9);
% Perform the fitting
[beta,resnorm,residual,exitflag,output] = lsqcurvefit(F, b0, mu, ydata, lb, ub, options);
% Display the results
disp('Fitted parameters:');
disp(beta);
In the above code:
  • b0 is the vector of initial guesses for the parameters b1, b2, and b3.
  • lb and ub are the vectors of lower and upper bounds for the parameters, respectively.
  • options is the set of options for the lsqcurvefit function. You can adjust the MaxIterations, FunctionTolerance, and StepTolerance to improve stability and convergence.
  • lsqcurvefit is used to perform the fitting within the specified bounds.
Remember to replace the ... with your actual data for mu and ydata. You can further tune the options to suit your specific problem. If lsqcurvefit does not provide satisfactory results, you can also try using fmincon, which offers even more flexibility in terms of defining constraints and customizing the optimization process.
If this answer helps you, please remember to accept the answer.
  1 Comment
Image Analyst
Image Analyst on 7 Feb 2024
@Joshua what do you mean by "Even after 2 or 3 interatiosn"? Are you updating the coefficient guesses with the result and then running it again to get updated coefficients?
Attach your data so we can try it.

Sign in to comment.

Categories

Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!