Using lsqnonlin with a joint boundary for multiple parameters

7 vues (au cours des 30 derniers jours)
Jessica Vidmark
Jessica Vidmark le 13 Mai 2020
Commenté : Walter Roberson le 22 Mai 2020
Hi MATLAB community,
My question is similar to this one, but I still cannot figure out how to apply that solution (if even possible) to my problem.
I am using lsqnonlin to find the best fit of a function with specific parameters to a dataset ("data"). This is working, but after visual inspection of my results, I would now like to force the difference between the sum of three of the parameters (exponential amplitude 1, exponential amplitude 2, and the DC offset), and the first data point, to be within +/- the standard deviation of the data - perhaps easier to understand in this mathematical equation:
abs(expAmp1+expAmp2+DCoffs-data(1)) <= std(data)
Hence, I would like to add this into my code so that the fit results don't violate this boundary condition, but I have yet to figure out how to. Let's assume for simplicity's sake that I am fitting my data to only two exponential decays and a DC offset, with an objective function like so:
function diff = objFunc(param,time,data)
%param(1)=exponential1 amplitude
%param(2)=exponential1 time constant
%param(3)=exponential2 amplitude
%param(4)=exponential2 time constant
%param(5)=DC offset
fitFunc=param(1)*exp(param(2)*time)+param(3)*exp(param(4)*time)+param(5); %Function composed of two exponentials and one DC offset (horizontal line)
diff=fitFunc-data; %Fit function to data by making diff as close to 0 as possible
end
I can make boundary conditions for the individual parameters, but I cannot figure out how/where I could include a boundary condition that combines three of the parameters, similar to this:
abs(param(1)+param(3)+param(5)-data(1)) <= std(data)
I've spent hours searching MATLAB Answers, reading the lsqnonlin documentation, and trying to logically come up with a solution, but I just can't figure it out on my own.
Your help would be so greatly appreciated! Thank you!
  3 commentaires
Walter Roberson
Walter Roberson le 21 Mai 2020
I cannot figure out how/where I could include a boundary condition that combines three of the parameters
That cannot be done with lsqnonlin.
Jessica Vidmark
Jessica Vidmark le 21 Mai 2020
@Walter,
Shoot, OK. Thanks for letting me know. Do you know if it could work with lsqlin? I might be able to use a linear solver. Or can you think of any other workaround? Combining the three variables into another one that has these boundaries, or something of the sort? Or using another MATLAB function for this fit?

Connectez-vous pour commenter.

Réponses (1)

Walter Roberson
Walter Roberson le 21 Mai 2020
lsqnonlin() relies upon a function returning a vector of values, and internally it minimizes the sum of squares of what is returned. The algorithm involved permits static upper and lower bounds, but no linear or nonlinear bounds.
What you need to do is build another layer,
LSQ = @(param) sum(objFunc(param, time, data).^2)
Now pass LSQ to fmincon(). As you know your data ahead of time, you can add in a pair of linear constraints
sd = std(data);
A = [ 1 0 1 0 1;
-1 0 -1 0 -1];
b = [sd+data(1);
sd-data(1)];
You would use Aeq = [], beq = [], use appropriate lb and ub, and would use [] for the nonlinear constraints.
As you extend your constraints you might find that you need to add nonlinear constraints. The search will be more efficient if you can avoid nonlinear constraints by rewriting them as linear inequalities or linear equalities.
  1 commentaire
Walter Roberson
Walter Roberson le 22 Mai 2020
fmincon is a local minimizer and for this kind of work it would be common for it to get stuck. Running a few times with different initial values can be advised. if you have the Global Optimization Toolbox then multistart can help

Connectez-vous pour commenter.

Produits


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by