[R] nlminb() - how do I constrain the parameter vector properly?
David Winsemius
dwinsemius at comcast.net
Mon Oct 21 02:19:07 CEST 2013
On Oct 20, 2013, at 3:01 PM, Steven LeBlanc wrote:
> Greets,
>
> I'm trying to use nlminb() to estimate the parameters of a bivariate normal sample and during one of the iterations it passes a parameter vector to the likelihood function resulting in an invalid covariance matrix that causes dmvnorm() to throw an error. Thus, it seems I need to somehow communicate to nlminb() that the final three parameters in my parameter vector are used to construct a positive semi-definite matrix, but I can't see how to achieve this using the constraint mechanism provided. Additional details are provided in the code below.
>
I recently noticed that teh dmvnorn function in package mixtools doe not throw an error when given a non-positive definite varaince-covariance matrix. Whether it should be doing so might be up for debate. Peter Dalgaard seemed to think that any self respecting such function _should_ be throwing NaN's back at you.
The code it was using is rather compact:
> mixtools::dmvnorm
function (y, mu = NULL, sigma = NULL)
{
exp(logdmvnorm(y, mu = mu, sigma = sigma))
}
<environment: namespace:mixtools>
> mixtools::logdmvnorm
function (y, mu = NULL, sigma = NULL)
{
if (is.vector(y))
y <- matrix(y, nrow = 1)
d <- ncol(y)
if (!is.null(mu))
y <- sweep(y, 2, mu, "-")
if (is.null(sigma))
sigma <- diag(d)
k <- d * 1.83787706640935
a <- qr(sigma)
logdet <- sum(log(abs(diag(a$qr))))
if (nrow(y) == 1)
mahaldist <- as.vector(y %*% qr.solve(a, t(y)))
else mahaldist <- rowSums((y %*% qr.solve(a)) * y)
-0.5 * (mahaldist + logdet + k)
}
I noticed that you were logging the dmvnorm values and so I wondered also if going directly to that function might save some time. (Note that I am way out of my mathematical dept here. Caveat emptor, maxima caveat emptor).
--
David.
> Suggestions?
>
> Best Regards,
> Steven
>
> Generate the data set I'm using:
>
> mu<-c(1,5)
> sigma<-c(1,2,2,6)
> dim(sigma)<-c(2,2)
> set.seed(83165026)
> sample.full<-sample.deleted<-mvrnorm(50,mu,sigma)
> delete.one<-c(1,5,13,20)
> delete.two<-c(3,11,17,31,40,41)
> sample.deleted[delete.one,1]<-NA
> sample.deleted[delete.two,2]<-NA
> missing<-c(delete.one,delete.two)
> complete<-sample.deleted[!(is.na(sample.deleted[,1]) | is.na(sample.deleted[,2])),]
> deleted<-sample.deleted[missing,]
>
> Try to estimate the parameters of the data set less the deleted values:
>
> exact<-function(theta,complete,deleted){
> one.only<-deleted[!(is.na(deleted[,1])),1]
> two.only<-deleted[!(is.na(deleted[,2])),2]
> u<-c(theta[1],theta[2])
> sigma<-c(theta[3],theta[5],theta[5],theta[4])
> dim(sigma)<-c(2,2)
> -sum(log(dmvnorm(x=complete,mean=u,sigma=sigma)))-
> sum(log(dnorm(one.only,u[1],sigma[1,1])))-
> sum(log(dnorm(two.only,u[2],sigma[2,2])))
> }
> nlminb(start=c(0,0,1,1,0),objective=exact,complete=complete,deleted=deleted,control=list(trace=1))
>
> Escape and it stops at Iteration 9 on my machine.
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
David Winsemius
Alameda, CA, USA
More information about the R-help
mailing list