*
* This organizes the graphs of an impulse response function from an already
* estimated VAR.
*
* @VARIRF(model=VAR model,other options)
*
* Options:
*    MODEL=VAR model whose IRF's are to be calculated
*    DECOMP=Factor of the covariance matrix [Cholesky of %SIGMA]
*    STEPS=number of forecast steps[48]
*    BYSHOCK/[NOBYSHOCK] Produce a separate graph for each shock with responses to all
*    BYVARIABLE/[NOBYVARIABLE] Produce a separate graph for each variable showing its responses
*     to all shocks
*    ERRORS/[NOERRORS] Produce a forecast error variance decomposition
*    VLABELS=VECTOR[STRINGS] of labels for variables [labels of dependent variables]
*    LABELS=VECTOR[STRINGS] of labels for shocks [same as VLABELS]
*
* Revision Schedule:
*  07/05 Written by Tom Doan, Estima.
*
procedure VARIRF
*
option rect    decomp
option model   model
option integer steps      48
option switch  byshock    0
option switch  byvariable 0
option switch  scale      1
option switch  errors     0
option vect[strings] labels
option vect[strings] vlabels
*
local rect[series] impblk
local vect[series] scaled
local vect[strings] resplabels
local vect[strings] shocklabels
local integer ieqn neqn
local integer i j
local string header
local rect   factor
*
if .not.%defined(model) {
   display 'Syntax: @VARIRF(model=VAR model,lags=# of lags,...)'
   return
}
compute neqn=%modelsize(model)
dim impblk(neqn,neqn) scaled(neqn) shocklabels(neqn) resplabels(neqn)
*
* Use the vlabels if provided, else use the labels of the dependent
* variables
*
if %defined(vlabels)
   compute resplabels=vlabels
else
   ewise resplabels(i)=%l(%modeldepvars(model)(i))
*
* Use the labels if provided, otherwise label the shocks the same as
* the responses
*
if %defined(labels)
   compute shocklabels=labels
else
   compute shocklabels=resplabels
*
* Use the DECOMP provided, otherwise take the standard factorization
* of the %SIGMA matrix
*
if %defined(decomp)
   compute factor=decomp
else
   compute factor=%decomp(%sigma)
*
list ieqn = 1 to neqn
*
*   This computes the full set of impulse responses, which are in the series in
*   IMPBLK. IMPBLK(i,j) is the response of variable i to a shock in j.
*
impulse(model=model,result=impblk,noprint,decomp=factor,steps=steps)
*
*   This loop graphs the responses of a variable to all shocks.
*   These don’t have to be normalized.
*
if byvariable
   do i=1,neqn
      compute header='Plot of responses of '+resplabels(i)
      graph(header=header,key=below,klabels=shocklabels,number=0,window='of_'+resplabels(i)) neqn
      cards impblk(i,ieqn) 1 steps
   end do i

if byshock
*
*   This loop plots the responses of all series to a single series. The response
*   of a series is normalized by dividing by its innovation variance. This
*   allows all the responses to a shock to be plotted on a single scale. Note that
*   these graphs get a bit hard to read with more than five or six variables.
*
*   As this program will generate a dozen graphs in a bunch, the WINDOW option
*   is used on the GRAPH instructions to give them descriptive labels in
*   the WINDOW menu.
*
   do i=1,neqn
      compute header='Plot of responses to '+shocklabels(i)
      do j=1,neqn
         set scaled(j) 1 steps = (impblk(j,i))/sqrt(%sigma(j,j))
      end do j
      graph(header=header,key=below,klabels=resplabels,number=0,$
         window='to_'+shocklabels(i)) neqn
      cards scaled(ieqn) 1 steps
    end do i
*
if errors
   errors(window='Decomposition of Variance',labels=shocklabels,decomp=factor,model=model) * steps
end varirf


