# [R] least square fit with non-negativity constraints for absorption spectra fitting

Prof Brian Ripley ripley at stats.ox.ac.uk
Fri Jul 14 16:18:10 CEST 2006

```On Fri, 14 Jul 2006, Joerg van den Hoff wrote:

> Xu, Xiuli (NIH/NHLBI) [E] wrote:
> > I would really appreciate it if someone can give suggestions on how to
> > do spectra fitting in R using ordinary least square fitting and
> > non-negativity constraints. The lm() function works well for ordinary
> > least square fitting, but how to specify non-negativity constraints? It
> > wouldn't make sense if the fitting coefficients coming out as negative
> > in absorption spectra deconvolution.
> >
> > Thanks.
> >
> > Xiuli
> >
>
> I'm not sure, but would presume that constraints could not be imposed on
> a linear least squares fit. maybe someone can correct me.

They can, and you get a simple quadratic programming problem.  So quadprog
could be used to solve this one, but optim(methods="L-BFGS-B") may be as
easy (and is pretty efficient on this class of QP problems).

S-PLUS has a function nnls.fit() for 'non-negative least squares'.

> if you move to `nls', i.e. non-linear least squares fitting, you should
> be able to transform your model function. say, you want some parameter
> `a' to stay positive. then you could e.g. substitute
>
> `a = exp(b)' in the model function and fit `b' without constraints in
> the "new" model and calculate `a' afterwards (which obviously is
> guaranteed now to be positive). note that error estimates would than
> have to be computed by gaussian error propagation from `b' to `a'.

The problem here is that a = 0 is a possible (and indeed plausible) value.

See MASS4 p.227 for nnls.fit and alternatives for use in R.  The MASS3
ch08 script had an example of a regression with non-negative slope:

data(whiteside)
attach(whiteside)
Gas <- Gas[Insul=="Before"]
Temp <- -Temp[Insul=="Before"]
#nnls.fit(cbind(1, -1, Temp), Gas)
# can use box-constrained optimizer
fn <- function(par) sum((Gas - par[1] - par[2]*Temp)^2)
optim(rep(0,2), fn, lower=c(-Inf,0), method="L-BFGS-B")\$par
rm(Gas, Temp)
detach()

--
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

```