Formula

The mixed model equations have following form, assuming that the variance-covariance-matrix (\(var(e)\)) of the error vector \(e\) has the simple form

\[var(e) = I * \sigma_e^2\] where \(I\) is the identity matrix. The mixed model equations are given by

\[ \begin{bmatrix}X^TX & X^TZ \\ Z^TX & Z^TZ + \lambda* A^{-1}\end{bmatrix} * \begin{bmatrix} \hat{\beta} \\ \hat{u}\end{bmatrix} = \begin{bmatrix} X^Ty \\Z^Ty\end{bmatrix} \]

Specification of the expected values and the variance-covariance matrices of all random effects. Random effects are \(e\), \(u\) and \(y\).

\[ E\begin{bmatrix}e \\ u \\y \end{bmatrix} = \begin{bmatrix} \\ \\ \end{bmatrix} \text{, } var\begin{bmatrix}e \\ u \\y \end{bmatrix} = \]

Data Set

The data set is given by

tbl_si_dat <- tibble::tibble(Animal = c(1:5),
                             Sire   = c(NA, NA, NA, 1, 4),
                             Dam    = c(NA, NA, NA, 2, 3),
                             Sex    = c("M", "F", "F", "M", "F"),
                             WWG    = c(4.5, 2.9, 3.9, 3.5, 5.0))

tbl_si_dat

Model Components

Model comonents are

Unknowns

  • vector \(\beta\) of fixed effects. In our data set the variable ‘Sex’ is treated as fixed effect. In general, in a data set the columns ‘Animal’, ‘Sire’ and ‘Dam’ belong to the pedigree, the column ‘WWG’ is our observation or response variable and everything in the dataset that does not belong to the pedigree and is not an observation or response variable, is treated as a fixed effect. As a consequence in our dataset, ‘Sex’ is a fixed effect. The lenght of the vector \(\beta\) depends on the number of levels that are available in the column ‘Sex’ in the complete dataset.

The number of levels in a given fixed effect can be determined using R

tbl_si_dat$Sex <- as.factor(tbl_si_dat$Sex)
tbl_si_dat
(n_level_sex <- nlevels(tbl_si_dat$Sex))
[1] 2

With that the length of the vector \(\beta\) is 2

\[\beta = \begin{bmatrix} \beta_M \\ \beta_F \end{bmatrix}\]

  • vector \(u\) of breeding values. Since we are fitting an animal model, \(u\) has as many compents as there are animals in the pedigree. In our dataset the vector \(u\) has 5 components.

\[u = \begin{bmatrix} u_1 \\ u_2 \\ u_3 \\ u_4 \\ u_5 \end{bmatrix}\]

  • vector \(e\) of random error terms. The length of the vector \(e\) is the same as the number of observations.

\[e = \begin{bmatrix} e_1 \\ e_2 \\ e_3 \\ e_4 \\ e_5 \end{bmatrix}\]

Observations

Observations corresponds to the vector \(y\). The vector \(y\) is known and therefore, we can insert numbers from the dataset into the vector \(y\).

vec_y <- tbl_si_dat$WWG
cat(paste(rmdhelp::bcolumn_vector(pvec = vec_y, ps_name = 'y', ps_env = '$$'), collapse = '\n'), '\n')

\[y = \begin{bmatrix} 4.5 \\2.9 \\3.9 \\3.5 \\5\end{bmatrix}\]

Design Matrices

Design matrix \(X\) links levels of fixed effects to observations. The matrix \(X\) has dimensions \(n\times p\) where \(n\) is the number of observations and \(p\) is the number of levels in our fixed effects. In our example \(n=5\) and \(p=2\)

\[ X = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 0 & 1 \\ 1 & 0 \\ 0 & 1 \end{bmatrix} \]

The design matrix \(Z\) links random breeding values (\(u\)) to observations. The matrix \(Z\) has dimensions \(n\times q\) where \(n\) is the number of observations and \(q\) is the number of animals in the pedgree.

