Uniform and Poisson distribution

Let’s generate 200 samples from uniform distribution in the interval \([0,10]\).

set.seed(2017)
n <- 1000
sample <- runif(n, min = 0, max = 10)
hist(sample, breaks = 100, probability = TRUE, col = 3, main = "Uniform distribution samples")
lines(density(sample, adjust = 2), col = 2)

If we divide the interval \([0,10]\) into \(k\) sub-intervals and count how many data points are inside each of them, say \(n_1, \cdots, n_k\). Then these counts will follow Poisson distribution. That is, \[ \mathbb{P} (m \text{ points in a unit interval}) = \frac{\lambda^m}{m!}e^{-\lambda}, m=0,1,\cdots\]

Therefore, we expect \(\{n_1, \cdots, n_k\}\) to follow a Poisson. Let’s verify it by simulation. We divide the interval into 100 sub-intervals, i.e. \(k = 100\).

k <- 100
tab <- table(cut(sample, breaks = seq(0, 10, length.out = k+1), include.lowest = TRUE))
head(tab, 10)

  [0,0.1] (0.1,0.2] (0.2,0.3] (0.3,0.4] (0.4,0.5] (0.5,0.6] (0.6,0.7] (0.7,0.8] (0.8,0.9]   (0.9,1] 
       13        10        13         8        11         5        11         7         6         7 
counts <- as.vector(tab)
head(counts, 10)
 [1] 13 10 13  8 11  5 11  7  6  7

So by theory, the counts should follow a Poisson process. Let’s compare it with a generated Poisson sequence. We know \(\lambda\) equals to the expected number of points in an interval, so here, we set \(\lambda = k^{-1}\sum_{i=1}^k n_i\).

hist(counts, breaks = 15, col = rgb(1,0,0,0.5), probability = TRUE, xlab = "number of points inside an interval", ylim = c(0,0.2))
lines(density(counts, adjust = 2), col = rgb(1,0,0,0.5))
Pois <- rpois(1000, lambda = mean(counts))
hist(Pois, breaks = 15, col = rgb(0,0,1,0.5), probability = TRUE, add = TRUE)
lines(density(Pois, adjust = 2), col = rgb(0,0,1,0.5))
legend(x = 14, y = 0.15, legend = c("sample", "Poisson"), lty = c(1,1), col = c(rgb(1,0,0,0.5), rgb(0,0,1,0.5)))

We can see our counts variable is indeed very close to Poisson distribution.

Pearson’s \(\chi^2\) Test (goodness of fit)

A test of goodness of fit establishes whether an observed frequency distribution differs from a theoretical distribution.

Test procedure

Let’s now use the Peason’s \(\chi^2\) test to check whether the sample does follow Uniform distribution (because we know we generated the sample from Uniform, so of course we should expect a good result).

  • Step 1. Calculate the chi-squared test statistic, \(\chi^2\), which resembles a normalized sum of squared deviations between observed and theoretical frequencies, \(O_i\) and \(E_i\). The formula is \[ \chi^2 = \sum_{i=1}^k \frac{(O_i - E_i)^2}{E_i} = n \sum_{i=1}^k \frac{(O_i/n - p_i)^2}{p_i}, \] where \(k\) is the number of cells or intervals in which you calculated frequencies, \(n\) is the total number of samples, and \(p_i = E_i/n\) is the expected probability in the \(i\)-th interval.

    Let’s calculate the observed and theoretical frequencies for our sample and Uniform distribution. We already have our \(O_i\)’s, for Uniform distribution, we know \(E_i = n/k = 1000/100\) in this case. We have \(\chi^2 = 82.2\).

E_i <- n/k
chi_2 <- sum((counts - E_i)^2/E_i)
chi_2
  • Step 2. Determine the degrees of freedom, df, of that statistic. In the test of goodness of fit, the degree of freedom equals to \(k - p\), where \(k\) is the number of cells or intervals, and \(p = s+1\) is the contraint in that distribution, here, \(s\) is the number of parameters for the distribution we want to test against. For example, a Normal distribution \(\mathcal{N}(\mu, \sigma^2)\) has two parameters, \(\mu\) and \(\sigma\), thus \(s = 2\). In our discrete Uniform case, we have \(p = 1\). So df will be \(100-1=99\).

  • Step 3. Select a desired level of confidence. We will select \(\alpha = 0.05\).

  • Step 4.
    • Compare the test statistic \(\chi^2\) to the value from the chi-squared distribution with df degrees of freedom and the selected confidence level, \(1 - \alpha\).
    • Or we can calculate the \(p\)-value, \(\mathbb{P}(X > \chi^2)\), where \(X\) is a chi-square random variable with df degree of freedoms.
    • Note that the test is one-sided.
