edX assignment link: http://bit.ly/2KE2g00

There have been many studies documenting that the average global temperature has been increasing over the last century. The consequences of a continued rise in global temperature will be dire. Rising sea levels and an increased frequency of extreme weather events will affect billions of people.

In this problem, we will attempt to study the relationship between average global temperature and several other factors.

The file climate_change.csv contains climate data from May 1983 to December 2008. The available variables include:

CO2, N2O and CH4 are expressed in ppmv (parts per million by volume – i.e., 397 ppmv of CO2 means that CO2 constitutes 397 millionths of the total volume of the atmosphere) CFC.11 and CFC.12 are expressed in ppbv (parts per billion by volume).


Section 1 - Creating Our First Model

1.1

We are interested in how changes in these variables affect future temperatures, as well as how well these variables explain temperature changes so far. To do this, first read the dataset climate_change.csv into R.

Then, split the data into a training set, consisting of all the observations up to and including 2006, and a testing set consisting of the remaining years (hint: use subset). A training set refers to the data that will be used to build the model (this is the data we give to the lm() function), and a testing set refers to the data we will use to test our predictive ability.

Next, build a linear regression model to predict the dependent variable Temp, using MEI, CO2, CH4, N2O, CFC.11, CFC.12, TSI, and Aerosols as independent variables (Year and Month should NOT be used in the model). Use the training set to build the model.

Enter the model R2 (the “Multiple R-squared” value):

climate_change = read.csv("D:/buiness_analytics/unit2/data/climate_change.csv")
str(climate_change)
'data.frame':   308 obs. of  11 variables:
 $ Year    : int  1983 1983 1983 1983 1983 1983 1983 1983 1984 1984 ...
 $ Month   : int  5 6 7 8 9 10 11 12 1 2 ...
 $ MEI     : num  2.556 2.167 1.741 1.13 0.428 ...
 $ CO2     : num  346 346 344 342 340 ...
 $ CH4     : num  1639 1634 1633 1631 1648 ...
 $ N2O     : num  304 304 304 304 304 ...
 $ CFC.11  : num  191 192 193 194 194 ...
 $ CFC.12  : num  350 352 354 356 357 ...
 $ TSI     : num  1366 1366 1366 1366 1366 ...
 $ Aerosols: num  0.0863 0.0794 0.0731 0.0673 0.0619 0.0569 0.0524 0.0486 0.0451 0.0416 ...
 $ Temp    : num  0.109 0.118 0.137 0.176 0.149 0.093 0.232 0.078 0.089 0.013 ...
train_data = subset(climate_change , Year <= 2006)
test_data = subset(climate_change, Year > 2006)
model1 = lm(Temp~MEI+CO2+CH4+N2O+CFC.11+CFC.12+TSI+Aerosols,data = train_data)
summary(model1)

