Karl,

I have written a function to compute the gradient of a multivariate normal
density (derivatives at a given point, with respect to the parameters of the
density).  It is in the atttached file.  I would appreciate any feedback.

There are couple of interesting points: 

1.  Note is that there is a minor adjustment needed to the formulas given by
Dwyer (Table 2, Eqs. (11.7 and 11.8) to account for the symmetry in the
derivatives of the covariance parameters.  Without this adjustment the
derivatives of covariances are off by a factor of 2.

2.  I couldn't figure out how to avoid inverting the covariance matrix for
Eq. (11.7), using `solve(sigma)'.  I would appreciate knowing if there is a
trick for doing this.

Ravi. 


----------------------------------------------------------------------------
-------

Ravi Varadhan, Ph.D.

Assistant Professor, The Center on Aging and Health

Division of Geriatric Medicine and Gerontology 

Johns Hopkins University

Ph: (410) 502-2619

Fax: (410) 614-9625

Email: rvarad...@jhmi.edu

Webpage:
http://www.jhsph.edu/agingandhealth/People/Faculty_personal_pages/Varadhan.h
tml

 

----------------------------------------------------------------------------
--------


-----Original Message-----
From: r-help-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On
Behalf Of Karl Ove Hufthammer
Sent: Wednesday, June 24, 2009 3:21 AM
To: r-h...@stat.math.ethz.ch
Subject: Re: [R] The gradient of a multivariate normal density with
respecttoits parameters

Ravi Varadhan:

> You may want to look at the paper by Dwyer on "Some applications of 
> matrix derivatives in multivariate analysis" (JASA 1967), especially 
> the Table 2 on p. 617.

Thanks! That's a *very* useful paper. Note there also is a small corrigenda
available:

Corrigenda: Some Applications of Matrix Derivatives in Multivariate Analysis
Paul S. Dwyer Journal of the American Statistical Association, Vol. 62, No.
320 (Dec., 1967), p. 1518 Stable URL: http://www.jstor.org/stable/2283811

--
Karl Ove Hufthammer

______________________________________________
R-help@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.
library(mvtnorm)
library(numDeriv)

####################################################
mvnorm.grad <- function(x, mu, sigma, log=FALSE) {
# x = a vector denoting location at which gradient is computed
# mu = a vector denoting mean of multivariate normal
# sigma = covariance matrix
# log = logical variable indicating whether density or log-density should be 
used
# Note:  gradient is computed with respect to location parameters, and with 
respect to variances and covariances 
#
# Author:  Ravi Varadhan, Johns Hopkins University, June 24, 2009
#
siginvmu <- c(solve(sigma, x-mu))
mu.grad <- siginvmu
sigma.grad <- tcrossprod(siginvmu) - solve(sigma)  # is there a way to avoid 
inverting `sigma'?
diag(sigma.grad) <- 0.5 * diag(sigma.grad)  # this is required to account for 
symmetry of covariance matrix

if (log) list(mu.grad=mu.grad, sigma.grad=sigma.grad) else 
        {
        f <- dmvnorm(x, mean=mu, sigma=sigma, log=FALSE)
        list(mu.grad=mu.grad*f, sigma.grad=sigma.grad*f)
        }               
}
####################################################

# application to a bivariate normal
#
f=function(pars, xx, yy, log=FALSE)
# Numerical gradient using "numDeriv" for bivariate normal
#
{
  mu = pars[1:2]
  sig1 = pars[3]
  sig12 = pars[4]
  sig2 = pars[5]
  sig = matrix(c(sig1,sig12,sig12,sig2),2)
  dmvnorm(c(xx,yy),mean=mu,sigma=sig, log=log)
}

mu1=1
mu2=2
sig1=3^2
sig2=4^2
sig12=.5 * sqrt(sig1 * sig2)
sig <- matrix(c(sig1,sig12,sig12,sig2), 2, 2)

xx=rnorm(1) # or a x vector
yy=rnorm(1) # or a y vector

ans1 <- jacobian(func=f, x=c(mu1,mu2,c(sig)[-3]), xx=xx, yy=yy)
ans2 <- mvnorm.grad(x=c(xx, yy), mu=c(mu1, mu2), sigma=sig)
ans1
ans2
all.equal(c(ans1), c(ans2$mu, ans2$sigma.grad[lower.tri(ans2$sigma.grad, 
diag=TRUE)]))

#########
# application to a 4-dim multivariate normal
mu <- rnorm(4, mean=c(1,2,4,8))
sigma <- matrix(rexp(16), 4, 4)
sigma <- sigma %*% t(sigma)  

x0 <- rnorm(4, mean=c(1,2,4,8))
ans <- mvnorm.grad(x=x0, mu=mu, sigma=sigma)
ans
______________________________________________
R-help@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.

Reply via email to