Методы статистической обработки информации


Практика 1. Моделирование и описательная статистика

Выполнил Глушков Егор Александрович, гр. 20М.04-мм

Варианты №4, 7

№4. Отрицательно биномиальное распределение

\(\beta_{neg}(k=3, p=0.4);\;P\{\xi=j\}=\frac{\Gamma(k+j)}{\Gamma(k)j!}p^k(1-p)^j,\;j=0,1,...,\infty\)

Моделируем данные по заданным параметрам \(k=3,\;p=0.4\)

library(moments)

N <- 1500
sz <- 3; p <- 0.4
X <- rnbinom(n=N, size=sz, prob=p)

На модельных данных строим гистограмму

hist(X)

Описательная статистика

Находим матожидание, дисперсию, стандартное отклонение, ошибку среднего и сравниваем с гипотетическими параметрами

expectation <- c(mean(X), sz * (1 - p) / p)
variance <- c(sd(X)^2, sz * (1 - p) / p^2)
st_dev <- c(sd(X), sqrt(variance[2]))
err <- c(st_dev[1] / sqrt(N), st_dev[2] / sqrt(N))

df1 <- data.frame(expectation, variance, st_dev, err, row.names = c("simulated", "hypothetical")); df1

Находим медиану, минимум, максимум, размах

c(median=median(X), min=min(X), max=max(X), R=max(X)-min(X))
median    min    max      R 
     4      0     19     19 

Находим квартили и интерквартильный размах

q <- quantile(X, probs=seq(0, 1, 0.25)); q
  0%  25%  50%  75% 100% 
   0    2    4    6   19 
Q <- q[4] - q[2]; unname(Q)
[1] 4
c(q25<-qnbinom(0.25, size=sz, prob=p), q75<-qnbinom(0.75, size=sz, prob=p), intqR=q75-q25)
            intqR 
    2     6     4 

Центральные моменты 2-4 порядков по формуле и через библиотеку [совпадают]

m2 <- moment(X, order=2, central=TRUE)
m3 <- moment(X, order=3, central=TRUE)
m4 <- moment(X, order=4, central=TRUE)
c(mean((X-mean(X))^3), m3)
[1] 37.27772 37.27772
c(mean((X-mean(X))^4), m4)
[1] 507.9319 507.9319

Подсчет коэффициентов асимметрии и эксцесса по формулам и через библиотеку [совпадают]

print(paste("skewness: ", m3 / m2 ^ 1.5, " (formula), ", skewness(X), " (lib)"))
[1] "skewness:  1.04018762905602  (formula),  1.04018762905602  (lib)"
print(paste("kurtosis: ", m4 / m2 ^ 2 - 3, " (formula), ", kurtosis(X) - 3, " (lib; corrected)"))
[1] "kurtosis:  1.2988789558756  (formula),  1.2988789558756  (lib; corrected)"
gamma1 <- (2 - p) / sqrt(sz * (1 - p))
gamma2 <- 6 / sz + p ^ 2 / (sz * (1 - p))
print(paste("excess sk and kur: ", gamma1, gamma2, " (by formulae)"))
[1] "excess sk and kur:  1.19256958799989 2.08888888888889  (by formulae)"

Характеристики асимметрии и эксцесса в целом соответствуют форме заданного распределения.

Оценка параметров

Метод моментов

Приравниваем выборочные моменты к соответствующим моментам распределения (при 2 неизвестных параметрах, т.е. используем 2 момента): \(\alpha_1 = \frac{k(1-p)}{p}\) приравниваем к \(\overline{x}\), \(\mu_2 = \frac{k(1-p)}{p^2} = \frac{\overline{x}}{p}\) приравниваем к \(m_2\). Получаем \(p_{mm} = \frac{\overline{x}}{m_2}\), \(k_{mm} = \frac{\overline{x}^2}{m_2 - \overline{x}}\)

p. <- mean(X) / m2
k. <- mean(X)^2 / (m2 - mean(X))
c(p.=p., k.=k.)
       p.        k. 
