View the
latest recording of this lecture
This topic introduces the concept of nonlinear regression models,
iterative fitting by direct search, Gauss-Newton algorithm.
When the Response is a Nonlinear Function of the Regression
Parameters
We consider what happens when the relationship between \(Y\) (response) and \(X\) (predictor) is known to be a particular
curve that cannot be made linear by transformation.
That is, suppose \[ y =
f(x) + \varepsilon\]
Where \(f(x)\) denotes some function
of \(x\) (e.g. a curve), and where the
error variation \(\varepsilon\) around
the curve is normally distributed with constant variance as before.
Suppose we have a general idea of the shape of the curve, but the
precise details depend on some unknown parameters, say \(\alpha, \beta\) and \(\gamma\).
The task, as in ordinary linear regression, reduces to that of
estimating the parameters. Now in principle we can estimate \(\alpha, \beta\) and \(\gamma\) by least squares as before. That
is, we simply choose those estimates that make the squared error of our
curve as small as possible: i.e. the least squares problem is to
minimize \[ SS_{error} = \sum \left(y_i -
f(x_i; \alpha,\beta,\gamma )\right) ^2 \] or equivalently
minimise the residual standard error \(S =
\sqrt{SS_{error}/{(n-p)}}\).
The only difficulty or difference to the previous situation is that
we do not have simple formulas to use arising out of the matrix linear
algebra, as the curve \(f(x)\) is not
linear in \(\alpha, \beta\) and \(\gamma\).
A couple of examples of functions \(f(x)\) that are nonlinear in the parameters
are:
- Suppose
\[ f(x_i; \alpha,\beta_0,\beta_1)
= \alpha~~ \frac{ e^{\beta_0+ \beta_1 x}}{ 1+e^{\beta_0+ \beta_1 x}
} + \varepsilon\]
This is the so-called logistic curve, which models a phenomenon (such
as sales) that goes from zero to some upper limit \(\alpha\).
(Note \(\alpha\) is an asymptote for
the curve but the individual data can go randomly above
or below the curve).
This model cannot be made linear, but in principle we can use any
mathematical method we wish to find those estimates of \(\alpha,\beta_0\),\(\beta_1\) that minimize
\(SS_{error} = \sum (y_i - \hat y_i
)^2\) where \[\hat y_i =
\hat\alpha~~\frac{e^{\hat\beta_0+ \hat\beta_1 x} }{ 1+e^{\hat\beta_0+
\hat\beta_1 x} } ~~.\]
- A somewhat simpler example, but also nonlinear, is
\[ y_i = \beta_0 + \beta_1 x_i^{\alpha}
\]
where \(\alpha\) is unknown. Again
this cannot be made linear in \(\alpha,\beta_0\) and \(\beta_1\) but in this example the model
fitting could be done simply by guessing \(\alpha\) and creating a new explanatory
variable \(x_{new} = x^\alpha\).
Then \(\beta_0\) and \(\beta_1\) can be found by linear regression
of \(y\) on \(x_{new}\).
Case Study using Direct Search
The following example concerns some data on \(Y\) = the number of manhours used
in surgical cases in 15 US navy hospitals, versus \(X\)= the number of cases
treated.
The purpose of the analysis was to develop a preliminary manpower
equation for estimation of manhours per month expended on surgical
services.
Download Manhours.csv
## manhours = read.csv("Manhours.csv", header = TRUE)
manhours
Manhours Cases
1 1275 230
2 1350 235
3 1650 250
4 2000 277
5 3750 522
6 4222 545
7 5018 625
8 6125 713
9 6200 735
10 8150 820
11 9975 992
12 12200 1322
13 12750 1900
14 13014 2022
15 13275 2155
plot(Manhours ~ Cases, data = manhours)
mh1 = lm(Manhours ~ Cases, data = manhours)
abline(coef(mh1))
We could use trial and error. A straight-line model \(\alpha=1\) does not seem suitable. We could
try a model \(\sqrt X\) (i.e. \(\alpha=0.5\)).
Cases = manhours$Cases
Manhours = manhours$Manhours
summary(mh1)
Call:
lm(formula = Manhours ~ Cases, data = manhours)
Residuals:
Min 1Q Median 3Q Max
-1697.0 -1003.5 -561.2 510.3 2653.2
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 936.9261 631.4785 1.484 0.162
Cases 6.5128 0.5764 11.299 4.29e-08 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 1428 on 13 degrees of freedom
Multiple R-squared: 0.9076, Adjusted R-squared: 0.9005
F-statistic: 127.7 on 1 and 13 DF, p-value: 4.288e-08
Casenew = Cases^0.5
mh2 = lm(Manhours ~ Casenew)
summary(mh2)
Call:
lm(formula = Manhours ~ Casenew)
Residuals:
Min 1Q Median 3Q Max
-1069.77 -547.39 -177.25 -65.14 2005.86
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -4803.30 708.57 -6.779 1.30e-05 ***
Casenew 412.48 23.76 17.362 2.25e-10 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 954.8 on 13 degrees of freedom
Multiple R-squared: 0.9587, Adjusted R-squared: 0.9555
F-statistic: 301.4 on 1 and 13 DF, p-value: 2.245e-10
plot(Manhours ~ Casenew, main = "Cases ^ 0.5")
abline(coef(mh2))
Note the residual standard error is smaller for this model. Let’s try
the fourth root.
Casenew = Cases^0.25
mh3 = lm(Manhours ~ Casenew)
summary(mh3)
Call:
lm(formula = Manhours ~ Casenew)
Residuals:
Min 1Q Median 3Q Max
-1134.3 -581.6 -184.9 309.2 1793.5
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -16232.1 1228.1 -13.22 6.51e-09 ***
Casenew 4417.8 232.3 19.02 7.15e-11 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 874.6 on 13 degrees of freedom
Multiple R-squared: 0.9653, Adjusted R-squared: 0.9626
F-statistic: 361.8 on 1 and 13 DF, p-value: 7.148e-11
plot(Manhours ~ Casenew, main = "Cases ^ 0.25")
abline(coef(mh3))
Again the residual standard error is smaller. Suppose we try a grid
of values for \(\alpha\)
alpha = rse = rep(0, 10)
for (i in 1:10) {
alpha[i] = i/10
casenew = Cases^alpha[i]
rse[i] = summary(lm(Manhours ~ casenew))$sigma
}
cbind(alpha, rse)
alpha rse
[1,] 0.1 920.0195
[2,] 0.2 881.7700
[3,] 0.3 875.5447
[4,] 0.4 901.2579
[5,] 0.5 954.8140
[6,] 0.6 1029.8343
[7,] 0.7 1119.6818
[8,] 0.8 1218.6620
[9,] 0.9 1322.3660
[10,] 1.0 1427.5653
It looks like the minimum is for \(\alpha\) between 0.2 and 0.4
alpha = rse = rep(0, 20)
for (i in 1:20) {
alpha[i] = 0.2 + i/100
casenew = Cases^alpha[i]
rse[i] = summary(lm(Manhours ~ casenew))$sigma
}
cbind(alpha, rse)
alpha rse
[1,] 0.21 879.6730
[2,] 0.22 877.9018
[3,] 0.23 876.4577
[4,] 0.24 875.3420
[5,] 0.25 874.5553
[6,] 0.26 874.0976
[7,] 0.27 873.9687
[8,] 0.28 874.1678
[9,] 0.29 874.6937
[10,] 0.30 875.5447
[11,] 0.31 876.7186
[12,] 0.32 878.2128
[13,] 0.33 880.0244
[14,] 0.34 882.1499
[15,] 0.35 884.5855
[16,] 0.36 887.3271
[17,] 0.37 890.3701
[18,] 0.38 893.7098
[19,] 0.39 897.3409
[20,] 0.40 901.2579
It looks like the minimum is for \(\alpha\) between 0.26 and 0.28.
alpha = rse = rep(0, 20)
for (i in 1:20) {
alpha[i] = 0.26 + i/1000
casenew = Cases^alpha[i]
rse[i] = summary(lm(Manhours ~ casenew))$sigma
}
cbind(alpha, rse)
alpha rse
[1,] 0.261 874.0699
[2,] 0.262 874.0455
[3,] 0.263 874.0244
[4,] 0.264 874.0066
[5,] 0.265 873.9921
[6,] 0.266 873.9809
[7,] 0.267 873.9729
[8,] 0.268 873.9682
[9,] 0.269 873.9668
[10,] 0.270 873.9687
[11,] 0.271 873.9739
[12,] 0.272 873.9823
[13,] 0.273 873.9941
[14,] 0.274 874.0091
[15,] 0.275 874.0273
[16,] 0.276 874.0489
[17,] 0.277 874.0737
[18,] 0.278 874.1018
[19,] 0.279 874.1332
[20,] 0.280 874.1678
It looks like the minimum \(S\) is
obtained for \(\alpha \approx 0.269\).
The procedure could be repeated to obtain the minimum RSE to more
significant figures but, in view of the small changes we are achieving,
little will be achieved by going further.
casenew = Cases^0.269
mh3 = lm(Manhours ~ casenew)
summary(mh3)
Call:
lm(formula = Manhours ~ casenew)
Residuals:
Min 1Q Median 3Q Max
-1111.6 -586.3 -207.4 278.2 1806.2
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -14619.7 1144.1 -12.78 9.80e-09 ***
casenew 3618.8 190.1 19.03 7.09e-11 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 874 on 13 degrees of freedom
Multiple R-squared: 0.9654, Adjusted R-squared: 0.9627
F-statistic: 362.3 on 1 and 13 DF, p-value: 7.086e-11
plot(Manhours ~ casenew, main = "Cases ^ 0.269")
abline(coef(mh3))
The Gauss-Newton Algorithm
The alternative to using direct search is to use a mathematical
technique such as the Gauss-Newton Algorithm .
The idea of the algorithm is to approximate the curve \(f(x_i; \alpha,\beta,\gamma)\) by a sum of
straight lines involving \(\alpha,\beta\) and \(\gamma\). That is, a linearized
approximation to the curve.
The mathematical ideas are in an word document on Stream, but are not
examinable.
The main points are:
The process of model-fitting is iterative. That is, it involves a
series of repeated linear regressions with slightly different data each
time, converging to a fixed answer as we get closer and closer to the
optimal estimates.
The Gauss-Newton method is guaranteed to converge quickly to the
optimal estimates, provided that our initial starting point is close
enough.
The method also produces approximate hypothesis tests and
confidence intervals.
The nls() nonlinear least squares procedure implements the
Gauss-Newton algorithm.
We need to specify the formula, and (preferably) reasonable starting
values.
manhours.nls = nls(Manhours ~ beta0 + beta1 * (Cases^alpha), start = list(alpha = 0.25,
beta0 = -16000, beta1 = 4400), data = manhours)
summary(manhours.nls)
Formula: Manhours ~ beta0 + beta1 * (Cases^alpha)
Parameters:
Estimate Std. Error t value Pr(>|t|)
alpha 2.689e-01 1.585e-01 1.697 0.115
beta0 -1.463e+04 1.256e+04 -1.164 0.267
beta1 3.622e+03 5.954e+03 0.608 0.554
Residual standard error: 909.7 on 12 degrees of freedom
Number of iterations to convergence: 6
Achieved convergence tolerance: 2.462e-06
plot(Manhours ~ Cases)
lines(predict(manhours.nls) ~ Cases)
We can calculate an approximate confidence interval for \(\alpha\) using \[ \hat\alpha \pm
t_{n-p}(0.025)*SE(\hat\alpha)\]
summary(manhours.nls)$coefficients
Estimate Std. Error t value Pr(>|t|)
alpha 2.689232e-01 0.158476 1.6969329 0.1154707
beta0 -1.462572e+04 12564.190279 -1.1640799 0.2670141
beta1 3.621670e+03 5954.344902 0.6082398 0.5543666
est = summary(manhours.nls)$coefficients[1]
se = summary(manhours.nls)$coefficients[4]
lower = est + qt(0.025, df = 15 - 3) * se
upper = est + qt(0.975, df = 15 - 3) * se
cbind(est, se, lower, upper)
est se lower upper
[1,] 0.2689232 0.158476 -0.07636641 0.6142128
We can conclude from this that we could not reject a hypothesis that
\(\alpha\) equalled any value between
-0.07 and 0.6.
In particular, we could have stuck with the square-root
transformation (\(\alpha=0.5\)) or used
the log transformation (recall this takes the place of \(\alpha=0\) in the ladder of powers).
Example: A Growth Curve Model with an Maximum
Recall the fev data relating forced expiration volume (FEV) to girls’
ages. This seemed to flatten off after about age 10.
We will model the growth using a logistic curve with unknown
maximum.
\[ f(x_i; \alpha,\beta_0,\beta_1)
= \alpha~~\frac{e^{\beta_0+ \beta_1 x}}{ 1+e^{\beta_0+ \beta_1 x} } +
\varepsilon\]
Download FEV.csv
## fev <- read.csv(file = "fev.csv", header = TRUE)
FEV = fev$FEV
Age = fev$Age
plot(FEV ~ Age)
From the graph the maximum \(\alpha \approx
3\), so setting \[FEV \approx 3
~~\frac{e^{\beta_0 + \beta_1 Age}}{ 1+ e^{\beta_0 + \beta_1
Age}}\] we can rearrange this as
\[1+ e^{\beta_0 + \beta_1
Age} \approx \frac{3}{FEV} ~ e^{\beta_0 + \beta_1
Age} \]
Gather up the \(e^{\beta_0 + \beta_1
Age}\) terms
\[ \frac{1}{3/FEV - 1} \approx e^{\beta_0
+ \beta_1 Age}\] and then if we take logs we can use the
left-hand side as the “response” in a regression
\[ Y_{new} = \log\left(\frac{1}{3/FEV -
1}\right)\approx \beta_0 + \beta_1 Age \] to give us starting
values for \(\beta_0\) and \(\beta_1\):
start.calc = lm(-log(3/FEV - 1) ~ Age)
Warning in log(3/FEV - 1): NaNs produced
Call:
lm(formula = -log(3/FEV - 1) ~ Age)
Residuals:
Min 1Q Median 3Q Max
-1.9603 -0.5223 -0.1590 0.2990 5.0842
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.30548 0.21129 -6.179 2.78e-09 ***
Age 0.28493 0.02226 12.799 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.9443 on 238 degrees of freedom
(78 observations deleted due to missingness)
Multiple R-squared: 0.4077, Adjusted R-squared: 0.4052
F-statistic: 163.8 on 1 and 238 DF, p-value: < 2.2e-16
So we will use starting values \(\alpha=3\), \(\beta_0= -1.3\) and \(\beta_1=0.28\)
fev.nls = nls(FEV ~ alpha * exp(beta0 + beta1 * Age)/(1 + exp(beta0 + beta1 * Age)),
start = list(alpha = 3, beta0 = -1.3, beta1 = 0.28))
summary(fev.nls)
Formula: FEV ~ alpha * exp(beta0 + beta1 * Age)/(1 + exp(beta0 + beta1 *
Age))
Parameters:
Estimate Std. Error t value Pr(>|t|)
alpha 3.21164 0.08682 36.99 <2e-16 ***
beta0 -2.16822 0.21482 -10.09 <2e-16 ***
beta1 0.36561 0.03620 10.10 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.3956 on 315 degrees of freedom
Number of iterations to convergence: 5
Achieved convergence tolerance: 6.266e-06
plot(FEV ~ Age)
lines(30:200/10, predict(fev.nls, newdata = data.frame(Age = 30:200/10)), lty = 1,
col = 2, lwd = 3)
This has converged. Note the residual standard error is 0.3956, which
is slightly bigger than for the piecewise model looked at earlier
(S=0.39) but the curve seems more reasonable than having a sharp
corner.
We can get a slightly better fit by adding a quadratic term in Age.
In the following we use starting value \(\beta_2=0\).
fev.nls2 = nls(FEV ~ alpha * exp(beta0 + beta1 * Age + beta2 * Age^2)/(1 + exp(beta0 +
beta1 * Age + beta2 * Age^2)), start = list(alpha = 3, beta0 = -1.3, beta1 = 0.28,
beta2 = 0), data = fev)
summary(fev.nls2)
Formula: FEV ~ alpha * exp(beta0 + beta1 * Age + beta2 * Age^2)/(1 + exp(beta0 +
beta1 * Age + beta2 * Age^2))
Parameters:
Estimate Std. Error t value Pr(>|t|)
alpha 3.03273 0.05788 52.393 < 2e-16 ***
beta0 -0.06772 0.75358 -0.090 0.92846
beta1 -0.23896 0.21936 -1.089 0.27684
beta2 0.04437 0.01619 2.741 0.00647 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.3906 on 314 degrees of freedom
Number of iterations to convergence: 7
Achieved convergence tolerance: 2.889e-06
plot(FEV ~ Age)
lines(30:200/10, predict(fev.nls2, newdata = data.frame(Age = 30:200/10)), lty = 1,
col = 2, lwd = 3)
Piecewise Regression with an Unknown Knot
Recall that sometimes we wish to fit a piecewise regression model,
but the location of the knot is unknown.
This then is becomes a nonlinear regression model, with the location
of the knot taking the role of the alpha parameter above (not meaning
that it enters the equation the same way, but that if the knot is known,
then every other parameter can be fitted by linear regression).
Strictly speaking the Gauss-Newton algorithm does not quite work, as
the knot gives a ‘corner’ to the lines, or even a jump in the level of
the lines, and this means that the calculus on which the method was
originally based breaks down. However the nls() routine can be made to
cope.
Nonlinear regression for a change-slope model: the Thai Baht.
The data here refer to the Thai Baht Exchange Rate \(Y\) vs Time (time measured in hundreds of
days, hDays. ) The graph below shows \(Y\) vs hDays with a cubic model.
The model looks like it would be unsafe for extrapolation on the
right.
Download baht.csv
## baht = read.csv("baht.csv", header = TRUE)
Y = baht$Y
hDays = baht$hDays
plot(Y ~ hDays)
cubic = lm(Y ~ poly(hDays, 3))
summary(cubic)$sigma
[1] 0.008618117
lines(predict(cubic) ~ hDays, col = 2, lwd = 2)
We consider a piecewise model \[ Y =
\beta_0 + \beta_1. hDays + \beta_2 (hDays-k)_+ \] where \(k\) is unknown but probably near 2. We will
use this guess to give starting values for the other parameters.
start.guess = lm(Y ~ hDays + I((abs(hDays - 2) + hDays - 2)/2))
summary(start.guess)
Call:
lm(formula = Y ~ hDays + I((abs(hDays - 2) + hDays - 2)/2))
Residuals:
Min 1Q Median 3Q Max
-0.024944 -0.005216 0.001020 0.004923 0.037731
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.3443525 0.0013566 253.84 <2e-16 ***
hDays -0.0201913 0.0008924 -22.63 <2e-16 ***
I((abs(hDays - 2) + hDays - 2)/2) 0.0219204 0.0012007 18.26 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.008564 on 386 degrees of freedom
Multiple R-squared: 0.6141, Adjusted R-squared: 0.6121
F-statistic: 307.2 on 2 and 386 DF, p-value: < 2.2e-16
This gives starting estimates \(\beta_0\approx 0.34, ~~ \beta_1 \approx -0.02,~~
\beta_2 \approx 0.022, ~~k=2\).
The following code fits the model, but some iteration control
parameters were needed, presumably because of the corner. (Other
statistical software such as SPSS and Minitab have less problems fitting
this model.)
baht.nls = nls(Y ~ beta0 + beta1 * hDays + beta2 * I((abs(hDays - k) + hDays - k)/2),
start = list(beta0 = 0.34, beta1 = -0.02, beta2 = 0.022, k = 2), data = baht,
nls.control(warnOnly = TRUE, minFactor = 1/2048))
Warning in nls(Y ~ beta0 + beta1 * hDays + beta2 * I((abs(hDays - k) + hDays -
: step factor 0.000244141 reduced below 'minFactor' of 0.000488281
Formula: Y ~ beta0 + beta1 * hDays + beta2 * I((abs(hDays - k) + hDays -
k)/2)
Parameters:
Estimate Std. Error t value Pr(>|t|)
beta0 0.349459 0.001597 218.88 <2e-16 ***
beta1 -0.027767 0.001772 -15.67 <2e-16 ***
beta2 0.028657 0.001821 15.73 <2e-16 ***
k 1.579995 0.064909 24.34 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.008074 on 385 degrees of freedom
Number of iterations till stop: 14
Achieved convergence tolerance: 0.008517
Reason stopped: step factor 0.000244141 reduced below 'minFactor' of 0.000488281
plot(Y ~ hDays)
lines(predict(baht.nls) ~ hDays, col = 2, lwd = 3)
The graph seems much more reasonable. Note it changed the \(k\) to 1.57.
In terms of residual standard error, which is the better-fitting
model, the cubic or the change-point model? (From above the cubic graph
S =0.008618).
LS0tDQp0aXRsZTogIkxlY3R1cmUgNDU6IE5vbmxpbmVhciBsZWFzdCBzcXVhcmVzIg0Kc3VidGl0bGU6IDE2MS4yNTEgUmVncmVzc2lvbiBNb2RlbGxpbmcNCmF1dGhvcjogIlByZXNlbnRlZCBieSBKb25hdGhhbiBHb2RmcmV5IDxhLmouZ29kZnJleUBtYXNzZXkuYWMubno+IiAgDQpkYXRlOiAiV2VlayAxMiBvZiBTZW1lc3RlciAyLCBgciBsdWJyaWRhdGU6OnllYXIobHVicmlkYXRlOjpub3coKSlgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGlvc2xpZGVzX3ByZXNlbnRhdGlvbjoNCiAgICB3aWRlc2NyZWVuOiB0cnVlDQogICAgc21hbGxlcjogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHNsaWR5X3ByZXNlbnRhdGlvbjogDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KDQoNCg0KW1ZpZXcgdGhlIGxhdGVzdCByZWNvcmRpbmcgb2YgdGhpcyBsZWN0dXJlXShodHRwczovL1ItUmVzb3VyY2VzLm1hc3NleS5hYy5uei92aWRlb3MvMjUxTDM3Lm1wNCkNCjwhLS0tIERhdGEgaXMgb24NCmh0dHBzOi8vci1yZXNvdXJjZXMubWFzc2V5LmFjLm56L2RhdGEvMTYxMjUxLw0KLS0tPg0KDQpgYGB7ciBzZXR1cCwgcHVybD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldChkZXY9YygicG5nIiwgInBkZiIpKQ0Kb3B0c19jaHVuayRzZXQoZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgZmlnLnBhdGg9IkZpZ3VyZXMvIiwgZmlnLmFsdD0idW5sYWJlbGxlZCIpDQpvcHRzX2NodW5rJHNldChjb21tZW50PSIiLCBmaWcuYWxpZ249ImNlbnRlciIsIHRpZHk9VFJVRSkNCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCjwhLS0tIERvIG5vdCBlZGl0IGFueXRoaW5nIGFib3ZlIHRoaXMgbGluZS4gLS0tPg0KDQoNClRoaXMgdG9waWMgaW50cm9kdWNlcyB0aGUgY29uY2VwdCBvZiBub25saW5lYXIgcmVncmVzc2lvbiBtb2RlbHMsIGl0ZXJhdGl2ZSBmaXR0aW5nIGJ5IGRpcmVjdCBzZWFyY2gsIEdhdXNzLU5ld3RvbiBhbGdvcml0aG0uIA0KDQojIyBXaGVuIHRoZSBSZXNwb25zZSBpcyBhIE5vbmxpbmVhciBGdW5jdGlvbiBvZiB0aGUgUmVncmVzc2lvbiBQYXJhbWV0ZXJzDQoNCldlIGNvbnNpZGVyIHdoYXQgaGFwcGVucyB3aGVuIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiAkWSQgKHJlc3BvbnNlKSBhbmQgJFgkIChwcmVkaWN0b3IpIGlzIGtub3duIHRvIGJlIGEgcGFydGljdWxhciBjdXJ2ZSB0aGF0IGNhbm5vdCBiZSBtYWRlIGxpbmVhciBieSB0cmFuc2Zvcm1hdGlvbi4NCg0KVGhhdCBpcywgc3VwcG9zZQkJJCQJeSA9IGYoeCkgICsgIFx2YXJlcHNpbG9uJCQgICAgDQoNCldoZXJlICAkZih4KSQgIGRlbm90ZXMgc29tZSBmdW5jdGlvbiBvZiAkeCQgKGUuZy4gYSBjdXJ2ZSksICBhbmQgd2hlcmUgdGhlIGVycm9yIHZhcmlhdGlvbiAkXHZhcmVwc2lsb24kIGFyb3VuZCB0aGUgY3VydmUgaXMgIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHdpdGggY29uc3RhbnQgdmFyaWFuY2UgYXMgYmVmb3JlLiAgDQoNClN1cHBvc2Ugd2UgaGF2ZSBhIGdlbmVyYWwgaWRlYSBvZiB0aGUgc2hhcGUgb2YgdGhlIGN1cnZlLCBidXQgdGhlIHByZWNpc2UgZGV0YWlscyBkZXBlbmQgb24gc29tZSB1bmtub3duIHBhcmFtZXRlcnMsIHNheSAgJFxhbHBoYSwgXGJldGEkIGFuZCAkXGdhbW1hJC4gDQoNClRoZSB0YXNrLCBhcyBpbiBvcmRpbmFyeSBsaW5lYXIgcmVncmVzc2lvbiwgcmVkdWNlcyB0byB0aGF0IG9mIGVzdGltYXRpbmcgdGhlIHBhcmFtZXRlcnMuICBOb3cgaW4gcHJpbmNpcGxlIHdlIGNhbiBlc3RpbWF0ZSAkXGFscGhhLCBcYmV0YSQgYW5kICRcZ2FtbWEkICAgYnkgbGVhc3Qgc3F1YXJlcyBhcyBiZWZvcmUuICBUaGF0IGlzLCAgd2Ugc2ltcGx5IGNob29zZSB0aG9zZSBlc3RpbWF0ZXMgdGhhdCBtYWtlIHRoZSBzcXVhcmVkIGVycm9yIG9mIG91ciBjdXJ2ZSBhcyBzbWFsbCBhcyBwb3NzaWJsZTogDQppLmUuIHRoZSBsZWFzdCBzcXVhcmVzIHByb2JsZW0gaXMgdG8gIG1pbmltaXplDQokJCBTU197ZXJyb3J9ID0gXHN1bSBcbGVmdCh5X2kgLSBmKHhfaTsgXGFscGhhLFxiZXRhLFxnYW1tYSApXHJpZ2h0KSBeMiAkJA0Kb3IgZXF1aXZhbGVudGx5IG1pbmltaXNlIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBlcnJvciANCiRTID0gXHNxcnR7U1Nfe2Vycm9yfS97KG4tcCl9fSQuIA0KDQogIA0KDQpUaGUgb25seSBkaWZmaWN1bHR5IG9yIGRpZmZlcmVuY2UgdG8gdGhlIHByZXZpb3VzIHNpdHVhdGlvbiBpcyB0aGF0IHdlIGRvIG5vdCBoYXZlIHNpbXBsZSBmb3JtdWxhcyB0byB1c2UgYXJpc2luZyBvdXQgb2YgdGhlIG1hdHJpeCBsaW5lYXIgYWxnZWJyYSwgYXMgdGhlIGN1cnZlICRmKHgpJCBpcyBub3QgbGluZWFyIGluICRcYWxwaGEsIFxiZXRhJCBhbmQgJFxnYW1tYSQuICAgICANCg0KQSBjb3VwbGUgb2YgZXhhbXBsZXMgb2YgZnVuY3Rpb25zICRmKHgpJCB0aGF0IGFyZSBub25saW5lYXIgaW4gdGhlIHBhcmFtZXRlcnMgYXJlOiANCg0KDQoxLiAgIFN1cHBvc2UgDQoNCiQkIGYoeF9pOyBcYWxwaGEsXGJldGFfMCxcYmV0YV8xKSA9ICBcYWxwaGF+fiBcZnJhY3sgZV57XGJldGFfMCsgXGJldGFfMSB4fX17IDErZV57XGJldGFfMCsgXGJldGFfMSB4fSB9ICArIFx2YXJlcHNpbG9uJCQNCg0KIFRoaXMgaXMgdGhlIHNvLWNhbGxlZCBsb2dpc3RpYyBjdXJ2ZSwgIHdoaWNoIG1vZGVscyBhIHBoZW5vbWVub24gIChzdWNoIGFzIHNhbGVzKSB0aGF0IGdvZXMgZnJvbSB6ZXJvICAgdG8gc29tZSB1cHBlciBsaW1pdCAkXGFscGhhJC4gIA0KIA0KIChOb3RlICRcYWxwaGEkIGlzIGFuIGFzeW1wdG90ZSBmb3IgdGhlICoqY3VydmUqKiBidXQgdGhlIGluZGl2aWR1YWwgZGF0YSBjYW4gZ28gcmFuZG9tbHkgYWJvdmUgb3IgYmVsb3cgdGhlIGN1cnZlKS4gICANCiANClRoaXMgbW9kZWwgIGNhbm5vdCBiZSAgbWFkZSBsaW5lYXIsIGJ1dCAgaW4gcHJpbmNpcGxlIHdlICBjYW4gdXNlIGFueSBtYXRoZW1hdGljYWwgbWV0aG9kIHdlIHdpc2ggIHRvIGZpbmQgdGhvc2UgZXN0aW1hdGVzICBvZiAkXGFscGhhLFxiZXRhXzAkLCRcYmV0YV8xJCB0aGF0IG1pbmltaXplICAgDQokU1Nfe2Vycm9yfSA9IFxzdW0gKHlfaSAtIFxoYXQgeV9pICleMiQgDQp3aGVyZSANCiQkXGhhdCB5X2kgPSBcaGF0XGFscGhhfn5cZnJhY3tlXntcaGF0XGJldGFfMCsgXGhhdFxiZXRhXzEgeH0gfXsgMStlXntcaGF0XGJldGFfMCsgXGhhdFxiZXRhXzEgeH0gfSB+fi4kJA0KDQoNCg0KMi4JQSBzb21ld2hhdCBzaW1wbGVyIGV4YW1wbGUsIGJ1dCBhbHNvIG5vbmxpbmVhciwgaXMgDQoNCiQkIHlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaV57XGFscGhhfSAkJA0KDQoNCgkJIA0Kd2hlcmUgJFxhbHBoYSQgaXMgIHVua25vd24uICBBZ2FpbiB0aGlzIGNhbm5vdCBiZSBtYWRlIGxpbmVhciBpbiAkXGFscGhhLFxiZXRhXzAkIGFuZCAkXGJldGFfMSQgYnV0IGluIHRoaXMgZXhhbXBsZSB0aGUgbW9kZWwgZml0dGluZyBjb3VsZCBiZSBkb25lIHNpbXBseSBieSBndWVzc2luZyAkXGFscGhhJCBhbmQgY3JlYXRpbmcgYSBuZXcgZXhwbGFuYXRvcnkgdmFyaWFibGUgJHhfe25ld30gICA9ICB4XlxhbHBoYSQuIA0KVGhlbiAkXGJldGFfMCQgYW5kICRcYmV0YV8xJCBjYW4gYmUgZm91bmQgYnkgbGluZWFyIHJlZ3Jlc3Npb24gb2YgJHkkIG9uICR4X3tuZXd9JC4gDQoNCg0KIyMgQ2FzZSBTdHVkeSB1c2luZyAgRGlyZWN0IFNlYXJjaA0KVGhlIGZvbGxvd2luZyBleGFtcGxlIGNvbmNlcm5zIHNvbWUgZGF0YSBvbiANCiRZJCA9IHRoZSBudW1iZXIgb2YgICptYW5ob3VycyogdXNlZCBpbiBzdXJnaWNhbCBjYXNlcyBpbiAxNSBVUyBuYXZ5IGhvc3BpdGFscywgICAgdmVyc3VzICAgJFgkPSB0aGUgbnVtYmVyIG9mICpjYXNlcyogdHJlYXRlZC4NCg0KVGhlIHB1cnBvc2Ugb2YgdGhlIGFuYWx5c2lzIHdhcyB0byBkZXZlbG9wIGEgcHJlbGltaW5hcnkgbWFucG93ZXIgZXF1YXRpb24gZm9yIGVzdGltYXRpb24gb2YgbWFuaG91cnMgcGVyIG1vbnRoIGV4cGVuZGVkIG9uIHN1cmdpY2FsIHNlcnZpY2VzLg0KDQpgciB4ZnVuOjplbWJlZF9maWxlKCIuLi8uLi9kYXRhL01hbmhvdXJzLmNzdiIpYA0KDQpgYGB7ciByZWFkIE1hbmhvdXJzLCBldmFsPS0xLCBlY2hvPS0yfQ0KbWFuaG91cnMgPSByZWFkLmNzdigiTWFuaG91cnMuY3N2IixoZWFkZXI9VFJVRSkNCm1hbmhvdXJzID0gcmVhZC5jc3YoIi4uLy4uL2RhdGEvTWFuaG91cnMuY3N2IixoZWFkZXI9VFJVRSkNCg0KbWFuaG91cnMgDQpwbG90KE1hbmhvdXJzIH4gQ2FzZXMsIGRhdGE9bWFuaG91cnMpIA0KbWgxID0gbG0oTWFuaG91cnN+Q2FzZXMsIGRhdGE9bWFuaG91cnMpICANCmFibGluZShjb2VmKG1oMSkpDQpgYGANCg0KV2UgY291bGQgdXNlIHRyaWFsIGFuZCBlcnJvci4gQSBzdHJhaWdodC1saW5lIG1vZGVsICRcYWxwaGE9MSQgZG9lcyBub3Qgc2VlbSBzdWl0YWJsZS4gV2UgY291bGQgdHJ5IGEgbW9kZWwgJFxzcXJ0IFgkICAoaS5lLiAkXGFscGhhPTAuNSQpLiAgIA0KDQoNCmBgYHtyIGZpcnN0IGZpdHN9DQoNCkNhc2VzPSBtYW5ob3VycyRDYXNlcw0KTWFuaG91cnMgPSBtYW5ob3VycyRNYW5ob3Vycw0KDQpzdW1tYXJ5KG1oMSkNCg0KQ2FzZW5ldyA9Q2FzZXNeMC41DQptaDIgPSBsbShNYW5ob3Vyc34gQ2FzZW5ldyAgKQ0Kc3VtbWFyeShtaDIpDQpwbG90KCBNYW5ob3VycyB+IENhc2VuZXcsIG1haW49IkNhc2VzIF4gMC41IikgDQphYmxpbmUoY29lZihtaDIpKQ0KYGBgDQoNCk5vdGUgdGhlIHJlc2lkdWFsIHN0YW5kYXJkIGVycm9yIGlzIHNtYWxsZXIgZm9yIHRoaXMgbW9kZWwuIA0KTGV0J3MgdHJ5IHRoZSBmb3VydGggcm9vdC4NCg0KDQpgYGB7ciBzZWNvbmQgZml0fQ0KQ2FzZW5ldyA9Q2FzZXNeMC4yNQ0KbWgzID0gbG0oTWFuaG91cnN+IENhc2VuZXcgICkNCnN1bW1hcnkobWgzKQ0KcGxvdCggTWFuaG91cnMgfiBDYXNlbmV3LCBtYWluPSJDYXNlcyBeIDAuMjUiKSANCmFibGluZShjb2VmKG1oMykpDQpgYGANCg0KDQpBZ2FpbiB0aGUgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3IgaXMgc21hbGxlci4gIFN1cHBvc2Ugd2UgdHJ5IGEgZ3JpZCBvZiB2YWx1ZXMgZm9yICRcYWxwaGEkDQoNCmBgYHtyIGdyaWQxfQ0KYWxwaGEgPSByc2U9IHJlcCgwLDEwKQ0KZm9yKCBpIGluIDE6MTAgKXsNCmFscGhhW2ldID0gaS8xMA0KY2FzZW5ldyA9IENhc2VzXmFscGhhW2ldDQpyc2VbaV0gPSBzdW1tYXJ5KGxtKE1hbmhvdXJzfmNhc2VuZXcpKSRzaWdtYX0NCmNiaW5kKGFscGhhLHJzZSkNCmBgYA0KDQpJdCBsb29rcyBsaWtlIHRoZSBtaW5pbXVtIGlzIGZvciAkXGFscGhhJCBiZXR3ZWVuIDAuMiBhbmQgMC40DQoNCg0KYGBge3IgZ3JpZDJ9DQphbHBoYSA9IHJzZT0gcmVwKDAsMjApDQpmb3IoIGkgaW4gMToyMCApew0KYWxwaGFbaV0gPSAwLjIrIGkvMTAwDQpjYXNlbmV3ID0gQ2FzZXNeYWxwaGFbaV0NCnJzZVtpXSA9IHN1bW1hcnkobG0oTWFuaG91cnN+Y2FzZW5ldykpJHNpZ21hfQ0KY2JpbmQoYWxwaGEscnNlKQ0KYGBgDQpJdCBsb29rcyBsaWtlIHRoZSBtaW5pbXVtIGlzIGZvciAkXGFscGhhJCBiZXR3ZWVuIDAuMjYgYW5kIDAuMjguDQpgYGB7ciBncmlkM30NCmFscGhhID0gcnNlPSByZXAoMCwyMCkNCmZvciggaSBpbiAxOjIwICl7DQphbHBoYVtpXSA9IDAuMjYrIGkvMTAwMA0KY2FzZW5ldyA9IENhc2VzXmFscGhhW2ldDQpyc2VbaV0gPSBzdW1tYXJ5KGxtKE1hbmhvdXJzfmNhc2VuZXcpKSRzaWdtYX0NCmNiaW5kKGFscGhhLHJzZSkNCmBgYA0KSXQgbG9va3MgbGlrZSB0aGUgbWluaW11bSAkUyQgaXMgb2J0YWluZWQgZm9yICRcYWxwaGEgXGFwcHJveCAwLjI2OSQuICBUaGUgcHJvY2VkdXJlIGNvdWxkIGJlIHJlcGVhdGVkIHRvIG9idGFpbiB0aGUgbWluaW11bSBSU0UgdG8gbW9yZSBzaWduaWZpY2FudCBmaWd1cmVzIGJ1dCwgaW4gdmlldyBvZiB0aGUgc21hbGwgY2hhbmdlcyB3ZSBhcmUgYWNoaWV2aW5nLCAgbGl0dGxlIHdpbGwgYmUgYWNoaWV2ZWQgYnkgZ29pbmcgZnVydGhlci4gDQoNCmBgYHtyIGxhc3QgZml0IH0NCmNhc2VuZXcgPUNhc2VzXjAuMjY5DQptaDMgPSBsbShNYW5ob3Vyc34gY2FzZW5ldyAgKQ0Kc3VtbWFyeShtaDMpDQpwbG90KCBNYW5ob3VycyB+IGNhc2VuZXcsIG1haW49IkNhc2VzIF4gMC4yNjkiKSANCmFibGluZShjb2VmKG1oMykpDQpgYGANCg0KIyMjIENvbW1lbnRzIG9uIGRpcmVjdCBzZWFyY2gNCg0KRGlyZWN0IHNlYXJjaGluZyBvbiBhIGdyaWQgbWF5IGdldCB0byBhIHNvbHV0aW9uLCBidXQgdGhlIG1ldGhvZCBoYXMgZGlzYWR2YW50YWdlcy4gDQoNCjEuIEl0IGlzIHRpbWUtY29uc3VtaW5nLCByZXF1aXJpbmcgcHJvZ3JhbW1pbmcgYW5kL29yIGh1bWFuIGludGVydmVudGlvbi4NCg0KMi4gSWYgd2UgaGF2ZSBzZXZlcmFsIHBhcmFtZXRlcnMgdG8gc2VhcmNoIGZvciwgd2UgbWF5IGhhdmUgdG8gdXNlIGEgZ3JpZCBpbiB0d28sIHRocmVlIG9yIG1vcmUgZGltZW5zaW9ucywgd2hpY2ggaXMgY29tcHV0YXRpb25hbGx5IGludGVuc2l2ZS4gDQoNCjMuIEV2ZW4gb25jZSB3ZSBnZXQgdG8gYSBwb2ludCBlc3RpbWF0ZSwgd2UgZG8gbm90IGhhdmUgYSBzdGFuZGFyZCBlcnJvciBmb3IgdGhlIGVzdGltYXRlLCBzbyB3ZSBkbyBub3Qga25vdyByZWFsbHkgaG93IGFjY3VyYXRlIGl0IGlzLiAgV2UgY2Fubm90IGNvbXB1dGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgb3IgaHlwb3RoZXNpcyB0ZXN0cyByZWdhcmRpbmcgdGhlIHBhcmFtZXRlcnMuIA0KDQpXZSBub3cgY29uc2lkZXIgYSBtb3JlIGNvbnZlbmllbnQgbWV0aG9kIHRoYXQgb3ZlcmNvbWVzIGFsbCB0aGVzZSBoYW5kaWNhcHMuIA0KDQojIyBUaGUgR2F1c3MtTmV3dG9uIEFsZ29yaXRobQ0KDQpUaGUgYWx0ZXJuYXRpdmUgdG8gdXNpbmcgZGlyZWN0IHNlYXJjaCBpcyB0byB1c2UgYSBtYXRoZW1hdGljYWwgdGVjaG5pcXVlIHN1Y2ggYXMgdGhlIEdhdXNzLU5ld3RvbiBBbGdvcml0aG0gLg0KDQpUaGUgaWRlYSBvZiB0aGUgYWxnb3JpdGhtIGlzIHRvIGFwcHJveGltYXRlIHRoZSBjdXJ2ZSAgICRmKHhfaTsgXGFscGhhLFxiZXRhLFxnYW1tYSkkICAgYnkgYSBzdW0gb2Ygc3RyYWlnaHQgbGluZXMgaW52b2x2aW5nICRcYWxwaGEsXGJldGEkIGFuZCAkXGdhbW1hJC4gIFRoYXQgaXMsIGEgICpsaW5lYXJpemVkKiAgYXBwcm94aW1hdGlvbiAgdG8gdGhlIGN1cnZlLiAgIA0KDQpUaGUgbWF0aGVtYXRpY2FsIGlkZWFzIGFyZSBpbiBhbiB3b3JkIGRvY3VtZW50IG9uIFN0cmVhbSwgYnV0IGFyZSBub3QgZXhhbWluYWJsZS4gDQoNClRoZSBtYWluIHBvaW50cyBhcmU6IA0KDQoxLglUaGUgcHJvY2VzcyBvZiBtb2RlbC1maXR0aW5nIGlzIGl0ZXJhdGl2ZS4gIFRoYXQgaXMsIGl0IGludm9sdmVzIGEgc2VyaWVzIG9mIHJlcGVhdGVkIGxpbmVhciByZWdyZXNzaW9ucyB3aXRoIHNsaWdodGx5IGRpZmZlcmVudCBkYXRhIGVhY2ggdGltZSwgY29udmVyZ2luZyB0byBhIGZpeGVkIGFuc3dlciBhcyB3ZSBnZXQgY2xvc2VyIGFuZCBjbG9zZXIgdG8gdGhlIG9wdGltYWwgZXN0aW1hdGVzLg0KDQoyLglUaGUgR2F1c3MtTmV3dG9uIG1ldGhvZCBpcyBndWFyYW50ZWVkIHRvIGNvbnZlcmdlIHF1aWNrbHkgdG8gdGhlIG9wdGltYWwgZXN0aW1hdGVzLCBwcm92aWRlZCB0aGF0IG91ciBpbml0aWFsIHN0YXJ0aW5nIHBvaW50IGlzIGNsb3NlIGVub3VnaC4NCg0KMy4JVGhlIG1ldGhvZCBhbHNvIHByb2R1Y2VzIGFwcHJveGltYXRlIGh5cG90aGVzaXMgdGVzdHMgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiAgDQoNClRoZSBubHMoKSAgIG5vbmxpbmVhciBsZWFzdCBzcXVhcmVzIHByb2NlZHVyZSBpbXBsZW1lbnRzIHRoZSBHYXVzcy1OZXd0b24gYWxnb3JpdGhtLg0KDQpXZSBuZWVkIHRvIHNwZWNpZnkgdGhlIGZvcm11bGEsIGFuZCAocHJlZmVyYWJseSkgcmVhc29uYWJsZSBzdGFydGluZyB2YWx1ZXMuIA0KDQpgYGB7ciwgZWNobz1GfQ0Kcm0oYWxwaGEpDQpgYGANCg0KYGBge3IgZ2F1c3MtbmV3dG9uIDF9DQptYW5ob3Vycy5ubHMgPSBubHMoTWFuaG91cnN+YmV0YTAgKyBiZXRhMSooQ2FzZXNeYWxwaGEpLCBzdGFydD1saXN0KGFscGhhPTAuMjUsYmV0YTA9LTE2MDAwLGJldGExPTQ0MDApLCBkYXRhPW1hbmhvdXJzKSAgDQoNCnN1bW1hcnkobWFuaG91cnMubmxzKQ0KDQpwbG90KE1hbmhvdXJzfkNhc2VzKQ0KbGluZXMocHJlZGljdChtYW5ob3Vycy5ubHMpfiBDYXNlcykNCmBgYA0KDQpXZSBjYW4gY2FsY3VsYXRlIGFuIGFwcHJveGltYXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yICRcYWxwaGEkIHVzaW5nICAkJCBcaGF0XGFscGhhIFxwbSB0X3tuLXB9KDAuMDI1KSpTRShcaGF0XGFscGhhKSQkDQoNCmBgYHtyIGNvbmZpZGVuY2UgaW50ZXJ2YWx9DQpzdW1tYXJ5KG1hbmhvdXJzLm5scykkY29lZmZpY2llbnRzDQplc3Q9IHN1bW1hcnkobWFuaG91cnMubmxzKSRjb2VmZmljaWVudHNbMV0gIA0Kc2U9c3VtbWFyeShtYW5ob3Vycy5ubHMpJGNvZWZmaWNpZW50c1s0XQ0KbG93ZXI9IGVzdCArIHF0KDAuMDI1LGRmPTE1LTMpKnNlDQp1cHBlcj0gZXN0ICsgcXQoMC45NzUsZGY9MTUtMykqc2UNCmNiaW5kKGVzdCxzZSxsb3dlcix1cHBlcikNCg0KYGBgDQoNCldlIGNhbiBjb25jbHVkZSBmcm9tIHRoaXMgdGhhdCB3ZSBjb3VsZCBub3QgcmVqZWN0IGEgaHlwb3RoZXNpcyAgdGhhdCAkXGFscGhhJCBlcXVhbGxlZCBhbnkgdmFsdWUgYmV0d2VlbiAtMC4wNyBhbmQgMC42LiAgDQoNCkluIHBhcnRpY3VsYXIsIHdlIGNvdWxkIGhhdmUgc3R1Y2sgd2l0aCB0aGUgc3F1YXJlLXJvb3QgdHJhbnNmb3JtYXRpb24gKCRcYWxwaGE9MC41JCkgb3IgdXNlZCB0aGUgKmxvZyogdHJhbnNmb3JtYXRpb24gKHJlY2FsbCB0aGlzIHRha2VzIHRoZSBwbGFjZSBvZiAkXGFscGhhPTAkIGluIHRoZSBsYWRkZXIgb2YgcG93ZXJzKS4NCg0KIyMgRXhhbXBsZTogIEEgR3Jvd3RoIEN1cnZlIE1vZGVsIHdpdGggYW4gTWF4aW11bSAgDQoNClJlY2FsbCB0aGUgZmV2IGRhdGEgcmVsYXRpbmcgZm9yY2VkIGV4cGlyYXRpb24gdm9sdW1lIChGRVYpIHRvIGdpcmxzJyBhZ2VzLiBUaGlzIHNlZW1lZCB0byBmbGF0dGVuIG9mZiBhZnRlciBhYm91dCBhZ2UgMTAuIA0KDQpXZSB3aWxsIG1vZGVsIHRoZSBncm93dGggdXNpbmcgYSBsb2dpc3RpYyBjdXJ2ZSB3aXRoIHVua25vd24gbWF4aW11bS4NCg0KJCQgZih4X2k7IFxhbHBoYSxcYmV0YV8wLFxiZXRhXzEpID0gIFxhbHBoYX5+XGZyYWN7ZV57XGJldGFfMCsgXGJldGFfMSB4fX17IDErZV57XGJldGFfMCsgXGJldGFfMSB4fSB9ICArIFx2YXJlcHNpbG9uJCQNCg0KDQpgciB4ZnVuOjplbWJlZF9maWxlKCIuLi8uLi9kYXRhL0ZFVi5jc3YiKWAgDQoNCmBgYHtyIGdldEZldkRhdGEsIGV2YWw9LTEsIGVjaG89LTJ9DQpmZXYgPC0gcmVhZC5jc3YoZmlsZT0iZmV2LmNzdiIsIGhlYWRlcj1UUlVFKQ0KZmV2IDwtIHJlYWQuY3N2KGZpbGU9Ii4uLy4uL2RhdGEvZmV2LmNzdiIsIGhlYWRlcj1UUlVFKQ0KDQpGRVYgPSBmZXYkRkVWDQpBZ2U9IGZldiRBZ2UNCg0KcGxvdChGRVZ+QWdlICkNCg0KYGBgDQoNCg0KRnJvbSB0aGUgZ3JhcGggdGhlIG1heGltdW0gJFxhbHBoYSBcYXBwcm94IDMkLCBzbyBzZXR0aW5nIA0KJCRGRVYgXGFwcHJveCAzIH5+XGZyYWN7ZV57XGJldGFfMCArIFxiZXRhXzEgQWdlfX17IDErIGVee1xiZXRhXzAgKyBcYmV0YV8xIEFnZX19JCQgDQp3ZSBjYW4gcmVhcnJhbmdlIHRoaXMgYXMgIA0KJCQxKyBlXntcYmV0YV8wICsgXGJldGFfMSBBZ2V9ICAgXGFwcHJveCAgXGZyYWN7M317RkVWfSB+ICBlXntcYmV0YV8wICsgXGJldGFfMSBBZ2V9ICAkJCANCg0KR2F0aGVyIHVwIHRoZSAkZV57XGJldGFfMCArIFxiZXRhXzEgQWdlfSQgdGVybXMgDQoNCg0KJCQgXGZyYWN7MX17My9GRVYgLSAxfSBcYXBwcm94IGVee1xiZXRhXzAgKyBcYmV0YV8xIEFnZX0kJA0KYW5kIHRoZW4gaWYgd2UgdGFrZSBsb2dzIHdlIGNhbiB1c2UgdGhlIGxlZnQtaGFuZCBzaWRlIGFzIHRoZSAicmVzcG9uc2UiIGluIGEgcmVncmVzc2lvbg0KDQokJCBZX3tuZXd9ID0gXGxvZ1xsZWZ0KFxmcmFjezF9ezMvRkVWIC0gMX1ccmlnaHQpXGFwcHJveCAgXGJldGFfMCArIFxiZXRhXzEgQWdlICQkDQp0byBnaXZlIHVzIHN0YXJ0aW5nIHZhbHVlcyBmb3IgJFxiZXRhXzAkIGFuZCAkXGJldGFfMSQ6DQoNCmBgYHtyIHN0YXJ0fQ0Kc3RhcnQuY2FsYyA9bG0oIC1sb2coMy9GRVYgLTEpIH4gQWdlKQ0KDQpgYGANCg0KDQpgYGB7cn0NCnN1bW1hcnkoc3RhcnQuY2FsYykNCmBgYA0KDQpTbyB3ZSB3aWxsIHVzZSBzdGFydGluZyB2YWx1ZXMgJFxhbHBoYT0zJCwgJFxiZXRhXzA9IC0xLjMkIGFuZCAkXGJldGFfMT0wLjI4JA0KDQoNCmBgYHtyIGZldi5ubHN9DQpmZXYubmxzPSBubHMoICBGRVYgfmFscGhhKmV4cChiZXRhMCArIGJldGExKkFnZSkvKDErIGV4cChiZXRhMCArIGJldGExKkFnZSkpLCBzdGFydD1saXN0KGFscGhhPTMsYmV0YTA9IC0xLjMsYmV0YTE9IDAuMjgpICkgIA0Kc3VtbWFyeShmZXYubmxzKQ0KDQpwbG90KEZFVn5BZ2UgKQ0KbGluZXMoMzA6MjAwLzEwLHByZWRpY3QoZmV2Lm5scywgbmV3ZGF0YT1kYXRhLmZyYW1lKEFnZSA9MzA6MjAwLzEwKSApICAgLCBsdHk9MSxjb2w9Mixsd2Q9MykNCmBgYA0KDQoNClRoaXMgaGFzIGNvbnZlcmdlZC4gTm90ZSB0aGUgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3IgaXMgDQpgciByb3VuZChzdW1tYXJ5KGZldi5ubHMpJHNpZ21hLDQpYCwgd2hpY2ggaXMgIHNsaWdodGx5IGJpZ2dlciB0aGFuIGZvciB0aGUgcGllY2V3aXNlIG1vZGVsIGxvb2tlZCBhdCBlYXJsaWVyIChTPTAuMzkpIGJ1dCB0aGUgY3VydmUgc2VlbXMgbW9yZSByZWFzb25hYmxlIHRoYW4gaGF2aW5nIGEgc2hhcnAgY29ybmVyLiAgDQoNCldlIGNhbiBnZXQgYSBzbGlnaHRseSBiZXR0ZXIgZml0IGJ5IGFkZGluZyBhIHF1YWRyYXRpYyB0ZXJtIGluIEFnZS4gSW4gdGhlIGZvbGxvd2luZyB3ZSB1c2Ugc3RhcnRpbmcgdmFsdWUgJFxiZXRhXzI9MCQuDQoNCmBgYHtyIGZldi5ubHMyYX0NCmZldi5ubHMyPSBubHMoICBGRVYgfmFscGhhKmV4cChiZXRhMCArIGJldGExKkFnZSsgYmV0YTIqQWdlXjIpLygxKyBleHAoYmV0YTAgKyBiZXRhMSpBZ2UrIGJldGEyKkFnZV4yKSksIHN0YXJ0PWxpc3QoYWxwaGE9MyxiZXRhMD0gLTEuMyxiZXRhMT0wLjI4LCBiZXRhMj0wKSwgZGF0YT1mZXYpICANCnN1bW1hcnkoZmV2Lm5sczIpDQpwbG90KEZFVn5BZ2UpDQpsaW5lcygzMDoyMDAvMTAscHJlZGljdChmZXYubmxzMiwgbmV3ZGF0YT1kYXRhLmZyYW1lKEFnZSA9MzA6MjAwLzEwKSApICAgLCBsdHk9MSxjb2w9Mixsd2Q9MykNCg0KYGBgIA0KDQoNCg0KIyMgUGllY2V3aXNlIFJlZ3Jlc3Npb24gd2l0aCBhbiBVbmtub3duIEtub3QNCg0KUmVjYWxsIHRoYXQgc29tZXRpbWVzIHdlIHdpc2ggdG8gZml0IGEgcGllY2V3aXNlIHJlZ3Jlc3Npb24gbW9kZWwsIGJ1dCB0aGUgbG9jYXRpb24gb2YgdGhlIGtub3QgaXMgdW5rbm93bi4gDQoNClRoaXMgdGhlbiBpcyBiZWNvbWVzIGEgbm9ubGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwsIHdpdGggdGhlIGxvY2F0aW9uIG9mIHRoZSBrbm90IHRha2luZyB0aGUgcm9sZSBvZiB0aGUgYWxwaGEgcGFyYW1ldGVyIGFib3ZlIChub3QgbWVhbmluZyB0aGF0IGl0IGVudGVycyB0aGUgZXF1YXRpb24gdGhlIHNhbWUgd2F5LCBidXQgdGhhdCBpZiB0aGUga25vdCBpcyBrbm93biwgdGhlbiBldmVyeSBvdGhlciBwYXJhbWV0ZXIgY2FuIGJlIGZpdHRlZCBieSAgbGluZWFyIHJlZ3Jlc3Npb24pLiAgIA0KDQpTdHJpY3RseSBzcGVha2luZyB0aGUgIEdhdXNzLU5ld3RvbiBhbGdvcml0aG0gZG9lcyBub3QgcXVpdGUgd29yaywgYXMgdGhlIGtub3QgZ2l2ZXMgYSDigJhjb3JuZXLigJkgdG8gdGhlIGxpbmVzLCBvciBldmVuIGEganVtcCBpbiB0aGUgbGV2ZWwgb2YgdGhlIGxpbmVzLCBhbmQgdGhpcyBtZWFucyB0aGF0IHRoZSBjYWxjdWx1cyBvbiB3aGljaCB0aGUgbWV0aG9kIHdhcyBvcmlnaW5hbGx5IGJhc2VkIGJyZWFrcyBkb3duLiAgSG93ZXZlciB0aGUgbmxzKCkgcm91dGluZSBjYW4gYmUgbWFkZSB0byBjb3BlLiANCg0KIyMjIE5vbmxpbmVhciByZWdyZXNzaW9uIGZvciBhIGNoYW5nZS1zbG9wZSBtb2RlbDogdGhlIFRoYWkgQmFodC4NCg0KVGhlIGRhdGEgaGVyZSByZWZlciB0byB0aGUgVGhhaSBCYWh0ICBFeGNoYW5nZSBSYXRlICRZJCB2cyBUaW1lICAodGltZSBtZWFzdXJlZCBpbiBodW5kcmVkcyBvZiBkYXlzLCAgKmhEYXlzKi4gKSAgIFRoZSBncmFwaCBiZWxvdyBzaG93cyAkWSQgdnMgKmhEYXlzKiB3aXRoIGEgY3ViaWMgbW9kZWwuICBUaGUgbW9kZWwgbG9va3MgbGlrZSBpdCB3b3VsZCBiZSB1bnNhZmUgZm9yIGV4dHJhcG9sYXRpb24gb24gdGhlIHJpZ2h0Lg0KDQoNCmByIHhmdW46OmVtYmVkX2ZpbGUoIi4uLy4uL2RhdGEvYmFodC5jc3YiKWAgDQoNCmBgYHtyIGJhaHQsIGV2YWw9LTEsIGVjaG89LTJ9DQpiYWh0PSByZWFkLmNzdiggImJhaHQuY3N2IixoZWFkZXI9VFJVRSkNCmJhaHQ9IHJlYWQuY3N2KCAiLi4vLi4vZGF0YS9iYWh0LmNzdiIsaGVhZGVyPVRSVUUpDQoNClk9IGJhaHQkWQ0KaERheXMgPSBiYWh0JGhEYXlzIA0KDQpwbG90KFkgfmhEYXlzKSANCmN1YmljID0gbG0oWX5wb2x5KGhEYXlzLDMpKTsgICBzdW1tYXJ5KGN1YmljKSRzaWdtYQ0KbGluZXMocHJlZGljdChjdWJpYyl+aERheXMsIGNvbD0yLGx3ZD0yKQ0KYGBgDQoNCldlIGNvbnNpZGVyIGEgcGllY2V3aXNlIG1vZGVsIA0KJCQgWSA9IFxiZXRhXzAgKyBcYmV0YV8xLiBoRGF5cyArIFxiZXRhXzIgKGhEYXlzLWspXysgJCQNCndoZXJlICRrJCBpcyB1bmtub3duIGJ1dCBwcm9iYWJseSBuZWFyIDIuIFdlIHdpbGwgdXNlIHRoaXMgZ3Vlc3MgdG8gZ2l2ZSBzdGFydGluZyB2YWx1ZXMgZm9yIHRoZSBvdGhlciBwYXJhbWV0ZXJzLg0KDQpgYGB7ciBwaWVjZXdpc2V9DQpzdGFydC5ndWVzcyA9IGxtKCBZIH4gaERheXMgKyBJKCAoYWJzKGhEYXlzLTIpK2hEYXlzLTIpLzIpICkNCnN1bW1hcnkoc3RhcnQuZ3Vlc3MpDQpgYGANClRoaXMgZ2l2ZXMgc3RhcnRpbmcgZXN0aW1hdGVzICRcYmV0YV8wXGFwcHJveCAwLjM0LCB+fiBcYmV0YV8xIFxhcHByb3ggLTAuMDIsfn4gXGJldGFfMiBcYXBwcm94IDAuMDIyLCB+fms9MiQuDQoNClRoZSBmb2xsb3dpbmcgY29kZSBmaXRzIHRoZSBtb2RlbCwgYnV0IHNvbWUgaXRlcmF0aW9uIGNvbnRyb2wgcGFyYW1ldGVycyB3ZXJlIG5lZWRlZCwgcHJlc3VtYWJseSBiZWNhdXNlIG9mIHRoZSBjb3JuZXIuIA0KKE90aGVyIHN0YXRpc3RpY2FsIHNvZnR3YXJlIHN1Y2ggYXMgU1BTUyBhbmQgTWluaXRhYiAgaGF2ZSBsZXNzIHByb2JsZW1zIGZpdHRpbmcgdGhpcyBtb2RlbC4pDQoNCmBgYHtyIHBpZWNld2lzZS5ubHN9DQoNCmJhaHQubmxzID0gbmxzKCAgWSB+IGJldGEwICsgYmV0YTEqaERheXMgKyBiZXRhMipJKCAoYWJzKGhEYXlzLWspK2hEYXlzLWspLzIpICwgc3RhcnQ9bGlzdChiZXRhMD0wLjM0ICwgYmV0YTE9IC0wLjAyLGJldGEyPSAwLjAyMiwgaz0yKSwgZGF0YT1iYWh0LCBubHMuY29udHJvbCh3YXJuT25seT1UUlVFLCBtaW5GYWN0b3I9MS8yMDQ4KSkgIA0Kc3VtbWFyeShiYWh0Lm5scykNCnBsb3QoWX5oRGF5cykNCmxpbmVzKHByZWRpY3QoYmFodC5ubHMgKX5oRGF5cyAsICAgY29sPTIsbHdkPTMpDQoNCmBgYA0KDQpUaGUgZ3JhcGggc2VlbXMgbXVjaCBtb3JlIHJlYXNvbmFibGUuIE5vdGUgaXQgY2hhbmdlZCB0aGUgJGskIHRvIDEuNTcuIA0KDQpJbiB0ZXJtcyBvZiByZXNpZHVhbCBzdGFuZGFyZCBlcnJvciwgd2hpY2ggaXMgdGhlIGJldHRlci1maXR0aW5nIG1vZGVsLCB0aGUgY3ViaWMgb3IgdGhlIGNoYW5nZS1wb2ludCBtb2RlbD8gKEZyb20gYWJvdmUgdGhlIGN1YmljIGdyYXBoICBTID1gciByb3VuZChzdW1tYXJ5KGN1YmljKSRzaWdtYSwgNilgKS4NCg0K
Comments on direct search
Direct searching on a grid may get to a solution, but the method has disadvantages.
It is time-consuming, requiring programming and/or human intervention.
If we have several parameters to search for, we may have to use a grid in two, three or more dimensions, which is computationally intensive.
Even once we get to a point estimate, we do not have a standard error for the estimate, so we do not know really how accurate it is. We cannot compute confidence intervals or hypothesis tests regarding the parameters.
We now consider a more convenient method that overcomes all these handicaps.