\[ Z = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1 \\ \end{bmatrix} \]

Model

Model in Matrix-Vector Notation

\[y = X \beta + Zu + e \] The equation for the first observation

\[y_1 = \beta_M + u_1 + e_1\]

Inverse Numerator Relationship Matrix

We use pedigreemm to construct \(A^{-1}\)

(ped <- pedigreemm::pedigree(sire = tbl_si_dat$Sire, dam = tbl_si_dat$Dam, label = as.character(tbl_si_dat$Animal)))

The function getAInv() returns the inverse numerator relationship matrix

(mat_AInv <- as.matrix(pedigreemm::getAInv(ped = ped)))
     1    2    3    4  5
1  1.5  0.5  0.0 -1.0  0
2  0.5  1.5  0.0 -1.0  0
3  0.0  0.0  1.5  0.5 -1
4 -1.0 -1.0  0.5  2.5 -1
5  0.0  0.0 -1.0 -1.0  2

Mixed Model Equations

The mixed model equations have the following structure

\[ M \cdot s = r\]

where \(M\) is the coefficient matrix, \(s\) is the vector of unknowns and \(r\) is the right-hand side vector. Our goal is to get solutions for the estimates and predictions of the vector of unknowns \(s\). The general for of the solution will be

\[s = M^{-1}\cdot r\]

\[M = \begin{bmatrix}X^TX & X^TZ \\ Z^TX & Z^TZ + \lambda* A^{-1}\end{bmatrix}\]

(mat_X <- matrix(c(1, 0, 
0, 1, 
0, 1,
1, 0,
0, 1), nrow = length(vec_y), byrow = TRUE))
     [,1] [,2]
[1,]    1    0
[2,]    0    1
[3,]    0    1
[4,]    1    0
[5,]    0    1
(mat_Z <- diag(1, nrow = length(vec_y)))
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    1    0    0    0
[3,]    0    0    1    0    0
[4,]    0    0    0    1    0
[5,]    0    0    0    0    1

The variable \(\lambda\) corresponds to the ration of the residual variance divided by the genetic additive variance. Here we assume that \(\lambda = 2\)

\[\lambda = \frac{\sigma_e^2}{\sigma_u^2}\]

lambda <- 2

Putting everything together into the coefficent matrix \(M\)

mat_XTX <- crossprod(mat_X)
mat_XTZ <- crossprod(mat_X, mat_Z)
mat_ZTX <- crossprod(mat_Z, mat_X)
mat_ZTZ_lAinv <- crossprod(mat_Z) + lambda * mat_AInv
(mat_M <- rbind(cbind(mat_XTX, mat_XTZ), cbind(mat_ZTX, mat_ZTZ_lAinv)))
       1  2  3  4  5
  2 0  1  0  0  1  0
  0 3  0  1  1  0  1
1 1 0  4  1  0 -2  0
2 0 1  1  4  0 -2  0
3 0 1  0  0  4  1 -2
4 1 0 -2 -2  1  6 -2
5 0 1  0  0 -2 -2  5

Right-Hand Side

The vector \(r\) is constructed from \(X^Ty\) and \(Z^Ty\)

\[ r = \begin{bmatrix} X^Ty \\ Z^Ty \end{bmatrix} \]

vec_XTy <- crossprod(mat_X, vec_y)
vec_ZTy <- crossprod(mat_Z, vec_y)
(vec_r <- rbind(vec_XTy, vec_ZTy))
     [,1]
[1,]  8.0
[2,] 11.8
[3,]  4.5
[4,]  2.9
[5,]  3.9
[6,]  3.5
[7,]  5.0

Soltion Vector

The solution vector \(s\) is computed as \(s = M^{-1} \cdot r\)

(vec_s <- solve(mat_M, vec_r))
         [,1]
   3.92898876
   3.91662921
