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


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

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

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

№7.Равномерное распределение U(a, b)

\(u(x|a=1,b=3) = \frac{1}{b-a}, a \leq x \leq b\)

Моделируем данные по заданным параметрам \(a=1,\;b=3\)

library(moments)

N <- 1500
a <- 1; b <- 3
X <- runif(n=N, min=a, max=b)

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

hist(X)

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

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

expectation <- c(mean(X), (a + b)/2)
variance <- c(sd(X)^2, (b - a)^2 / 12)
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 
2.015534 1.001458 2.999714 1.998257 

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

q <- quantile(X, probs=seq(0, 1, 0.25)); q
      0%      25%      50%      75%     100% 
1.001458 1.506522 2.015534 2.526824 2.999714 
Q <- q[4] - q[2]; unname(Q)
[1] 1.020302
c(q25<-qunif(0.25, min=a, max=b), q75<-qunif(0.75, min=a, max=b), intqR=q75-q25)
            intqR 
  1.5   2.5   1.0 

Центральные моменты 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] -0.007347369 -0.007347369
c(mean((X-mean(X))^4), m4)
[1] 0.2099826 0.2099826

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

print(paste("skewness: ", m3 / m2 ^ 1.5, " (formula), ", skewness(X), " (lib)"))
[1] "skewness:  -0.0363542532864743  (formula),  -0.0363542532864743  (lib)"
print(paste("kurtosis: ", m4 / m2 ^ 2 - 3, " (formula), ", kurtosis(X) - 3, " (lib; corrected)"))
[1] "kurtosis:  -1.22956030083928  (formula),  -1.22956030083928  (lib; corrected)"
gamma1 <- 0
gamma2 <- - 6/5
print(paste("excess sk and kur: ", gamma1, gamma2, " (by formulae)"))
[1] "excess sk and kur:  0 -1.2  (by formulae)"

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

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

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

Приравниваем выборочные моменты к соответствующим моментам распределения (при 2 неизвестных параметрах, т.е. используем 2 момента): \(\alpha_1 = \frac{a+b}{2}\) приравниваем к \(\overline{x}\), \(\mu_2 = \frac{(b-a)^2}{12}\) приравниваем к \(m_2 = \sigma^2\). Получаем \(a_{mm} = \overline{x} - \sqrt{3} \sigma\), \(b_{mm} = \overline{x} + \sqrt{3} \sigma\)

a. <- mean(X) - sqrt(3) * sd(X)
b. <- mean(X) + sqrt(3) * sd(X)
c(a.=a., b.=b.)
       a.        b. 
0.9884036 3.0219822 

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

xx. <- runif(1500, min=a., max=b.)

hist(X, freq=FALSE, 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(dunif(X, min = x[1], max = x[2], log = TRUE))
res <- optim(c(0.97, 3.1), Func.prob.log) # 0.9, 3.1 as initial values
a.. <- res$par[1]; b.. <- res$par[2];
c(a..=a.., b..=b..)
     a..      b.. 
1.001458 2.999714 

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

xx.. <- runif(1500, min=a.., max=b..)

hist(X, freq=FALSE, 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))

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

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

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

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

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

tab <- cbind(h$counts, length(X) * p.i); tab
      [,1] [,2]
 [1,]  168  150
 [2,]  142  150
 [3,]  144  150
 [4,]  137  150
 [5,]  148  150
 [6,]  136  150
 [7,]  164  150
 [8,]  148  150
 [9,]  160  150
[10,]  153  150

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

