When working in one dimension, the Gibbs sampler seems to produce random samples with the wrong variance:
library(tmvtnorm)
set.seed(2023)
y_mean <- 0
y_var <- 0.1
y_trunc <- 0
y <- rnorm(1000, sd = sqrt(y_var))
# Moments of truncated distribution
mtmvnorm(mean = y_mean, sigma = y_var, lower = y_trunc)
$tmean
[1] 0.2523133
$tvar
[,1]
[1,] 0.03633802
# Samples from truncated distribution
y_new <- rtmvnorm(sum(y > y_trunc), mean = y_mean, sigma = y_var,
lower = y_trunc, algorithm = "gibbs")
c(mean(y_new), var(y_new))
[1] 0.079204130 0.003461616
And we can see from the histogram that the new samples don't follow the desired distribution:
y[y > y_trunc] <- y_new
hist(y, breaks = 50)
![Rplot](https://private-user-images.githubusercontent.com/11401835/273090644-4032d839-e32b-4e3b-990a-982b99748e93.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjEzNzQwNjAsIm5iZiI6MTcyMTM3Mzc2MCwicGF0aCI6Ii8xMTQwMTgzNS8yNzMwOTA2NDQtNDAzMmQ4MzktZTMyYi00ZTNiLTk5MGEtOTgyYjk5NzQ4ZTkzLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE5VDA3MjI0MFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWVjNzFkMDIyNTk1ZGNlZDA4Y2QwYWVlOGNkMmM5ODkyMmI5YjJkOGVjZDc5YjI0MzI4MDgyYjc2YjBjZjliZDQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.hsQikZ8gNSEpOADjJgWlds1uXYhqH0bTb0wi6fKljDc)
Rejection sampling works as expected:
y_new_rej <- rtmvnorm(sum(y > y_trunc), mean = y_mean, sigma = y_var,
lower = y_trunc, algorithm = "rejection")
c(mean(y_new_rej), var(y_new_rej))
[1] 0.24295202 0.03373638
As does Gibbs sampling in 2 independent dimensions:
y_new_2d <- rtmvnorm(sum(y > y_trunc), mean = rep(y_mean, 2),
sigma = diag(y_var, 2), lower = rep(y_trunc, 2),
algorithm = "gibbs")
colMeans(y_new_2d)
[,1] [,2]
[1,] 0.03777465 -0.00102825
[2,] -0.00102825 0.04048425
I believe the issue is because rtnorm.gibbs
treats the argument sigma
as the standard deviation (as per its documentation), but whenever it is called (lines 318, 425, 521 & 523 of rtmvnorm.R), the variance sigma[1,1]
is supplied. I think changing either the function or the calls to take the square root should resolve the issue.
(BTW - I am not sure if line 521 is supposed to have 1 / H[1,1]
instead of 1 / sigma[1,1]
as well)