MATLAB: Non linear regression fiting with both, weights and parameter boundaries

bothboundariesconstraintsfitnlmlsqcurvefitnon-linear regressionparametersweights

I have been able to find two different functions, fitnlm and lsqcurvefit. Problem with first function is that I cannot set boundaries for parameters but I can use weights. The problem with lsqcurvefit is, that I can't use weights but I can use boundaries for parameters. Is there another more general function where I can use both weights and boundaries for parameters?
Examples:
mdl = fitnlm(x,y,fun,p0,'Weights',weights)
p = lsqcurvefit(fun,p0,x,y,lb,ub)
I can't use 'Weights' in lsqcurvefit, and I can't use lb and ub in fitnlm. Help me please.

Best Answer

Well, you CAN do it with either of these tools, but fitnlm is more difficult.
lsqnonlin is actually the simplest way to achieve your goal. No, it does not directly admit weights. No problem.
First, what is a weight? All data points by default have a weight of 1. A weight of 2 is equivalent to replicating that point, so there are two such points. I.e., effectively, a weight of 2 means that point is twice as important in the sum of squares of residuals. A weight of k means the point is k times as important. k may be less than 1 of course, but there the idea of a weight as a replication factor is not as intuitive. No matter. Just think of the weight as a replication factor.
The idea is that lsqnonlin works by your objective function returning a list of RESIDUALS. So if a point has a weight of k, then multiply the corresponding residual for that point by sqrt(k). Then when lsqnonlin implicitly squares those residuals and sums them, that point will contribute k times as much to the aggregate sum of squares of residuals.
So all it takes is, if you have a vector of weights W, before your objective function returns the residual vector, multiply that vector element-wise by the vector W.
So the final computation in your objective function for lsqnonlin would look like this:
Resids = Resids.*sqrt(W);
Easy peasy.
You could also have accomplished the same thing using lsqcurvefit, but with slightly more effort. Putting bound constraints on the unknowns for a tool like fitnlm can be done, but that would take more effort yet. Just use lsqnonlin as I describe.