chi2 <- sum(apply(tab, 1, function(x) (x[1] - x[2])^2 / x[2])); chi2
[1] 7.346667
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.394"
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.394\), поэтому гипотеза о согласии эмпирического и теоретического распределения НЕ отвергается при заданном \(\alpha = 0.05\).

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCiMjIyDQnNC10YLQvtC00Ysg0YHRgtCw0YLQuNGB0YLQuNGH0LXRgdC60L7QuSDQvtCx0YDQsNCx0L7RgtC60Lgg0LjQvdGE0L7RgNC80LDRhtC40LgNCl9fXw0KIyMg0J/RgNCw0LrRgtC40LrQsCAxLiDQnNC+0LTQtdC70LjRgNC+0LLQsNC90LjQtSDQuCDQvtC/0LjRgdCw0YLQtdC70YzQvdCw0Y8g0YHRgtCw0YLQuNGB0YLQuNC60LANCiMjIyMg0JLRi9C/0L7Qu9C90LjQuyDQk9C70YPRiNC60L7QsiDQldCz0L7RgCDQkNC70LXQutGB0LDQvdC00YDQvtCy0LjRhywg0LPRgC4gMjDQnC4wNC3QvNC8DQrQktCw0YDQuNCw0L3RgtGLIOKEljQsIDcNCg0KIyMjIyDihJY3LtCg0LDQstC90L7QvNC10YDQvdC+0LUg0YDQsNGB0L/RgNC10LTQtdC70LXQvdC40LUgVShhLCBiKQ0KDQokdSh4fGE9MSxiPTMpID0gXGZyYWN7MX17Yi1hfSwgYSBcbGVxIHggXGxlcSBiJA0KDQrQnNC+0LTQtdC70LjRgNGD0LXQvCDQtNCw0L3QvdGL0LUg0L/QviDQt9Cw0LTQsNC90L3Ri9C8INC/0LDRgNCw0LzQtdGC0YDQsNC8ICRhPTEsXDtiPTMkDQpgYGB7cn0NCmxpYnJhcnkobW9tZW50cykNCg0KTiA8LSAxNTAwDQphIDwtIDE7IGIgPC0gMw0KWCA8LSBydW5pZihuPU4sIG1pbj1hLCBtYXg9YikNCmBgYA0KDQrQndCwINC80L7QtNC10LvRjNC90YvRhSDQtNCw0L3QvdGL0YUg0YHRgtGA0L7QuNC8INCz0LjRgdGC0L7Qs9GA0LDQvNC80YMNCmBgYHtyfQ0KaGlzdChYKQ0KYGBgDQoNCiMjIyDQntC/0LjRgdCw0YLQtdC70YzQvdCw0Y8g0YHRgtCw0YLQuNGB0YLQuNC60LANCg0K0J3QsNGF0L7QtNC40Lwg0LzQsNGC0L7QttC40LTQsNC90LjQtSwg0LTQuNGB0L/QtdGA0YHQuNGOLCDRgdGC0LDQvdC00LDRgNGC0L3QvtC1INC+0YLQutC70L7QvdC10L3QuNC1LCDQvtGI0LjQsdC60YMg0YHRgNC10LTQvdC10LPQviDQuCDRgdGA0LDQstC90LjQstCw0LXQvCDRgSDQs9C40L/QvtGC0LXRgtC40YfQtdGB0LrQuNC80Lgg0L/QsNGA0LDQvNC10YLRgNCw0LzQuA0KYGBge3J9DQpleHBlY3RhdGlvbiA8LSBjKG1lYW4oWCksIChhICsgYikvMikNCnZhcmlhbmNlIDwtIGMoc2QoWCleMiwgKGIgLSBhKV4yIC8gMTIpDQpzdF9kZXYgPC0gYyhzZChYKSwgc3FydCh2YXJpYW5jZVsyXSkpDQplcnIgPC0gYyhzdF9kZXZbMV0gLyBzcXJ0KE4pLCBzdF9kZXZbMl0gLyBzcXJ0KE4pKQ0KDQpkZjEgPC0gZGF0YS5mcmFtZShleHBlY3RhdGlvbiwgdmFyaWFuY2UsIHN0X2RldiwgZXJyLCByb3cubmFtZXMgPSBjKCJzaW11bGF0ZWQiLCAiaHlwb3RoZXRpY2FsIikpOyBkZjENCmBgYA0KDQrQndCw0YXQvtC00LjQvCDQvNC10LTQuNCw0L3Rgywg0LzQuNC90LjQvNGD0LwsINC80LDQutGB0LjQvNGD0LwsINGA0LDQt9C80LDRhQ0KYGBge3J9DQpjKG1lZGlhbj1tZWRpYW4oWCksIG1pbj1taW4oWCksIG1heD1tYXgoWCksIFI9bWF4KFgpLW1pbihYKSkNCmBgYA0KDQrQndCw0YXQvtC00LjQvCDQutCy0LDRgNGC0LjQu9C4INC4INC40L3RgtC10YDQutCy0LDRgNGC0LjQu9GM0L3Ri9C5INGA0LDQt9C80LDRhQ0KYGBge3J9DQpxIDwtIHF1YW50aWxlKFgsIHByb2JzPXNlcSgwLCAxLCAwLjI1KSk7IHENClEgPC0gcVs0XSAtIHFbMl07IHVubmFtZShRKQ0KYGBgDQoNCmBgYHtyfQ0KYyhxMjU8LXF1bmlmKDAuMjUsIG1pbj1hLCBtYXg9YiksIHE3NTwtcXVuaWYoMC43NSwgbWluPWEsIG1heD1iKSwgaW50cVI9cTc1LXEyNSkNCmBgYA0KDQrQptC10L3RgtGA0LDQu9GM0L3Ri9C1INC80L7QvNC10L3RgtGLIDItNCDQv9C+0YDRj9C00LrQvtCyINC/0L4g0YTQvtGA0LzRg9C70LUg0Lgg0YfQtdGA0LXQtyDQsdC40LHQu9C40L7RgtC10LrRgyBb0YHQvtCy0L/QsNC00LDRjtGCXQ0KYGBge3J9DQptMiA8LSBtb21lbnQoWCwgb3JkZXI9MiwgY2VudHJhbD1UUlVFKQ0KbTMgPC0gbW9tZW50KFgsIG9yZGVyPTMsIGNlbnRyYWw9VFJVRSkNCm00IDwtIG1vbWVudChYLCBvcmRlcj00LCBjZW50cmFsPVRSVUUpDQpjKG1lYW4oKFgtbWVhbihYKSleMyksIG0zKQ0KYyhtZWFuKChYLW1lYW4oWCkpXjQpLCBtNCkNCmBgYA0KDQrQn9C+0LTRgdGH0LXRgiDQutC+0Y3RhNGE0LjRhtC40LXQvdGC0L7QsiDQsNGB0LjQvNC80LXRgtGA0LjQuCDQuCDRjdC60YHRhtC10YHRgdCwINC/0L4g0YTQvtGA0LzRg9C70LDQvCDQuCDRh9C10YDQtdC3INCx0LjQsdC70LjQvtGC0LXQutGDIFvRgdC+0LLQv9Cw0LTQsNGO0YJdDQpgYGB7cn0NCnByaW50KHBhc3RlKCJza2V3bmVzczogIiwgbTMgLyBtMiBeIDEuNSwgIiAoZm9ybXVsYSksICIsIHNrZXduZXNzKFgpLCAiIChsaWIpIikpDQpwcmludChwYXN0ZSgia3VydG9zaXM6ICIsIG00IC8gbTIgXiAyIC0gMywgIiAoZm9ybXVsYSksICIsIGt1cnRvc2lzKFgpIC0gMywgIiAobGliOyBjb3JyZWN0ZWQpIikpDQpgYGANCmBgYHtyfQ0KZ2FtbWExIDwtIDANCmdhbW1hMiA8LSAtIDYvNQ0KcHJpbnQocGFzdGUoImV4Y2VzcyBzayBhbmQga3VyOiAiLCBnYW1tYTEsIGdhbW1hMiwgIiAoYnkgZm9ybXVsYWUpIikpDQpgYGANCg0KDQrQpdCw0YDQsNC60YLQtdGA0LjRgdGC0LjQutC4INCw0YHQuNC80LzQtdGC0YDQuNC4INC4INGN0LrRgdGG0LXRgdGB0LAg0LIg0YbQtdC70L7QvCDRgdC+0L7RgtCy0LXRgtGB0YLQstGD0Y7RgiDRhNC+0YDQvNC1INC30LDQtNCw0L3QvdC+0LPQviDRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjRjy4NCg0KDQojIyMg0J7RhtC10L3QutCwINC/0LDRgNCw0LzQtdGC0YDQvtCyDQojIyMjINCc0LXRgtC+0LQg0LzQvtC80LXQvdGC0L7Qsg0KDQrQn9GA0LjRgNCw0LLQvdC40LLQsNC10Lwg0LLRi9Cx0L7RgNC+0YfQvdGL0LUg0LzQvtC80LXQvdGC0Ysg0Log0YHQvtC+0YLQstC10YLRgdGC0LLRg9GO0YnQuNC8INC80L7QvNC10L3RgtCw0Lwg0YDQsNGB0L/RgNC10LTQtdC70LXQvdC40Y8gKNC/0YDQuCAyINC90LXQuNC30LLQtdGB0YLQvdGL0YUg0L/QsNGA0LDQvNC10YLRgNCw0YUsINGCLtC1LiDQuNGB0L/QvtC70YzQt9GD0LXQvCAyINC80L7QvNC10L3RgtCwKTogJFxhbHBoYV8xID0gXGZyYWN7YStifXsyfSQg0L/RgNC40YDQsNCy0L3QuNCy0LDQtdC8INC6ICRcb3ZlcmxpbmV7eH0kLCAkXG11XzIgPSBcZnJhY3soYi1hKV4yfXsxMn0kINC/0YDQuNGA0LDQstC90LjQstCw0LXQvCDQuiAkbV8yID0gXHNpZ21hXjIkLiDQn9C+0LvRg9GH0LDQtdC8IA0KJGFfe21tfSA9IFxvdmVybGluZXt4fSAtIFxzcXJ0ezN9IFxzaWdtYSQsIA0KJGJfe21tfSA9IFxvdmVybGluZXt4fSArIFxzcXJ0ezN9IFxzaWdtYSQNCg0KYGBge3J9DQphLiA8LSBtZWFuKFgpIC0gc3FydCgzKSAqIHNkKFgpDQpiLiA8LSBtZWFuKFgpICsgc3FydCgzKSAqIHNkKFgpDQpjKGEuPWEuLCBiLj1iLikNCmBgYA0KDQrQnNC+0LTQtdC70LjRgNGD0LXQvCDQuNGB0YHQu9C10LTRg9C10LzQvtC1INGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNC1INGBINGC0LXQvtGA0LXRgtC40YfQtdGB0LrQuNC80Lgg0Lgg0YEg0L7RhtC10L3QvtGH0L3Ri9C80LggKNC/0L4g0LzQtdGC0L7QtNGDINC80L7QvNC10L3RgtC+0LIpINC/0LDRgNCw0LzQtdGC0YDQsNC80LguINCh0YLRgNC+0LjQvCDQs9GA0LDRhNC40LoNCmBgYHtyfQ0KeHguIDwtIHJ1bmlmKDE1MDAsIG1pbj1hLiwgbWF4PWIuKQ0KDQpoaXN0KFgsIGZyZXE9RkFMU0UsIG1haW49Ik1ldGhvZCBvZiBtb21lbnRzIikNCmxpbmVzKGRlbnNpdHkoWCksIGNvbD0yKQ0KbGluZXMoZGVuc2l0eSh4eC4pLCBjb2w9MykNCmxlZ2VuZCgndG9wcmlnaHQnLCBjKCJoeXAiLCJtbSIpLCBwY2g9MjAsIGNvbD1jKDIsMykpDQoNCmBgYA0KDQojIyMjINCc0LXRgtC+0LQg0LzQsNC60YHQuNC80LDQu9GM0L3QvtCz0L4g0L/RgNCw0LLQtNC+0L/QvtC00L7QsdC40Y8NCg0K0J7RhtC10L3QutC4INC/0LDRgNCw0LzQtdGC0YDQvtCyINC/0L4g0LzQtdGC0L7QtNGDINC80LDQutGB0LjQvNCw0LvRjNC90L7Qs9C+INC/0YDQsNCy0LTQvtC/0L7QtNC+0LHQuNGPDQpgYGB7cn0NCkZ1bmMucHJvYi5sb2cgPC0gZnVuY3Rpb24oeCkgLSBzdW0oZHVuaWYoWCwgbWluID0geFsxXSwgbWF4ID0geFsyXSwgbG9nID0gVFJVRSkpDQpyZXMgPC0gb3B0aW0oYygwLjk3LCAzLjEpLCBGdW5jLnByb2IubG9nKSAjIDAuOSwgMy4xIGFzIGluaXRpYWwgdmFsdWVzDQphLi4gPC0gcmVzJHBhclsxXTsgYi4uIDwtIHJlcyRwYXJbMl07DQpjKGEuLj1hLi4sIGIuLj1iLi4pDQpgYGANCg0K0J/QvtGB0YLRgNC+0LjQvCDQs9GA0LDRhNC40Log0YHQviDRgdGA0LDQstC90LXQvdC40LXQvCDRgtC10L7RgNC10YLQuNGH0LXRgdC60L7Qs9C+INGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGPINGBINGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGP0LzQuCwg0L/QvtGB0YLRgNC+0LXQvdC90YvQvNC4INC/0L4g0L/QsNGA0LDQvNC10YLRgNCw0LwsINC/0L7Qu9GD0YfQtdC90L3Ri9C8INCyINC80LXRgtC+0LTQsNGFINC80L7QvNC10L3RgtC+0LIgKG1tKSDQuCDQvNCw0LrRgdC40LzQsNC70YzQvdC+0LPQviDQv9GA0LDQstC00L7Qv9C+0LTQvtCx0LjRjyAobWxlKQ0KYGBge3J9DQp4eC4uIDwtIHJ1bmlmKDE1MDAsIG1pbj1hLi4sIG1heD1iLi4pDQoNCmhpc3QoWCwgZnJlcT1GQUxTRSwgbWFpbj0iTU0sIE1MRSIpDQpsaW5lcyhkZW5zaXR5KFgpLCBjb2w9MikNCmxpbmVzKGRlbnNpdHkoeHguKSwgY29sPTMpDQpsaW5lcyhkZW5zaXR5KHh4Li4pLCBjb2w9NCkNCmxlZ2VuZCgndG9wcmlnaHQnLCBjKCJoeXAiLCJtbSIsICJtbGUiKSwgcGNoPTIwLCBjb2w9YygyLDMsNCkpDQpgYGANCg0K0JfQsNC80LXRgtC40LwsINGH0YLQviDQvtGG0LXQvdC60LgsINC/0L7Qu9GD0YfQtdC90L3Ri9C1INC60LDQuiDQv9C+INC80LXRgtC+0LTRgyDQvNC+0LzQtdC90YLQvtCyLCDRgtCw0Log0Lgg0L/QviDQvNC10YLQvtC00YMg0LzQsNC60YHQuNC80LDQu9GM0L3QvtCz0L4g0L/RgNCw0LLQtNC+0L/QvtC00L7QsdC40Y8sINC00L7RgdGC0LDRgtC+0YfQvdC+INCx0LvQuNC30LrQuCDQuiDRgtC10L7RgNC10YLQuNGH0LXRgdC60LjQvC4g0JTQu9GPINC/0L7Qu9GD0YfQtdC90LjRjyDQsdC+0LvQtdC1INGC0L7Rh9C90YvRhSDQvtGG0LXQvdC+0Log0YHQu9C10LTRg9C10YIg0YPQstC10LvQuNGH0LjRgtGMINC+0LHRitC10Lwg0LzQvtC00LXQu9C40YDRg9C10LzRi9GFINC00LDQvdC90YvRhQ0KDQojIyMg0J/RgNC+0LLQtdGA0LrQsCDRgdC+0LPQu9Cw0YHQuNGPINGN0LzQv9C40YDQuNGH0LXRgdC60L7Qs9C+INC4INGC0LXQvtGA0LXRgtC40YfQtdGB0LrQvtCz0L4g0YDQsNGB0L/RgNC10LTQtdC70LXQvdC40Y8g0L/QviDQutGA0LjRgtC10YDQuNGOINGF0Lwt0LrQstCw0LTRgNCw0YIg0J/QuNGA0YHQvtC90LANCg0KYGBge3J9DQojINGN0LzQv9C40YDQuNGH0LXRgdC60LjQtSDRh9Cw0YHRgtC+0YLRiw0KaCA8LSBoaXN0KFgsIHBsb3Q9RkFMU0UpDQoNCiMg0LPQuNC/0L7RgtC10YLQuNGH0LXRgdC60LjQtSDRh9Cw0YHRgtC+0YLRiw0KcC5pIDwtIHNhcHBseShzZXEobGVuZ3RoKGgkYnJlYWtzKS0xKSArIDEsIGZ1bmN0aW9uKGkpIHB1bmlmKGgkYnJlYWtzW2ldLCBtaW49YSwgbWF4PWIpIC0gcHVuaWYoaCRicmVha3NbaS0xXSwgbWluPWEsIG1heD1iKSkNCnAuaVsxXSA8LSBwdW5pZihoJGJyZWFrc1syXSwgbWluPWEsIG1heD1iKQ0KcC5pW2xlbmd0aChwLmkpXSA8LSAxIC0gcHVuaWYoaCRicmVha3NbbGVuZ3RoKGgkYnJlYWtzKSAtIDFdLCBtaW49YSwgbWF4PWIpDQpzdW0ocC5pKSAjINC00L7Qu9C20L3QviDQsdGL0YLRjCDRgNCw0LLQvdC+IDENCg0KYGBgDQoNCtCf0YDQvtCy0LXRgNC60LAg0YPRgdC70L7QstC40Y8gJG5wX2kgXGdlcSA1JCAo0LTQu9GPINC/0YDQuNC80LXQvdC10L3QuNGPINC60YDQuNGC0LXRgNC40Y8g0YHQvtCz0LvQsNGB0LjRjyDQn9C40YDRgdC+0L3QsCkNCmBgYHtyfQ0KdGFiIDwtIGNiaW5kKGgkY291bnRzLCBsZW5ndGgoWCkgKiBwLmkpOyB0YWINCmBgYA0KDQrQndCw0LHQu9GO0LTQsNC10LzQvtC1INC30L3QsNGH0LXQvdC40LUg0YHRgtCw0YLQuNGB0YLQuNC60LggJFxjaGleMiQNCmBgYHtyfQ0KY2hpMiA8LSBzdW0oYXBwbHkodGFiLCAxLCBmdW5jdGlvbih4KSAoeFsxXSAtIHhbMl0pXjIgLyB4WzJdKSk7IGNoaTINCmBgYA0KDQoNCmBgYHtyfQ0KYWxwaGEgPC0gMC4wNQ0KcF92YWx1ZSA8LSAxIC0gcGNoaXNxKGNoaTIsIG5yb3codGFiKSAtIDIgLSAxKTsgDQpwcmludChwYXN0ZSgicF92YWx1ZSIsIHJvdW5kKHBfdmFsdWUsIDMpLCBzZXA9IiA9ICIpKQ0KaWYgKHBfdmFsdWUgPiBhbHBoYSkgcHJpbnQocGFzdGUoIlRoZSBoeXBvdGhlc2lzIG9mIHRoZSBhZ3JlZW1lbnQgb2YgdGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgb25lIGlzIG5vdCByZWplY3RlZCB3aXRoIHRoZSBzaWduaWZpY2FuY2UgbGV2ZWwgYWxwaGEiLCBhbHBoYSwgc2VwPSI9IikpIGVsc2UgcHJpbnQoIlRoZSBoeXBvdGhlc2lzIG9mIHRoZSBhZ3JlZW1lbnQgb2YgdGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgb25lIGlzIHJlamVjdGVkIikNCmBgYCANCg0KJHAudmFsdWUgPSBgciByb3VuZChwX3ZhbHVlLCAzKWAkLCDQv9C+0Y3RgtC+0LzRgyDQs9C40L/QvtGC0LXQt9CwINC+INGB0L7Qs9C70LDRgdC40Lgg0Y3QvNC/0LjRgNC40YfQtdGB0LrQvtCz0L4g0Lgg0YLQtdC+0YDQtdGC0LjRh9C10YHQutC+0LPQviDRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjRjyDQndCVINC+0YLQstC10YDQs9Cw0LXRgtGB0Y8g0L/RgNC4INC30LDQtNCw0L3QvdC+0LwgJFxhbHBoYSA9IGByIGFscGhhYCQuDQoNCg==