Website link : https://rpubs.com/Isaiah-Mireles/1446105
# random samples
n <- 10000
# Generate Uniform(0,1) random numbers
u <- runif(n)
# Allocate memory
x <- numeric(n)
# Inverse transform method
x[u <= 0.30] <- 1
x[u > 0.30 & u <= 0.50] <- 2
x[u > 0.50 & u <= 0.65] <- 3
x[u > 0.65 & u <= 0.75] <- 4
x[u > 0.75] <- 5
table(x) / n
## x
## 1 2 3 4 5
## 0.2971 0.1937 0.1576 0.0971 0.2545
(table(x) / n) |> barplot()
true <- c(0.3, 0.2, 0.15, 0.1, 0.25)
(table(x) / n) - true
## x
## 1 2 3 4 5
## -0.0029 -0.0063 0.0076 -0.0029 0.0045
Below I describe the recursive algorithm for poiss() :
set.seed(123)
n <- 10000
lambda <- 4.2
x <- numeric(n)
for (i in 1:n) {
u <- runif(1) # generate a single value
xi <- 0
p <- exp(-lambda) # x=0
cdf <- p
# stop when we reach the max value
while (cdf < u) {
xi <- xi + 1
p <- p * lambda / xi # recursive def.
cdf <- cdf + p
}
x[i] <- xi
}
hist(x,
probability = TRUE,
breaks = seq(-0.5, max(x) + 0.5, by = 1),
col = "lightgray",
main = "Inverse CDF Poisson Samples",
xlab = "x")
k <- 0:max(x)
points(k, dpois(k, lambda), col = "red", pch = 19)
lines(k, dpois(k, lambda), col = "red", lwd = 2)
# Target distribution
x <- 1:5
p_x <- c(0.30, 0.20, 0.15, 0.10, 0.25)
# Proposal distribution
g <- rep(0.2, 5)
# Compute M
M <- max(p_x / g)
# Acceptance probabilities
p_accept <- p_x / (M * g)
# Number of proposals
n <- 10000
# Generate proposals from g : here we assign equal prob. g (0.2 each)
x_prop <- sample(x, size = n, replace = TRUE, prob = g)
# Independent uniforms
u <- runif(n)
# Accept/reject
accepted <- u <= p_accept[x_prop]
print("Empirical Acceptance Rate")
## [1] "Empirical Acceptance Rate"
mean(accepted)
## [1] 0.6667
print("Theoretical Acceptance Rate")
## [1] "Theoretical Acceptance Rate"
1/M
## [1] 0.6666667
# Accepted samples
x_accept <- x_prop[accepted]
print("est.")
## [1] "est."
table(x_accept) / length(x_accept)
## x_accept
## 1 2 3 4 5
## 0.2977351 0.2083396 0.1486426 0.1022949 0.2429879
print("True prob.")
## [1] "True prob."
p_x
## [1] 0.30 0.20 0.15 0.10 0.25
not bad!
We may find better luck pushing certain x values more likely to match the true dist better
g <- c(.25, .2, .15, .1, .3)
# Compute M
M <- max(p_x / g)
# Acceptance probabilities
p_accept <- p_x / (M * g)
# Number of proposals
n <- 10000
# Generate proposals from g :
x_prop <- sample(x, size = n, replace = TRUE, prob = g)
# Independent uniforms
u <- runif(n)
# Accept/reject
accepted <- u <= p_accept[x_prop]
print("Empirical Acceptance Rate")
## [1] "Empirical Acceptance Rate"
mean(accepted)
## [1] 0.8367
print("Theoretical Acceptance Rate")
## [1] "Theoretical Acceptance Rate"
1/M
## [1] 0.8333333
Suppose we identically match true
g <- p_x
# Compute M
M <- max(p_x / g)
# Acceptance probabilities
p_accept <- p_x / (M * g)
# Number of proposals
n <- 10000
# Generate proposals from g :
x_prop <- sample(x, size = n, replace = TRUE, prob = g)
# Independent uniforms
u <- runif(n)
# Accept/reject
accepted <- u <= p_accept[x_prop]
print("Empirical Acceptance Rate")
## [1] "Empirical Acceptance Rate"
mean(accepted)
## [1] 1
print("Theoretical Acceptance Rate")
## [1] "Theoretical Acceptance Rate"
1/M
## [1] 1
Here’s a more concise version:A proposal distribution (g(x)) that closely matches the target distribution (p(x)) is more efficient because it produces a higher acceptance rate and fewer rejected samples. In the ideal case where (g(x)=p(x)), every proposal is accepted, so both the theoretical and empirical acceptance rates are 100%. Using a uniform proposal is generally less efficient because it ignores the shape of (p(x)), leading to more rejections. The empirical acceptance rate may differ from the theoretical rate due to random sampling, but it converges to the theoretical value as the sample size increases.
set.seed(123)
# Generate x values
x <- seq(0, 2*pi, length.out = 100)
# Random error ~ N(0, 1)
error <- rnorm(length(x), mean = 0, sd = 1)
# Example response: sin(x) + error
y <- sin(x) + error
# Combine into a data frame
df <- data.frame(x, y, error)
plot(x,y)
lines(x, sin(x), col = "red", lwd = 3)
# Fit models
m1 <- lm(y ~ x, data = df)
m2 <- lm(y ~ sin(x), data = df)
# Scatterplot
plot(df$x, df$y,
pch = 1,
xlab = "x",
ylab = "y",
main = "Comparison of Models")
# True model
lines(df$x, sin(df$x),
col = "red",
lwd = 3)
# m1: Linear regression
abline(m1,
col = "blue",
lwd = 2)
# m2: Sine regression
lines(df$x,
predict(m2),
col = "darkgreen",
lwd = 2)
legend("topright",
legend = c("True Model", "m1: y ~ x", "m2: y ~ sin(x)"),
col = c("red", "blue", "darkgreen"),
lwd = c(3, 2, 2),
bty = "n",
cex = .5)
Website link : https://rpubs.com/Isaiah-Mireles/1446105