Definición PDF
Una distribución bivariada es de la forma \[p(y_1,y_2)=P(Y_1=y_1,Y_2=y_2)\] la cual podemos ver tiene dos variables aleatorias.
Propiedades
- \(p(y_1.y_2)\geq 0\)
- \(\sum_{y_1}\sum_{y_2}p(y_1,y_2)=1, \forall (y_1,y_2)\)
Definición CDF
La funcion de distribución acumulada se define como, \[F(y_1,y_2)=P(Y_1 \leq y_1, Y_2 \leq y_2)\]
Caso Discreto
\[\sum_{t_1 \in (-\infty,y_1]}\sum_{t_2 \in (-\infty,y_2]}f(t_1,t_2)\]
Caso continuo
\[\int_{-\infty}^{y_1}\int_{-\infty}^{y_2}f(t_1,t_2)dt_2dt_1\]
Propiedades
- \(F(-\infty,-\infty)=F(-\infty,y_2)=F(y_1,-\infty)=0\)
- \(F(\infty, \infty)=1\)
Ejemplo clase
La administración en un restaurante de comida rápida está interesada en el comportamiento conjunto de las variables aleatorias \(Y_1\), definidas como el tiempo total entre la llegada de un cliente a la tienda y la salida de la ventanilla de servicio y \(Y_2\), el tiempo que un cliente espera en la fila antes de llegar a la ventanilla de servicio. Como \(Y_1\) incluye el tiempo que un cliente espera en la fila, debemos tener \(Y_1 \geq Y_2\). La distribución de frecuencia relativa de valores observados de \(Y_1\) y \(Y_2\) puede ser modelada por la función de densidad de probabilidad \[f(y_1,y_2)=\begin{cases}
e^{-y_1} & \text{ , } 0 \leq y_2 \leq y_1 < \infty \\
0 & \text{ , en cualquier otro punto}
\end{cases}\]
Con el tiempo medido en minutos. Encuentre
- \(P(Y_1<2, Y_2>1)\)
- \(P(Y_1 \geq 2Y_2)\)
- \(P(Y_1-Y_2 \geq 1)\) (Observese que \(Y_1-Y_2\) denota el tiempo que se pasa en la ventanilla de servicio)
Laboratorio en R
Usaremos el dataset demanda de bicicletas. Para determinar demostrar la utilizacion en campo de la teoria aprendidad en clase. El dataset lo puede encontrar en el GES.
bici<- read.csv("hour.csv",
na.strings = FALSE,
strip.white = TRUE)
colnames(bici)
[1] "instant" "dteday" "season" "yr" "mnth" "hr" "holiday"
[8] "weekday" "workingday" "weathersit" "temp" "atemp" "hum" "windspeed"
[15] "casual" "registered" "cnt"
datetime - hourly date + timestamp
season - 1 = spring, 2 = summer, 3 = fall, 4 = winter
holiday - whether the day is considered a holiday
workingday - whether the day is neither a weekend nor holiday
weather - 1: Clear, Few clouds, Partly cloudy, Partly cloudy 2: Mist + Cloudy, Mist + Broken clouds, Mist + Few clouds, Mist 3: Light Snow, Light Rain + Thunderstorm + Scattered clouds, Light Rain + Scattered clouds 4: Heavy Rain + Ice Pallets + Thunderstorm + Mist, Snow + Fog
temp - temperature in Celsius
atemp - “feels like” temperature in Celsius
humidity - relative humidity
windspeed - wind speed
casual - number of non-registered user rentals initiated
registered - number of registered user rentals initiated
count - number of total rentals
library(dplyr)
package <U+393C><U+3E31>dplyr<U+393C><U+3E32> was built under R version 3.3.3
Attaching package: <U+393C><U+3E31>dplyr<U+393C><U+3E32>
The following objects are masked from <U+393C><U+3E31>package:stats<U+393C><U+3E32>:
filter, lag
The following objects are masked from <U+393C><U+3E31>package:base<U+393C><U+3E32>:
intersect, setdiff, setequal, union
library(ggplot2)
library(MASS)
Attaching package: <U+393C><U+3E31>MASS<U+393C><U+3E32>
The following object is masked from <U+393C><U+3E31>package:dplyr<U+393C><U+3E32>:
select
seasonx<-2
bici_data<-
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum)
hist(bici_data$atemp)

