*
* @denton  oldseries start end newseries
* # related series (just one)
*
* This implements the proportional Denton method of benchmarking, distributing the sum from
* a low frequency series based upon the period-to-period rates of change of a (single)
* higher frequency series. This is designed to be used when the two series are closely
* related, with the more frequent series being a noisier measure of the less frequent one.
* The newer procedure disaggregate.src handles this calculation and more.
*
* Parameters:
*
*   oldser = series to distribute. This should be set up in the higher frequency. If
*            you read the series from a RATS format file in the higher frequency, it
*            will be set up this way automatically.
*
*   start end  = range over which to do the calculation. By default, the defined
*            range of <<oldser>>
*
*   newser = generated higher frequency series. Note that, if you want the output to
*            be at annual rates, you'll have to scale this up at the end because @denton
*            distributes the sum across the sum periods.
*
* Options:
*
*   FACTOR=Increase in the recording frequency (3 for quarterly to monthly, 4 for
*          quarterly to annual)
*
* Revision schedule:
*   03/2002 Written as an example program by Tom Doan, Estima
*   02/2008 Revised into a procedure. Switched to use of exact initial Kalman smoother
*
* Reference:
*   Quarterly National Accounts Manual—Concepts, Data Sources, and
*   Compilation, by Bloem, Dippelsman, and Maehle, chapter 6.
*   http://www.imf.org/external/pubs/ft/qna/2000/textbook/
*
* Requirement:
*   Version 7.00 or later of RATS
*
procedure denton oldser start end newser
type series oldser *newser
type integer start end
*
option integer factor 3
*
local frml[vect]   cf
local vect         cx
local symm         sw
local integer      startl endl
local integer      i j n
local series       related y
local equation     xvar
local series[vect] states
local rect         a
*
* Get the one related series. If the user provides more than one, exit with an
* error.
*
equation xvar *
compute n=%eqnsize(xvar)
if n<>1 {
   disp "####@Denton requires only single related series"
   return
}
*
* Get the range from <<oldser>> and normalize so it begins at a first subperiod.
*
inquire(series=oldser) startl<<start endl<<end
if %clock(startl,factor)<>1
   compute startl=startl-%clock(startl,factor)+1
*
* Extract the related series
*
set related startl endl = %eqnxvector(xvar,t)(1)
*
* This is estimated using Kalman smoothing. The states are defined to be the ratio
* between the benchmark estimates of the higher frequency data and the observed
* quarterly data. The measurement equation says that the benchmark estimates sum
* to the low frequency number with no error.
*
* The states evolve according to a random walk. This has to be augmented by
* <<factor>>-1 lags in order to apply the adding-up measurement equation.
*
dim a(factor,factor)
ewise a(i,j)=(i==1.and.j==1.or.i==j+1)
compute sw=%outerxx(%unitv(factor,1))
*
dim cx(factor)
frml cf = %do(i,1,factor,cx(i)=related(t-(i-1))),cx
*
* Patch over the <<oldser>> so we only have a measurement equation for the final
* subperiod.
*
set y startl endl = %if(%clock(t,factor)==factor,oldser,%na)
*
* Smooth using exact initial smoothing
*
dlm(type=smoothed,c=cf,y=y,sw=sw,a=a,exact,presample=ergodic) startl endl states
*
* The interpolated data are obtained by multiplying the higher frequency
* observables by the Kalman smoothed states.
*
set newser startl endl = states(t)(1)*related
end

