Skip to content

Commit fbd883e

Browse files
committed
Monte Carlo simulation example and MC integration
1 parent cdc0c40 commit fbd883e

1 file changed

Lines changed: 119 additions & 0 deletions

File tree

R/README.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,122 @@ rejection_sample_vec <- function(n, f, M, r_m, batch_size = 10000) {
635635
- Output partial results to a file
636636
- Prefer `replicate` and `apply` function
637637
- Analyze simulation results
638+
639+
### Statistical Monte Carlo Simulation Example
640+
641+
The key idea is that if you repeatedly sample data and construct intervals the same way, about 95% of those intervals will contain the true mean `μ`.
642+
643+
Let `Xi​∼N(μ=10,σ=2)`, true mean `μ=10`
644+
645+
- Repeat sampling `K` times
646+
- Compute confidence intervals
647+
- Check coverage
648+
649+
Setup:
650+
651+
```r
652+
set.seed(251407053)
653+
654+
# true population parameters
655+
mu_true <- 10
656+
sigma <- 2
657+
658+
# simulation settings
659+
n <- 50 # sample size
660+
K <- 10000 # number of repetitions
661+
662+
# store results
663+
contains_mu <- logical(K)
664+
```
665+
666+
Simulation loop:
667+
668+
```r
669+
for (k in 1:K) {
670+
671+
# DGP: generate sample
672+
x <- rnorm(n, mean = mu_true, sd = sigma)
673+
674+
# estimate
675+
x_bar <- mean(x)
676+
s <- sd(x)
677+
678+
# 95% confidence interval (z approximation as in your notes)
679+
margin <- 1.96 * s / sqrt(n)
680+
lower <- x_bar - margin
681+
upper <- x_bar + margin
682+
683+
# check if interval contains true mean
684+
contains_mu[k] <- (lower <= mu_true && mu_true <= upper)
685+
}
686+
```
687+
688+
Simulation result:
689+
690+
```r
691+
# Monte Carlo estimate of coverage
692+
coverage <- mean(contains_mu)
693+
coverage
694+
```
695+
696+
With `replicate`:
697+
698+
```r
699+
set.seed(123)
700+
701+
mu_true <- 10
702+
sigma <- 2
703+
n <- 50
704+
K <- 10000
705+
706+
contains_mu <- replicate(K, {
707+
708+
# DGP
709+
x <- rnorm(n, mean = mu_true, sd = sigma)
710+
711+
# estimator
712+
x_bar <- mean(x)
713+
s <- sd(x)
714+
715+
# CI
716+
margin <- 1.96 * s / sqrt(n)
717+
lower <- x_bar - margin
718+
upper <- x_bar + margin
719+
720+
# return logical result
721+
(lower <= mu_true && mu_true <= upper)
722+
})
723+
724+
mean(contains_mu)
725+
```
726+
727+
## Monte Carlo Integration
728+
729+
Monte Carlo integration estimates the average value of a function by sampling inputs uniformly (randomly probing) and averaging outputs (heights).
730+
731+
Since `U` is uniform over `[0,1]`, sampling `g(U)` evaluates the function at uniformly distributed points. Averaging these values approximates the expected value `E[g(U)]`, which equals the integral. Because the interval has length 1, this expectation represents the average height of the function, which is equal to the area under the curve.
732+
733+
Law of Large Numbers: As the number of independent random samples increases, the sample average converges to the true expected value (population mean).
734+
735+
```cpp
736+
#include <iostream>
737+
#include <random>
738+
739+
int main() {
740+
std::mt19937 rng(std::random_device{}());
741+
742+
std::uniform_real_distribution<double> dist(0.0, 1.0);
743+
744+
const int n = 1'000'000;
745+
double sum = 0.0;
746+
747+
for (int i = 0; i < n; ++i) {
748+
double u = dist(rng);
749+
sum += u * u;
750+
}
751+
752+
double estimate = sum / n;
753+
754+
std::cout << "Estimate: " << estimate << "\n";
755+
}
756+
```

0 commit comments

Comments
 (0)