*
* @GLSDetrend(options) y start end yd
*
* Local to unity GLS detrending routine. Includes the ERS cases (no
* constant, constant, constant and trend) as well as the Perron and
* Rodriguez cases (constant and trend with a single break). This just
* does the detrending, not the actual unit root test(s). For models with
* breaks, you need to input the break point.
*
* Parameters:
*
*   y  = input series
*   start end = range to detrend [by default, defined range of y]
*   yd = output detrended series (required)
*
* Options:
*   DET=NONE/[CONSTANT]/TREND
*   BREAK=[NONE]/INTERCEPT/TREND/BOTH
*     Note - Perron and Rodriguez don't include the case with just a break in
*     the intercept.
*   TB=entry for break (required if any of the BREAK options are used).
*     The dummies are (t>TB) for the intercept and max(t-TB,0) for the
*     trend, so the structure is different at TB+1 than at TB.
*   CBAR=(positive) value for GLS rho=1-cbar/T. Default depends upon model.
*   U/[NOU]  U indicates unconditional distribution (for U0) is to be used
*
* References:
*   Elliott, Rothenberg and Stock(1996), "Efficient Tests for an
*     Autoregressive Unit Root", Econometrica, vol 64, no. 4, pp 813-836.
*
*   Perron and Rodriguez(2003), "GLS Detrending, Efficient Unit Root Tests
*     and Structural Change",  Journal of Econometrics, vol 115, pp 1-27.
*
* Variables Defined:
*   The standard regression variables can be used. The regressors are in
*   order 1, t, intercept break dummy, trend break dummy
*
*   %RHO = transformation value
*
* Revision Schedule:
*   08/2008 Written by Tom Doan, Estima.
*   09/2009 Added definition of %rho
*   06/2014 Add PRINT option
*
procedure GLSDetrend y start end yd
type series  y *yd
type integer start end
*
option choice  det      2  none constant trend
option choice  break    0  none intercept trend both
option integer tb
option switch  u        0
option real    cbar
option switch  print    0
*
local integer        startl endl nobs i
local vect[series]   z za
local series         ya yd
local real rhot      initialsf
*
if .not.%defined(y) {
   disp "Syntax: @GLSDetrend(options)  Y start end yd"
   return
}
if .not.%defined(yd) {
   disp "Syntax: @GLSDetrend(options)  y start end YD(required)"
   return
}
inquire(series=y) startl<<start endl<<end
stats(noprint) y startl endl
if %nmiss>0 {
   disp "@GLSDetrend can't be used on data with missing values"
   return
}
compute nobs=%nobs
*
if (break>=2) {
   if .not.%defined(tb) {
      disp "@GLSDetrend(break=...) requires option TB to set break point"
      return
   }
   *
   * Break models always include 1 and t
   *
   dim z(3+(break==4))
   compute rhot=%if(%defined(cbar),1-abs(cbar)/nobs,1-23.0/nobs)
}
else
if (det==3) {
   dim z(2)
   compute rhot=%if(%defined(cbar),1-abs(cbar)/nobs,%if(u,1-10.0/nobs,1-13.5/nobs))
}
else
if (det==2) {
   dim z(1)
   compute rhot=%if(%defined(cbar),1-abs(cbar)/nobs,%if(u,1-10.0/nobs,1-7.0/nobs))
}
else {
   dim z(0)
   compute rhot=%if(%defined(cbar),1-abs(cbar)/nobs,1-10.0/nobs)
}

compute initialsf=%if(u,sqrt(1-rhot^2),1.0)

if %rows(z)>=1
   set z(1)  startl endl = 1.0
if %rows(z)>=2
   set z(2)  startl endl = t-startl+1
if %rows(z)>=3 {
   if break<>3
      set z(3) startl endl = t>tb
   else
      set z(3) startl endl = %max(t-tb,0.0)
   if break==4
      set z(4) startl endl = %max(t-tb,0.0)
}
dim za(%rows(z))
do i=1,%rows(z)
   set za(i) startl endl = %if(t==startl,initialsf*z(i),z(i)-rhot*z(i){1})
end do i
set ya startl endl = %if(t==startl,initialsf*y,y-rhot*y{1})
*
linreg(print=print,title="GLS Detrending") ya startl endl
# za
set yd startl endl = y-%dot(%xt(z,t),%beta)
*
compute %rho=rhot
*
end