0.4104918 3.1070206 

Моделируем исследуемое распределение с теоретическими и с оценочными (по методу моментов) параметрами. Строим график

xx. <- rnbinom(1500, size=k., prob=p.)

hist(X, freq=FALSE, xlim=c(-1, 25), main="Method of moments")
lines(density(X), col=2)
lines(density(xx.), col=3)
legend('topright',c("hyp","mm"),pch=20,col=c(2,3))

Метод максимального правдоподобия

Оценки параметров по методу максимального правдоподобия

Func.prob.log <- function(x) - sum(dnbinom(X, size = x[1], prob = x[2], log = TRUE))
res <- optim(c(k., p.), Func.prob.log) # k. and p. as initial values
k.. <- res$par[1]; p.. <- res$par[2];
c(k..=k.., p..=p..)
      k..       p.. 
2.9438163 0.3974773 

Построим график со сравнением теоретического распределения с распределениями, построенными по параметрам, полученным в методах моментов (mm) и максимального правдоподобия (mle)

xx.. <- rnbinom(1500, size=k.., prob=p..)

hist(X, freq=FALSE, xlim=c(-1, 25), main="MM, MLE")
lines(density(X), col=2)
lines(density(xx.), col=3)
lines(density(xx..), col=4)
legend('topright',c("hyp","mm", "mle"),pch=20,col=c(2,3,4))

В случае, когда параметр k (т.е. size) известен и требуется найти p, то оценка параметра p по методу максимального правдоподобия, будет иметь вид: \(p_{mle} = \frac {k} {k + \overline{x}}\)

k <- sz
p_mle <- k/(k+mean(X)); p_mle
[1] 0.402037

Заметим, что оценки, полученные как по методу моментов, так и по методу максимального правдоподобия, достаточно близки к теоретическим. Для получения более точных оценок следует увеличить объем моделируемых данных

Проверка согласия эмпирического и теоретического распределения по критерию хм-квадрат Пирсона

# эмпирические частоты
h <- hist(X, plot=FALSE)

# гипотетические частоты
p.i <- sapply(seq(length(h$breaks)-1) + 1, function(i) pnbinom(h$breaks[i], size=k, prob=p) - pnbinom(h$breaks[i-1], size=k, prob=p))
p.i[1] <- pnbinom(h$breaks[2], size=k, prob=p)
p.i[length(p.i)] <- 1 - pnbinom(h$breaks[length(h$breaks) - 1], size=k, prob=p)
sum(p.i) # должно быть равно 1
[1] 1

Проверка условия \(np_i \geq 5\) (для применения критерия согласия Пирсона)

tab <- cbind(h$counts, length(X) * p.i); tab
      [,1]       [,2]
 [1,]  487 476.160000
 [2,]  374 393.984000
 [3,]  295 282.175488
 [4,]  164 169.305293
 [5,]  100  91.521604
 [6,]   45  46.182614
 [7,]   20  22.192731
 [8,]    7  10.282381
 [9,]    6   4.631134
[10,]    2   3.564754

Объединяем строки с малыми значениями

Tab <- rbind(tab[1:8, ], c(sum(tab[9:nrow(tab), 1]), sum(tab[9:nrow(tab), 2]))); Tab
      [,1]       [,2]
 [1,]  487 476.160000
 [2,]  374 393.984000
 [3,]  295 282.175488
 [4,]  164 169.305293
 [5,]  100  91.521604
 [6,]   45  46.182614
 [7,]   20  22.192731
 [8,]    7  10.282381
 [9,]    8   8.195889

Наблюдаемое значение статистики \(\chi^2\)