hist(bici_data$hum)

bici_data %>%
ggplot(aes(atemp))+
geom_histogram(bins=30, aes(y = ..density..) )+
geom_rug()+
geom_density()

bici_data %>%
ggplot(aes(hum))+
geom_histogram(bins=30, aes(y = ..density..) )+
geom_rug()+
geom_density()

Grafica de contorno spring
seasonx<-1
bici_data<-
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum)
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum) %>%
ggplot( aes(atemp, hum) ) +
geom_raster(aes(fill=cnt), interpolate = FALSE)+
geom_point(size=0.1)+
geom_density_2d()+
geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z)
sum(bici_density$z)
[1] 1
Heatmap spring
cols1 <- colorRampPalette(c("red", "white", "blue"),
space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,
col = cols3,
zlim=c(min(bici_density$z), max(bici_density$z)))

Grafica de contorno summer
seasonx<-2
bici_data<-
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum)
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum) %>%
ggplot( aes(atemp, hum) ) +
geom_raster(aes(fill=cnt), interpolate = FALSE)+
geom_point(size=0.1)+
geom_density_2d()+
geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z)
sum(bici_density$z)
[1] 1
Heatmap summer
cols1 <- colorRampPalette(c("red", "white", "blue"),
space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,
col = cols3,
zlim=c(min(bici_density$z), max(bici_density$z)))

Grafica de contorno fall
seasonx<-3
bici_data<-
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum)
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum) %>%
ggplot( aes(atemp, hum) ) +
geom_raster(aes(fill=cnt), interpolate = FALSE)+
geom_point(size=0.1)+
geom_density_2d()+
geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z)
sum(bici_density$z)
[1] 1
Heatmap fall
cols1 <- colorRampPalette(c("red", "white", "blue"),
space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,
col = cols3,
zlim=c(min(bici_density$z), max(bici_density$z)))

Grafica de contorno winter
seasonx<-4
bici_data<-
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum)
bici %>%
dplyr::select(season, atemp, hum, cnt) %>%
filter(season == seasonx) %>%
group_by(atemp,hum) %>%
ggplot( aes(atemp, hum) ) +
geom_raster(aes(fill=cnt), interpolate = FALSE)+
geom_point(size=0.1)+
geom_density_2d()+
geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z)
sum(bici_density$z)
[1] 1
Heatmap winter
cols1 <- colorRampPalette(c("red", "white", "blue"),
space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,
col = cols3,
zlim=c(min(bici_density$z), max(bici_density$z)))

