Simple Linear Regression
Given a set of data \[
(x_1,y_1), (x_2,y_2),\ldots,(x_n,y_n)
\] a regression analysis is a means of determining if there is a correlation between the \(x\)-data and the \(y\)-data.
A Scatter Plot is a means of tentatively determining whether or not the data is correlated, simply by observing the shape of the plot
Example 1 - Strong Linear Correlation
Plot the following data points on a scatter plot
\[
(1.2, 10.3), (1.5,10.45), (1.6, 10.79), (2.1, 10.8), (2.2,11.0), (2.4, 11.2), (2.5,11.5), (2.9, 12.2), (3.1,12.4), (3.8,13.0), (4.1,13.4)
\]
For this data set we create two data vectors, one for the \(x\)-variables and one for the \(y\)-variables, and plot the result, with the \(x\)-data plotted along the horizontal axis, and the \(y\)-data plotted along the vertical axis.
X1<-c(1.2,1.5,1.6,2.1,2.1,2.4,2.5,2.9,3.1,3.8,4.1)
Y1<-c(10.3,10.45,10.79,10.8,11.0,11.2,11.5,12.2,12.4,13.0,13.4)
plot(X1,Y1,xlab="x",ylab="y",col="red", main="Linearly Correlated Data",pch=18)

Example 2 - Non-correlated Data
In this example we will plot the following data set \[
(-1.4,2.4), (0.4,1.3), (1.4,6.5), (2.1,3.4), (4.5,12.3), (5.2, 2.1), (5.8,3.1), (6.5,5.4), (6.9, 6.7)
\]
X2<-c(-1.4,0.4,1.4,2.1,4.5,5.2,5.8,6.5,6.9)
Y2<-c(2.4,1.3,6.5,3.4,12.3,2.1,3.1,13.4,6.7)
plot(X2,Y2,xlab="x",ylab="y",col="red", main="Non-correlated Data",pch=19)

It is clear from the scatter plot that there is no immediately obvious trend relating the \(x\) and \(y\) variables in this plot, in which case we say the \(x\) and \(y\) variables are not correlated.
While the scatter plot doesn’t rule out a correlation between the \(x\) and \(y\) variables, it does give an initial indication as to whether or not a relationship exists.
The Line of Best Fit
Given the data set above, there are values of the estimated parameters \(\hat{\beta}_0\) an \(\hat{\beta}_1\) which will yield a line which best fits the points of the data plot.
One way to find a line which passes through or close to these data point is to obtain the lie slope from the first and last data points as follows: \[
b=\frac{6.7-2.4}{6.9+1.4}=\frac{4.3}{8.3}=0.518.
\]
Taking the mean of the \(x\) and \(y\) data, we have
mean(X1)
[1] 2.481818
mean(Y1)
[1] 11.54909
This now allows us to find an estimate for the parameter \(\beta_0\) as follows \[
\bar{y}=a+b\bar{x}\Rightarrow 11.54909=a+0.518\times 2.481818 \Rightarrow a=10.2635.
\]
Our first approximation at a linear model relating the \(x\) and \(y\) data is now given by \[y=10.2635+0.518x\]
We now plot this line through the data points as follows: \[x=0\Rightarrow y=10.2635\qquad x=5\Rightarrow y=12.8535\]
X1<-c(1.2,1.5,1.6,2.1,2.1,2.4,2.5,2.9,3.1,3.8,4.1)
Y1<-c(10.3,10.45,10.79,10.8,11.0,11.2,11.5,12.2,12.4,13.0,13.4)
plot(X1,Y1,xlab="x",ylab="y",col="red",main="Linearly Correlated Data",pch=18)
segments(0,10.2635,x1=5,y1=12.8535,col ="blue",lwd=2)

- Clearly, this line doesn’t fit the data very well, and there are better approximations available to represent the relationship between to \(x\) and \(y\) data.
The Method of Least Squares
X1<-c(1.2,1.5,1.6,2.1,2.1,2.4,2.5,2.9,3.1,3.8,4.1)
Y1<-c(10.3,10.45,10.79,10.8,11.0,11.2,11.5,12.2,12.4,13.0,13.4)
plot(X1,Y1,xlab="x",ylab="y",col="red",main="Linearly Correlated Data",pch=18)
segments(X1,Y1,x1=X1,y1=10.2635+0.518*X1,col ="darkgreen",lwd=2)
segments(0,10.2635,x1=5,y1=12.8535,col ="blue",lwd=2)

