Author: Kayla Keyue Chen
Last updated: 2024.4.28
Sampling Distribution of the Mean
The sampling distribution of a statistic is the distribution of that
statistic when derived from a random sample of size n.
It may be considered as the distribution of the statistic for all
possible samples from the same population of a given sample
size.
In many contexts, only one sample is observed, but the sampling
distribution can be found theoretically.
Let’s see some simulations to understand the concept.
We assume that IQ scores are normally distributed. Suppose it is true
that the population have mean of 100 and SD of 15 (note: we wouldn’t
know this, if it’s real-world research … we just assume this for our
simulation here).
- Now, we recruit 100 participants and assess their IQ.
# assess 100 participants and record their IQ scores
IQ1 <- rnorm(100, mean = 100, sd = 15)
# see the first 10 values
IQ1[1:10]
[1] 119.99916 85.70619 88.90712 59.95192 76.12173 106.15860 104.91585
[8] 82.89396 117.54255 93.64971
# get the mean of the sample
(mean1 <- mean(IQ1))
[1] 98.55371
- This is only one sample. Let’s have another four samples
# assess another 4 groups of 100 participants and record their IQ scores
IQ2 <- rnorm(100, mean = 100, sd = 15)
IQ3 <- rnorm(100, mean = 100, sd = 15)
IQ4 <- rnorm(100, mean = 100, sd = 15)
IQ5 <- rnorm(100, mean = 100, sd = 15)
# get the mean of the sample
mean2 <- mean(IQ2)
mean3 <- mean(IQ3)
mean4 <- mean(IQ4)
mean5 <- mean(IQ5)
# save all means into a vector
means <- c(mean1, mean2, mean3, mean4, mean5)
# calculate the mean of the sample means
mean(means) # which is quite close to 100!
[1] 99.77822
- Let’s create a function so that we don’t need to do it by hand each
time!
- n_exp = number of experiments
- sample_size = the sample size of each experiment
- mean and sd are the mean (100) and sd (15) of the population we
assumed
# define a function called do_experiment
# it's like we are recruiting participants from the population, and for each experiment, we record the mean of IQ of the group of participants.
do_experiment <- function(n_exp, sample_size, mean, sd){
mean_list <- c()
for (n in 1:n_exp){
one_mean <- mean(rnorm(sample_size, mean, sd))
mean_list <- c(mean_list, one_mean)
}
return(mean_list)
}
# Try 10 experiment, with each of sample size = 100.
# Note again the population is assumed to have the mean of 100, and the sd of 15.
do_experiment(n_exp=10, sample_size=100, mean=100, sd=15) # mean IQ of the 10 experiments we did are shown below
[1] 102.64072 100.89270 99.71262 98.86433 101.30048 100.22463 98.00525
[8] 99.35039 101.01348 99.52282
- Do three types of simulations listed below, calculate the mean and
SD of the sample means, and plot the distribution of the means using
histogram.
- Do 1000 experiments. Each time we recruit 5 participants.
- Do 1000 experiments. Each time we recruit 20 participants.
- Do 1000 experiments. Each time we recruit 100 participants.
set.seed(99)
# Do 1000 experiments. Each time we recruit 5, 20, or 100 participants.
results <- data.frame(size5 = do_experiment(1000, 5, 100, 15),
size20 = do_experiment(1000, 20, 100, 15),
size100 = do_experiment(1000, 100, 100, 15))
# show means from the first 6 experiments for each sample size
head(results)
size5 size20 size100
1 102.58741 95.90019 100.4875
2 94.27028 100.34994 101.9814
3 86.12904 97.99459 99.9001
4 95.89241 104.24758 102.4212
5 105.01035 93.62778 102.4371
6 102.16650 100.83881 100.3689
# draw a histogram of means for each sample size
results_long <- results %>% gather(size, means, 1:3) %>%
mutate(size = factor(size, levels = c("size5","size20","size100")))
ggplot(results_long, aes(x = means)) +
geom_histogram(binwidth = 2, fill = "white", color = "black") +
xlim(70, 130) +
facet_wrap(~size)

