[R] faster GLS code

Carlo Fezzi c.fezzi at uea.ac.uk
Thu Jan 7 21:25:41 CET 2010


Dear Ravi and Chuck,

thanks a lot for your suggestions. I should have make it clear earlier,
but unfortunately I need "betav" because this is part of a longer code to
estimate a bayesian SUR tobit. Ravi, in your approach is there are way to
compute "betav" as well? Also, I was aware of the model reduction to a
simple OLS when the regressors are the same, but I still need the full GLS
estimator because of its use with the rest of the model.

Thanks a lot,

Carlo


> On Thu, 7 Jan 2010, Ravi Varadhan wrote:
>
>> Try this:
>>
>>
>> X <- kronecker(diag(1,3),x)
>> Y <- c(y) # stack the y in a vector
>>
>> # residual covariance matrix for each observation
>> covar <- kronecker(sigma,diag(1,N))
>>
>> csig <- chol2inv(covar)
>> betam2 <- ginv(csig %*% X) %*% csig %*% Y
>>
>> This is more than 2 times faster than your code (however, it doesn't
>> compute `betav') .
>>
>
> Faster still (by a wide margin) if X will truly be of that form:
>
>> B <- coef(lm(y~0+.,as.data.frame(x)))
>> all.equal( as.vector((B)), as.vector(betam))
> [1] TRUE
>
> When X is of that form, the covariance matrix drops out of the
> computation.
>
> :)
>
> Chuck
>
>
>> Here is a timing comparison:
>>
>> # Your method
>> # GLS betas covariance matrix
>> system.time({
>> inv.sigma <- solve(covar)
>> betav <- solve(t(X)%*%inv.sigma%*%X)
>>
>> # GLS mean parameter estimates
>> betam <- betav%*%t(X)%*%inv.sigma%*%Y
>> })
>>
>> # New method
>> system.time({
>> csig <- chol2inv(covar)
>> betam2 <- ginv(csig %*% X) %*% csig %*% Y
>> })
>>
>> all.equal(betam, betam2)
>>
>>> # GLS betas covariance matrix
>>> system.time({
>> + inv.sigma <- solve(covar)
>> + betav <- solve(t(X)%*%inv.sigma%*%X)
>> +
>> + # GLS mean parameter estimates
>> + betam <- betav%*%t(X)%*%inv.sigma%*%Y
>> + })
>>   user  system elapsed
>>   1.14    0.51    1.76
>>>
>>> system.time({
>> + csig <- chol2inv(covar)
>> + betam2 <- ginv(csig %*% X) %*% csig %*% Y
>> + })
>>   user  system elapsed
>>   0.47    0.08    0.61
>>>
>>> all.equal(betam, betam2)
>> [1] TRUE
>>>
>>
>>
>> Hope this helps,
>> Ravi.
>> ____________________________________________________________________
>>
>> Ravi Varadhan, Ph.D.
>> Assistant Professor,
>> Division of Geriatric Medicine and Gerontology
>> School of Medicine
>> Johns Hopkins University
>>
>> Ph. (410) 502-2619
>> email: rvaradhan at jhmi.edu
>>
>>
>> ----- Original Message -----
>> From: Carlo Fezzi <c.fezzi at uea.ac.uk>
>> Date: Thursday, January 7, 2010 12:13 pm
>> Subject: [R] faster GLS code
>> To: r-help at r-project.org
>>
>>
>>> Dear helpers,
>>>
>>>  I wrote a code which estimates a multi-equation model with generalized
>>>  least squares (GLS). I can use GLS because I know the covariance
>>> matrix of
>>>  the residuals a priori. However, it is a bit slow and I wonder if
>>> anybody
>>>  would be able to point out a way to make it faster (it is part of a
>>> bigger
>>>  code and needs to run several times).
>>>
>>>  Any suggestion would be greatly appreciated.
>>>
>>>  Carlo
>>>
>>>
>>>  ***************************************
>>>  Carlo Fezzi
>>>  Senior Research Associate
>>>
>>>  Centre for Social and Economic Research
>>>  on the Global Environment (CSERGE),
>>>  School of Environmental Sciences,
>>>  University of East Anglia,
>>>  Norwich, NR4 7TJ
>>>  United Kingdom.
>>>  email: c.fezzi at uea.ac.uk
>>>  ***************************************
>>>
>>>  Here is an example with 3 equations and 2 exogenous variables:
>>>
>>>  ----- start code ------
>>>
>>>
>>>  N <- 1000        	# number of observations
>>>  library(MASS)
>>>
>>>  ## parameters ##
>>>
>>>  # eq. 1
>>>  b10 <- 7; b11 <- 2; b12 <- -1
>>>
>>>  # eq. 2
>>>  b20 <- 5; b21 <- -2; b22 <- 1
>>>
>>>  # eq.3
>>>  b30 <- 1; b31 <- 5; b32 <- 2
>>>
>>>  # exogenous variables
>>>
>>>  x1 <- runif(min=-10,max=10,N)
>>>  x2 <- runif(min=-5,max=5,N)
>>>
>>>  # residual covariance matrix
>>>  sigma <- matrix(c(2,1,0.7,1,1.5,0.5,0.7,0.5,2),3,3)
>>>
>>>  # residuals
>>>  r <- mvrnorm(N,mu=rep(0,3), Sigma=sigma)
>>>
>>>  # endogenous variables
>>>
>>>  y1 <- b10 + b11 * x1 + b12*x2 + r[,1]
>>>  y2 <- b20 + b21 * x1 + b22*x2 + r[,2]
>>>  y3 <- b30 + b31 * x1 + b32*x2 + r[,3]
>>>
>>>  y <- cbind(y1,y2,y3)        	# matrix of endogenous
>>>  x <- cbind(1,x1, x2)        	# matrix of exogenous
>>>
>>>
>>>  #### MODEL ESTIMATION ###
>>>
>>>  # build the big X matrix needed for GLS estimation:
>>>
>>>  X <- kronecker(diag(1,3),x)
>>>  Y <- c(y)                  # stack the y in a vector
>>>
>>>  # residual covariance matrix for each observation
>>>  covar <- kronecker(sigma,diag(1,N))
>>>
>>>  # GLS betas covariance matrix
>>>  inv.sigma <- solve(covar)
>>>  betav <- solve(t(X)%*%inv.sigma%*%X)
>>>
>>>  # GLS mean parameter estimates
>>>  betam <- betav%*%t(X)%*%inv.sigma%*%Y
>>>
>>>  ----- end of code ----
>>>
>>>  ______________________________________________
>>>  R-help at r-project.org mailing list
>>>
>>>  PLEASE do read the posting guide
>>>  and provide commented, minimal, self-contained, reproducible code.
>>
>> ______________________________________________
>> 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.
>>
>
> Charles C. Berry                            (858) 534-2098
>                                              Dept of Family/Preventive
> Medicine
> E mailto:cberry at tajo.ucsd.edu	            UC San Diego
> http://famprevmed.ucsd.edu/faculty/cberry/  La Jolla, San Diego 92093-0901
>
>
>



More information about the R-help mailing list