chi2_compare <- qchisq(p = 0.95, df = 99)
chi2_compare
p_value <- 1 - pchisq(chi_2, df = 99)
p_value

Built-in R function

We can also use the built-in function chisq.test().

p_i <- rep(E_i/n, k)
chisq.test(counts, p = p_i)

Standardized residual plot

We can also plot the standardized residuals, which are defined to be \[ R_i = \frac{|O_i - E_i|}{\sqrt{E_i}}\] in each interval. So recall the definition of \(\chi^2\) statistic, we actually have \[\chi^2 = \sum_{i=1}^k R_i^2.\]

Residuals <- (counts - E_i) / sqrt(E_i)
plot(Residuals, type = 'h', ylab = "standardized residuals", xlab = "interval index")

Two Sample t-test

set.seed(2017)
sample1 <- rnorm(200, mean = 0, sd = 1)
sample2 <- rnorm(300, mean = 2, sd = 1)
sample3 <- rnorm(250, mean = 0, sd = 10)

Check if two samples have the same variance.

var.test(sample1, sample2)

    F test to compare two variances

data:  sample1 and sample2
F = 0.96949, num df = 199, denom df = 299, p-value = 0.8179
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.7543491 1.2542128
sample estimates:
ratio of variances 
         0.9694931 
var.test(sample1, sample3)

    F test to compare two variances

data:  sample1 and sample3
F = 0.0096017, num df = 199, denom df = 249, p-value < 2.2e-16
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.007386628 0.012530430
sample estimates:
ratio of variances 
       0.009601719 

At level \(\alpha = 0.05\), we accept sample1 and sample2 have the same variance, and reject the hypothesis that sample1 and sample3 have the same variance.

t.test(sample1, sample2, paired = FALSE, var.equal = TRUE)

    Two Sample t-test

data:  sample1 and sample2
t = -22.493, df = 498, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2.160604 -1.813477
sample estimates:
 mean of x  mean of y 
0.02008153 2.00712204 
t.test(sample1, sample3, paired = FALSE, var.equal = FALSE)

    Welch Two Sample t-test

data:  sample1 and sample3
t = -1.2912, df = 254.97, p-value = 0.1978
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2.0295776  0.4221389
sample estimates:
 mean of x  mean of y 
0.02008153 0.82380085 

At level \(\alpha = 0.05\), we can conclude that sample1 and sample2 have different means, while sample1 and sample3 have the same mean.

