Fast Non-Negative Least Squares
Finds the vector b
minimizing
sum( (y - X %*% b)^2 ) |
subject to b[j] >= 0
for all j
.
fnnls(XtX, Xty, ntol = NULL)
XtX
: Crossproduct matrix crossprod(X)
of dimension p-by-p.Xty
: Crossproduct vector crossprod(X,y)
of length p-by-1.ntol
: Tolerance for non-negativity.The vector b
such that b[j] >= 0
for all j
.
Bro, R., & De Jong, S. (1997). A fast non-negativity-constrained least squares algorithm. Journal of Chemometrics, 11, 393-401.
Nathaniel E. Helwig helwig@umn.edu
Default non-negativity tolerance: ntol=10*(.Machine$double.eps)*max(colSums(abs(XtX)))*p
.
########## EXAMPLE 1 ########## X <- matrix(1:100,50,2) y <- matrix(101:150,50,1) beta <- solve(crossprod(X))%*%crossprod(X,y) beta beta <- fnnls(crossprod(X),crossprod(X,y)) beta ########## EXAMPLE 2 ########## X <- cbind(-(1:50),51:100) y <- matrix(101:150,50,1) beta <- solve(crossprod(X))%*%crossprod(X,y) beta beta <- fnnls(crossprod(X),crossprod(X,y)) beta ########## EXAMPLE 3 ########## X <- matrix(rnorm(400),100,4) btrue <- c(1,2,0,7) y <- X%*%btrue + rnorm(100) fnnls(crossprod(X),crossprod(X,y)) ########## EXAMPLE 4 ########## X <- matrix(rnorm(2000),100,20) btrue <- runif(20) y <- X%*%btrue + rnorm(100) beta <- fnnls(crossprod(X),crossprod(X,y)) crossprod(btrue-beta)/20
Useful links