chi2 <- sum(apply(Tab, 1, function(x) (x[1] - x[2])^2 / x[2])); chi2
[1] 4.09438
alpha <- 0.05
p_value <- 1 - pchisq(chi2, nrow(Tab) - 2 - 1); 
print(paste("p_value", round(p_value, 3), sep=" = "))
[1] "p_value = 0.664"
if (p_value > alpha) print(paste("The hypothesis of the agreement of the empirical distribution with the theoretical one is not rejected with the significance level alpha", alpha, sep="=")) else print("The hypothesis of the agreement of the empirical distribution with the theoretical one is rejected")
[1] "The hypothesis of the agreement of the empirical distribution with the theoretical one is not rejected with the significance level alpha=0.05"

\(p.value = 0.664\), поэтому гипотеза о согласии эмпирического и теоретического распределения НЕ отвергается при заданном \(\alpha = 0.05\).

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCiMjIyDQnNC10YLQvtC00Ysg0YHRgtCw0YLQuNGB0YLQuNGH0LXRgdC60L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0LjQvdGE0L7RgNC80LDRhtC40LgNCl9fXw0KIyMg0J/RgNCw0LrRgtC40LrQsCAxLiDQnNC+0LTQtdC70LjRgNC+0LLQsNC90LjQtSDQuCDQvtC/0LjRgdCw0YLQtdC70YzQvdCw0Y8g0YHRgtCw0YLQuNGB0YLQuNC60LANCiMjIyMg0JLRi9C/0L7Qu9C90LjQuyDQk9C70YPRiNC60L7QsiDQldCz0L7RgCDQkNC70LXQutGB0LDQvdC00YDQvtCy0LjRhywg0LPRgC4gMjDQnC4wNC3QvNC8DQrQktCw0YDQuNCw0L3RgtGLIOKEljQsIDcNCg0KIyMjIyDihJY0LiDQntGC0YDQuNGG0LDRgtC10LvRjNC90L4g0LHQuNC90L7QvNC40LDQu9GM0L3QvtC1INGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNC1DQokXGJldGFfe25lZ30oaz0zLCBwPTAuNCk7XDtQXHtceGk9alx9PVxmcmFje1xHYW1tYShrK2opfXtcR2FtbWEoaylqIX1wXmsoMS1wKV5qLFw7aj0wLDEsLi4uLFxpbmZ0eSQNCg0KDQrQnNC+0LTQtdC70LjRgNGD0LXQvCDQtNCw0L3QvdGL0LUg0L/QviDQt9Cw0LTQsNC90L3Ri9C8INC/0LDRgNCw0LzQtdGC0YDQsNC8ICRrPTMsXDtwPTAuNCQNCmBgYHtyfQ0KbGlicmFyeShtb21lbnRzKQ0KDQpOIDwtIDE1MDANCnN6IDwtIDM7IHAgPC0gMC40DQpYIDwtIHJuYmlub20obj1OLCBzaXplPXN6LCBwcm9iPXApDQpgYGANCg0K0J3QsCDQvNC+0LTQtdC70YzQvdGL0YUg0LTQsNC90L3Ri9GFINGB0YLRgNC+0LjQvCDQs9C40YHRgtC+0LPRgNCw0LzQvNGDDQpgYGB7cn0NCmhpc3QoWCkNCmBgYA0KDQojIyMg0J7Qv9C40YHQsNGC0LXQu9GM0L3QsNGPINGB0YLQsNGC0LjRgdGC0LjQutCwDQoNCtCd0LDRhdC+0LTQuNC8INC80LDRgtC+0LbQuNC00LDQvdC40LUsINC00LjRgdC/0LXRgNGB0LjRjiwg0YHRgtCw0L3QtNCw0YDRgtC90L7QtSDQvtGC0LrQu9C+0L3QtdC90LjQtSwg0L7RiNC40LHQutGDINGB0YDQtdC00L3QtdCz0L4g0Lgg0YHRgNCw0LLQvdC40LLQsNC10Lwg0YEg0LPQuNC/0L7RgtC10YLQuNGH0LXRgdC60LjQvNC4INC/0LDRgNCw0LzQtdGC0YDQsNC80LgNCmBgYHtyfQ0KZXhwZWN0YXRpb24gPC0gYyhtZWFuKFgpLCBzeiAqICgxIC0gcCkgLyBwKQ0KdmFyaWFuY2UgPC0gYyhzZChYKV4yLCBzeiAqICgxIC0gcCkgLyBwXjIpDQpzdF9kZXYgPC0gYyhzZChYKSwgc3FydCh2YXJpYW5jZVsyXSkpDQplcnIgPC0gYyhzdF9kZXZbMV0gLyBzcXJ0KE4pLCBzdF9kZXZbMl0gLyBzcXJ0KE4pKQ0KDQpkZjEgPC0gZGF0YS5mcmFtZShleHBlY3RhdGlvbiwgdmFyaWFuY2UsIHN0X2RldiwgZXJyLCByb3cubmFtZXMgPSBjKCJzaW11bGF0ZWQiLCAiaHlwb3RoZXRpY2FsIikpOyBkZjENCmBgYA0KDQrQndCw0YXQvtC00LjQvCDQvNC10LTQuNCw0L3Rgywg0LzQuNC90LjQvNGD0LwsINC80LDQutGB0LjQvNGD0LwsINGA0LDQt9C80LDRhQ0KYGBge3J9DQpjKG1lZGlhbj1tZWRpYW4oWCksIG1pbj1taW4oWCksIG1heD1tYXgoWCksIFI9bWF4KFgpLW1pbihYKSkNCmBgYA0KDQrQndCw0YXQvtC00LjQvCDQutCy0LDRgNGC0LjQu9C4INC4INC40L3RgtC10YDQutCy0LDRgNGC0LjQu9GM0L3Ri9C5INGA0LDQt9C80LDRhQ0KYGBge3J9DQpxIDwtIHF1YW50aWxlKFgsIHByb2JzPXNlcSgwLCAxLCAwLjI1KSk7IHENClEgPC0gcVs0XSAtIHFbMl07IHVubmFtZShRKQ0KYGBgDQoNCmBgYHtyfQ0KYyhxMjU8LXFuYmlub20oMC4yNSwgc2l6ZT1zeiwgcHJvYj1wKSwgcTc1PC1xbmJpbm9tKDAuNzUsIHNpemU9c3osIHByb2I9cCksIGludHFSPXE3NS1xMjUpDQpgYGANCg0K0KbQtdC90YLRgNCw0LvRjNC90YvQtSDQvNC+0LzQtdC90YLRiyAyLTQg0L/QvtGA0Y/QtNC60L7QsiDQv9C+INGE0L7RgNC80YPQu9C1INC4INGH0LXRgNC10Lcg0LHQuNCx0LvQuNC+0YLQtdC60YMgW9GB0L7QstC/0LDQtNCw0Y7Rgl0NCmBgYHtyfQ0KbTIgPC0gbW9tZW50KFgsIG9yZGVyPTIsIGNlbnRyYWw9VFJVRSkNCm0zIDwtIG1vbWVudChYLCBvcmRlcj0zLCBjZW50cmFsPVRSVUUpDQptNCA8LSBtb21lbnQoWCwgb3JkZXI9NCwgY2VudHJhbD1UUlVFKQ0KYyhtZWFuKChYLW1lYW4oWCkpXjMpLCBtMykNCmMobWVhbigoWC1tZWFuKFgpKV40KSwgbTQpDQpgYGANCg0K0J/QvtC00YHRh9C10YIg0LrQvtGN0YTRhNC40YbQuNC10L3RgtC+0LIg0LDRgdC40LzQvNC10YLRgNC40Lgg0Lgg0Y3QutGB0YbQtdGB0YHQsCDQv9C+INGE0L7RgNC80YPQu9Cw0Lwg0Lgg0YfQtdGA0LXQtyDQsdC40LHQu9C40L7RgtC10LrRgyBb0YHQvtCy0L/QsNC00LDRjtGCXQ0KYGBge3J9DQpwcmludChwYXN0ZSgic2tld25lc3M6ICIsIG0zIC8gbTIgXiAxLjUsICIgKGZvcm11bGEpLCAiLCBza2V3bmVzcyhYKSwgIiAobGliKSIpKQ0KcHJpbnQocGFzdGUoImt1cnRvc2lzOiAiLCBtNCAvIG0yIF4gMiAtIDMsICIgKGZvcm11bGEpLCAiLCBrdXJ0b3NpcyhYKSAtIDMsICIgKGxpYjsgY29ycmVjdGVkKSIpKQ0KYGBgDQoNCmBgYHtyfQ0KZ2FtbWExIDwtICgyIC0gcCkgLyBzcXJ0KHN6ICogKDEgLSBwKSkNCmdhbW1hMiA8LSA2IC8gc3ogKyBwIF4gMiAvIChzeiAqICgxIC0gcCkpDQpwcmludChwYXN0ZSgiZXhjZXNzIHNrIGFuZCBrdXI6ICIsIGdhbW1hMSwgZ2FtbWEyLCAiIChieSBmb3JtdWxhZSkiKSkNCmBgYA0KDQoNCtCl0LDRgNCw0LrRgtC10YDQuNGB0YLQuNC60Lgg0LDRgdC40LzQvNC10YLRgNC40Lgg0Lgg0Y3QutGB0YbQtdGB0YHQsCDQsiDRhtC10LvQvtC8INGB0L7QvtGC0LLQtdGC0YHRgtCy0YPRjtGCINGE0L7RgNC80LUg0LfQsNC00LDQvdC90L7Qs9C+INGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGPLg0KDQoNCiMjIyDQntGG0LXQvdC60LAg0L/QsNGA0LDQvNC10YLRgNC+0LINCiMjIyMg0JzQtdGC0L7QtCDQvNC+0LzQtdC90YLQvtCyDQoNCtCf0YDQuNGA0LDQstC90LjQstCw0LXQvCDQstGL0LHQvtGA0L7Rh9C90YvQtSDQvNC+0LzQtdC90YLRiyDQuiDRgdC+0L7RgtCy0LXRgtGB0YLQstGD0Y7RidC40Lwg0LzQvtC80LXQvdGC0LDQvCDRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjRjyAo0L/RgNC4IDIg0L3QtdC40LfQstC10YHRgtC90YvRhSDQv9Cw0YDQsNC80LXRgtGA0LDRhSwg0YIu0LUuINC40YHQv9C+0LvRjNC30YPQtdC8IDIg0LzQvtC80LXQvdGC0LApOiAkXGFscGhhXzEgPSBcZnJhY3trKDEtcCl9e3B9JCDQv9GA0LjRgNCw0LLQvdC40LLQsNC10Lwg0LogJFxvdmVybGluZXt4fSQsICRcbXVfMiA9IFxmcmFje2soMS1wKX17cF4yfSA9IFxmcmFje1xvdmVybGluZXt4fX17cH0kINC/0YDQuNGA0LDQstC90LjQstCw0LXQvCDQuiAkbV8yJC4g0J/QvtC70YPRh9Cw0LXQvCANCiRwX3ttbX0gPSBcZnJhY3tcb3ZlcmxpbmV7eH19e21fMn0kLCANCiRrX3ttbX0gPSBcZnJhY3tcb3ZlcmxpbmV7eH1eMn17bV8yIC0gXG92ZXJsaW5le3h9fSQNCg0KDQpgYGB7cn0NCnAuIDwtIG1lYW4oWCkgLyBtMg0Kay4gPC0gbWVhbihYKV4yIC8gKG0yIC0gbWVhbihYKSkNCmMocC49cC4sIGsuPWsuKQ0KYGBgDQoNCtCc0L7QtNC10LvQuNGA0YPQtdC8INC40YHRgdC70LXQtNGD0LXQvNC+0LUg0YDQsNGB0L/RgNC10LTQtdC70LXQvdC40LUg0YEg0YLQtdC+0YDQtdGC0LjRh9C10YHQutC40LzQuCDQuCDRgSDQvtGG0LXQvdC+0YfQvdGL0LzQuCAo0L/QviDQvNC10YLQvtC00YMg0LzQvtC80LXQvdGC0L7Qsikg0L/QsNGA0LDQvNC10YLRgNCw0LzQuC4g0KHRgtGA0L7QuNC8INCz0YDQsNGE0LjQug0KYGBge3J9DQp4eC4gPC0gcm5iaW5vbSgxNTAwLCBzaXplPWsuLCBwcm9iPXAuKQ0KDQpoaXN0KFgsIGZyZXE9RkFMU0UsIHhsaW09YygtMSwgMjUpLCBtYWluPSJNZXRob2Qgb2YgbW9tZW50cyIpDQpsaW5lcyhkZW5zaXR5KFgpLCBjb2w9MikNCmxpbmVzKGRlbnNpdHkoeHguKSwgY29sPTMpDQpsZWdlbmQoJ3RvcHJpZ2h0JyxjKCJoeXAiLCJtbSIpLHBjaD0yMCxjb2w9YygyLDMpKQ0KDQpgYGANCg0KIyMjIyDQnNC10YLQvtC0INC80LDQutGB0LjQvNCw0LvRjNC90L7Qs9C+INC/0YDQsNCy0LTQvtC/0L7QtNC+0LHQuNGPDQoNCtCe0YbQtdC90LrQuCDQv9Cw0YDQsNC80LXRgtGA0L7QsiDQv9C+INC80LXRgtC+0LTRgyDQvNCw0LrRgdC40LzQsNC70YzQvdC+0LPQviDQv9GA0LDQstC00L7Qv9C+0LTQvtCx0LjRjw0KYGBge3J9DQpGdW5jLnByb2IubG9nIDwtIGZ1bmN0aW9uKHgpIC0gc3VtKGRuYmlub20oWCwgc2l6ZSA9IHhbMV0sIHByb2IgPSB4WzJdLCBsb2cgPSBUUlVFKSkNCnJlcyA8LSBvcHRpbShjKGsuLCBwLiksIEZ1bmMucHJvYi5sb2cpICMgay4gYW5kIHAuIGFzIGluaXRpYWwgdmFsdWVzDQprLi4gPC0gcmVzJHBhclsxXTsgcC4uIDwtIHJlcyRwYXJbMl07DQpjKGsuLj1rLi4sIHAuLj1wLi4pDQpgYGANCg0K0J/QvtGB0YLRgNC+0LjQvCDQs9GA0LDRhNC40Log0YHQviDRgdGA0LDQstC90LXQvdC40LXQvCDRgtC10L7RgNC10YLQuNGH0LXRgdC60L7Qs9C+INGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGPINGBINGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGP0LzQuCwg0L/QvtGB0YLRgNC+0LXQvdC90YvQvNC4INC/0L4g0L/QsNGA0LDQvNC10YLRgNCw0LwsINC/0L7Qu9GD0YfQtdC90L3Ri9C8INCyINC80LXRgtC+0LTQsNGFINC80L7QvNC10L3RgtC+0LIgKG1tKSDQuCDQvNCw0LrRgdC40LzQsNC70YzQvdC+0LPQviDQv9GA0LDQstC00L7Qv9C+0LTQvtCx0LjRjyAobWxlKQ0KYGBge3J9DQp4eC4uIDwtIHJuYmlub20oMTUwMCwgc2l6ZT1rLi4sIHByb2I9cC4uKQ0KDQpoaXN0KFgsIGZyZXE9RkFMU0UsIHhsaW09YygtMSwgMjUpLCBtYWluPSJNTSwgTUxFIikNCmxpbmVzKGRlbnNpdHkoWCksIGNvbD0yKQ0KbGluZXMoZGVuc2l0eSh4eC4pLCBjb2w9MykNCmxpbmVzKGRlbnNpdHkoeHguLiksIGNvbD00KQ0KbGVnZW5kKCd0b3ByaWdodCcsYygiaHlwIiwibW0iLCAibWxlIikscGNoPTIwLGNvbD1jKDIsMyw0KSkNCmBgYA0KDQrQkiDRgdC70YPRh9Cw0LUsINC60L7Qs9C00LAg0L/QsNGA0LDQvNC10YLRgCBrICjRgi7QtS4gc2l6ZSkg0LjQt9Cy0LXRgdGC0LXQvSDQuCDRgtGA0LXQsdGD0LXRgtGB0Y8g0L3QsNC50YLQuCBwLCDRgtC+INC+0YbQtdC90LrQsCDQv9Cw0YDQsNC80LXRgtGA0LAgcCDQv9C+INC80LXRgtC+0LTRgyDQvNCw0LrRgdC40LzQsNC70YzQvdC+0LPQviDQv9GA0LDQstC00L7Qv9C+0LTQvtCx0LjRjywg0LHRg9C00LXRgiDQuNC80LXRgtGMINCy0LjQtDogJHBfe21sZX0gPSBcZnJhYyB7a30ge2sgKyBcb3ZlcmxpbmV7eH19JA0KYGBge3J9DQprIDwtIHN6DQpwX21sZSA8LSBrLyhrK21lYW4oWCkpOyBwX21sZQ0KYGBgDQrQl9Cw0LzQtdGC0LjQvCwg0YfRgtC+INC+0YbQtdC90LrQuCwg0L/QvtC70YPRh9C10L3QvdGL0LUg0LrQsNC6INC/0L4g0LzQtdGC0L7QtNGDINC80L7QvNC10L3RgtC+0LIsINGC0LDQuiDQuCDQv9C+INC80LXRgtC+0LTRgyDQvNCw0LrRgdC40LzQsNC70YzQvdC+0LPQviDQv9GA0LDQstC00L7Qv9C+0LTQvtCx0LjRjywg0LTQvtGB0YLQsNGC0L7Rh9C90L4g0LHQu9C40LfQutC4INC6INGC0LXQvtGA0LXRgtC40YfQtdGB0LrQuNC8LiDQlNC70Y8g0L/QvtC70YPRh9C10L3QuNGPINCx0L7Qu9C10LUg0YLQvtGH0L3Ri9GFINC+0YbQtdC90L7QuiDRgdC70LXQtNGD0LXRgiDRg9Cy0LXQu9C40YfQuNGC0Ywg0L7QsdGK0LXQvCDQvNC+0LTQtdC70LjRgNGD0LXQvNGL0YUg0LTQsNC90L3Ri9GFDQoNCiMjIyDQn9GA0L7QstC10YDQutCwINGB0L7Qs9C70LDRgdC40Y8g0Y3QvNC/0LjRgNC40YfQtdGB0LrQvtCz0L4g0Lgg0YLQtdC+0YDQtdGC0LjRh9C10YHQutC+0LPQviDRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjRjyDQv9C+INC60YDQuNGC0LXRgNC40Y4g0YXQvC3QutCy0LDQtNGA0LDRgiDQn9C40YDRgdC+0L3QsA0KDQpgYGB7cn0NCiMg0Y3QvNC/0LjRgNC40YfQtdGB0LrQuNC1INGH0LDRgdGC0L7RgtGLDQpoIDwtIGhpc3QoWCwgcGxvdD1GQUxTRSkNCg0KIyDQs9C40L/QvtGC0LXRgtC40YfQtdGB0LrQuNC1INGH0LDRgdGC0L7RgtGLDQpwLmkgPC0gc2FwcGx5KHNlcShsZW5ndGgoaCRicmVha3MpLTEpICsgMSwgZnVuY3Rpb24oaSkgcG5iaW5vbShoJGJyZWFrc1tpXSwgc2l6ZT1rLCBwcm9iPXApIC0gcG5iaW5vbShoJGJyZWFrc1tpLTFdLCBzaXplPWssIHByb2I9cCkpDQpwLmlbMV0gPC0gcG5iaW5vbShoJGJyZWFrc1syXSwgc2l6ZT1rLCBwcm9iPXApDQpwLmlbbGVuZ3RoKHAuaSldIDwtIDEgLSBwbmJpbm9tKGgkYnJlYWtzW2xlbmd0aChoJGJyZWFrcykgLSAxXSwgc2l6ZT1rLCBwcm9iPXApDQpzdW0ocC5pKSAjINC00L7Qu9C20L3QviDQsdGL0YLRjCDRgNCw0LLQvdC+IDENCg0KYGBgDQoNCtCf0YDQvtCy0LXRgNC60LAg0YPRgdC70L7QstC40Y8gJG5wX2kgXGdlcSA1JCAo0LTQu9GPINC/0YDQuNC80LXQvdC10L3QuNGPINC60YDQuNGC0LXRgNC40Y8g0YHQvtCz0LvQsNGB0LjRjyDQn9C40YDRgdC+0L3QsCkNCmBgYHtyfQ0KdGFiIDwtIGNiaW5kKGgkY291bnRzLCBsZW5ndGgoWCkgKiBwLmkpOyB0YWINCmBgYA0KDQrQntCx0YrQtdC00LjQvdGP0LXQvCDRgdGC0YDQvtC60Lgg0YEg0LzQsNC70YvQvNC4INC30L3QsNGH0LXQvdC40Y/QvNC4DQpgYGB7cn0NClRhYiA8LSByYmluZCh0YWJbMTo4LCBdLCBjKHN1bSh0YWJbOTpucm93KHRhYiksIDFdKSwgc3VtKHRhYls5Om5yb3codGFiKSwgMl0pKSk7IFRhYg0KYGBgDQoNCtCd0LDQsdC70Y7QtNCw0LXQvNC+0LUg0LfQvdCw0YfQtdC90LjQtSDRgdGC0LDRgtC40YHRgtC40LrQuCAkXGNoaV4yJA0KYGBge3J9DQpjaGkyIDwtIHN1bShhcHBseShUYWIsIDEsIGZ1bmN0aW9uKHgpICh4WzFdIC0geFsyXSleMiAvIHhbMl0pKTsgY2hpMg0KYGBgDQoNCg0KYGBge3J9DQphbHBoYSA8LSAwLjA1DQpwX3ZhbHVlIDwtIDEgLSBwY2hpc3EoY2hpMiwgbnJvdyhUYWIpIC0gMiAtIDEpOyANCnByaW50KHBhc3RlKCJwX3ZhbHVlIiwgcm91bmQocF92YWx1ZSwgMyksIHNlcD0iID0gIikpDQppZiAocF92YWx1ZSA+IGFscGhhKSBwcmludChwYXN0ZSgiVGhlIGh5cG90aGVzaXMgb2YgdGhlIGFncmVlbWVudCBvZiB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBvbmUgaXMgbm90IHJlamVjdGVkIHdpdGggdGhlIHNpZ25pZmljYW5jZSBsZXZlbCBhbHBoYSIsIGFscGhhLCBzZXA9Ij0iKSkgZWxzZSBwcmludCgiVGhlIGh5cG90aGVzaXMgb2YgdGhlIGFncmVlbWVudCBvZiB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBvbmUgaXMgcmVqZWN0ZWQiKQ0KYGBgIA0KDQokcC52YWx1ZSA9IGByIHJvdW5kKHBfdmFsdWUsIDMpYCQsINC/0L7RjdGC0L7QvNGDINCz0LjQv9C+0YLQtdC30LAg0L4g0YHQvtCz0LvQsNGB0LjQuCDRjdC80L/QuNGA0LjRh9C10YHQutC+0LPQviDQuCDRgtC10L7RgNC10YLQuNGH0LXRgdC60L7Qs9C+INGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGPINCd0JUg0L7RgtCy0LXRgNCz0LDQtdGC0YHRjyDQv9GA0Lgg0LfQsNC00LDQvdC90L7QvCAkXGFscGhhID0gYHIgYWxwaGFgJC4NCg0K