A function for calculating the root \(\mathbf\Sigma^{\frac{1}{2}}\) of a covariance matrix, using a spectral decomposition:

makeRoot <- function(Sig){
  U <- eigen(Sig)
  RootSigma <- U$vectors %*% diag(sqrt(U$values)) %*% t(U$vectors)
  return(RootSigma)
}

An example covariance matrix \(\mathbf\Sigma\):

(mat <- matrix(c(1, 1.3, 1.3, 2), 2))
##      [,1] [,2]
## [1,]  1.0  1.3
## [2,]  1.3  2.0
cov2cor(mat)
##           [,1]      [,2]
## [1,] 1.0000000 0.9192388
## [2,] 0.9192388 1.0000000

And an example dataset \(\mathbf{X}\):

library("mvtnorm")
dat <- data.frame(rmvnorm(1000, sigma=mat))
head(dat)
##           X1          X2
## 1  1.2136601  1.49413055
## 2  0.4067333 -0.08562505
## 3 -0.3736126 -0.72329755
## 4 -0.2192473 -0.37922115
## 5 -0.8129728  0.13743406
## 6 -0.1860610 -0.67367826
cov(dat)
##          X1       X2
## X1 0.981142 1.256768
## X2 1.256768 1.905774
cor(dat)
##           X1        X2
## X1 1.0000000 0.9190802
## X2 0.9190802 1.0000000

De-correlate \(\mathbf{X}\) so as to get \(\mathbf{X}^* = \mathbf\Sigma^{-\frac{1}{2}} \mathbf{X}\):

DAT <- as.matrix(dat) %*% solve(makeRoot(cov(dat)))
cov(DAT)
##              [,1]         [,2]
## [1,] 1.000000e+00 2.269818e-16
## [2,] 2.269818e-16 1.000000e+00
cor(DAT)
##              [,1]         [,2]
## [1,] 1.000000e+00 2.269818e-16
## [2,] 2.269818e-16 1.000000e+00

Undo the de-correlation of \(\mathbf{X}\) (“re-correlate” \(\mathbf{X}^*\)):

dat2 <- DAT %*% makeRoot(cov(dat))
cov(dat2)
##          [,1]     [,2]
## [1,] 0.981142 1.256768
## [2,] 1.256768 1.905774
cor(dat2)
##           [,1]      [,2]
## [1,] 1.0000000 0.9190802
## [2,] 0.9190802 1.0000000