Using lsqnonlin with a joint boundary for multiple parameters

13 visualizaciones (últimos 30 días)
Jessica Vidmark
Jessica Vidmark el 13 de Mayo de 2020
Comentada: Walter Roberson el 22 de Mayo de 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 comentarios
Walter Roberson
Walter Roberson el 21 de Mayo de 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 el 21 de Mayo de 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?

Iniciar sesión para comentar.

Respuestas (1)

Walter Roberson
Walter Roberson el 21 de Mayo de 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 comentario
Walter Roberson
Walter Roberson el 22 de Mayo de 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

Iniciar sesión para comentar.

Productos


Versión

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by