LS0tCnRpdGxlOiAiTWF0aCAxODkvMjg5IExhYiAzIgphdXRob3I6ICJBbGV4IEhhbmJvIExpIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIFVuaWZvcm0gYW5kIFBvaXNzb24gZGlzdHJpYnV0aW9uCkxldCdzIGdlbmVyYXRlIDIwMCBzYW1wbGVzIGZyb20gdW5pZm9ybSBkaXN0cmlidXRpb24gaW4gdGhlIGludGVydmFsICRbMCwxMF0kLgpgYGB7cn0Kc2V0LnNlZWQoMjAxNykKbiA8LSAxMDAwCnNhbXBsZSA8LSBydW5pZihuLCBtaW4gPSAwLCBtYXggPSAxMCkKaGlzdChzYW1wbGUsIGJyZWFrcyA9IDEwMCwgcHJvYmFiaWxpdHkgPSBUUlVFLCBjb2wgPSAzLCBtYWluID0gIlVuaWZvcm0gZGlzdHJpYnV0aW9uIHNhbXBsZXMiKQpsaW5lcyhkZW5zaXR5KHNhbXBsZSwgYWRqdXN0ID0gMiksIGNvbCA9IDIpCmBgYAoKSWYgd2UgZGl2aWRlIHRoZSBpbnRlcnZhbCAkWzAsMTBdJCBpbnRvICRrJCBzdWItaW50ZXJ2YWxzIGFuZCBjb3VudCBob3cgbWFueSBkYXRhIHBvaW50cyBhcmUgaW5zaWRlIGVhY2ggb2YgdGhlbSwgc2F5ICRuXzEsIFxjZG90cywgbl9rJC4gVGhlbiB0aGVzZSBjb3VudHMgd2lsbCBmb2xsb3cgUG9pc3NvbiBkaXN0cmlidXRpb24uIFRoYXQgaXMsCiQkIFxtYXRoYmJ7UH0gKG0gXHRleHR7IHBvaW50cyBpbiBhIHVuaXQgaW50ZXJ2YWx9KSA9IFxmcmFje1xsYW1iZGFebX17bSF9ZV57LVxsYW1iZGF9LCBtPTAsMSxcY2RvdHMkJAoKVGhlcmVmb3JlLCB3ZSBleHBlY3QgJFx7bl8xLCBcY2RvdHMsIG5fa1x9JCB0byBmb2xsb3cgYSBQb2lzc29uLiBMZXQncyB2ZXJpZnkgaXQgYnkgc2ltdWxhdGlvbi4gV2UgZGl2aWRlIHRoZSBpbnRlcnZhbCBpbnRvIDEwMCBzdWItaW50ZXJ2YWxzLCBpLmUuICRrID0gMTAwJC4KYGBge3J9CmsgPC0gMTAwCnRhYiA8LSB0YWJsZShjdXQoc2FtcGxlLCBicmVha3MgPSBzZXEoMCwgMTAsIGxlbmd0aC5vdXQgPSBrKzEpLCBpbmNsdWRlLmxvd2VzdCA9IFRSVUUpKQpoZWFkKHRhYiwgMTApCmNvdW50cyA8LSBhcy52ZWN0b3IodGFiKQpoZWFkKGNvdW50cywgMTApCmBgYAoKU28gYnkgdGhlb3J5LCB0aGUgKipjb3VudHMqKiBzaG91bGQgZm9sbG93IGEgUG9pc3NvbiBwcm9jZXNzLiBMZXQncyBjb21wYXJlIGl0IHdpdGggYSBnZW5lcmF0ZWQgUG9pc3NvbiBzZXF1ZW5jZS4gV2Uga25vdyAkXGxhbWJkYSQgZXF1YWxzIHRvIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgcG9pbnRzIGluIGFuIGludGVydmFsLCBzbyBoZXJlLCB3ZSBzZXQgJFxsYW1iZGEgPSBrXnstMX1cc3VtX3tpPTF9Xmsgbl9pJC4KYGBge3J9Cmhpc3QoY291bnRzLCBicmVha3MgPSAxNSwgY29sID0gcmdiKDEsMCwwLDAuNSksIHByb2JhYmlsaXR5ID0gVFJVRSwgeGxhYiA9ICJudW1iZXIgb2YgcG9pbnRzIGluc2lkZSBhbiBpbnRlcnZhbCIsIHlsaW0gPSBjKDAsMC4yKSkKbGluZXMoZGVuc2l0eShjb3VudHMsIGFkanVzdCA9IDIpLCBjb2wgPSByZ2IoMSwwLDAsMC41KSkKUG9pcyA8LSBycG9pcygxMDAwLCBsYW1iZGEgPSBtZWFuKGNvdW50cykpCmhpc3QoUG9pcywgYnJlYWtzID0gMTUsIGNvbCA9IHJnYigwLDAsMSwwLjUpLCBwcm9iYWJpbGl0eSA9IFRSVUUsIGFkZCA9IFRSVUUpCmxpbmVzKGRlbnNpdHkoUG9pcywgYWRqdXN0ID0gMiksIGNvbCA9IHJnYigwLDAsMSwwLjUpKQpsZWdlbmQoeCA9IDE0LCB5ID0gMC4xNSwgbGVnZW5kID0gYygic2FtcGxlIiwgIlBvaXNzb24iKSwgbHR5ID0gYygxLDEpLCBjb2wgPSBjKHJnYigxLDAsMCwwLjUpLCByZ2IoMCwwLDEsMC41KSkpCmBgYAoKV2UgY2FuIHNlZSBvdXIgKipjb3VudHMqKiB2YXJpYWJsZSBpcyBpbmRlZWQgdmVyeSBjbG9zZSB0byBQb2lzc29uIGRpc3RyaWJ1dGlvbi4KCgoKIyBQZWFyc29uJ3MgJFxjaGleMiQgVGVzdCAoZ29vZG5lc3Mgb2YgZml0KQoKQSB0ZXN0IG9mIGdvb2RuZXNzIG9mIGZpdCBlc3RhYmxpc2hlcyB3aGV0aGVyIGFuIG9ic2VydmVkICoqZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbioqIGRpZmZlcnMgZnJvbSBhICoqdGhlb3JldGljYWwgZGlzdHJpYnV0aW9uKiouCgojIyMgVGVzdCBwcm9jZWR1cmUKTGV0J3Mgbm93IHVzZSB0aGUgUGVhc29uJ3MgJFxjaGleMiQgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSAqKnNhbXBsZSoqIGRvZXMgZm9sbG93IFVuaWZvcm0gZGlzdHJpYnV0aW9uIChiZWNhdXNlIHdlIGtub3cgd2UgZ2VuZXJhdGVkIHRoZSBzYW1wbGUgZnJvbSBVbmlmb3JtLCBzbyBvZiBjb3Vyc2Ugd2Ugc2hvdWxkIGV4cGVjdCBhIGdvb2QgcmVzdWx0KS4KCiogU3RlcCAxLiAKQ2FsY3VsYXRlIHRoZSBjaGktc3F1YXJlZCB0ZXN0IHN0YXRpc3RpYywgJFxjaGleMiQsIHdoaWNoIHJlc2VtYmxlcyBhIG5vcm1hbGl6ZWQgc3VtIG9mIHNxdWFyZWQgZGV2aWF0aW9ucyBiZXR3ZWVuIG9ic2VydmVkIGFuZCB0aGVvcmV0aWNhbCBmcmVxdWVuY2llcywgJE9faSQgYW5kICRFX2kkLiBUaGUgZm9ybXVsYSBpcyAKJCQgXGNoaV4yID0gXHN1bV97aT0xfV5rIFxmcmFjeyhPX2kgLSBFX2kpXjJ9e0VfaX0gPSBuIFxzdW1fe2k9MX1eayBcZnJhY3soT19pL24gLSBwX2kpXjJ9e3BfaX0sICQkCndoZXJlICRrJCBpcyB0aGUgbnVtYmVyIG9mIGNlbGxzIG9yIGludGVydmFscyBpbiB3aGljaCB5b3UgY2FsY3VsYXRlZCBmcmVxdWVuY2llcywgJG4kIGlzIHRoZSB0b3RhbCBudW1iZXIgb2Ygc2FtcGxlcywgYW5kICRwX2kgPSBFX2kvbiQgaXMgdGhlIGV4cGVjdGVkIHByb2JhYmlsaXR5IGluIHRoZSAkaSQtdGggaW50ZXJ2YWwuCgogICAgTGV0J3MgY2FsY3VsYXRlIHRoZSBvYnNlcnZlZCBhbmQgdGhlb3JldGljYWwgZnJlcXVlbmNpZXMgZm9yIG91ciBzYW1wbGUgYW5kIFVuaWZvcm0gZGlzdHJpYnV0aW9uLiAKICAgIFdlIGFscmVhZHkgaGF2ZSBvdXIgJE9faSQncywgZm9yIFVuaWZvcm0gZGlzdHJpYnV0aW9uLCB3ZSBrbm93ICRFX2kgPSBuL2sgPSAxMDAwLzEwMCQgaW4gdGhpcyBjYXNlLiBXZSBoYXZlICRcY2hpXjIgPSA4Mi4yJC4KICAgIAoKYGBge3J9CkVfaSA8LSBuL2sKY2hpXzIgPC0gc3VtKChjb3VudHMgLSBFX2kpXjIvRV9pKQpjaGlfMgpgYGAKCiogU3RlcCAyLgpEZXRlcm1pbmUgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSwgKmRmKiwgb2YgdGhhdCBzdGF0aXN0aWMuIEluIHRoZSB0ZXN0IG9mIGdvb2RuZXNzIG9mIGZpdCwgdGhlIGRlZ3JlZSBvZiBmcmVlZG9tIGVxdWFscyB0byAkayAtIHAkLCB3aGVyZSAkayQgaXMgdGhlIG51bWJlciBvZiBjZWxscyBvciBpbnRlcnZhbHMsIGFuZCAkcCA9IHMrMSQgaXMgdGhlIGNvbnRyYWludCBpbiB0aGF0IGRpc3RyaWJ1dGlvbiwgaGVyZSwgJHMkIGlzIHRoZSBudW1iZXIgb2YgcGFyYW1ldGVycyBmb3IgdGhlIGRpc3RyaWJ1dGlvbiB3ZSB3YW50IHRvIHRlc3QgYWdhaW5zdC4gRm9yIGV4YW1wbGUsIGEgTm9ybWFsIGRpc3RyaWJ1dGlvbiAkXG1hdGhjYWx7Tn0oXG11LCBcc2lnbWFeMikkIGhhcyB0d28gcGFyYW1ldGVycywgJFxtdSQgYW5kICRcc2lnbWEkLCB0aHVzICRzID0gMiQuIEluIG91ciBkaXNjcmV0ZSBVbmlmb3JtIGNhc2UsIHdlIGhhdmUgJHAgPSAxJC4gU28gKmRmKiB3aWxsIGJlICQxMDAtMT05OSQuCgoqIFN0ZXAgMy4KU2VsZWN0IGEgZGVzaXJlZCBsZXZlbCBvZiBjb25maWRlbmNlLiBXZSB3aWxsIHNlbGVjdCAkXGFscGhhID0gMC4wNSQuCgoqIFN0ZXAgNC4KICAgICsgQ29tcGFyZSB0aGUgdGVzdCBzdGF0aXN0aWMgJFxjaGleMiQgdG8gdGhlIHZhbHVlIGZyb20gdGhlIGNoaS1zcXVhcmVkIGRpc3RyaWJ1dGlvbiB3aXRoICpkZiogZGVncmVlcyBvZiBmcmVlZG9tIGFuZCB0aGUgc2VsZWN0ZWQgY29uZmlkZW5jZSBsZXZlbCwgJDEgLSBcYWxwaGEkLgogICAgKyBPciB3ZSBjYW4gY2FsY3VsYXRlIHRoZSAkcCQtdmFsdWUsICRcbWF0aGJie1B9KFggPiBcY2hpXjIpJCwgd2hlcmUgJFgkIGlzIGEgY2hpLXNxdWFyZSByYW5kb20gdmFyaWFibGUgd2l0aCAqZGYqIGRlZ3JlZSBvZiBmcmVlZG9tcy4KICAgICsgTm90ZSB0aGF0IHRoZSB0ZXN0IGlzIG9uZS1zaWRlZC4KYGBge3J9CmNoaTJfY29tcGFyZSA8LSBxY2hpc3EocCA9IDAuOTUsIGRmID0gOTkpCmNoaTJfY29tcGFyZQpwX3ZhbHVlIDwtIDEgLSBwY2hpc3EoY2hpXzIsIGRmID0gOTkpCnBfdmFsdWUKYGBgCgojIyMgQnVpbHQtaW4gUiBmdW5jdGlvbgpXZSBjYW4gYWxzbyB1c2UgdGhlIGJ1aWx0LWluIGZ1bmN0aW9uIGBjaGlzcS50ZXN0KClgLgpgYGB7cn0KcF9pIDwtIHJlcChFX2kvbiwgaykKY2hpc3EudGVzdChjb3VudHMsIHAgPSBwX2kpCmBgYAoKIyMjIFN0YW5kYXJkaXplZCByZXNpZHVhbCBwbG90CldlIGNhbiBhbHNvIHBsb3QgdGhlIHN0YW5kYXJkaXplZCByZXNpZHVhbHMsIHdoaWNoIGFyZSBkZWZpbmVkIHRvIGJlCiQkIFJfaSA9IFxmcmFje3xPX2kgLSBFX2l8fXtcc3FydHtFX2l9fSQkCmluIGVhY2ggaW50ZXJ2YWwuClNvIHJlY2FsbCB0aGUgZGVmaW5pdGlvbiBvZiAkXGNoaV4yJCBzdGF0aXN0aWMsIHdlIGFjdHVhbGx5IGhhdmUgCiQkXGNoaV4yID0gXHN1bV97aT0xfV5rIFJfaV4yLiQkCmBgYHtyfQpSZXNpZHVhbHMgPC0gKGNvdW50cyAtIEVfaSkgLyBzcXJ0KEVfaSkKcGxvdChSZXNpZHVhbHMsIHR5cGUgPSAnaCcsIHlsYWIgPSAic3RhbmRhcmRpemVkIHJlc2lkdWFscyIsIHhsYWIgPSAiaW50ZXJ2YWwgaW5kZXgiKQpgYGAKCiMgVHdvIFNhbXBsZSB0LXRlc3QKKiBUd28gc2FtcGxlIHQtdGVzdCBjYW4gYmUgdXNlZCB0byBkZXRlcm1pbmUgaWYgdGhlIG1lYW5zIG9mIHR3byBzZXRzIG9mIGRhdGEgYXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50LiBCdXQgb25lIG9mIHRoZSB1bmRlcmx5aW5nIGFzc3VtcHRpb25zIGlzIHRoYXQgYm90aCBncm91cCBvZiBkYXRhIGZvbGxvdyBOb3JtYWwgZGlzdHJpYnV0aW9uLiBTbyB3ZSBzaG91bGQgZmlyc3QgY2hlY2sgaWYgTm9ybWFsaXR5IGFzc3VtcHRpb24gaXMgc2F0aXNmaWVkIChRLVEgcGxvdCwgZWNkZiwgU2hhcGlyb+KAk1dpbGssIEtvbG1vZ29yb3bigJNTbWlybm92KSBiZWZvcmUgd2UgYXBwbHkgdGhpcyB0ZXN0LgoqIFdlIHNob3VsZCBmaXJzdCBjaGVjayBpZiB0d28gc2FtcGxlcyBoYXZlIHRoZSBzYW1lIHZhcmlhbmNlLiBUaGlzIGNhbiBiZSBkb25lIHVzaW5nIEZpc2hlcidzIEYtdGVzdCAoaXQgY291bnRzIGluIHRoZSBlZmZlY3Qgb2YgZGlmZmVyZW50IHNhbXBsZSBzaXplcykuCiogRGV0YWlscyBvZiB0d28gc2FtcGxlIHQtdGVzdCBhcmUgcG9zdHBvbmVkIHRvIE1BVEggMTgxIGlmIHlvdSBoYXZlIG5vdCB0b3VjaGVkIGl0IGJlZm9yZS4KYGBge3J9CnNldC5zZWVkKDIwMTcpCnNhbXBsZTEgPC0gcm5vcm0oMjAwLCBtZWFuID0gMCwgc2QgPSAxKQpzYW1wbGUyIDwtIHJub3JtKDMwMCwgbWVhbiA9IDIsIHNkID0gMSkKc2FtcGxlMyA8LSBybm9ybSgyNTAsIG1lYW4gPSAwLCBzZCA9IDEwKQpgYGAKCkNoZWNrIGlmIHR3byBzYW1wbGVzIGhhdmUgdGhlIHNhbWUgdmFyaWFuY2UuCmBgYHtyfQp2YXIudGVzdChzYW1wbGUxLCBzYW1wbGUyKQp2YXIudGVzdChzYW1wbGUxLCBzYW1wbGUzKQpgYGAKCkF0IGxldmVsICRcYWxwaGEgPSAwLjA1JCwgd2UgYWNjZXB0ICpzYW1wbGUxKiBhbmQgKnNhbXBsZTIqIGhhdmUgdGhlIHNhbWUgdmFyaWFuY2UsIGFuZCByZWplY3QgdGhlIGh5cG90aGVzaXMgdGhhdCAqc2FtcGxlMSogYW5kICpzYW1wbGUzKiBoYXZlIHRoZSBzYW1lIHZhcmlhbmNlLgoKYGBge3J9CnQudGVzdChzYW1wbGUxLCBzYW1wbGUyLCBwYWlyZWQgPSBGQUxTRSwgdmFyLmVxdWFsID0gVFJVRSkKdC50ZXN0KHNhbXBsZTEsIHNhbXBsZTMsIHBhaXJlZCA9IEZBTFNFLCB2YXIuZXF1YWwgPSBGQUxTRSkKYGBgCkF0IGxldmVsICRcYWxwaGEgPSAwLjA1JCwgd2UgY2FuIGNvbmNsdWRlIHRoYXQgKnNhbXBsZTEqIGFuZCAqc2FtcGxlMiogaGF2ZSBkaWZmZXJlbnQgbWVhbnMsIHdoaWxlICpzYW1wbGUxKiBhbmQgKnNhbXBsZTMqIGhhdmUgdGhlIHNhbWUgbWVhbi4KCiogU28gd2hhdCBpZiB0aGUgTm9ybWFsaXR5IGFzc3VtcHRpb24gaXMgbm90IHZhbGlkLiBXZWxsLCB3aGVuIHNhbXBsZSBzaXplIGlzIGxhcmdlIGVub3VnaCwgYnkgdGhlIGNlbnRyYWwgbGltaXQgdGhlb3JlbSwgdGhlIHR3byBzYW1wbGUgdC10ZXN0IGlzIHN0aWxsIGEgZGVjZW50IHdheSB0byBhY2hpZXZlIG91ciBnb2FsLiBJbiBhbm90aGVyIHdvcmQsIHdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIG1vZGVyYXRlIG9yIGxhcmdlLCB0aGUgdHdvIHNhbXBsZSB0LXRlc3QgaXMgcm9idXN0IHRvIG5vbi1Ob3JtYWxpdHkuCgo=