Model1<-lm(Y1 ~ X1)
Model1
Call:
lm(formula = Y1 ~ X1)
Coefficients:
(Intercept) X1
8.784 1.114
- Hence the values of the parameters are given by \[
a=8.784\qquad b=1.114
\]
- Lastly, we can plot the simple linear regression model \[y=8.784+1.114x\] onto our scatter plot as follows:
plot(X1,Y1,col="red",pch=18)
abline(Model1,col="darkgreen")

Example 3 - From Lectures
We were given the following data relating Weekly Natural Gas Consumption in a U.S. city along with the Hourly Average Temperature in that city for the same week.
| 1 |
28.0 |
12.4 |
| 2 |
28.0 |
11.7 |
| 3 |
32.5 |
12.4 |
| 4 |
39.0 |
10.8 |
| 5 |
45.9 |
9.4 |
| 6 |
57.8 |
9.5 |
| 7 |
58.1 |
8.0 |
| 8 |
62.5 |
7.5 |
Using this data answer the following:
- Create a data file to represent this data.
- Import this data into R.
- Create two data vectors corresponding to temperature and consumption.
- Create a scatter plot to represent this data
- Use the lm() function to create a linear model for these data vectors.
- Using this model estimate the parameters \(\hat{\beta}_0\) and \(\hat{\beta}_1\) for the simple linear model.
- Plot the line of best fit along with the scatter plot for the data set.
Solution:
The data file for this data set is available on Moodle and is called FuelConsumption.csv
FuelData<-read.csv("FuelConsumption.csv")
FuelData
Temp<-FuelData$Temp
Temp
[1] 28.0 28.0 32.5 39.0 45.9 57.8 58.1 62.5
Fuel<-FuelData$Fuel
Fuel
[1] 12.4 11.7 12.4 10.8 9.4 9.5 8.0 7.5
plot(Temp,Fuel,col="red",pch=18)

FuelModel<-lm(Fuel ~ Temp)
FuelModel
Call:
lm(formula = Fuel ~ Temp)
Coefficients:
(Intercept) Temp
15.8379 -0.1279
The parameters of the Fuel Model are \[a=15.8379\quad b=-0.1279.\]
plot(Temp,Fuel,col="red",pch=18)
abline(FuelModel,col="darkgreen")

LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpc2F0aW9uIDIwMTkgLSBBc3NpZ25tZW50IDUiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCgojIyMgTGlzdCBvZiBSIGNvbG9yczoKCmh0dHA6Ly93d3cuc3RhdC5jb2x1bWJpYS5lZHUvfnR6aGVuZy9maWxlcy9SY29sb3IucGRmCgojIF9fU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uX18KCiogR2l2ZW4gYSBzZXQgb2YgZGF0YSAKXFsKKHhfMSx5XzEpLCAoeF8yLHlfMiksXGxkb3RzLCh4X24seV9uKQpcXQphIHJlZ3Jlc3Npb24gYW5hbHlzaXMgaXMgYSBtZWFucyBvZiBkZXRlcm1pbmluZyBpZiB0aGVyZSBpcyBhIF9fY29ycmVsYXRpb25fXyBiZXR3ZWVuIHRoZSAkeCQtZGF0YSBhbmQgdGhlICR5JC1kYXRhLgoKKiBBIF9fU2NhdHRlciBQbG90X18gaXMgYSBtZWFucyBvZiB0ZW50YXRpdmVseSBkZXRlcm1pbmluZyB3aGV0aGVyIG9yIG5vdCB0aGUgZGF0YSBpcyBjb3JyZWxhdGVkLCBzaW1wbHkgYnkgb2JzZXJ2aW5nIHRoZSBzaGFwZSBvZiB0aGUgcGxvdAoKIyMjIEV4YW1wbGUgMSAtIFN0cm9uZyBMaW5lYXIgQ29ycmVsYXRpb24KClBsb3QgdGhlIGZvbGxvd2luZyBkYXRhIHBvaW50cyBvbiBhIHNjYXR0ZXIgcGxvdAoKXFsKKDEuMiwgMTAuMyksICgxLjUsMTAuNDUpLCAoMS42LCAxMC43OSksICgyLjEsIDEwLjgpLCAoMi4yLDExLjApLCAoMi40LCAxMS4yKSwgKDIuNSwxMS41KSwgKDIuOSwgMTIuMiksICgzLjEsMTIuNCksICgzLjgsMTMuMCksICg0LjEsMTMuNCkKXF0KCkZvciB0aGlzIGRhdGEgc2V0IHdlIGNyZWF0ZSBfdHdvXyBkYXRhIHZlY3RvcnMsIG9uZSBmb3IgdGhlICR4JC12YXJpYWJsZXMgYW5kIG9uZSBmb3IgdGhlICR5JC12YXJpYWJsZXMsIGFuZCBwbG90IHRoZSByZXN1bHQsIHdpdGggdGhlICR4JC1kYXRhIHBsb3R0ZWQgYWxvbmcgdGhlIGhvcml6b250YWwgYXhpcywgYW5kIHRoZSAkeSQtZGF0YSBwbG90dGVkIGFsb25nIHRoZSB2ZXJ0aWNhbCBheGlzLgpgYGB7cn0KWDE8LWMoMS4yLDEuNSwxLjYsMi4xLDIuMSwyLjQsMi41LDIuOSwzLjEsMy44LDQuMSkKWTE8LWMoMTAuMywxMC40NSwxMC43OSwxMC44LDExLjAsMTEuMiwxMS41LDEyLjIsMTIuNCwxMy4wLDEzLjQpCnBsb3QoWDEsWTEseGxhYj0ieCIseWxhYj0ieSIsY29sPSJyZWQiLCBtYWluPSJMaW5lYXJseSBDb3JyZWxhdGVkIERhdGEiLHBjaD0xOCkKYGBgCiMjIyMgUmVtYXJrczogClRoZSBhcmd1bWVudCBfX3BjaF9fIGFsbG93cyB1cyB0byBjaGFuZ2UgdGhlIHR5cGUgb2YgbWFya2VyIHVzZWQgdG8gcGxvdCB0aGUgZGF0YSBwb2ludHMuIAoKICAxLiBUaGVyZSBhIDI1IG9wdGlvbnMgYXZhaWxhYmxlLCBqdXN0IGJ5IHNlbGVjdGluZyB0aGUgdmFsdWVzIGZyb20gMSB0byAyNS4KICAyLiBBbHRlcm5hdGl2ZWx5LCBpdCBpcyBwb3NzaWJsZSB0byBzZXQgZWFjaCBtYXJrZXIgdG8gYSBzaW5nbGUgbGV0dGVyIG9yIHN5bWJvbC4gRm9yIGluc3RhbmNlIHRvIHNldCBlYWNoIG1hcmtlciB0byBfX8KjX18gd2UgY291bGQgdXNlIF9fcGNoPSLCoyJfXwogIAojIyMgQ29ycmVsYXRlZCBEYXRhCiAgKiBJdCBpcyBjbGVhciBmcm9tIHRoZSBzY2F0dGVyIHBsb3QgdGhhdCBhcyAkeCQgaW5jcmVhc2VzIHRoZSAkeSQgdmFsdWVzIGFsc28gdGVuZCB0byBpbmNyZWFzZS4KCiAgKiBJdCBhbHNvIHNlZW1zIGNsZWFyIGZyb20gdGhlIHBsb3QgdGhhdCBhIHN0cmFpZ2h0IGxpbmUgY2FuIGJlIGRyYXduIHRocm91Z2ggdGhlIGRhdGEgcG9pbnRzLCB3aGljaCB3ZSB3b3VsZCBpbnRlcnByZXQgdG8gbWVhbiB0aGVyZSBleGlzdHMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlICR4JCBhbmQgJHkkIHZhcmlhYmxlcywgb2YgdGhlIGZvcm0KXFsKeT1hICtiIHguClxdCgoKCiMjIyBFeGFtcGxlIDIgLSBOb24tY29ycmVsYXRlZCBEYXRhCkluIHRoaXMgZXhhbXBsZSB3ZSB3aWxsIHBsb3QgdGhlIGZvbGxvd2luZyBkYXRhIHNldApcWwooLTEuNCwyLjQpLCAoMC40LDEuMyksICgxLjQsNi41KSwgKDIuMSwzLjQpLCAoNC41LDEyLjMpLCAoNS4yLCAyLjEpLCAoNS44LDMuMSksICg2LjUsNS40KSwgKDYuOSwgNi43KQpcXQoKYGBge3J9ClgyPC1jKC0xLjQsMC40LDEuNCwyLjEsNC41LDUuMiw1LjgsNi41LDYuOSkKWTI8LWMoMi40LDEuMyw2LjUsMy40LDEyLjMsMi4xLDMuMSwxMy40LDYuNykKcGxvdChYMixZMix4bGFiPSJ4Iix5bGFiPSJ5Iixjb2w9InJlZCIsIG1haW49Ik5vbi1jb3JyZWxhdGVkIERhdGEiLHBjaD0xOSkKYGBgCiogSXQgaXMgY2xlYXIgZnJvbSB0aGUgc2NhdHRlciBwbG90IHRoYXQgdGhlcmUgaXMgbm8gaW1tZWRpYXRlbHkgb2J2aW91cyB0cmVuZCByZWxhdGluZyB0aGUgJHgkIGFuZCAkeSQgdmFyaWFibGVzIGluIHRoaXMgcGxvdCwgaW4gd2hpY2ggY2FzZSB3ZSBzYXkgdGhlICR4JCBhbmQgJHkkIHZhcmlhYmxlcyBhcmUgX19ub3QgY29ycmVsYXRlZF9fLgoKKiBXaGlsZSB0aGUgc2NhdHRlciBwbG90IGRvZXNuJ3QgcnVsZSBvdXQgYSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSAkeCQgYW5kICR5JCB2YXJpYWJsZXMsIGl0IGRvZXMgZ2l2ZSBhbiBpbml0aWFsIGluZGljYXRpb24gYXMgdG8gd2hldGhlciBvciBub3QgYSByZWxhdGlvbnNoaXAgZXhpc3RzLgoKCiMjIFRoZSBMaW5lIG9mIEJlc3QgRml0CgoqIEdpdmVuIHRoZSBkYXRhIHNldCBhYm92ZSwgdGhlcmUgYXJlIHZhbHVlcyBvZiB0aGUgZXN0aW1hdGVkIHBhcmFtZXRlcnMgJFxoYXR7XGJldGF9XzAkIGFuICRcaGF0e1xiZXRhfV8xJCB3aGljaCB3aWxsIHlpZWxkIGEgbGluZSB3aGljaCBiZXN0IGZpdHMgdGhlIHBvaW50cyBvZiB0aGUgZGF0YSBwbG90LgoKKiBPbmUgd2F5IHRvIGZpbmQgYSBsaW5lIHdoaWNoIHBhc3NlcyB0aHJvdWdoIG9yIGNsb3NlIHRvIHRoZXNlIGRhdGEgcG9pbnQgaXMgdG8gb2J0YWluIHRoZSBsaWUgc2xvcGUgZnJvbSB0aGUgZmlyc3QgYW5kIGxhc3QgZGF0YSBwb2ludHMgYXMgZm9sbG93czoKXFsKYj1cZnJhY3s2LjctMi40fXs2LjkrMS40fT1cZnJhY3s0LjN9ezguM309MC41MTguClxdCgoqIFRha2luZyB0aGUgbWVhbiBvZiB0aGUgJHgkIGFuZCAkeSQgZGF0YSwgd2UgaGF2ZQpgYGB7cn0KbWVhbihYMSkKbWVhbihZMSkKYGBgCiogVGhpcyBub3cgYWxsb3dzIHVzIHRvIGZpbmQgYW4gZXN0aW1hdGUgZm9yIHRoZSBwYXJhbWV0ZXIgJFxiZXRhXzAkIGFzIGZvbGxvd3MKXFsKXGJhcnt5fT1hK2JcYmFye3h9XFJpZ2h0YXJyb3cgMTEuNTQ5MDk9YSswLjUxOFx0aW1lcyAyLjQ4MTgxOCBcUmlnaHRhcnJvdyBhPTEwLjI2MzUuClxdCgoqIE91ciBmaXJzdCBhcHByb3hpbWF0aW9uIGF0IGEgbGluZWFyIG1vZGVsIHJlbGF0aW5nIHRoZSAkeCQgYW5kICR5JCBkYXRhIGlzIG5vdyBnaXZlbiBieQpcW3k9MTAuMjYzNSswLjUxOHhcXQoKKiBXZSBub3cgcGxvdCB0aGlzIGxpbmUgdGhyb3VnaCB0aGUgZGF0YSBwb2ludHMgYXMgZm9sbG93czoKXFt4PTBcUmlnaHRhcnJvdyB5PTEwLjI2MzVccXF1YWQgeD01XFJpZ2h0YXJyb3cgeT0xMi44NTM1XF0KYGBge3J9ClgxPC1jKDEuMiwxLjUsMS42LDIuMSwyLjEsMi40LDIuNSwyLjksMy4xLDMuOCw0LjEpClkxPC1jKDEwLjMsMTAuNDUsMTAuNzksMTAuOCwxMS4wLDExLjIsMTEuNSwxMi4yLDEyLjQsMTMuMCwxMy40KQpwbG90KFgxLFkxLHhsYWI9IngiLHlsYWI9InkiLGNvbD0icmVkIixtYWluPSJMaW5lYXJseSBDb3JyZWxhdGVkIERhdGEiLHBjaD0xOCkKc2VnbWVudHMoMCwxMC4yNjM1LHgxPTUseTE9MTIuODUzNSxjb2wgPSJibHVlIixsd2Q9MikKYGBgCiogQ2xlYXJseSwgdGhpcyBsaW5lIGRvZXNuJ3QgZml0IHRoZSBkYXRhIHZlcnkgd2VsbCwgYW5kIHRoZXJlIGFyZSBiZXR0ZXIgYXBwcm94aW1hdGlvbnMgYXZhaWxhYmxlIHRvIHJlcHJlc2VudCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdG8gJHgkIGFuZCAkeSQgZGF0YS4gCgojIyBUaGUgTWV0aG9kIG9mIExlYXN0IFNxdWFyZXMKCmBgYHtyfQpYMTwtYygxLjIsMS41LDEuNiwyLjEsMi4xLDIuNCwyLjUsMi45LDMuMSwzLjgsNC4xKQpZMTwtYygxMC4zLDEwLjQ1LDEwLjc5LDEwLjgsMTEuMCwxMS4yLDExLjUsMTIuMiwxMi40LDEzLjAsMTMuNCkKcGxvdChYMSxZMSx4bGFiPSJ4Iix5bGFiPSJ5Iixjb2w9InJlZCIsbWFpbj0iTGluZWFybHkgQ29ycmVsYXRlZCBEYXRhIixwY2g9MTgpCnNlZ21lbnRzKFgxLFkxLHgxPVgxLHkxPTEwLjI2MzUrMC41MTgqWDEsY29sID0iZGFya2dyZWVuIixsd2Q9MikKc2VnbWVudHMoMCwxMC4yNjM1LHgxPTUseTE9MTIuODUzNSxjb2wgPSJibHVlIixsd2Q9MikKYGBgCiogVGhlIF9fTWV0aG9kIG9mIExlYXN0IFNxdWFyZXNfXyBpcyBtZXRob2QgdG8gY2hvb3NlIHZhbHVlcyBvZiB0aGUgcGFyYW1ldGVycyAkYSQgYW5kICRiJCB3aGljaCByZXR1cm5zIHRoZSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwKXFt5PWErYnguXF0KKiBFdmFsdWF0aW5nIHRoZSB2YWx1ZXMgb2YgJHkkIGF0IGVhY2ggb2YgdGhlIGRhdGEgdmFsdWVzICR4XzEsXGxkb3RzLHhfezExfSQgZ2l2ZXMgY29ycmVzcG9uZGluZyB2YWx1ZXMgJFxoYXR7eX1fMT1hK2J4XzEsJC4uLiwgJFxoYXR7eX1fezExfT1hK2J4X3sxMX0kCiogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGVzZSBfX3ByZWRpY3RlZCB2YWx1ZXNfXyBhbmQgdGhlIF9fYWN0dWFsIGRhdGEgdmFsdWVzX18gaXMgZ2l2ZW4gYnkKJFxoYXR7eX1fMS15XzEkLC4uLiwkXGhhdHt5fV97MTF9LXlfezExfSQuCiogVGhlIG1ldGhvZCBvZiBsZWFzdCBzcXVhcmVzIGlzIHRoZSBtZWFucyBvZiBjaG9vc2luZyB2YWx1ZXMgZm9yICRhJCBhbmQgJGIkIHNvIHRoYXQgdGhlIF9fc3VtIG9mIHRoZSBzcXVhcmVzIG9mIHRoZXNlIGRpZmZlcmVuY2VzX18gaXMgbWluaW1pc2VkLCBpLmUuClxbKFxoYXR7eX1fMS15XzEpXjIrXGxkb3RzKyhcaGF0e3l9X3sxMX0teV97MTF9KV4yXF0KaXMgdGhlIHNtYWxsZXN0IHZhbHVlIHBvc3NpYmxlLgoqIEluIHRlcm1zIG9mIHRoZSBncmFwaCBhYm92ZSBpdCBtZWFucyB3ZSBoYXZlIGNob3NlbiB0aGUgYmx1ZSBsaW5lIHNvIHRoYXQgdGhlIF9fc3VtIG9mIHRoZSBsZW5naHRzIG9mIGVhY2ggZ3JlZW4gbGluZSBzZWdtZW50IHNxdWFyZWRfXyBpcyB0aGUgbWluaW11bSBwb3NzaWJsZSB2YWx1ZS4gCiogVGhlIHZhbHVlIGZvciAkYiQgaXMgb2J0YWluZWQgYnkgbWVhbnMgb2YgZmFpcmx5IHN0cmFpZ2h0IGZvcndhcmQgY2FsY3VsdXMsIHdoaWNoIHdlIG9taXQgaGVyZSwgYnV0IHdoaWNoIGdpdmVzIHRoZSByZXN1bHQKXFtiPVxmcmFje25cc3VtX3tpPTF9XntufXhfaXlfaS1cc3VtX3tpPTF9XntufXhfaVxzdW1fe2k9MX1ee259eV9pfXtuXHN1bV97aT0xfV57bn14X2leMi1cbGVmdChcc3VtX3tpPTF9XntufXhfaVxyaWdodCleMn0uXF0KKiBUaGUgdmFsdWUgb2YgJGEkIGlzIG9idGFpbmVkIGZyb20gClxbXGJhcnt5fT1hK2JcYmFye3h9XFJpZ2h0YXJyb3cgYT1cYmFye3l9LWJcYmFye3h9LlxdCgoqIFRoZXNlIHBhcmFtZXRlcnMgYXJlIG9idGFpbmVkIGF1dG9tYXRpY2FsbHkgZm9yIHVzIGZyb20gdGhlIGRhdGEgc2V0IHVzaW5nIHRoZSBfX2xtKClfXyBmdW5jdGlvbjoKYGBge3J9Ck1vZGVsMTwtbG0oWTEgfiBYMSkKTW9kZWwxCmBgYAoqIEhlbmNlIHRoZSB2YWx1ZXMgb2YgdGhlIHBhcmFtZXRlcnMgYXJlIGdpdmVuIGJ5ClxbCmE9OC43ODRccXF1YWQgYj0xLjExNApcXQoqIExhc3RseSwgd2UgY2FuIHBsb3QgdGhlIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbApcW3k9OC43ODQrMS4xMTR4XF0Kb250byBvdXIgc2NhdHRlciBwbG90IGFzIGZvbGxvd3M6CmBgYHtyfQpwbG90KFgxLFkxLGNvbD0icmVkIixwY2g9MTgpCmFibGluZShNb2RlbDEsY29sPSJkYXJrZ3JlZW4iKQpgYGAKCiMjIEV4YW1wbGUgMyAtIEZyb20gTGVjdHVyZXMKV2Ugd2VyZSBnaXZlbiB0aGUgZm9sbG93aW5nIGRhdGEgcmVsYXRpbmcgV2Vla2x5IE5hdHVyYWwgR2FzIENvbnN1bXB0aW9uIGluIGEgVS5TLiBjaXR5IGFsb25nIHdpdGggdGhlIEhvdXJseSBBdmVyYWdlIFRlbXBlcmF0dXJlIGluIHRoYXQgY2l0eSBmb3IgdGhlIHNhbWUgd2Vlay4KCnwgX19XZWVrX18gfCBfX0hvdXJseSBBdmcuIFRlbXAuICgkXntcY2lyY30kRilfXyAgICAgfCBfX1dlZWtseSBOYXR1cmFsIEdhcyBDb25zdW1wdGlvbiAoTU1jZilfXyB8CnwtLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgICAgIDEgICAgfCAgICAgICAgICAgICAgMjguMCAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAxMi40ICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDIgICAgfCAgICAgICAgICAgICAgMjguMCAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAxMS43ICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDMgICAgfCAgICAgICAgICAgICAgMzIuNSAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAxMi40ICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDQgICAgfCAgICAgICAgICAgICAgMzkuMCAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAxMC44ICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDUgICAgfCAgICAgICAgICAgICAgNDUuOSAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICA5LjQgICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDYgICAgfCAgICAgICAgICAgICAgNTcuOCAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICA5LjUgICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDcgICAgfCAgICAgICAgICAgICAgNTguMSAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICA4LjAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgIDggICAgfCAgICAgICAgICAgICAgNjIuNSAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICA3LjUgICAgICAgICAgICAgICAgICAgICB8CgpVc2luZyB0aGlzIGRhdGEgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBDcmVhdGUgYSBkYXRhIGZpbGUgdG8gcmVwcmVzZW50IHRoaXMgZGF0YS4KMi4gSW1wb3J0IHRoaXMgZGF0YSBpbnRvIF9fUl9fLgozLiBDcmVhdGUgdHdvIGRhdGEgdmVjdG9ycyBjb3JyZXNwb25kaW5nIHRvIHRlbXBlcmF0dXJlIGFuZCBjb25zdW1wdGlvbi4KNC4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHRvIHJlcHJlc2VudCB0aGlzIGRhdGEKNS4gVXNlIHRoZSBfX2xtKClfXyBmdW5jdGlvbiB0byBjcmVhdGUgYSBsaW5lYXIgbW9kZWwgZm9yIHRoZXNlIGRhdGEgdmVjdG9ycy4KNi4gVXNpbmcgdGhpcyBtb2RlbCBlc3RpbWF0ZSB0aGUgcGFyYW1ldGVycyAkXGhhdHtcYmV0YX1fMCQgYW5kICRcaGF0e1xiZXRhfV8xJCBmb3IgdGhlIHNpbXBsZSBsaW5lYXIgbW9kZWwuCjcuIFBsb3QgdGhlIGxpbmUgb2YgYmVzdCBmaXQgYWxvbmcgd2l0aCB0aGUgc2NhdHRlciBwbG90IGZvciB0aGUgZGF0YSBzZXQuCgojIyBTb2x1dGlvbjoKCjEuIFRoZSBkYXRhIGZpbGUgZm9yIHRoaXMgZGF0YSBzZXQgaXMgYXZhaWxhYmxlIG9uIE1vb2RsZSBhbmQgaXMgY2FsbGVkIF9fRnVlbENvbnN1bXB0aW9uLmNzdl9fCgoyLiAKYGBge3J9CkZ1ZWxEYXRhPC1yZWFkLmNzdigiRnVlbENvbnN1bXB0aW9uLmNzdiIpCmBgYAoKYGBge3J9CkZ1ZWxEYXRhCmBgYAozLgpgYGB7cn0KVGVtcDwtRnVlbERhdGEkVGVtcApUZW1wCmBgYAoKYGBge3J9CkZ1ZWw8LUZ1ZWxEYXRhJEZ1ZWwKRnVlbApgYGAKNC4gCmBgYHtyfQpwbG90KFRlbXAsRnVlbCxjb2w9InJlZCIscGNoPTE4KQpgYGAKCjUuCmBgYHtyfQpGdWVsTW9kZWw8LWxtKEZ1ZWwgfiBUZW1wKQpGdWVsTW9kZWwKYGBgCgo2LgpUaGUgcGFyYW1ldGVycyBvZiB0aGUgRnVlbCBNb2RlbCBhcmUKXFthPTE1LjgzNzlccXVhZCBiPS0wLjEyNzkuXF0KCjcuCmBgYHtyfQpwbG90KFRlbXAsRnVlbCxjb2w9InJlZCIscGNoPTE4KQphYmxpbmUoRnVlbE1vZGVsLGNvbD0iZGFya2dyZWVuIikKYGBgCgojIEV4ZXJjaXNlcwoKIyMgRXhlcmNpc2UgMSAtIE1vb2RsZSAtIFByb2JsZW0gU2V0IDUgLUV4ZXJjaXNlIDEKVXNpbmcgdGhlIGRhdGEgdGFibGUgZ2l2ZW4gaW4gX19Qcm9ibGVtIFNldCA1IC0tIEV4ZXJjaXNlIDFfXyBhbnN3ZXIgdGhlIGZvbGxvd2luZzoKCjEuIElkZW50aWZ5IHRoZSBkZXBlbmRlbnQgYW5kIGluZGVwZW5kZW50IHZhcmlhYmxlcy4KMi4gQ3JlYXRlIGEgX18uY3N2X18gZmlsZSB0byByZXByZXNlbnQgdGhpcyBkYXRhLgozLiBJbXBvcnQgdGhpcyBkYXRhIGZpbGUgaW50byBfX1JfXy4KNC4gQ3JlYXRlIHR3byBkYXRhIHZlY3RvcnMgZnJvbSB0aGVzZSBkYXRhIHNldC4KNS4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHVzaW5nIHRoZXNlIGRhdGEgdmVjdG9ycy4KNi4gVXNlIHRoZSBfX2xtKClfXyBmdW5jdGlvbiB0byBjcmVhdGUgYSBsaW5lYXIgbW9kZWwgZm9yIHRoZXNlIGRhdGEgdmVjdG9ycy4KNy4gVXNpbmcgdGhpcyBtb2RlbCBlc3RpbWF0ZSB0aGUgcGFyYW1ldGVycyAkXGhhdHtcYmV0YX1fMCQgYW5kICRcaGF0e1xiZXRhfV8xJCBmb3IgbGluZSBvZiBiZXN0IGZpdC4KOC4gUGxvdCB0aGUgbGluZSBvZiBiZXN0IGZpdCBhbG9uZyB3aXRoIHRoZSBzY2F0dGVyIHBsb3QgZm9yIHRoZSBkYXRhIHNldC4KCiMjIEV4ZXJjaXNlIDIgLSBNb29kbGUgLSBQcm9ibGVtIFNldCA1IC0gRXhlcmNpc2UgMgpVc2luZyB0aGUgZGF0YSB0YWJsZSBnaXZlbiBpbiBfX1Byb2JsZW0gU2V0IDUgLS0gRXhlcmNpc2UgMl9fIGFuc3dlciB0aGUgZm9sbG93aW5nOgoKMS4gSWRlbnRpZnkgdGhlIGRlcGVuZGVudCBhbmQgaW5kZXBlbmRlbnQgdmFyaWFibGVzLgoyLiBDcmVhdGUgYSBfXy5jc3ZfXyBmaWxlIHRvIHJlcHJlc2VudCB0aGlzIGRhdGEuCjMuIEltcG9ydCB0aGlzIGRhdGEgZmlsZSBpbnRvIF9fUl9fLgo0LiBDcmVhdGUgdHdvIGRhdGEgdmVjdG9ycyBmcm9tIHRoaXMgZGF0YSBzZXQuCjUuIENyZWF0ZSBhIHNjYXR0ZXIgcGxvdCB1c2luZyB0aGVzZSBkYXRhIHZlY3RvcnMuCjYuIFVzZSB0aGUgX19sbSgpX18gZnVuY3Rpb24gdG8gY3JlYXRlIGEgbGluZWFyIG1vZGVsIGZvciB0aGVzZSBkYXRhIHZlY3RvcnMuCjcuIFVzaW5nIHRoaXMgbW9kZWwgZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgJFxoYXR7XGJldGF9XzAkIGFuZCAkXGhhdHtcYmV0YX1fMSQgZm9yIGxpbmUgb2YgYmVzdCBmaXQuCjguIFBsb3QgdGhlIGxpbmUgb2YgYmVzdCBmaXQgYWxvbmcgd2l0aCB0aGUgc2NhdHRlciBwbG90IGZvciB0aGUgZGF0YSBzZXQuCgojIyBFeGVyY2lzZSAzCgpVc2luZyB0aGUgZGF0YSBpbiB0aGUgZmlsZXMgX19JcmVsYW5kSW5mbGF0aW9uX18gYW5kIF9fSXJlbGFuZEVtaXNzaW9uc19fIGF2YWlsYWJsZSBvbiBNb29kbGUgYW5zd2VyIHRoZSBmb2xsb3dpbmcKCjEuIEltcG9ydCB0aGVzZSB0d28gZGF0YSBmaWxlcyBpbnRvIF9fUl9fIGFzIHR3byBzZXBhcmF0ZSBkYXRhIHN0cnVjdHVyZXMuCjIuIEV4dHJhY3QgdGhlIGRhdGEgZm9yIF9fQ08yIEVtaXNzaW9uc19fIGFuZCB0aGUgZGF0YSBmb3IgX19JbmZsYXRpb25SYXRlX18gYXMgdHdvIHNlcGFyYXRlIGRhdGEgc3RydWN0dXJlcy4KMy4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IGZvciBlYWNoIG9mIHRoZXNlIGRhdGEgdmVjdG9ycy4KNC4gRG9lcyB0aGVyZSBhcHBlYXIgdG8gYmUgY29ycmVsYXRpb24gYmV0d2VlbiBpbmZsYXRpb24gYW5kIENPMiBlbWlzc2lvbnMsIGZyb20gdGhlIGRhdGE/CjUuIFVzZSB0aGUgX19sbSgpX18gZnVuY3Rpb24gdG8gY3JlYXRlIGEgbGluZWFyIG1vZGVsIGZvciB0aGVzZSBkYXRhIHZlY3RvcnMuCjYuIFVzZSB0aGlzIG1vZGVsIHRvIGVzdGltYXRlIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgbGluZSBvZiBiZXN0IGZpdC4KNy4gUGxvdCB0aGlzIGxpbmUgb2YgYmVzdCBmaXQgYWxvbmcgd2l0aCB0aGUgc2NhdHRlciBwbG90LiA=