What do you find about the spreading of the distributions? - The
larger the sample size, the more spreading the distribution of sample
means is.
Standard Error of the Mean (SEM)
Recall that \(Standard\ Error\ of\ the\
Mean\ (SEM) = \frac{SD}{\sqrt{N}}\).
Since the denominator is the square root of the sample size (N), the
larger the sample size, the smaller the SEM. This is consistent with our
observation above. The larger the sample size, the more spreading the
distribution of sample means is!
- Let’s calculate the SEM using the equation above, and compare to the
SD of the distribution of sample means (we’ve got them from part
4).
compare <- data.frame(size5 = c(sd(rnorm(5, 100, 15))/sqrt(5), sd(results$size5)),
size20 = c(sd(rnorm(20, 100, 15))/sqrt(20), sd(results$size20)),
size100 = c(sd(rnorm(100, 100, 15))/sqrt(100), sd(results$size100)))
row.names(compare) <- c("Calculated", "Simulated")
compare
size5 size20 size100
Calculated 5.341117 2.86946 1.462043
Simulated 7.004362 3.42136 1.502792
Every time you run this chunk of code, the results would be slightly
different for the “Calculated” SEM. This is because every time you run
the code, you are recruiting new groups of participants. Nevertheless,
you can see that the results are close to those in our previous
simulations (in part 4) at least most of the time. They are closer for
larger sample size, 20 and 100.
NB: For the purpose of replication, you can set seed by
set.seed()
to get the same results every time (as long as
the seed is the same). This is what we did in some other code
chunks.
95% Confidence Interval (CI) of the Mean
Confidence interval (CI) is a range of estimates for an unknown
parameter. A confidence interval is computed at a designated confidence
level, most commonly 95%.
The equation to calculate 95% CI is \(CI =
Mean\ \pm\ 1.96 \times SEM\)
- Let’s define a function to do numerous experiments for us.
- n_exp = number of experiments
- sample_size = the sample size of each experiment
- p_mean and p_sd are the mean and sd of the population we
assumed
The function will record the following information:
- Whether CI includes the population mean (i.e., 100) in each
experiment
- The proportion of experiments in which CIs include the population
mean
- All the CIs (all pairs of upper and lower bounds from all
experiments)
# define a function called CI_include
# it's like we are recruiting participants from the population, and for each experiment, we calculate CI of the mean of IQ.
CI_include <- function(n_exp, sample_size, p_mean, p_sd){
all_results <- c()
include_list <- c()
CI <- c()
for (i in 1:n_exp){
samples <- rnorm(sample_size, p_mean, p_sd)
mean <- mean(samples)
sd <- sd(samples)
se <- sd/sqrt(sample_size)
CI[[i]] <- c(mean - 1.96 * se, mean + 1.96 * se)
if (CI[[i]][1] <= 100 & CI[[i]][2] >= 100){
include_list <- c(include_list, TRUE)}
else {
include_list <- c(include_list, FALSE)}
}
all_results[[1]] <- include_list # whether CI includes the population mean (i.e., 100) in each experiment
all_results[[2]] <- mean(include_list) # the proportion of experiments in which CIs include the population mean
all_results[[3]] <- CI # all the CIs (all pairs of upper and lower bounds from all experiments)
return(all_results)
}
- Do 1000 experiments, and see in what proportion of the experiment,
the calculated CIs (based on the equation above) contain the true
population mean (which we assume is 100).
set.seed(99)
# use the function CI_include() we defined above
# let's set the sample size to be 30 (ie. recruit 30 participants for each experiment)
CI_30 <- CI_include(1000, 30, 100, 15)
CI_30[[2]]
[1] 0.946
# In 94.6% of the 1000 experiments, we have calculated a CI that contains the true population mean (100).
Therefore, 95% confidence is a confidence that in the long-run 95% of
the CIs will include the population mean. It is a confidence in the
algorithm and not a statement about a single, specific CI.
LS0tDQp0aXRsZTogIlBMSU5TVEFUIGxlY3R1cmUgMjogU0VNIGFuZCBDSSBFeHBsYWluZWQgYnkgU2ltdWxhdGlvbiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KcGFyYW1zOg0KICBmbGV4OiBUUlVFDQotLS0NCiAgDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiNzdHVkZW50czogdGhpcyBpcyB0aGUgc2V0IHVwIGNodW5rLCBpdCBjYW4gYmUgaWdub3JlZA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGNvbW1lbnQgPSAiIikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpBdXRob3I6IEtheWxhIEtleXVlIENoZW4NCg0KTGFzdCB1cGRhdGVkOiAyMDI0LjQuMjgNCg0KIyMgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIHRoZSBNZWFuDQoNClRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYSBzdGF0aXN0aWMgaXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGF0IHN0YXRpc3RpYyB3aGVuIGRlcml2ZWQgZnJvbSBhIHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSBuLiANCg0KKiBJdCBtYXkgYmUgY29uc2lkZXJlZCBhcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBzdGF0aXN0aWMgZm9yIGFsbCBwb3NzaWJsZSBzYW1wbGVzIGZyb20gdGhlIHNhbWUgcG9wdWxhdGlvbiBvZiBhIGdpdmVuIHNhbXBsZSBzaXplLg0KDQoqIEluIG1hbnkgY29udGV4dHMsIG9ubHkgb25lIHNhbXBsZSBpcyBvYnNlcnZlZCwgYnV0IHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gY2FuIGJlIGZvdW5kIHRoZW9yZXRpY2FsbHkuDQoNCkxldCdzIHNlZSBzb21lIHNpbXVsYXRpb25zIHRvIHVuZGVyc3RhbmQgdGhlIGNvbmNlcHQuIA0KDQpXZSBhc3N1bWUgdGhhdCBJUSBzY29yZXMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBTdXBwb3NlIGl0IGlzIHRydWUgdGhhdCB0aGUgcG9wdWxhdGlvbiBoYXZlIG1lYW4gb2YgMTAwIGFuZCBTRCBvZiAxNSAobm90ZTogd2Ugd291bGRuJ3Qga25vdyB0aGlzLCBpZiBpdCdzIHJlYWwtd29ybGQgcmVzZWFyY2ggLi4uIHdlIGp1c3QgYXNzdW1lIHRoaXMgZm9yIG91ciBzaW11bGF0aW9uIGhlcmUpLiANCg0KMS4gTm93LCB3ZSByZWNydWl0IDEwMCBwYXJ0aWNpcGFudHMgYW5kIGFzc2VzcyB0aGVpciBJUS4gDQoNCmBgYHtyfQ0KIyBhc3Nlc3MgMTAwIHBhcnRpY2lwYW50cyBhbmQgcmVjb3JkIHRoZWlyIElRIHNjb3Jlcw0KSVExIDwtIHJub3JtKDEwMCwgbWVhbiA9IDEwMCwgc2QgPSAxNSkNCiMgc2VlIHRoZSBmaXJzdCAxMCB2YWx1ZXMgDQpJUTFbMToxMF0NCiMgZ2V0IHRoZSBtZWFuIG9mIHRoZSBzYW1wbGUNCihtZWFuMSA8LSBtZWFuKElRMSkpDQpgYGANCjIuIFRoaXMgaXMgb25seSBvbmUgc2FtcGxlLiBMZXQncyBoYXZlIGFub3RoZXIgZm91ciBzYW1wbGVzIA0KYGBge3J9DQojIGFzc2VzcyBhbm90aGVyIDQgZ3JvdXBzIG9mIDEwMCBwYXJ0aWNpcGFudHMgYW5kIHJlY29yZCB0aGVpciBJUSBzY29yZXMNCklRMiA8LSBybm9ybSgxMDAsIG1lYW4gPSAxMDAsIHNkID0gMTUpDQpJUTMgPC0gcm5vcm0oMTAwLCBtZWFuID0gMTAwLCBzZCA9IDE1KQ0KSVE0IDwtIHJub3JtKDEwMCwgbWVhbiA9IDEwMCwgc2QgPSAxNSkNCklRNSA8LSBybm9ybSgxMDAsIG1lYW4gPSAxMDAsIHNkID0gMTUpDQojIGdldCB0aGUgbWVhbiBvZiB0aGUgc2FtcGxlDQptZWFuMiA8LSBtZWFuKElRMikNCm1lYW4zIDwtIG1lYW4oSVEzKQ0KbWVhbjQgPC0gbWVhbihJUTQpDQptZWFuNSA8LSBtZWFuKElRNSkNCg0KIyBzYXZlIGFsbCBtZWFucyBpbnRvIGEgdmVjdG9yDQptZWFucyA8LSBjKG1lYW4xLCBtZWFuMiwgbWVhbjMsIG1lYW40LCBtZWFuNSkNCg0KIyBjYWxjdWxhdGUgdGhlIG1lYW4gb2YgdGhlIHNhbXBsZSBtZWFucyANCm1lYW4obWVhbnMpICMgd2hpY2ggaXMgcXVpdGUgY2xvc2UgdG8gMTAwISANCmBgYA0KDQozLiBMZXQncyBjcmVhdGUgYSBmdW5jdGlvbiBzbyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gZG8gaXQgYnkgaGFuZCBlYWNoIHRpbWUhIA0KDQoqIG5fZXhwID0gbnVtYmVyIG9mIGV4cGVyaW1lbnRzDQoqIHNhbXBsZV9zaXplID0gdGhlIHNhbXBsZSBzaXplIG9mIGVhY2ggZXhwZXJpbWVudA0KKiBtZWFuIGFuZCBzZCBhcmUgdGhlIG1lYW4gKDEwMCkgYW5kIHNkICgxNSkgb2YgdGhlIHBvcHVsYXRpb24gd2UgYXNzdW1lZCANCg0KYGBge3J9DQojIGRlZmluZSBhIGZ1bmN0aW9uIGNhbGxlZCBkb19leHBlcmltZW50DQojIGl0J3MgbGlrZSB3ZSBhcmUgcmVjcnVpdGluZyBwYXJ0aWNpcGFudHMgZnJvbSB0aGUgcG9wdWxhdGlvbiwgYW5kIGZvciBlYWNoIGV4cGVyaW1lbnQsIHdlIHJlY29yZCB0aGUgbWVhbiBvZiBJUSBvZiB0aGUgZ3JvdXAgb2YgcGFydGljaXBhbnRzLiANCmRvX2V4cGVyaW1lbnQgPC0gZnVuY3Rpb24obl9leHAsIHNhbXBsZV9zaXplLCBtZWFuLCBzZCl7DQogIG1lYW5fbGlzdCA8LSBjKCkNCiAgICBmb3IgKG4gaW4gMTpuX2V4cCl7DQogICAgICBvbmVfbWVhbiA8LSBtZWFuKHJub3JtKHNhbXBsZV9zaXplLCBtZWFuLCBzZCkpDQogICAgICBtZWFuX2xpc3QgPC0gYyhtZWFuX2xpc3QsIG9uZV9tZWFuKQ0KICAgIH0NCiAgcmV0dXJuKG1lYW5fbGlzdCkNCn0NCg0KIyBUcnkgMTAgZXhwZXJpbWVudCwgd2l0aCBlYWNoIG9mIHNhbXBsZSBzaXplID0gMTAwLiANCiMgTm90ZSBhZ2FpbiB0aGUgcG9wdWxhdGlvbiBpcyBhc3N1bWVkIHRvIGhhdmUgdGhlIG1lYW4gb2YgMTAwLCBhbmQgdGhlIHNkIG9mIDE1Lg0KZG9fZXhwZXJpbWVudChuX2V4cD0xMCwgc2FtcGxlX3NpemU9MTAwLCBtZWFuPTEwMCwgc2Q9MTUpICMgbWVhbiBJUSBvZiB0aGUgMTAgZXhwZXJpbWVudHMgd2UgZGlkIGFyZSBzaG93biBiZWxvdw0KYGBgDQoNCjQuIERvIHRocmVlIHR5cGVzIG9mIHNpbXVsYXRpb25zIGxpc3RlZCBiZWxvdywgY2FsY3VsYXRlIHRoZSBtZWFuIGFuZCBTRCBvZiB0aGUgc2FtcGxlIG1lYW5zLCBhbmQgcGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBtZWFucyB1c2luZyBoaXN0b2dyYW0uIA0KDQoqIERvIDEwMDAgZXhwZXJpbWVudHMuIEVhY2ggdGltZSB3ZSByZWNydWl0IDUgcGFydGljaXBhbnRzLiANCiogRG8gMTAwMCBleHBlcmltZW50cy4gRWFjaCB0aW1lIHdlIHJlY3J1aXQgMjAgcGFydGljaXBhbnRzLiANCiogRG8gMTAwMCBleHBlcmltZW50cy4gRWFjaCB0aW1lIHdlIHJlY3J1aXQgMTAwIHBhcnRpY2lwYW50cy4gDQoNCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0Kc2V0LnNlZWQoOTkpDQoNCiMgRG8gMTAwMCBleHBlcmltZW50cy4gRWFjaCB0aW1lIHdlIHJlY3J1aXQgNSwgMjAsIG9yIDEwMCBwYXJ0aWNpcGFudHMuIA0KcmVzdWx0cyA8LSBkYXRhLmZyYW1lKHNpemU1ID0gZG9fZXhwZXJpbWVudCgxMDAwLCA1LCAxMDAsIDE1KSwNCiAgICAgICAgICAgICAgICAgICAgICBzaXplMjAgPSBkb19leHBlcmltZW50KDEwMDAsIDIwLCAxMDAsIDE1KSwNCiAgICAgICAgICAgICAgICAgICAgICBzaXplMTAwID0gZG9fZXhwZXJpbWVudCgxMDAwLCAxMDAsIDEwMCwgMTUpKQ0KDQojIHNob3cgbWVhbnMgZnJvbSB0aGUgZmlyc3QgNiBleHBlcmltZW50cyBmb3IgZWFjaCBzYW1wbGUgc2l6ZQ0KaGVhZChyZXN1bHRzKQ0KDQojIGRyYXcgYSBoaXN0b2dyYW0gb2YgbWVhbnMgZm9yIGVhY2ggc2FtcGxlIHNpemUNCnJlc3VsdHNfbG9uZyA8LSByZXN1bHRzICU+JSBnYXRoZXIoc2l6ZSwgbWVhbnMsIDE6MykgJT4lIA0KICBtdXRhdGUoc2l6ZSA9IGZhY3RvcihzaXplLCBsZXZlbHMgPSBjKCJzaXplNSIsInNpemUyMCIsInNpemUxMDAiKSkpDQpnZ3Bsb3QocmVzdWx0c19sb25nLCBhZXMoeCA9IG1lYW5zKSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAyLCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArIA0KICB4bGltKDcwLCAxMzApICsgDQogIGZhY2V0X3dyYXAofnNpemUpDQpgYGANCg0KV2hhdCBkbyB5b3UgZmluZCBhYm91dCB0aGUgc3ByZWFkaW5nIG9mIHRoZSBkaXN0cmlidXRpb25zPyAtIFRoZSBsYXJnZXIgdGhlIHNhbXBsZSBzaXplLCB0aGUgbW9yZSBzcHJlYWRpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgaXMuIA0KDQojIyBTdGFuZGFyZCBFcnJvciBvZiB0aGUgTWVhbiAoU0VNKQ0KDQpSZWNhbGwgdGhhdCAkU3RhbmRhcmRcIEVycm9yXCBvZlwgdGhlXCBNZWFuXCAoU0VNKSA9IFxmcmFje1NEfXtcc3FydHtOfX0kLiANCg0KU2luY2UgdGhlIGRlbm9taW5hdG9yIGlzIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgc2FtcGxlIHNpemUgKE4pLCB0aGUgbGFyZ2VyIHRoZSBzYW1wbGUgc2l6ZSwgdGhlIHNtYWxsZXIgdGhlIFNFTS4gVGhpcyBpcyBjb25zaXN0ZW50IHdpdGggb3VyIG9ic2VydmF0aW9uIGFib3ZlLiBUaGUgbGFyZ2VyIHRoZSBzYW1wbGUgc2l6ZSwgdGhlIG1vcmUgc3ByZWFkaW5nIHRoZSBkaXN0cmlidXRpb24gb2Ygc2FtcGxlIG1lYW5zIGlzISANCg0KNS4gTGV0J3MgY2FsY3VsYXRlIHRoZSBTRU0gdXNpbmcgdGhlIGVxdWF0aW9uIGFib3ZlLCBhbmQgY29tcGFyZSB0byB0aGUgU0Qgb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgKHdlJ3ZlIGdvdCB0aGVtIGZyb20gcGFydCA0KS4NCg0KYGBge3J9DQpjb21wYXJlIDwtIGRhdGEuZnJhbWUoc2l6ZTUgPSBjKHNkKHJub3JtKDUsIDEwMCwgMTUpKS9zcXJ0KDUpLCBzZChyZXN1bHRzJHNpemU1KSksDQogICAgICAgICAgICAgICAgICAgICAgc2l6ZTIwID0gYyhzZChybm9ybSgyMCwgMTAwLCAxNSkpL3NxcnQoMjApLCBzZChyZXN1bHRzJHNpemUyMCkpLA0KICAgICAgICAgICAgICAgICAgICAgIHNpemUxMDAgPSBjKHNkKHJub3JtKDEwMCwgMTAwLCAxNSkpL3NxcnQoMTAwKSwgc2QocmVzdWx0cyRzaXplMTAwKSkpDQpyb3cubmFtZXMoY29tcGFyZSkgPC0gYygiQ2FsY3VsYXRlZCIsICJTaW11bGF0ZWQiKQ0KY29tcGFyZQ0KYGBgDQoNCkV2ZXJ5IHRpbWUgeW91IHJ1biB0aGlzIGNodW5rIG9mIGNvZGUsIHRoZSByZXN1bHRzIHdvdWxkIGJlIHNsaWdodGx5IGRpZmZlcmVudCBmb3IgdGhlICJDYWxjdWxhdGVkIiBTRU0uIFRoaXMgaXMgYmVjYXVzZSBldmVyeSB0aW1lIHlvdSBydW4gdGhlIGNvZGUsIHlvdSBhcmUgcmVjcnVpdGluZyBuZXcgZ3JvdXBzIG9mIHBhcnRpY2lwYW50cy4gTmV2ZXJ0aGVsZXNzLCB5b3UgY2FuIHNlZSB0aGF0IHRoZSByZXN1bHRzIGFyZSBjbG9zZSB0byB0aG9zZSBpbiBvdXIgcHJldmlvdXMgc2ltdWxhdGlvbnMgKGluIHBhcnQgNCkgYXQgbGVhc3QgbW9zdCBvZiB0aGUgdGltZS4gVGhleSBhcmUgY2xvc2VyIGZvciBsYXJnZXIgc2FtcGxlIHNpemUsIDIwIGFuZCAxMDAuDQoNCk5COiBGb3IgdGhlIHB1cnBvc2Ugb2YgcmVwbGljYXRpb24sIHlvdSBjYW4gc2V0IHNlZWQgYnkgYHNldC5zZWVkKClgIHRvIGdldCB0aGUgc2FtZSByZXN1bHRzIGV2ZXJ5IHRpbWUgKGFzIGxvbmcgYXMgdGhlIHNlZWQgaXMgdGhlIHNhbWUpLiBUaGlzIGlzIHdoYXQgd2UgZGlkIGluIHNvbWUgb3RoZXIgY29kZSBjaHVua3MuIA0KDQojIyA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbCAoQ0kpIG9mIHRoZSBNZWFuIA0KDQpDb25maWRlbmNlIGludGVydmFsIChDSSkgaXMgYSByYW5nZSBvZiBlc3RpbWF0ZXMgZm9yIGFuIHVua25vd24gcGFyYW1ldGVyLiBBIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgY29tcHV0ZWQgYXQgYSBkZXNpZ25hdGVkIGNvbmZpZGVuY2UgbGV2ZWwsIG1vc3QgY29tbW9ubHkgOTUlLg0KDQpUaGUgZXF1YXRpb24gdG8gY2FsY3VsYXRlIDk1JSBDSSBpcyAkQ0kgPSBNZWFuXCBccG1cIDEuOTYgXHRpbWVzIFNFTSQNCg0KNi4gTGV0J3MgZGVmaW5lIGEgZnVuY3Rpb24gdG8gZG8gbnVtZXJvdXMgZXhwZXJpbWVudHMgZm9yIHVzLiANCg0KKiBuX2V4cCA9IG51bWJlciBvZiBleHBlcmltZW50cw0KKiBzYW1wbGVfc2l6ZSA9IHRoZSBzYW1wbGUgc2l6ZSBvZiBlYWNoIGV4cGVyaW1lbnQNCiogcF9tZWFuIGFuZCBwX3NkIGFyZSB0aGUgbWVhbiBhbmQgc2Qgb2YgdGhlIHBvcHVsYXRpb24gd2UgYXNzdW1lZCANCg0KVGhlIGZ1bmN0aW9uIHdpbGwgcmVjb3JkIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb246IA0KDQoqIFdoZXRoZXIgQ0kgaW5jbHVkZXMgdGhlIHBvcHVsYXRpb24gbWVhbiAoaS5lLiwgMTAwKSBpbiBlYWNoIGV4cGVyaW1lbnQNCiogVGhlIHByb3BvcnRpb24gb2YgZXhwZXJpbWVudHMgaW4gd2hpY2ggQ0lzIGluY2x1ZGUgdGhlIHBvcHVsYXRpb24gbWVhbiANCiogQWxsIHRoZSBDSXMgKGFsbCBwYWlycyBvZiB1cHBlciBhbmQgbG93ZXIgYm91bmRzIGZyb20gYWxsIGV4cGVyaW1lbnRzKQ0KDQpgYGB7cn0NCiMgZGVmaW5lIGEgZnVuY3Rpb24gY2FsbGVkIENJX2luY2x1ZGUNCiMgaXQncyBsaWtlIHdlIGFyZSByZWNydWl0aW5nIHBhcnRpY2lwYW50cyBmcm9tIHRoZSBwb3B1bGF0aW9uLCBhbmQgZm9yIGVhY2ggZXhwZXJpbWVudCwgd2UgY2FsY3VsYXRlIENJIG9mIHRoZSBtZWFuIG9mIElRLiANCkNJX2luY2x1ZGUgPC0gZnVuY3Rpb24obl9leHAsIHNhbXBsZV9zaXplLCBwX21lYW4sIHBfc2Qpew0KICBhbGxfcmVzdWx0cyA8LSBjKCkNCiAgaW5jbHVkZV9saXN0IDwtIGMoKQ0KICBDSSA8LSBjKCkNCiAgICBmb3IgKGkgaW4gMTpuX2V4cCl7DQogICAgICBzYW1wbGVzIDwtIHJub3JtKHNhbXBsZV9zaXplLCBwX21lYW4sIHBfc2QpDQogICAgICBtZWFuIDwtIG1lYW4oc2FtcGxlcykNCiAgICAgIHNkIDwtIHNkKHNhbXBsZXMpDQogICAgICBzZSA8LSBzZC9zcXJ0KHNhbXBsZV9zaXplKQ0KICAgICAgQ0lbW2ldXSA8LSBjKG1lYW4gLSAxLjk2ICogc2UsIG1lYW4gKyAxLjk2ICogc2UpDQogICAgICBpZiAoQ0lbW2ldXVsxXSA8PSAxMDAgJiBDSVtbaV1dWzJdID49IDEwMCl7DQogICAgICAgIGluY2x1ZGVfbGlzdCA8LSBjKGluY2x1ZGVfbGlzdCwgVFJVRSl9DQogICAgICBlbHNlIHsNCiAgICAgICAgaW5jbHVkZV9saXN0IDwtIGMoaW5jbHVkZV9saXN0LCBGQUxTRSl9DQogICAgfQ0KICBhbGxfcmVzdWx0c1tbMV1dIDwtIGluY2x1ZGVfbGlzdCAjIHdoZXRoZXIgQ0kgaW5jbHVkZXMgdGhlIHBvcHVsYXRpb24gbWVhbiAoaS5lLiwgMTAwKSBpbiBlYWNoIGV4cGVyaW1lbnQNCiAgYWxsX3Jlc3VsdHNbWzJdXSA8LSBtZWFuKGluY2x1ZGVfbGlzdCkgIyB0aGUgcHJvcG9ydGlvbiBvZiBleHBlcmltZW50cyBpbiB3aGljaCBDSXMgaW5jbHVkZSB0aGUgcG9wdWxhdGlvbiBtZWFuIA0KICBhbGxfcmVzdWx0c1tbM11dIDwtIENJICMgYWxsIHRoZSBDSXMgKGFsbCBwYWlycyBvZiB1cHBlciBhbmQgbG93ZXIgYm91bmRzIGZyb20gYWxsIGV4cGVyaW1lbnRzKQ0KICByZXR1cm4oYWxsX3Jlc3VsdHMpDQp9DQpgYGANCg0KNy4gRG8gMTAwMCBleHBlcmltZW50cywgYW5kIHNlZSBpbiB3aGF0IHByb3BvcnRpb24gb2YgdGhlIGV4cGVyaW1lbnQsIHRoZSBjYWxjdWxhdGVkIENJcyAoYmFzZWQgb24gdGhlIGVxdWF0aW9uIGFib3ZlKSBjb250YWluIHRoZSB0cnVlIHBvcHVsYXRpb24gbWVhbiAod2hpY2ggd2UgYXNzdW1lIGlzIDEwMCkuIA0KDQpgYGB7cn0NCnNldC5zZWVkKDk5KQ0KDQojIHVzZSB0aGUgZnVuY3Rpb24gQ0lfaW5jbHVkZSgpIHdlIGRlZmluZWQgYWJvdmUNCiMgbGV0J3Mgc2V0IHRoZSBzYW1wbGUgc2l6ZSB0byBiZSAzMCAoaWUuIHJlY3J1aXQgMzAgcGFydGljaXBhbnRzIGZvciBlYWNoIGV4cGVyaW1lbnQpDQpDSV8zMCA8LSBDSV9pbmNsdWRlKDEwMDAsIDMwLCAxMDAsIDE1KQ0KQ0lfMzBbWzJdXQ0KIyBJbiA5NC42JSBvZiB0aGUgMTAwMCBleHBlcmltZW50cywgd2UgaGF2ZSBjYWxjdWxhdGVkIGEgQ0kgdGhhdCBjb250YWlucyB0aGUgdHJ1ZSBwb3B1bGF0aW9uIG1lYW4gKDEwMCkuIA0KYGBgDQpUaGVyZWZvcmUsIDk1JSBjb25maWRlbmNlIGlzIGEgY29uZmlkZW5jZSB0aGF0IGluIHRoZSBsb25nLXJ1biA5NSUgb2YgdGhlIENJcyB3aWxsIGluY2x1ZGUgdGhlIHBvcHVsYXRpb24gbWVhbi4gSXQgaXMgYSBjb25maWRlbmNlIGluIHRoZSBhbGdvcml0aG0gYW5kIG5vdCBhIHN0YXRlbWVudCBhYm91dCBhIHNpbmdsZSwgc3BlY2lmaWMgQ0kuDQo=