1  0.19775281
2 -0.33146067
3  0.13370787
4 -0.05573034
5  0.24786517

The solutions can be interpreted as

\[ \hat{\beta} = \begin{bmatrix} \hat{\beta}_M \\ \hat{\beta}_F \end{bmatrix}= \begin{bmatrix} 3.9289888 \\ 3.9166292\end{bmatrix} \]

The predicted breeding values are

\[\hat{u} = \begin{bmatrix} \hat{u}_1 \\ \hat{u}_2 \\ \hat{u}_3 \\ \hat{u}_4 \\ \hat{u}_5 \end{bmatrix} = \begin{bmatrix} 0.1977528 \\ -0.3314607 \\ 0.1337079 \\ -0.0557303 \\ 0.2478652 \\ \end{bmatrix} \]

LS0tCnRpdGxlOiAiU2V0dXAgTWl4ZWQgTW9kZWwgRXF1YXRpb25zIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIEZvcm11bGEKVGhlIG1peGVkIG1vZGVsIGVxdWF0aW9ucyBoYXZlIGZvbGxvd2luZyBmb3JtLCBhc3N1bWluZyB0aGF0IHRoZSB2YXJpYW5jZS1jb3ZhcmlhbmNlLW1hdHJpeCAoJHZhcihlKSQpIG9mIHRoZSBlcnJvciB2ZWN0b3IgJGUkIGhhcyB0aGUgc2ltcGxlIGZvcm0KCiQkdmFyKGUpID0gSSAqIFxzaWdtYV9lXjIkJAp3aGVyZSAkSSQgaXMgdGhlIGlkZW50aXR5IG1hdHJpeC4gVGhlIG1peGVkIG1vZGVsIGVxdWF0aW9ucyBhcmUgZ2l2ZW4gYnkKCiQkClxiZWdpbntibWF0cml4fVheVFggJiBYXlRaIFxcIFpeVFggJiBaXlRaICsgXGxhbWJkYSogQV57LTF9XGVuZHtibWF0cml4fSAqIFxiZWdpbntibWF0cml4fSBcaGF0e1xiZXRhfSBcXCBcaGF0e3V9XGVuZHtibWF0cml4fQo9ClxiZWdpbntibWF0cml4fSBYXlR5IFxcWl5UeVxlbmR7Ym1hdHJpeH0KJCQKClNwZWNpZmljYXRpb24gb2YgdGhlIGV4cGVjdGVkIHZhbHVlcyBhbmQgdGhlIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cmljZXMgb2YgYWxsIHJhbmRvbSBlZmZlY3RzLiBSYW5kb20gZWZmZWN0cyBhcmUgJGUkLCAkdSQgYW5kICR5JC4gCgokJCAKRVxiZWdpbntibWF0cml4fWUgXFwgdSBcXHkgXGVuZHtibWF0cml4fSA9IFxiZWdpbntibWF0cml4fSBcXCBcXCBcZW5ke2JtYXRyaXh9IFx0ZXh0eywgfSB2YXJcYmVnaW57Ym1hdHJpeH1lIFxcIHUgXFx5IFxlbmR7Ym1hdHJpeH0gPSAKJCQKCiMgRGF0YSBTZXQKVGhlIGRhdGEgc2V0IGlzIGdpdmVuIGJ5CgpgYGB7cn0KdGJsX3NpX2RhdCA8LSB0aWJibGU6OnRpYmJsZShBbmltYWwgPSBjKDE6NSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2lyZSAgID0gYyhOQSwgTkEsIE5BLCAxLCA0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYW0gICAgPSBjKE5BLCBOQSwgTkEsIDIsIDMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNleCAgICA9IGMoIk0iLCAiRiIsICJGIiwgIk0iLCAiRiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdXRyAgICA9IGMoNC41LCAyLjksIDMuOSwgMy41LCA1LjApKQoKdGJsX3NpX2RhdApgYGAKCgojIE1vZGVsIENvbXBvbmVudHMKTW9kZWwgY29tb25lbnRzIGFyZQoKKiBUaHJlZSB2ZWN0b3Igb2YgdW5rbm93bnMgJFxiZXRhJCwgJHUkIGFuZCAkZSQKKiBWZWN0b3Igb2Ygb2JzZXJ2YXRpb25zICR5JAoqIERlc2lnbiBtYXRyaWNlcyAkWCQgYW5kICRaJAoqIEludmVyc2UgbnVtZXJhdG9yIHJlbGF0aW9uc2hpcCBtYXRyaXggJEFeey0xfSQKCiMjIFVua25vd25zCgoqIHZlY3RvciAkXGJldGEkIG9mIGZpeGVkIGVmZmVjdHMuIEluIG91ciBkYXRhIHNldCB0aGUgdmFyaWFibGUgJ1NleCcgaXMgdHJlYXRlZCBhcyBmaXhlZCBlZmZlY3QuIEluIGdlbmVyYWwsIGluIGEgZGF0YSBzZXQgdGhlIGNvbHVtbnMgJ0FuaW1hbCcsICdTaXJlJyBhbmQgJ0RhbScgYmVsb25nIHRvIHRoZSBwZWRpZ3JlZSwgdGhlIGNvbHVtbiAnV1dHJyBpcyBvdXIgb2JzZXJ2YXRpb24gb3IgcmVzcG9uc2UgdmFyaWFibGUgYW5kIGV2ZXJ5dGhpbmcgaW4gdGhlIGRhdGFzZXQgdGhhdCBkb2VzIG5vdCBiZWxvbmcgdG8gdGhlIHBlZGlncmVlIGFuZCBpcyBub3QgYW4gb2JzZXJ2YXRpb24gb3IgcmVzcG9uc2UgdmFyaWFibGUsIGlzIHRyZWF0ZWQgYXMgYSBmaXhlZCBlZmZlY3QuIEFzIGEgY29uc2VxdWVuY2UgaW4gb3VyIGRhdGFzZXQsICdTZXgnIGlzIGEgZml4ZWQgZWZmZWN0LiBUaGUgbGVuZ2h0IG9mIHRoZSB2ZWN0b3IgJFxiZXRhJCBkZXBlbmRzIG9uIHRoZSBudW1iZXIgb2YgbGV2ZWxzIHRoYXQgYXJlIGF2YWlsYWJsZSBpbiB0aGUgY29sdW1uICdTZXgnIGluIHRoZSBjb21wbGV0ZSBkYXRhc2V0LiAKClRoZSBudW1iZXIgb2YgbGV2ZWxzIGluIGEgZ2l2ZW4gZml4ZWQgZWZmZWN0IGNhbiBiZSBkZXRlcm1pbmVkIHVzaW5nIFIKCmBgYHtyfQp0Ymxfc2lfZGF0JFNleCA8LSBhcy5mYWN0b3IodGJsX3NpX2RhdCRTZXgpCnRibF9zaV9kYXQKYGBgCgpgYGB7cn0KKG5fbGV2ZWxfc2V4IDwtIG5sZXZlbHModGJsX3NpX2RhdCRTZXgpKQpgYGAKCldpdGggdGhhdCB0aGUgbGVuZ3RoIG9mIHRoZSB2ZWN0b3IgJFxiZXRhJCBpcyBgciBuX2xldmVsX3NleGAKCiQkXGJldGEgPSBcYmVnaW57Ym1hdHJpeH0gXGJldGFfTSBcXCBcYmV0YV9GIFxlbmR7Ym1hdHJpeH0kJAoKKiB2ZWN0b3IgJHUkIG9mIGJyZWVkaW5nIHZhbHVlcy4gU2luY2Ugd2UgYXJlIGZpdHRpbmcgYW4gYW5pbWFsIG1vZGVsLCAkdSQgaGFzIGFzIG1hbnkgY29tcGVudHMgYXMgdGhlcmUgYXJlIGFuaW1hbHMgaW4gdGhlIHBlZGlncmVlLiBJbiBvdXIgZGF0YXNldCB0aGUgdmVjdG9yICR1JCBoYXMgNSBjb21wb25lbnRzLgoKJCR1ID0gXGJlZ2lue2JtYXRyaXh9IHVfMSBcXCB1XzIgXFwgdV8zIFxcIHVfNCBcXCB1XzUgXGVuZHtibWF0cml4fSQkCgoqIHZlY3RvciAkZSQgb2YgcmFuZG9tIGVycm9yIHRlcm1zLiBUaGUgbGVuZ3RoIG9mIHRoZSB2ZWN0b3IgJGUkIGlzIHRoZSBzYW1lIGFzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zLiAKCiQkZSA9IFxiZWdpbntibWF0cml4fSBlXzEgXFwgZV8yIFxcIGVfMyBcXCBlXzQgXFwgZV81IFxlbmR7Ym1hdHJpeH0kJAoKIyMgT2JzZXJ2YXRpb25zCk9ic2VydmF0aW9ucyBjb3JyZXNwb25kcyB0byB0aGUgdmVjdG9yICR5JC4gVGhlIHZlY3RvciAkeSQgaXMga25vd24gYW5kIHRoZXJlZm9yZSwgd2UgY2FuIGluc2VydCBudW1iZXJzIGZyb20gdGhlIGRhdGFzZXQgaW50byB0aGUgdmVjdG9yICR5JC4gCgpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9CnZlY195IDwtIHRibF9zaV9kYXQkV1dHCmNhdChwYXN0ZShybWRoZWxwOjpiY29sdW1uX3ZlY3RvcihwdmVjID0gdmVjX3ksIHBzX25hbWUgPSAneScsIHBzX2VudiA9ICckJCcpLCBjb2xsYXBzZSA9ICdcbicpLCAnXG4nKQpgYGAKCgojIyBEZXNpZ24gTWF0cmljZXMKRGVzaWduIG1hdHJpeCAkWCQgbGlua3MgbGV2ZWxzIG9mIGZpeGVkIGVmZmVjdHMgdG8gb2JzZXJ2YXRpb25zLiBUaGUgbWF0cml4ICRYJCBoYXMgZGltZW5zaW9ucyAkblx0aW1lcyBwJCB3aGVyZSAkbiQgaXMgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgYW5kICRwJCBpcyB0aGUgbnVtYmVyIG9mIGxldmVscyBpbiBvdXIgZml4ZWQgZWZmZWN0cy4gSW4gb3VyIGV4YW1wbGUgJG49NSQgYW5kICRwPTIkCgokJApYID0gXGJlZ2lue2JtYXRyaXh9IAoxICAmICAwIFxcCjAgICYgIDEgXFwKMCAgJiAgMSBcXAoxICAmICAwIFxcCjAgICYgIDEKXGVuZHtibWF0cml4fQokJAoKClRoZSBkZXNpZ24gbWF0cml4ICRaJCBsaW5rcyByYW5kb20gYnJlZWRpbmcgdmFsdWVzICgkdSQpIHRvIG9ic2VydmF0aW9ucy4gVGhlIG1hdHJpeCAkWiQgaGFzIGRpbWVuc2lvbnMgJG5cdGltZXMgcSQgd2hlcmUgJG4kIGlzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGFuZCAkcSQgaXMgdGhlIG51bWJlciBvZiBhbmltYWxzIGluIHRoZSBwZWRncmVlLiAKCiQkClogPSBcYmVnaW57Ym1hdHJpeH0gCjEgJiAwICYgMCAgJiAwICAmIDAgXFwKMCAmIDEgJiAwICAmIDAgICYgMCBcXAowICYgMCAmIDEgICYgMCAgJiAwIFxcCjAgJiAwICYgMCAgJiAxICAmIDAgXFwKMCAmIDAgJiAwICAmIDAgICYgMSBcXApcZW5ke2JtYXRyaXh9CiQkCgoKIyBNb2RlbApNb2RlbCBpbiBNYXRyaXgtVmVjdG9yIE5vdGF0aW9uCgokJHkgPSBYIFxiZXRhICsgWnUgKyBlICQkClRoZSBlcXVhdGlvbiBmb3IgdGhlIGZpcnN0IG9ic2VydmF0aW9uCgokJHlfMSA9IFxiZXRhX00gKyB1XzEgKyBlXzEkJAoKIyMgSW52ZXJzZSBOdW1lcmF0b3IgUmVsYXRpb25zaGlwIE1hdHJpeApXZSB1c2UgYHBlZGlncmVlbW1gIHRvIGNvbnN0cnVjdCAkQV57LTF9JAoKYGBge3J9CihwZWQgPC0gcGVkaWdyZWVtbTo6cGVkaWdyZWUoc2lyZSA9IHRibF9zaV9kYXQkU2lyZSwgZGFtID0gdGJsX3NpX2RhdCREYW0sIGxhYmVsID0gYXMuY2hhcmFjdGVyKHRibF9zaV9kYXQkQW5pbWFsKSkpCmBgYAoKIFRoZSBmdW5jdGlvbiBgZ2V0QUludigpYCByZXR1cm5zIHRoZSBpbnZlcnNlIG51bWVyYXRvciByZWxhdGlvbnNoaXAgbWF0cml4CiAKYGBge3J9CihtYXRfQUludiA8LSBhcy5tYXRyaXgocGVkaWdyZWVtbTo6Z2V0QUludihwZWQgPSBwZWQpKSkKYGBgCiAKIyBNaXhlZCBNb2RlbCBFcXVhdGlvbnMKVGhlIG1peGVkIG1vZGVsIGVxdWF0aW9ucyBoYXZlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlCgokJCBNIFxjZG90IHMgPSByJCQKCndoZXJlICRNJCBpcyB0aGUgY29lZmZpY2llbnQgbWF0cml4LCAkcyQgaXMgdGhlIHZlY3RvciBvZiB1bmtub3ducyBhbmQgJHIkIGlzIHRoZSByaWdodC1oYW5kIHNpZGUgdmVjdG9yLiBPdXIgZ29hbCBpcyB0byBnZXQgc29sdXRpb25zIGZvciB0aGUgZXN0aW1hdGVzIGFuZCBwcmVkaWN0aW9ucyBvZiB0aGUgdmVjdG9yIG9mIHVua25vd25zICRzJC4gVGhlIGdlbmVyYWwgZm9yIG9mIHRoZSBzb2x1dGlvbiB3aWxsIGJlCgokJHMgPSBNXnstMX1cY2RvdCByJCQKCiQkTSA9IFxiZWdpbntibWF0cml4fVheVFggJiBYXlRaIFxcIFpeVFggJiBaXlRaICsgXGxhbWJkYSogQV57LTF9XGVuZHtibWF0cml4fSQkCgpgYGB7cn0KKG1hdF9YIDwtIG1hdHJpeChjKDEsIDAsIAowLCAxLCAKMCwgMSwKMSwgMCwKMCwgMSksIG5yb3cgPSBsZW5ndGgodmVjX3kpLCBieXJvdyA9IFRSVUUpKQpgYGAKCmBgYHtyfQoobWF0X1ogPC0gZGlhZygxLCBucm93ID0gbGVuZ3RoKHZlY195KSkpCmBgYAoKVGhlIHZhcmlhYmxlICRcbGFtYmRhJCBjb3JyZXNwb25kcyB0byB0aGUgcmF0aW9uIG9mIHRoZSByZXNpZHVhbCB2YXJpYW5jZSBkaXZpZGVkIGJ5IHRoZSBnZW5ldGljIGFkZGl0aXZlIHZhcmlhbmNlLiBIZXJlIHdlIGFzc3VtZSB0aGF0ICRcbGFtYmRhID0gMiQKCiQkXGxhbWJkYSA9IFxmcmFje1xzaWdtYV9lXjJ9e1xzaWdtYV91XjJ9JCQKCmBgYHtyfQpsYW1iZGEgPC0gMgpgYGAKClB1dHRpbmcgZXZlcnl0aGluZyB0b2dldGhlciBpbnRvIHRoZSBjb2VmZmljZW50IG1hdHJpeCAkTSQKCmBgYHtyfQptYXRfWFRYIDwtIGNyb3NzcHJvZChtYXRfWCkKbWF0X1hUWiA8LSBjcm9zc3Byb2QobWF0X1gsIG1hdF9aKQptYXRfWlRYIDwtIGNyb3NzcHJvZChtYXRfWiwgbWF0X1gpCm1hdF9aVFpfbEFpbnYgPC0gY3Jvc3Nwcm9kKG1hdF9aKSArIGxhbWJkYSAqIG1hdF9BSW52CihtYXRfTSA8LSByYmluZChjYmluZChtYXRfWFRYLCBtYXRfWFRaKSwgY2JpbmQobWF0X1pUWCwgbWF0X1pUWl9sQWludikpKQpgYGAKCgojIyBSaWdodC1IYW5kIFNpZGUKVGhlIHZlY3RvciAkciQgaXMgY29uc3RydWN0ZWQgZnJvbSAkWF5UeSQgYW5kICRaXlR5JAoKJCQKciA9IFxiZWdpbntibWF0cml4fSBYXlR5IFxcIFpeVHkgXGVuZHtibWF0cml4fQokJApgYGB7cn0KdmVjX1hUeSA8LSBjcm9zc3Byb2QobWF0X1gsIHZlY195KQp2ZWNfWlR5IDwtIGNyb3NzcHJvZChtYXRfWiwgdmVjX3kpCih2ZWNfciA8LSByYmluZCh2ZWNfWFR5LCB2ZWNfWlR5KSkKYGBgCgoKIyMgU29sdGlvbiBWZWN0b3IKVGhlIHNvbHV0aW9uIHZlY3RvciAkcyQgaXMgY29tcHV0ZWQgYXMgJHMgPSBNXnstMX0gXGNkb3QgciQKCmBgYHtyfQoodmVjX3MgPC0gc29sdmUobWF0X00sIHZlY19yKSkKYGBgCgpUaGUgc29sdXRpb25zIGNhbiBiZSBpbnRlcnByZXRlZCBhcyAKCiQkIFxoYXR7XGJldGF9ID0gXGJlZ2lue2JtYXRyaXh9IFxoYXR7XGJldGF9X00gXFwgXGhhdHtcYmV0YX1fRiBcZW5ke2JtYXRyaXh9PSBcYmVnaW57Ym1hdHJpeH0gYHIgdmVjX3NbMV1gIFxcICBgciAgdmVjX3NbMl1gXGVuZHtibWF0cml4fSAkJAoKVGhlIHByZWRpY3RlZCBicmVlZGluZyB2YWx1ZXMgYXJlCgokJFxoYXR7dX0gPSBcYmVnaW57Ym1hdHJpeH0gXGhhdHt1fV8xIFxcIFxoYXR7dX1fMiBcXCBcaGF0e3V9XzMgXFwgXGhhdHt1fV80IFxcIFxoYXR7dX1fNSBcZW5ke2JtYXRyaXh9ID0gClxiZWdpbntibWF0cml4fSAKYHIgdmVjX3NbM11gIFxcCmByIHZlY19zWzRdYCBcXApgciB2ZWNfc1s1XWAgXFwKYHIgdmVjX3NbNl1gIFxcCmByIHZlY19zWzddYCBcXApcZW5ke2JtYXRyaXh9CiQkCg==