# Nonlinear fit with constraints in R2012b

6 views (last 30 days)

Show older comments

Hi

I am running R2012b and doing nonlinear weighted regression as explained here: http://www.mathworks.se/help/stats/examples/weighted-nonlinear-regression.html. In other words, I am using NonLinearModel.fit.

However is there a way to constrain one of the fit parameters to be positive?

Best, Niles.

##### 0 Comments

### Answers (3)

Star Strider
on 22 Sep 2012

Edited: Star Strider
on 22 Sep 2012

The Statistics Toolbox functions (such as you referenced in the link) won't let you constrain the parameters but the Optimization Toolbox functions (such as lsqcurvefit) will.

You can do weighted nonlinear regression with lsqcurvefit, using an interim anonymous function. So if the model you have coded as a function and want to fit is called ‘nonlinmodel’, you would normally call it from lsqcurvefit this way:

x = lsqcurvefit(@nonlinmodel,x0,xdata,ydata,lb,ub);

To do weighted nonlinear regression with it, you need to incorporate your weight vector into an anonymous function, and then call the anonymous fiunction from lsqcurvefit:

Weights = 1./(N.*SE.^2);

nonlinmodelW = @(B,t) Weights .* nonlinearmodel(B,t);

x = lsqcurvefit(nonlinmodelW,x0,xdata,ydata,lb,ub);

For ‘Weights’, I used the typical standard errors usually provided, with N being the number of observations used to calculate each of them. This produces inverse-variance weights, the conventional scheme. Note that ‘Weights’ is a vector of the same dimensions as the vector ‘nonlinearmodel’ returns.

When you simulate your function with your estimated parameters to plot with your data, remember to use the anonymous function. It (here ‘nonlinmodelW’) is the function you fitted, not your original ‘nonlinmodel’.

This anonymous function approach will work with both lsqcurvefit and nlinfit. Before weights were added to nlinfit in 2012b, this was the standard way of doing weighted nonlinear regression with both. I've done weighted nonlinear regression using this approach many times with lsqcurvefit in order to take advantage of the parameter constraints.

##### 4 Comments

Zhaorong Wang
on 8 Nov 2013

Thanks Star Strider for providing a nice trick to do weighted fitting using the most powerful lsqcurvefit! However, one thing has to be corrected, if you weight the fitting function "nonlinmodel", you have to weight the ydata as well. Because you are minimizing

sum((nonlinmodelW(B,xdata) - ydata).^2),

readers better deal with this carefully, like writing some wrapper function lsqcurvefit_weighted() for lsqcurvefit()

Sarah Garre
on 20 Dec 2013

Sarah Garre
on 20 Dec 2013

if I understand it well, it should be enough to manage it like this:

Weights = 1./(N.*SE.^2);

nonlinmodelW = @(B,t) Weights .* nonlinearmodel(B,t);

x = lsqcurvefit(nonlinmodelW,x0,xdata,Weights .* ydata,lb,ub);

Am I right?

##### 2 Comments

Richard Andersson
on 15 Apr 2014

Star Strider
on 15 Apr 2014

Sarah — That looks correct. I haven’t tested it to be sure.

Richeard — The argument B is the vector of parameters (usually termed β in the literature), and t is the independent variable vector, probably time in this example.

The same objective function format works for both lsqcurvefit and nlinfit, but the arguments must be in the (B,t) order.

In the last few versions, nlinfit has the option of a weighted regression. I haven’t needed to use it recently, so I refer you to the documentation.

Bhavin Khatri
on 9 Oct 2019

I think by usual maximum likelihood arguments the weights should be

weights = 1./se.^2

not

weights 1./(N.*se.^2).

Intuitively, it doesn't make sense either, since according to the latter, the more observations you have for a particular data point the smaller the weight!

(Of course you can choose whatever weights you want, but assuming Gaussian errors etc..., if you want the maximum likelihood estimate the weights should be the inverse of the standard error.)

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!