Call:
lm(formula = Temp ~ MEI + CO2 + CH4 + N2O + CFC.11 + CFC.12 + 
    TSI + Aerosols, data = train_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.25888 -0.05913 -0.00082  0.05649  0.32433 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.246e+02  1.989e+01  -6.265 1.43e-09 ***
MEI          6.421e-02  6.470e-03   9.923  < 2e-16 ***
CO2          6.457e-03  2.285e-03   2.826  0.00505 ** 
CH4          1.240e-04  5.158e-04   0.240  0.81015    
N2O         -1.653e-02  8.565e-03  -1.930  0.05467 .  
CFC.11      -6.631e-03  1.626e-03  -4.078 5.96e-05 ***
CFC.12       3.808e-03  1.014e-03   3.757  0.00021 ***
TSI          9.314e-02  1.475e-02   6.313 1.10e-09 ***
Aerosols    -1.538e+00  2.133e-01  -7.210 5.41e-12 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.09171 on 275 degrees of freedom
Multiple R-squared:  0.7509,    Adjusted R-squared:  0.7436 
F-statistic: 103.6 on 8 and 275 DF,  p-value: < 2.2e-16
test_result = predict(model1, newdata = test_data)
summary(test_result)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.3139  0.3437  0.3762  0.3835  0.4238  0.4686 

1.2

Which variables are significant in the model? We will consider a variable signficant only if the p-value is below 0.05. (Select all that apply.)

  • MEI
  • CO2
  • CH4
  • N2O
  • CFC.11
  • CFC.12
  • TSI
  • Aerosols
  • unanswered
#MEI          6.421e-02  6.470e-03   9.923  < 2e-16 *** ->顯著
#CO2          6.457e-03  2.285e-03   2.826  0.00505 ** 
#CH4          1.240e-04  5.158e-04   0.240  0.81015    
#N2O         -1.653e-02  8.565e-03  -1.930  0.05467 .  
#CFC.11      -6.631e-03  1.626e-03  -4.078 5.96e-05 *** ->顯著
#CFC.12       3.808e-03  1.014e-03   3.757  0.00021 *** ->顯著
#TSI          9.314e-02  1.475e-02   6.313 1.10e-09 *** ->顯著
#Aerosols    -1.538e+00  2.133e-01  -7.210 5.41e-12 *** ->顯著

Section 2 - Understanding the Model

Current scientific opinion is that nitrous oxide and CFC-11 are greenhouse gases: gases that are able to trap heat from the sun and contribute to the heating of the Earth. However, the regression coefficients of both the N2O and CFC-11 variables are negative, indicating that increasing atmospheric concentrations of either of these two compounds is associated with lower global temperatures.

2.1

Which of the following is the simplest correct explanation for this contradiction?

  • Climate scientists are wrong that N2O and CFC-11 are greenhouse gases - this regression analysis constitutes part of a disproof.

  • There is not enough data, so the regression coefficients being estimated are not accurate.

  • All of the gas concentration variables reflect human development - N2O and CFC.11 are correlated with other variables in the data set.

str(train_data)
'data.frame':   284 obs. of  11 variables:
 $ Year    : int  1983 1983 1983 1983 1983 1983 1983 1983 1984 1984 ...
 $ Month   : int  5 6 7 8 9 10 11 12 1 2 ...
 $ MEI     : num  2.556 2.167 1.741 1.13 0.428 ...
 $ CO2     : num  346 346 344 342 340 ...
 $ CH4     : num  1639 1634 1633 1631 1648 ...
 $ N2O     : num  304 304 304 304 304 ...
 $ CFC.11  : num  191 192 193 194 194 ...
 $ CFC.12  : num  350 352 354 356 357 ...
 $ TSI     : num  1366 1366 1366 1366 1366 ...
 $ Aerosols: num  0.0863 0.0794 0.0731 0.0673 0.0619 0.0569 0.0524 0.0486 0.0451 0.0416 ...
 $ Temp    : num  0.109 0.118 0.137 0.176 0.149 0.093 0.232 0.078 0.089 0.013 ...
cor(train_data[3:11])
                  MEI         CO2        CH4         N2O      CFC.11       CFC.12
MEI       1.000000000 -0.04114717 -0.0334193 -0.05081978  0.06900044  0.008285544
CO2      -0.041147165  1.00000000  0.8772796  0.97671982  0.51405975  0.852689627
CH4      -0.033419301  0.87727963  1.0000000  0.89983864  0.77990402  0.963616248
N2O      -0.050819775  0.97671982  0.8998386  1.00000000  0.52247732  0.867930776
CFC.11    0.069000439  0.51405975  0.7799040  0.52247732  1.00000000  0.868985183
CFC.12    0.008285544  0.85268963  0.9636162  0.86793078  0.86898518  1.000000000
TSI      -0.154491923  0.17742893  0.2455284  0.19975668  0.27204596  0.255302814
Aerosols  0.340237787 -0.35615480 -0.2678092 -0.33705457 -0.04392120 -0.225131244
Temp      0.172470751  0.78852921  0.7032550  0.77863893  0.40771029  0.687557548
                 TSI    Aerosols       Temp
MEI      -0.15449192  0.34023779  0.1724708
CO2       0.17742893 -0.35615480  0.7885292
CH4       0.24552844 -0.26780919  0.7032550
N2O       0.19975668 -0.33705457  0.7786389
CFC.11    0.27204596 -0.04392120  0.4077103
CFC.12    0.25530281 -0.22513124  0.6875575
TSI       1.00000000  0.05211651  0.2433827
Aerosols  0.05211651  1.00000000 -0.3849137
Temp      0.24338269 -0.38491375  1.0000000
#All of the gas concentration variables reflect human development - N2O and CFC.11 are correlated with other variables in the data set.

2.2

Compute the correlations between all the variables in the training set. Which of the following independent variables is N2O highly correlated with (absolute correlation greater than 0.7)? Select all that apply.

  • MEI
  • CO2
  • CH4
  • CFC.11
  • CFC.12
  • Aerosols
  • TSI
cor(train_data[3:11])
                  MEI         CO2        CH4         N2O      CFC.11       CFC.12
MEI       1.000000000 -0.04114717 -0.0334193 -0.05081978  0.06900044  0.008285544
CO2      -0.041147165  1.00000000  0.8772796  0.97671982  0.51405975  0.852689627
CH4      -0.033419301  0.87727963  1.0000000  0.89983864  0.77990402  0.963616248
N2O      -0.050819775  0.97671982  0.8998386  1.00000000  0.52247732  0.867930776
CFC.11    0.069000439  0.51405975  0.7799040  0.52247732  1.00000000  0.868985183
CFC.12    0.008285544  0.85268963  0.9636162  0.86793078  0.86898518  1.000000000
TSI      -0.154491923  0.17742893  0.2455284  0.19975668  0.27204596  0.255302814
Aerosols  0.340237787 -0.35615480 -0.2678092 -0.33705457 -0.04392120 -0.225131244
Temp      0.172470751  0.78852921  0.7032550  0.77863893  0.40771029  0.687557548
                 TSI    Aerosols       Temp
MEI      -0.15449192  0.34023779  0.1724708
CO2       0.17742893 -0.35615480  0.7885292
CH4       0.24552844 -0.26780919  0.7032550
N2O       0.19975668 -0.33705457  0.7786389
CFC.11    0.27204596 -0.04392120  0.4077103
CFC.12    0.25530281 -0.22513124  0.6875575
TSI       1.00000000  0.05211651  0.2433827
Aerosols  0.05211651  1.00000000 -0.3849137
Temp      0.24338269 -0.38491375  1.0000000
#Anser = CO2,CH4,CFC.12

Which of the following independent variables is CFC.11 highly correlated with? Select all that apply.

  • MEI
  • CO2
  • CH4
  • CFC.11
  • CFC.12
  • Aerosols
  • TSI
cor(train_data[3:11])
                  MEI         CO2        CH4         N2O      CFC.11       CFC.12
MEI       1.000000000 -0.04114717 -0.0334193 -0.05081978  0.06900044  0.008285544
CO2      -0.041147165  1.00000000  0.8772796  0.97671982  0.51405975  0.852689627
CH4      -0.033419301  0.87727963  1.0000000  0.89983864  0.77990402  0.963616248
N2O      -0.050819775  0.97671982  0.8998386  1.00000000  0.52247732  0.867930776
CFC.11    0.069000439  0.51405975  0.7799040  0.52247732  1.00000000  0.868985183
CFC.12    0.008285544  0.85268963  0.9636162  0.86793078  0.86898518  1.000000000
TSI      -0.154491923  0.17742893  0.2455284  0.19975668  0.27204596  0.255302814
Aerosols  0.340237787 -0.35615480 -0.2678092 -0.33705457 -0.04392120 -0.225131244
Temp      0.172470751  0.78852921  0.7032550  0.77863893  0.40771029  0.687557548
                 TSI    Aerosols       Temp
MEI      -0.15449192  0.34023779  0.1724708
CO2       0.17742893 -0.35615480  0.7885292
CH4       0.24552844 -0.26780919  0.7032550
N2O       0.19975668 -0.33705457  0.7786389
CFC.11    0.27204596 -0.04392120  0.4077103
CFC.12    0.25530281 -0.22513124  0.6875575
TSI       1.00000000  0.05211651  0.2433827
Aerosols  0.05211651  1.00000000 -0.3849137
Temp      0.24338269 -0.38491375  1.0000000
#Anser = CH4,CFC.12

Section 3 - Simplifying the Model

Given that the correlations are so high, let us focus on the N2O variable and build a model with only MEI, TSI, Aerosols and N2O as independent variables. Remember to use the training set to build the model.

Enter the coefficient of N2O in this reduced model:

model_n2o = lm(Temp~MEI+TSI+Aerosols+N2O, data = train_data)
summary(model_n2o)

Call:
lm(formula = Temp ~ MEI + TSI + Aerosols + N2O, data = train_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.27916 -0.05975 -0.00595  0.05672  0.34195 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.162e+02  2.022e+01  -5.747 2.37e-08 ***
MEI          6.419e-02  6.652e-03   9.649  < 2e-16 ***
TSI          7.949e-02  1.487e-02   5.344 1.89e-07 ***
Aerosols    -1.702e+00  2.180e-01  -7.806 1.19e-13 ***
N2O          2.532e-02  1.311e-03  19.307  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.09547 on 279 degrees of freedom
Multiple R-squared:  0.7261,    Adjusted R-squared:  0.7222 
F-statistic: 184.9 on 4 and 279 DF,  p-value: < 2.2e-16
#Anser = 2.532e-02

(How does this compare to the coefficient in the previous model with all of the variables?)

Enter the model R2:

#Anser = 0.7261

Section 4 - Automatically Building the Model

We have many variables in this problem, and as we have seen above, dropping some from the model does not decrease model quality. R provides a function, step, that will automate the procedure of trying different combinations of variables to find a good compromise of model simplicity and R2. This trade-off is formalized by the Akaike information criterion (AIC) - it can be informally thought of as the quality of the model with a penalty for the number of variables in the model.

The step function has one argument - the name of the initial model. It returns a simplified model. Use the step function in R to derive a new model, with the full model as the initial model (HINT: If your initial full model was called “climateLM”, you could create a new model with the step function by typing step(climateLM). Be sure to save your new model to a variable name so that you can look at the summary. For more information about the step function, type ?step in your R console.)

4.1

Enter the R2 value of the model produced by the step function:

step_model = step(model1)
Start:  AIC=-1348.16
Temp ~ MEI + CO2 + CH4 + N2O + CFC.11 + CFC.12 + TSI + Aerosols

           Df Sum of Sq    RSS     AIC
- CH4       1   0.00049 2.3135 -1350.1
<none>                  2.3130 -1348.2
- N2O       1   0.03132 2.3443 -1346.3
- CO2       1   0.06719 2.3802 -1342.0
- CFC.12    1   0.11874 2.4318 -1335.9
- CFC.11    1   0.13986 2.4529 -1333.5
- TSI       1   0.33516 2.6482 -1311.7
- Aerosols  1   0.43727 2.7503 -1301.0
- MEI       1   0.82823 3.1412 -1263.2

Step:  AIC=-1350.1
Temp ~ MEI + CO2 + N2O + CFC.11 + CFC.12 + TSI + Aerosols

           Df Sum of Sq    RSS     AIC
<none>                  2.3135 -1350.1
- N2O       1   0.03133 2.3448 -1348.3
- CO2       1   0.06672 2.3802 -1344.0
- CFC.12    1   0.13023 2.4437 -1336.5
- CFC.11    1   0.13938 2.4529 -1335.5
- TSI       1   0.33500 2.6485 -1313.7
- Aerosols  1   0.43987 2.7534 -1302.7
- MEI       1   0.83118 3.1447 -1264.9
summary(step_model)

Call:
lm(formula = Temp ~ MEI + CO2 + N2O + CFC.11 + CFC.12 + TSI + 
    Aerosols, data = train_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.25770 -0.05994 -0.00104  0.05588  0.32203 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.245e+02  1.985e+01  -6.273 1.37e-09 ***
MEI          6.407e-02  6.434e-03   9.958  < 2e-16 ***
CO2          6.402e-03  2.269e-03   2.821 0.005129 ** 
N2O         -1.602e-02  8.287e-03  -1.933 0.054234 .  
CFC.11      -6.609e-03  1.621e-03  -4.078 5.95e-05 ***
CFC.12       3.868e-03  9.812e-04   3.942 0.000103 ***
TSI          9.312e-02  1.473e-02   6.322 1.04e-09 ***
Aerosols    -1.540e+00  2.126e-01  -7.244 4.36e-12 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.09155 on 276 degrees of freedom
Multiple R-squared:  0.7508,    Adjusted R-squared:  0.7445 
F-statistic: 118.8 on 7 and 276 DF,  p-value: < 2.2e-16
#Anser = 0.7508

4.2

Which of the following variable(s) were eliminated from the full model by the step function? Select all that apply.

  • MEI
  • CO2
  • CH4
  • N2O
  • CFC.11
  • CFC.12
  • TSI
  • Aerosols
#lm(formula = Temp ~ MEI + CO2 + N2O + CFC.11 + CFC.12 + TSI + Aerosols, data = train_data)
#Anser = CH4

It is interesting to note that the step function does not address the collinearity of the variables, except that adding highly correlated variables will not improve the R2 significantly. The consequence of this is that the step function will not necessarily produce a very interpretable model - just a model that has balanced quality and simplicity for a particular weighting of quality and simplicity (AIC).

Section 5 - Testing on Unseen Data

We have developed an understanding of how well we can fit a linear regression to the training data, but does the model quality hold when applied to unseen data?

Using the model produced from the step function, calculate temperature predictions for the testing data set, using the predict function.

5.1

Enter the testing set R2:

test_model = predict(step_model, newdata = test_data)
summary(test_model)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.3142  0.3418  0.3771  0.3832  0.4245  0.4678 
SSE = sum(( test_model-test_data$Temp )^2)
SST = sum(( mean(train_data$Temp)-test_data$Temp )^2)
RQuare = 1 - SSE/SST
RQuare
[1] 0.6286051
#0.6286051
LS0tDQp0aXRsZTogIkFTMi0xIENsaW1hdGUgQ2hhbmdlIg0KYXV0aG9yOiAirEmq9j8/PyBNMDY0MDIwMDE3Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KZWRYIGFzc2lnbm1lbnQgbGluazogaHR0cDovL2JpdC5seS8yS0UyZzAwDQoNClRoZXJlIGhhdmUgYmVlbiBtYW55IHN0dWRpZXMgZG9jdW1lbnRpbmcgdGhhdCB0aGUgYXZlcmFnZSBnbG9iYWwgdGVtcGVyYXR1cmUgaGFzIGJlZW4gaW5jcmVhc2luZyBvdmVyIHRoZSBsYXN0IGNlbnR1cnkuIFRoZSBjb25zZXF1ZW5jZXMgb2YgYSBjb250aW51ZWQgcmlzZSBpbiBnbG9iYWwgdGVtcGVyYXR1cmUgd2lsbCBiZSBkaXJlLiBSaXNpbmcgc2VhIGxldmVscyBhbmQgYW4gaW5jcmVhc2VkIGZyZXF1ZW5jeSBvZiBleHRyZW1lIHdlYXRoZXIgZXZlbnRzIHdpbGwgYWZmZWN0IGJpbGxpb25zIG9mIHBlb3BsZS4NCg0KDQpJbiB0aGlzIHByb2JsZW0sIHdlIHdpbGwgYXR0ZW1wdCB0byBzdHVkeSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYXZlcmFnZSBnbG9iYWwgdGVtcGVyYXR1cmUgYW5kIHNldmVyYWwgb3RoZXIgZmFjdG9ycy4NCg0KDQpUaGUgZmlsZSBjbGltYXRlX2NoYW5nZS5jc3YgY29udGFpbnMgY2xpbWF0ZSBkYXRhIGZyb20gTWF5IDE5ODMgdG8gRGVjZW1iZXIgMjAwOC4gVGhlIGF2YWlsYWJsZSB2YXJpYWJsZXMgaW5jbHVkZToNCg0KDQorIFllYXI6IHRoZSBvYnNlcnZhdGlvbiB5ZWFyLg0KDQorIE1vbnRoOiB0aGUgb2JzZXJ2YXRpb24gbW9udGguDQoNCisgVGVtcDogdGhlIGRpZmZlcmVuY2UgaW4gZGVncmVlcyBDZWxzaXVzIGJldHdlZW4gdGhlIGF2ZXJhZ2UgZ2xvYmFsIHRlbXBlcmF0dXJlIGluIHRoYXQgcGVyaW9kIGFuZCBhIHJlZmVyZW5jZSB2YWx1ZS4gVGhpcyBkYXRhIGNvbWVzIGZyb20gdGhlIENsaW1hdGljIFJlc2VhcmNoIFVuaXQgYXQgdGhlIFVuaXZlcnNpdHkgb2YgRWFzdCBBbmdsaWEuDQoNCisgQ08yLCBOMk8sIENINCwgQ0ZDLjExLCBDRkMuMTI6IGF0bW9zcGhlcmljIGNvbmNlbnRyYXRpb25zIG9mIGNhcmJvbiBkaW94aWRlIChDTzIpLCBuaXRyb3VzIG94aWRlIChOMk8pLCBtZXRoYW5lICAoQ0g0KSwgdHJpY2hsb3JvZmx1b3JvbWV0aGFuZSAoQ0NsM0Y7IGNvbW1vbmx5IHJlZmVycmVkIHRvIGFzIENGQy0xMSkgYW5kIGRpY2hsb3JvZGlmbHVvcm9tZXRoYW5lIChDQ2wyRjI7IGNvbW1vbmx5IHJlZmVycmVkIHRvIGFzIENGQy0xMiksIHJlc3BlY3RpdmVseS4gVGhpcyBkYXRhIGNvbWVzIGZyb20gdGhlIEVTUkwvTk9BQSBHbG9iYWwgTW9uaXRvcmluZyBEaXZpc2lvbi4NCg0KQ08yLCBOMk8gYW5kIENINCBhcmUgZXhwcmVzc2VkIGluIHBwbXYgKHBhcnRzIHBlciBtaWxsaW9uIGJ5IHZvbHVtZSAgLS0gaS5lLiwgMzk3IHBwbXYgb2YgQ08yIG1lYW5zIHRoYXQgQ08yIGNvbnN0aXR1dGVzIDM5NyBtaWxsaW9udGhzIG9mIHRoZSB0b3RhbCB2b2x1bWUgb2YgdGhlIGF0bW9zcGhlcmUpDQpDRkMuMTEgYW5kIENGQy4xMiBhcmUgZXhwcmVzc2VkIGluIHBwYnYgKHBhcnRzIHBlciBiaWxsaW9uIGJ5IHZvbHVtZSkuIA0KDQorIEFlcm9zb2xzOiB0aGUgbWVhbiBzdHJhdG9zcGhlcmljIGFlcm9zb2wgb3B0aWNhbCBkZXB0aCBhdCA1NTAgbm0uIFRoaXMgdmFyaWFibGUgaXMgbGlua2VkIHRvIHZvbGNhbm9lcywgYXMgdm9sY2FuaWMgZXJ1cHRpb25zIHJlc3VsdCBpbiBuZXcgcGFydGljbGVzIGJlaW5nIGFkZGVkIHRvIHRoZSBhdG1vc3BoZXJlLCB3aGljaCBhZmZlY3QgaG93IG11Y2ggb2YgdGhlIHN1bidzIGVuZXJneSBpcyByZWZsZWN0ZWQgYmFjayBpbnRvIHNwYWNlLiBUaGlzIGRhdGEgaXMgZnJvbSB0aGUgR29kYXJkIEluc3RpdHV0ZSBmb3IgU3BhY2UgU3R1ZGllcyBhdCBOQVNBLg0KDQorIFRTSTogdGhlIHRvdGFsIHNvbGFyIGlycmFkaWFuY2UgKFRTSSkgaW4gVy9tMiAodGhlIHJhdGUgYXQgd2hpY2ggdGhlIHN1bidzIGVuZXJneSBpcyBkZXBvc2l0ZWQgcGVyIHVuaXQgYXJlYSkuIER1ZSB0byBzdW5zcG90cyBhbmQgb3RoZXIgc29sYXIgcGhlbm9tZW5hLCB0aGUgYW1vdW50IG9mIGVuZXJneSB0aGF0IGlzIGdpdmVuIG9mZiBieSB0aGUgc3VuIHZhcmllcyBzdWJzdGFudGlhbGx5IHdpdGggdGltZS4gVGhpcyBkYXRhIGlzIGZyb20gdGhlIFNPTEFSSVMtSEVQUEEgcHJvamVjdCB3ZWJzaXRlLg0KDQorIE1FSTogbXVsdGl2YXJpYXRlIEVsIE5pbm8gU291dGhlcm4gT3NjaWxsYXRpb24gaW5kZXggKE1FSSksIGEgbWVhc3VyZSBvZiB0aGUgc3RyZW5ndGggb2YgdGhlIEVsIE5pbm8vTGEgTmluYS1Tb3V0aGVybiBPc2NpbGxhdGlvbiAoYSB3ZWF0aGVyIGVmZmVjdCBpbiB0aGUgUGFjaWZpYyBPY2VhbiB0aGF0IGFmZmVjdHMgZ2xvYmFsIHRlbXBlcmF0dXJlcykuIFRoaXMgZGF0YSBjb21lcyBmcm9tIHRoZSBFU1JML05PQUEgUGh5c2ljYWwgU2NpZW5jZXMgRGl2aXNpb24uDQoNCg0KLSAtIC0NCg0KDQojIyMgU2VjdGlvbiAxIC0gQ3JlYXRpbmcgT3VyIEZpcnN0IE1vZGVsDQoNCiMjIyMgMS4xIA0KV2UgYXJlIGludGVyZXN0ZWQgaW4gaG93IGNoYW5nZXMgaW4gdGhlc2UgdmFyaWFibGVzIGFmZmVjdCBmdXR1cmUgdGVtcGVyYXR1cmVzLCBhcyB3ZWxsIGFzIGhvdyB3ZWxsIHRoZXNlIHZhcmlhYmxlcyBleHBsYWluIHRlbXBlcmF0dXJlIGNoYW5nZXMgc28gZmFyLiBUbyBkbyB0aGlzLCBmaXJzdCByZWFkIHRoZSBkYXRhc2V0IGNsaW1hdGVfY2hhbmdlLmNzdiBpbnRvIFIuDQoNClRoZW4sIHNwbGl0IHRoZSBkYXRhIGludG8gYSB0cmFpbmluZyBzZXQsIGNvbnNpc3Rpbmcgb2YgYWxsIHRoZSBvYnNlcnZhdGlvbnMgdXAgdG8gYW5kIGluY2x1ZGluZyAyMDA2LCBhbmQgYSB0ZXN0aW5nIHNldCBjb25zaXN0aW5nIG9mIHRoZSByZW1haW5pbmcgeWVhcnMgKGhpbnQ6IHVzZSBzdWJzZXQpLiBBIHRyYWluaW5nIHNldCByZWZlcnMgdG8gdGhlIGRhdGEgdGhhdCB3aWxsIGJlIHVzZWQgdG8gYnVpbGQgdGhlIG1vZGVsICh0aGlzIGlzIHRoZSBkYXRhIHdlIGdpdmUgdG8gdGhlIGxtKCkgZnVuY3Rpb24pLCBhbmQgYSB0ZXN0aW5nIHNldCByZWZlcnMgdG8gdGhlIGRhdGEgd2Ugd2lsbCB1c2UgdG8gdGVzdCBvdXIgcHJlZGljdGl2ZSBhYmlsaXR5Lg0KDQpOZXh0LCBidWlsZCBhIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIHRvIHByZWRpY3QgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBUZW1wLCB1c2luZyBNRUksIENPMiwgQ0g0LCBOMk8sIENGQy4xMSwgQ0ZDLjEyLCBUU0ksIGFuZCBBZXJvc29scyBhcyBpbmRlcGVuZGVudCB2YXJpYWJsZXMgKFllYXIgYW5kIE1vbnRoIHNob3VsZCBOT1QgYmUgdXNlZCBpbiB0aGUgbW9kZWwpLiBVc2UgdGhlIHRyYWluaW5nIHNldCB0byBidWlsZCB0aGUgbW9kZWwuDQoNCkVudGVyIHRoZSBtb2RlbCBSMiAodGhlICJNdWx0aXBsZSBSLXNxdWFyZWQiIHZhbHVlKToNCg0KYGBge3J9DQpjbGltYXRlX2NoYW5nZSA9IHJlYWQuY3N2KCJEOi9idWluZXNzX2FuYWx5dGljcy91bml0Mi9kYXRhL2NsaW1hdGVfY2hhbmdlLmNzdiIpDQpzdHIoY2xpbWF0ZV9jaGFuZ2UpDQp0cmFpbl9kYXRhID0gc3Vic2V0KGNsaW1hdGVfY2hhbmdlICwgWWVhciA8PSAyMDA2KQ0KdGVzdF9kYXRhID0gc3Vic2V0KGNsaW1hdGVfY2hhbmdlLCBZZWFyID4gMjAwNikNCm1vZGVsMSA9IGxtKFRlbXB+TUVJK0NPMitDSDQrTjJPK0NGQy4xMStDRkMuMTIrVFNJK0Flcm9zb2xzLGRhdGEgPSB0cmFpbl9kYXRhKQ0Kc3VtbWFyeShtb2RlbDEpDQp0ZXN0X3Jlc3VsdCA9IHByZWRpY3QobW9kZWwxLCBuZXdkYXRhID0gdGVzdF9kYXRhKQ0Kc3VtbWFyeSh0ZXN0X3Jlc3VsdCkNCmBgYA0KDQoNCiMjIyMgMS4yIA0KV2hpY2ggdmFyaWFibGVzIGFyZSBzaWduaWZpY2FudCBpbiB0aGUgbW9kZWw/IFdlIHdpbGwgY29uc2lkZXIgYSB2YXJpYWJsZSBzaWduZmljYW50IG9ubHkgaWYgdGhlIHAtdmFsdWUgaXMgYmVsb3cgMC4wNS4gKFNlbGVjdCBhbGwgdGhhdCBhcHBseS4pDQoNCisgTUVJDQorIENPMg0KKyBDSDQNCisgTjJPDQorIENGQy4xMQ0KKyBDRkMuMTINCisgVFNJDQorIEFlcm9zb2xzDQorIHVuYW5zd2VyZWQNCg0KYGBge3J9DQojTUVJICAgICAgICAgIDYuNDIxZS0wMiAgNi40NzBlLTAzICAgOS45MjMgIDwgMmUtMTYgKioqIC0+xeO12w0KI0NPMiAgICAgICAgICA2LjQ1N2UtMDMgIDIuMjg1ZS0wMyAgIDIuODI2ICAwLjAwNTA1ICoqIA0KI0NINCAgICAgICAgICAxLjI0MGUtMDQgIDUuMTU4ZS0wNCAgIDAuMjQwICAwLjgxMDE1ICAgIA0KI04yTyAgICAgICAgIC0xLjY1M2UtMDIgIDguNTY1ZS0wMyAgLTEuOTMwICAwLjA1NDY3IC4gIA0KI0NGQy4xMSAgICAgIC02LjYzMWUtMDMgIDEuNjI2ZS0wMyAgLTQuMDc4IDUuOTZlLTA1ICoqKiAtPsXjtdsNCiNDRkMuMTIgICAgICAgMy44MDhlLTAzICAxLjAxNGUtMDMgICAzLjc1NyAgMC4wMDAyMSAqKiogLT7F47XbDQojVFNJICAgICAgICAgIDkuMzE0ZS0wMiAgMS40NzVlLTAyICAgNi4zMTMgMS4xMGUtMDkgKioqIC0+xeO12w0KI0Flcm9zb2xzICAgIC0xLjUzOGUrMDAgIDIuMTMzZS0wMSAgLTcuMjEwIDUuNDFlLTEyICoqKiAtPsXjtdsNCg0KYGBgDQoNCg0KIyMjIFNlY3Rpb24gMiAtIFVuZGVyc3RhbmRpbmcgdGhlIE1vZGVsDQoNCkN1cnJlbnQgc2NpZW50aWZpYyBvcGluaW9uIGlzIHRoYXQgbml0cm91cyBveGlkZSBhbmQgQ0ZDLTExIGFyZSBncmVlbmhvdXNlIGdhc2VzOiBnYXNlcyB0aGF0IGFyZSBhYmxlIHRvIHRyYXAgaGVhdCBmcm9tIHRoZSBzdW4gYW5kIGNvbnRyaWJ1dGUgdG8gdGhlIGhlYXRpbmcgb2YgdGhlIEVhcnRoLiBIb3dldmVyLCB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgb2YgYm90aCB0aGUgTjJPIGFuZCBDRkMtMTEgdmFyaWFibGVzIGFyZSBuZWdhdGl2ZSwgaW5kaWNhdGluZyB0aGF0IGluY3JlYXNpbmcgYXRtb3NwaGVyaWMgY29uY2VudHJhdGlvbnMgb2YgZWl0aGVyIG9mIHRoZXNlIHR3byBjb21wb3VuZHMgaXMgYXNzb2NpYXRlZCB3aXRoIGxvd2VyIGdsb2JhbCB0ZW1wZXJhdHVyZXMuDQoNCg0KIyMjIyAyLjEgDQoNCldoaWNoIG9mIHRoZSBmb2xsb3dpbmcgaXMgdGhlIHNpbXBsZXN0IGNvcnJlY3QgZXhwbGFuYXRpb24gZm9yIHRoaXMgY29udHJhZGljdGlvbj8NCg0KKyBDbGltYXRlIHNjaWVudGlzdHMgYXJlIHdyb25nIHRoYXQgTjJPIGFuZCBDRkMtMTEgYXJlIGdyZWVuaG91c2UgZ2FzZXMgLSB0aGlzIHJlZ3Jlc3Npb24gYW5hbHlzaXMgY29uc3RpdHV0ZXMgcGFydCBvZiBhIGRpc3Byb29mLg0KDQorIFRoZXJlIGlzIG5vdCBlbm91Z2ggZGF0YSwgc28gdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGJlaW5nIGVzdGltYXRlZCBhcmUgbm90IGFjY3VyYXRlLg0KDQorIEFsbCBvZiB0aGUgZ2FzIGNvbmNlbnRyYXRpb24gdmFyaWFibGVzIHJlZmxlY3QgaHVtYW4gZGV2ZWxvcG1lbnQgLSBOMk8gYW5kIENGQy4xMSBhcmUgY29ycmVsYXRlZCB3aXRoIG90aGVyIHZhcmlhYmxlcyBpbiB0aGUgZGF0YSBzZXQuDQoNCg0KYGBge3J9DQpzdHIodHJhaW5fZGF0YSkNCmNvcih0cmFpbl9kYXRhWzM6MTFdKQ0KI0FsbCBvZiB0aGUgZ2FzIGNvbmNlbnRyYXRpb24gdmFyaWFibGVzIHJlZmxlY3QgaHVtYW4gZGV2ZWxvcG1lbnQgLSBOMk8gYW5kIENGQy4xMSBhcmUgY29ycmVsYXRlZCB3aXRoIG90aGVyIHZhcmlhYmxlcyBpbiB0aGUgZGF0YSBzZXQuDQoNCmBgYA0KDQojIyMjIDIuMiANCg0KQ29tcHV0ZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gYWxsIHRoZSB2YXJpYWJsZXMgaW4gdGhlIHRyYWluaW5nIHNldC4gV2hpY2ggb2YgdGhlIGZvbGxvd2luZyBpbmRlcGVuZGVudCB2YXJpYWJsZXMgaXMgTjJPIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggKGFic29sdXRlIGNvcnJlbGF0aW9uIGdyZWF0ZXIgdGhhbiAwLjcpPyBTZWxlY3QgYWxsIHRoYXQgYXBwbHkuDQoNCisgTUVJDQorIENPMg0KKyBDSDQNCisgQ0ZDLjExDQorIENGQy4xMg0KKyBBZXJvc29scw0KKyBUU0kNCg0KDQpgYGB7cn0NCmNvcih0cmFpbl9kYXRhWzM6MTFdKQ0KI0Fuc2VyID0gQ08yLENINCxDRkMuMTINCg0KYGBgDQoNCg0KV2hpY2ggb2YgdGhlIGZvbGxvd2luZyBpbmRlcGVuZGVudCB2YXJpYWJsZXMgaXMgQ0ZDLjExIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGg/IFNlbGVjdCBhbGwgdGhhdCBhcHBseS4NCg0KKyBNRUkNCisgQ08yDQorIENINA0KKyBDRkMuMTENCisgQ0ZDLjEyDQorIEFlcm9zb2xzDQorIFRTSQ0KDQoNCmBgYHtyfQ0KY29yKHRyYWluX2RhdGFbMzoxMV0pDQojQW5zZXIgPSBDSDQsQ0ZDLjEyDQpgYGANCg0KDQojIyMgU2VjdGlvbiAzIC0gU2ltcGxpZnlpbmcgdGhlIE1vZGVsDQoNCg0KR2l2ZW4gdGhhdCB0aGUgY29ycmVsYXRpb25zIGFyZSBzbyBoaWdoLCBsZXQgdXMgZm9jdXMgb24gdGhlIE4yTyB2YXJpYWJsZSBhbmQgYnVpbGQgYSBtb2RlbCB3aXRoIG9ubHkgTUVJLCBUU0ksIEFlcm9zb2xzIGFuZCBOMk8gYXMgaW5kZXBlbmRlbnQgdmFyaWFibGVzLiBSZW1lbWJlciB0byB1c2UgdGhlIHRyYWluaW5nIHNldCB0byBidWlsZCB0aGUgbW9kZWwuDQoNCkVudGVyIHRoZSBjb2VmZmljaWVudCBvZiBOMk8gaW4gdGhpcyByZWR1Y2VkIG1vZGVsOg0KDQpgYGB7cn0NCm1vZGVsX24ybyA9IGxtKFRlbXB+TUVJK1RTSStBZXJvc29scytOMk8sIGRhdGEgPSB0cmFpbl9kYXRhKQ0Kc3VtbWFyeShtb2RlbF9uMm8pDQojQW5zZXIgPSAyLjUzMmUtMDINCg0KYGBgDQoNCg0KKEhvdyBkb2VzIHRoaXMgY29tcGFyZSB0byB0aGUgY29lZmZpY2llbnQgaW4gdGhlIHByZXZpb3VzIG1vZGVsIHdpdGggYWxsIG9mIHRoZSB2YXJpYWJsZXM/KQ0KDQpFbnRlciB0aGUgbW9kZWwgUjI6DQoNCmBgYHtyfQ0KI0Fuc2VyID0gMC43MjYxDQpgYGANCg0KDQojIyMgU2VjdGlvbiA0IC0gQXV0b21hdGljYWxseSBCdWlsZGluZyB0aGUgTW9kZWwNCg0KDQpXZSBoYXZlIG1hbnkgdmFyaWFibGVzIGluIHRoaXMgcHJvYmxlbSwgYW5kIGFzIHdlIGhhdmUgc2VlbiBhYm92ZSwgZHJvcHBpbmcgc29tZSBmcm9tIHRoZSBtb2RlbCBkb2VzIG5vdCBkZWNyZWFzZSBtb2RlbCBxdWFsaXR5LiBSIHByb3ZpZGVzIGEgZnVuY3Rpb24sIHN0ZXAsIHRoYXQgd2lsbCBhdXRvbWF0ZSB0aGUgcHJvY2VkdXJlIG9mIHRyeWluZyBkaWZmZXJlbnQgY29tYmluYXRpb25zIG9mIHZhcmlhYmxlcyB0byBmaW5kIGEgZ29vZCBjb21wcm9taXNlIG9mIG1vZGVsIHNpbXBsaWNpdHkgYW5kIFIyLiBUaGlzIHRyYWRlLW9mZiBpcyBmb3JtYWxpemVkIGJ5IHRoZSBBa2Fpa2UgaW5mb3JtYXRpb24gY3JpdGVyaW9uIChBSUMpIC0gaXQgY2FuIGJlIGluZm9ybWFsbHkgdGhvdWdodCBvZiBhcyB0aGUgcXVhbGl0eSBvZiB0aGUgbW9kZWwgd2l0aCBhIHBlbmFsdHkgZm9yIHRoZSBudW1iZXIgb2YgdmFyaWFibGVzIGluIHRoZSBtb2RlbC4NCg0KVGhlIHN0ZXAgZnVuY3Rpb24gaGFzIG9uZSBhcmd1bWVudCAtIHRoZSBuYW1lIG9mIHRoZSBpbml0aWFsIG1vZGVsLiBJdCByZXR1cm5zIGEgc2ltcGxpZmllZCBtb2RlbC4gVXNlIHRoZSBzdGVwIGZ1bmN0aW9uIGluIFIgdG8gZGVyaXZlIGEgbmV3IG1vZGVsLCB3aXRoIHRoZSBmdWxsIG1vZGVsIGFzIHRoZSBpbml0aWFsIG1vZGVsIChISU5UOiBJZiB5b3VyIGluaXRpYWwgZnVsbCBtb2RlbCB3YXMgY2FsbGVkICJjbGltYXRlTE0iLCB5b3UgY291bGQgY3JlYXRlIGEgbmV3IG1vZGVsIHdpdGggdGhlIHN0ZXAgZnVuY3Rpb24gYnkgdHlwaW5nIHN0ZXAoY2xpbWF0ZUxNKS4gQmUgc3VyZSB0byBzYXZlIHlvdXIgbmV3IG1vZGVsIHRvIGEgdmFyaWFibGUgbmFtZSBzbyB0aGF0IHlvdSBjYW4gbG9vayBhdCB0aGUgc3VtbWFyeS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN0ZXAgZnVuY3Rpb24sIHR5cGUgP3N0ZXAgaW4geW91ciBSIGNvbnNvbGUuKQ0KDQoNCiMjIyMgNC4xDQpFbnRlciB0aGUgUjIgdmFsdWUgb2YgdGhlIG1vZGVsIHByb2R1Y2VkIGJ5IHRoZSBzdGVwIGZ1bmN0aW9uOg0KDQpgYGB7cn0NCnN0ZXBfbW9kZWwgPSBzdGVwKG1vZGVsMSkNCnN1bW1hcnkoc3RlcF9tb2RlbCkNCiNBbnNlciA9IDAuNzUwOA0KDQpgYGANCg0KIyMjIyA0LjIgDQpXaGljaCBvZiB0aGUgZm9sbG93aW5nIHZhcmlhYmxlKHMpIHdlcmUgZWxpbWluYXRlZCBmcm9tIHRoZSBmdWxsIG1vZGVsIGJ5IHRoZSBzdGVwIGZ1bmN0aW9uPyBTZWxlY3QgYWxsIHRoYXQgYXBwbHkuDQoNCisgTUVJDQorIENPMg0KKyBDSDQNCisgTjJPDQorIENGQy4xMQ0KKyBDRkMuMTINCisgVFNJDQorIEFlcm9zb2xzDQoNCmBgYHtyfQ0KI2xtKGZvcm11bGEgPSBUZW1wIH4gTUVJICsgQ08yICsgTjJPICsgQ0ZDLjExICsgQ0ZDLjEyICsgVFNJICsgQWVyb3NvbHMsIGRhdGEgPSB0cmFpbl9kYXRhKQ0KI0Fuc2VyID0gQ0g0DQpgYGANCg0KSXQgaXMgaW50ZXJlc3RpbmcgdG8gbm90ZSB0aGF0IHRoZSBzdGVwIGZ1bmN0aW9uIGRvZXMgbm90IGFkZHJlc3MgdGhlIGNvbGxpbmVhcml0eSBvZiB0aGUgdmFyaWFibGVzLCBleGNlcHQgdGhhdCBhZGRpbmcgaGlnaGx5IGNvcnJlbGF0ZWQgdmFyaWFibGVzIHdpbGwgbm90IGltcHJvdmUgdGhlIFIyIHNpZ25pZmljYW50bHkuIFRoZSBjb25zZXF1ZW5jZSBvZiB0aGlzIGlzIHRoYXQgdGhlIHN0ZXAgZnVuY3Rpb24gd2lsbCBub3QgbmVjZXNzYXJpbHkgcHJvZHVjZSBhIHZlcnkgaW50ZXJwcmV0YWJsZSBtb2RlbCAtIGp1c3QgYSBtb2RlbCB0aGF0IGhhcyBiYWxhbmNlZCBxdWFsaXR5IGFuZCBzaW1wbGljaXR5IGZvciBhIHBhcnRpY3VsYXIgd2VpZ2h0aW5nIG9mIHF1YWxpdHkgYW5kIHNpbXBsaWNpdHkgKEFJQykuDQoNCg0KIyMjIFNlY3Rpb24gNSAtIFRlc3Rpbmcgb24gVW5zZWVuIERhdGENCg0KV2UgaGF2ZSBkZXZlbG9wZWQgYW4gdW5kZXJzdGFuZGluZyBvZiBob3cgd2VsbCB3ZSBjYW4gZml0IGEgbGluZWFyIHJlZ3Jlc3Npb24gdG8gdGhlIHRyYWluaW5nIGRhdGEsIGJ1dCBkb2VzIHRoZSBtb2RlbCBxdWFsaXR5IGhvbGQgd2hlbiBhcHBsaWVkIHRvIHVuc2VlbiBkYXRhPw0KDQpVc2luZyB0aGUgbW9kZWwgcHJvZHVjZWQgZnJvbSB0aGUgc3RlcCBmdW5jdGlvbiwgY2FsY3VsYXRlIHRlbXBlcmF0dXJlIHByZWRpY3Rpb25zIGZvciB0aGUgdGVzdGluZyBkYXRhIHNldCwgdXNpbmcgdGhlIHByZWRpY3QgZnVuY3Rpb24uDQoNCiMjIyM1LjEgDQpFbnRlciB0aGUgdGVzdGluZyBzZXQgUjI6DQoNCmBgYHtyfQ0KdGVzdF9tb2RlbCA9IHByZWRpY3Qoc3RlcF9tb2RlbCwgbmV3ZGF0YSA9IHRlc3RfZGF0YSkNCnN1bW1hcnkodGVzdF9tb2RlbCkNClNTRSA9IHN1bSgoIHRlc3RfbW9kZWwtdGVzdF9kYXRhJFRlbXAgKV4yKQ0KU1NUID0gc3VtKCggbWVhbih0cmFpbl9kYXRhJFRlbXApLXRlc3RfZGF0YSRUZW1wICleMikNClJRdWFyZSA9IDEgLSBTU0UvU1NUDQpSUXVhcmUNCiMwLjYyODYwNTENCmBgYA0KDQoNCg0KDQo=