str(bici_density)
List of 3
$ x: num [1:100] 0.151 0.157 0.162 0.168 0.173 ...
$ y: num [1:100] 0.16 0.168 0.177 0.185 0.194 ...
$ z: num [1:100, 1:100] 3.38e-15 7.71e-15 1.66e-14 3.36e-14 6.44e-14 ...
filterX<-bici_density$x>=0.5
filterY<-bici_density$y<=0.3
bici_density$z[filterX,filterY] %>% sum()
[1] 0.003170821
filterX<-bici_density$x>=0.4 & bici_density$x<=0.8
filterY<-bici_density$y>=0.6 & bici_density$y<=0.85
bici_density$z[filterX,filterY] %>% sum()
[1] 0.2296997
bici_data<-
bici %>%
dplyr::select(season,atemp,hum,cnt)%>%
filter(season==4)
##bici_density$y
x<-matrix(rep(bici_density$y,3),nrow = 3, byrow = TRUE)
sum(x*bici_density$y)
[1] 106.9188
library(expm)
Loading required package: Matrix
Attaching package: <U+393C><U+3E31>expm<U+393C><U+3E32>
The following object is masked from <U+393C><U+3E31>package:Matrix<U+393C><U+3E32>:
expm
p<-rbind(c(1,0,0,0),c(0.5,0,0.5,0),c(0,0.5,0,0.5),c(0,0,0,1))
w<-matrix(p,nrow = 4)
c(0,0,1,0) %*% (p%^%20)
[,1] [,2] [,3] [,4]
[1,] 0.333333 0 9.536743e-07 0.666666
LS0tDQp0aXRsZTogIkRpc3RyaWJ1Y2lvbmVzIGRlIHByb2JhYmlsaWRhZCBiaXZhcmlhZGFzIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQoNCiMjIERlZmluaWNpw4PCs24gUERGDQpVbmEgZGlzdHJpYnVjacODwrNuIGJpdmFyaWFkYSBlcyBkZSBsYSBmb3JtYSAkJHAoeV8xLHlfMik9UChZXzE9eV8xLFlfMj15XzIpJCQNCmxhIGN1YWwgcG9kZW1vcyB2ZXIgdGllbmUgZG9zICp2YXJpYWJsZXMgYWxlYXRvcmlhcyouDQoNCiMjIFByb3BpZWRhZGVzDQoxLiAkcCh5XzEueV8yKVxnZXEgMCQNCjIuICRcc3VtX3t5XzF9XHN1bV97eV8yfXAoeV8xLHlfMik9MSwgXGZvcmFsbCAoeV8xLHlfMikkDQoNCiMjIERlZmluaWNpw4PCs24gQ0RGDQpMYSBmdW5jaW9uIGRlIGRpc3RyaWJ1Y2nDg8KzbiBhY3VtdWxhZGEgc2UgZGVmaW5lIGNvbW8sDQokJEYoeV8xLHlfMik9UChZXzEgXGxlcSB5XzEsIFlfMiBcbGVxIHlfMikkJA0KDQojIyMgQ2FzbyBEaXNjcmV0bw0KDQokJFxzdW1fe3RfMSBcaW4gKC1caW5mdHkseV8xXX1cc3VtX3t0XzIgXGluICgtXGluZnR5LHlfMl19Zih0XzEsdF8yKSQkDQoNCiMjIyBDYXNvIGNvbnRpbnVvDQokJFxpbnRfey1caW5mdHl9Xnt5XzF9XGludF97LVxpbmZ0eX1ee3lfMn1mKHRfMSx0XzIpZHRfMmR0XzEkJA0KDQojIyBQcm9waWVkYWRlcw0KMS4gJEYoLVxpbmZ0eSwtXGluZnR5KT1GKC1caW5mdHkseV8yKT1GKHlfMSwtXGluZnR5KT0wJA0KMi4gJEYoXGluZnR5LCBcaW5mdHkpPTEkDQoNCiMjIEVqZW1wbG8gY2xhc2UNCkxhIGFkbWluaXN0cmFjacODwrNuIGVuIHVuIHJlc3RhdXJhbnRlIGRlIGNvbWlkYSByw4PCoXBpZGEgZXN0w4PCoSBpbnRlcmVzYWRhIGVuIGVsIGNvbXBvcnRhbWllbnRvIGNvbmp1bnRvIGRlIGxhcyB2YXJpYWJsZXMgYWxlYXRvcmlhcyAkWV8xJCwgZGVmaW5pZGFzIGNvbW8gZWwgdGllbXBvIHRvdGFsIGVudHJlIGxhIGxsZWdhZGEgZGUgdW4gY2xpZW50ZSBhIGxhIHRpZW5kYSB5IGxhIHNhbGlkYSBkZSBsYSB2ZW50YW5pbGxhIGRlIHNlcnZpY2lvIHkgJFlfMiQsIGVsIHRpZW1wbyBxdWUgdW4gY2xpZW50ZSBlc3BlcmEgZW4gbGEgZmlsYSBhbnRlcyBkZSBsbGVnYXIgYSBsYSB2ZW50YW5pbGxhIGRlIHNlcnZpY2lvLiBDb21vICRZXzEkIGluY2x1eWUgZWwgdGllbXBvIHF1ZSB1biBjbGllbnRlIGVzcGVyYSBlbiBsYSBmaWxhLCBkZWJlbW9zIHRlbmVyICRZXzEgXGdlcSBZXzIkLiBMYSBkaXN0cmlidWNpw4PCs24gZGUgZnJlY3VlbmNpYSByZWxhdGl2YSBkZSB2YWxvcmVzIG9ic2VydmFkb3MgZGUgJFlfMSQgeSAkWV8yJCBwdWVkZSBzZXIgbW9kZWxhZGEgcG9yIGxhIGZ1bmNpw4PCs24gZGUgZGVuc2lkYWQgZGUgcHJvYmFiaWxpZGFkDQokJGYoeV8xLHlfMik9XGJlZ2lue2Nhc2VzfQ0KZV57LXlfMX0gJiBcdGV4dHsgLCB9IDAgXGxlcSB5XzIgXGxlcSB5XzEgPCBcaW5mdHkgXFwgDQowICYgXHRleHR7ICwgIGVuIGN1YWxxdWllciBvdHJvIHB1bnRvfSAgIA0KXGVuZHtjYXNlc30kJA0KDQoNCg0KQ29uIGVsIHRpZW1wbyBtZWRpZG8gZW4gbWludXRvcy4gRW5jdWVudHJlDQoNCmEuICRQKFlfMTwyLCBZXzI+MSkkDQpiLiAkUChZXzEgXGdlcSAyWV8yKSQNCmMuICRQKFlfMS1ZXzIgXGdlcSAxKSQgKE9ic2VydmVzZSBxdWUgJFlfMS1ZXzIkIGRlbm90YSBlbCB0aWVtcG8gcXVlIHNlIHBhc2EgZW4gbGEgdmVudGFuaWxsYSBkZSBzZXJ2aWNpbykNCg0KDQojIExhYm9yYXRvcmlvIGVuIFINCg0KVXNhcmVtb3MgZWwgZGF0YXNldCBkZW1hbmRhIGRlIGJpY2ljbGV0YXMuIFBhcmEgZGV0ZXJtaW5hciBkZW1vc3RyYXIgbGEgdXRpbGl6YWNpb24gZW4gY2FtcG8gZGUgbGEgdGVvcmlhIGFwcmVuZGlkYWQgZW4gY2xhc2UuIEVsIGRhdGFzZXQgbG8gcHVlZGUgZW5jb250cmFyIGVuIGVsIEdFUy4NCg0KYGBge3J9DQpiaWNpPC0gcmVhZC5jc3YoImhvdXIuY3N2IiwNCiAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gRkFMU0UsDQogICAgICAgICAgICAgICAgc3RyaXAud2hpdGUgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0KY29sbmFtZXMoYmljaSkNCmBgYA0KDQoqKmRhdGV0aW1lKiogLSBob3VybHkgZGF0ZSArIHRpbWVzdGFtcCANCg0KKipzZWFzb24qKiAtICAxID0gc3ByaW5nLCAyID0gc3VtbWVyLCAzID0gZmFsbCwgNCA9IHdpbnRlciANCg0KKipob2xpZGF5KiogLSB3aGV0aGVyIHRoZSBkYXkgaXMgY29uc2lkZXJlZCBhIGhvbGlkYXkNCg0KKip3b3JraW5nZGF5KiogLSB3aGV0aGVyIHRoZSBkYXkgaXMgbmVpdGhlciBhIHdlZWtlbmQgbm9yIGhvbGlkYXkNCg0KKip3ZWF0aGVyKiogLSAqMToqIENsZWFyLCBGZXcgY2xvdWRzLCBQYXJ0bHkgY2xvdWR5LCBQYXJ0bHkgY2xvdWR5DQoqMjoqIE1pc3QgKyBDbG91ZHksIE1pc3QgKyBCcm9rZW4gY2xvdWRzLCBNaXN0ICsgRmV3IGNsb3VkcywgTWlzdCANCiozOiogTGlnaHQgU25vdywgTGlnaHQgUmFpbiArIFRodW5kZXJzdG9ybSArIFNjYXR0ZXJlZCBjbG91ZHMsIExpZ2h0IFJhaW4gKyBTY2F0dGVyZWQgY2xvdWRzIA0KKjQ6KiBIZWF2eSBSYWluICsgSWNlIFBhbGxldHMgKyBUaHVuZGVyc3Rvcm0gKyBNaXN0LCBTbm93ICsgRm9nIA0KICAgICAgICAgICAgDQoqKnRlbXAqKiAtIHRlbXBlcmF0dXJlIGluIENlbHNpdXMNCg0KKiphdGVtcCoqIC0gImZlZWxzIGxpa2UiIHRlbXBlcmF0dXJlIGluIENlbHNpdXMNCg0KKipodW1pZGl0eSoqIC0gcmVsYXRpdmUgaHVtaWRpdHkNCg0KKip3aW5kc3BlZWQqKiAtIHdpbmQgc3BlZWQNCg0KKipjYXN1YWwqKiAtIG51bWJlciBvZiBub24tcmVnaXN0ZXJlZCB1c2VyIHJlbnRhbHMgaW5pdGlhdGVkDQoNCioqcmVnaXN0ZXJlZCoqIC0gbnVtYmVyIG9mIHJlZ2lzdGVyZWQgdXNlciByZW50YWxzIGluaXRpYXRlZA0KDQoqKmNvdW50KiogLSBudW1iZXIgb2YgdG90YWwgcmVudGFscw0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KE1BU1MpDQpgYGANCg0KDQpgYGB7cn0NCnNlYXNvbng8LTINCmJpY2lfZGF0YTwtDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSANCmBgYA0KDQoNCmBgYHtyfQ0KaGlzdChiaWNpX2RhdGEkYXRlbXApDQpgYGANCg0KYGBge3J9DQpoaXN0KGJpY2lfZGF0YSRodW0pDQpgYGANCg0KDQoNCmBgYHtyfQ0KYmljaV9kYXRhICU+JSANCiAgZ2dwbG90KGFlcyhhdGVtcCkpKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zPTMwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSApKw0KICBnZW9tX3J1ZygpKw0KICBnZW9tX2RlbnNpdHkoKQ0KYGBgDQoNCg0KYGBge3J9DQpiaWNpX2RhdGEgJT4lIA0KICBnZ3Bsb3QoYWVzKGh1bSkpKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zPTMwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSApKw0KICBnZW9tX3J1ZygpKw0KICBnZW9tX2RlbnNpdHkoKQ0KYGBgDQoNCiNHcmFmaWNhIGRlIGNvbnRvcm5vIHNwcmluZw0KDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtMQ0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KDQpgYGB7cn0NCmJpY2lfZGVuc2l0eSA8LSBrZGUyZChiaWNpX2RhdGEkYXRlbXAsYmljaV9kYXRhJGh1bSwgbj0xMDApDQpiaWNpX2RlbnNpdHkkeiA8LSBiaWNpX2RlbnNpdHkkei9zdW0oIGJpY2lfZGVuc2l0eSR6KSANCnN1bShiaWNpX2RlbnNpdHkkeikNCg0KDQpgYGANCg0KI0hlYXRtYXAgc3ByaW5nDQoNCmBgYHtyfQ0KY29sczEgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJyZWQiLCAid2hpdGUiLCAiYmx1ZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2UgPSAiTGFiIikoMjU2KQ0KDQpjb2xzMiA8LSBjb2xvclJhbXBQYWxldHRlKGMoIiNGRkZGRDQiLCAiI0ZFRDk4RSIsICIjRkU5OTI5IiwgIiNEOTVGMEUiLCAiIzk5MzQwNCIpLHNwYWNlPSJMYWIiKSgyNTYpDQoNCmNvbHMzPC1jb2xvclJhbXBQYWxldHRlKGMoImJsYWNrIiwiYmx1ZSIsImdyZWVuIiwib3JhbmdlIiwicmVkIikpKDEwMDApDQoNCg0KaW1hZ2UoYmljaV9kZW5zaXR5JHosICANCiAgICAgIGNvbCA9IGNvbHMzLCANCiAgICAgIHpsaW09YyhtaW4oYmljaV9kZW5zaXR5JHopLCBtYXgoYmljaV9kZW5zaXR5JHopKSkNCg0KYGBgDQoNCg0KI0dyYWZpY2EgZGUgY29udG9ybm8gc3VtbWVyDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtMg0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KYGBge3J9DQpiaWNpX2RlbnNpdHkgPC0ga2RlMmQoYmljaV9kYXRhJGF0ZW1wLGJpY2lfZGF0YSRodW0sIG49MTAwKQ0KYmljaV9kZW5zaXR5JHogPC0gYmljaV9kZW5zaXR5JHovc3VtKCBiaWNpX2RlbnNpdHkkeikgDQpzdW0oYmljaV9kZW5zaXR5JHopDQoNCg0KYGBgDQoNCiNIZWF0bWFwIHN1bW1lcg0KDQpgYGB7cn0NCmNvbHMxIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygicmVkIiwgIndoaXRlIiwgImJsdWUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlID0gIkxhYiIpKDI1NikNCg0KY29sczIgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCIjRkZGRkQ0IiwgIiNGRUQ5OEUiLCAiI0ZFOTkyOSIsICIjRDk1RjBFIiwgIiM5OTM0MDQiKSxzcGFjZT0iTGFiIikoMjU2KQ0KDQpjb2xzMzwtY29sb3JSYW1wUGFsZXR0ZShjKCJibGFjayIsImJsdWUiLCJncmVlbiIsIm9yYW5nZSIsInJlZCIpKSgxMDAwKQ0KDQoNCmltYWdlKGJpY2lfZGVuc2l0eSR6LCAgDQogICAgICBjb2wgPSBjb2xzMywgDQogICAgICB6bGltPWMobWluKGJpY2lfZGVuc2l0eSR6KSwgbWF4KGJpY2lfZGVuc2l0eSR6KSkpDQoNCmBgYA0KDQojR3JhZmljYSBkZSBjb250b3JubyBmYWxsDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtMw0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KYGBge3J9DQpiaWNpX2RlbnNpdHkgPC0ga2RlMmQoYmljaV9kYXRhJGF0ZW1wLGJpY2lfZGF0YSRodW0sIG49MTAwKQ0KYmljaV9kZW5zaXR5JHogPC0gYmljaV9kZW5zaXR5JHovc3VtKCBiaWNpX2RlbnNpdHkkeikgDQpzdW0oYmljaV9kZW5zaXR5JHopDQoNCg0KYGBgDQoNCiNIZWF0bWFwIGZhbGwNCg0KYGBge3J9DQpjb2xzMSA8LSBjb2xvclJhbXBQYWxldHRlKGMoInJlZCIsICJ3aGl0ZSIsICJibHVlIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZSA9ICJMYWIiKSgyNTYpDQoNCmNvbHMyIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygiI0ZGRkZENCIsICIjRkVEOThFIiwgIiNGRTk5MjkiLCAiI0Q5NUYwRSIsICIjOTkzNDA0Iiksc3BhY2U9IkxhYiIpKDI1NikNCg0KY29sczM8LWNvbG9yUmFtcFBhbGV0dGUoYygiYmxhY2siLCJibHVlIiwiZ3JlZW4iLCJvcmFuZ2UiLCJyZWQiKSkoMTAwMCkNCg0KDQppbWFnZShiaWNpX2RlbnNpdHkkeiwgIA0KICAgICAgY29sID0gY29sczMsIA0KICAgICAgemxpbT1jKG1pbihiaWNpX2RlbnNpdHkkeiksIG1heChiaWNpX2RlbnNpdHkkeikpKQ0KDQpgYGANCg0KI0dyYWZpY2EgZGUgY29udG9ybm8gd2ludGVyDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtNA0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KYGBge3J9DQpiaWNpX2RlbnNpdHkgPC0ga2RlMmQoYmljaV9kYXRhJGF0ZW1wLGJpY2lfZGF0YSRodW0sIG49MTAwKQ0KYmljaV9kZW5zaXR5JHogPC0gYmljaV9kZW5zaXR5JHovc3VtKCBiaWNpX2RlbnNpdHkkeikgDQpzdW0oYmljaV9kZW5zaXR5JHopDQoNCg0KYGBgDQoNCiNIZWF0bWFwIHdpbnRlcg0KDQpgYGB7cn0NCmNvbHMxIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygicmVkIiwgIndoaXRlIiwgImJsdWUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlID0gIkxhYiIpKDI1NikNCg0KY29sczIgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCIjRkZGRkQ0IiwgIiNGRUQ5OEUiLCAiI0ZFOTkyOSIsICIjRDk1RjBFIiwgIiM5OTM0MDQiKSxzcGFjZT0iTGFiIikoMjU2KQ0KDQpjb2xzMzwtY29sb3JSYW1wUGFsZXR0ZShjKCJibGFjayIsImJsdWUiLCJncmVlbiIsIm9yYW5nZSIsInJlZCIpKSgxMDAwKQ0KDQoNCmltYWdlKGJpY2lfZGVuc2l0eSR6LCAgDQogICAgICBjb2wgPSBjb2xzMywgDQogICAgICB6bGltPWMobWluKGJpY2lfZGVuc2l0eSR6KSwgbWF4KGJpY2lfZGVuc2l0eSR6KSkpDQoNCmBgYA0KDQpgYGB7cn0NCnN0cihiaWNpX2RlbnNpdHkpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KZmlsdGVyWDwtYmljaV9kZW5zaXR5JHg+PTAuNQ0KZmlsdGVyWTwtYmljaV9kZW5zaXR5JHk8PTAuMw0KYmljaV9kZW5zaXR5JHpbZmlsdGVyWCxmaWx0ZXJZXSAlPiUgc3VtKCkNCmBgYA0KDQpgYGB7cn0NCmZpbHRlclg8LWJpY2lfZGVuc2l0eSR4Pj0wLjQgJiBiaWNpX2RlbnNpdHkkeDw9MC44DQpmaWx0ZXJZPC1iaWNpX2RlbnNpdHkkeT49MC42ICYgYmljaV9kZW5zaXR5JHk8PTAuODUNCmJpY2lfZGVuc2l0eSR6W2ZpbHRlclgsZmlsdGVyWV0gJT4lIHN1bSgpDQpgYGANCg0KDQoNCmBgYHtyfQ0KYmljaV9kYXRhPC0NCiAgYmljaSAlPiUNCiAgZHBseXI6OnNlbGVjdChzZWFzb24sYXRlbXAsaHVtLGNudCklPiUNCiAgZmlsdGVyKHNlYXNvbj09NCkNCiMjYmljaV9kZW5zaXR5JHkNCng8LW1hdHJpeChyZXAoYmljaV9kZW5zaXR5JHksMyksbnJvdyA9IDMsIGJ5cm93ID0gVFJVRSkNCnN1bSh4KmJpY2lfZGVuc2l0eSR5KQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShleHBtKQ0KcDwtcmJpbmQoYygxLDAsMCwwKSxjKDAuNSwwLDAuNSwwKSxjKDAsMC41LDAsMC41KSxjKDAsMCwwLDEpKQ0KdzwtbWF0cml4KHAsbnJvdyA9IDQpDQpjKDAsMCwxLDApICUqJSAocCVeJTIwKQ0KYGBgDQoNCg==