18 February 2012

Going non-linear

by Jaromir Benes

A simple non-linear solver, equivalent to perfect-foresight solution, has been in IRIS for quite some time by now. Recently (17 February 2012), I released a new version of IRIS with two improvements in it. Let me explain how things work.

The main idea of the non-linear solver in IRIS is that you yourself first choose which equations contain critical non-linearities, and earmark these in the model code. How? By using a =# sign instead of the usual equal sign in, =, in those equations. The non-linear solver will then concentrate on the earmarked equations only, using first-order solution for the rest of the model. The main advantage of this approach is computational: in typical macroeconomic models, there are rather few equations that produce significant non-linear behaviour, while for the rest, first-order approximation is fair enough. If you don't believe me, just try it :)

How do we then actually run a non-linear simulation? The easiest way is using the simulate function with the option 'nonlinearise='. In this option, you specify the range of periods in which non-linearities will be solved for. In other words, if your entire simulation range is 1:60, and you choose 'nonlinearise=' 1:40, the solver will find a path with the non-linearities in the earmarked equations preserved in the first 40 periods, while everything will be first-order solution in the remaining 20 last periods.

Technically, IRIS takes the first-order solution of the entire model, and tries to find such add-factors added to the earmarked non-linear equations that will result in exact solution for them (meaning the LHS equals the RHS in the original forms of the earmarked equations). Obviously, these add-factors must be treated as anticipated – think of them as anticipated shocks included in the earmarked equations. Also, to make sure the final paths found are valid and on a stable node, you need to check some diagnostics. All these details will be the subject of another knowledge base article I'm preparing to be posted on the project website.

The first of the recent improvements relates to the iterative process of finding the right add-factors. One of the critical parameters in the iterative procedure is the size of the step by which the add-factors are adjusted in response to discrepancies between the LHS and the RHS of the original equations, called lambda. If lambda is too large, the procedure can easily get on a divergence path. If lambda is too small, the procedure may take way too long to converge. The step size had to be set manually by the user in earlier versions, using the option 'lambda=' in simulate. This has changed: Now, the user sets the starting value for the step size, which is by default 'lambda=' 1, and IRIS itself reduces it whenever the algorithm appears to be diverging instead of converging.

The second of the improvements relate to the fact that this is a perfect-foresight-equivalent algorithm. One of the implications is that simulating unanticipated shocks is a bit of pain. Let's say we have unanticipated shocks hitting in periods t=1, t=10, and t=20, and we know we have to preserve non-linearities at least for 40 periods after each shock to get the paths down to steady state sufficiently. We have to run a total of three simulations as follows. The first simulation will run from t=1 to t=40 with a shock at t=1 (but none of the other shocks included). The second simulation will run from t=10 to t=49, with initial condition taken from the first simulation, and a shock placed at t=10. The last simulation will run from t=20 to t=59, with initial condition taken from the second simulation and a new shock at t=20. Before, this had to be set up manually by the user, say in a for loop. Now, IRIS automatically detects unanticipated shocks, divides the overall simulation range into appropriate "segments" according to the appearance of unanticipated shokc, and runs the proper number of consecutive simulations. Each of the segmented simulations preserves the non-linearities for the same number of periods (given by the user), even though the end date in one of the later segments may go beyond the end date of the overall simulation range.

Both of these enhancements will be soon illustrated in an extended version of the existing tutorial on "Non-linear simulations".

What else is in the shop for non-linear models? I have started writing a simple non-linear least-square filter for estimating unobservable variables (and ultimately also parameters)... So, if you have an interesting application in mind, I will be happy reading your comment on this post.

5 comments:

  1. I have downloaded the Tutorial Jaromirs_Simple_SPBC_20110520, and I when running the estimate_params file I get the following error message that I am unable to solve: Undefined function 'chi2inv' for input arguments of type 'double'.

    Error in poster/stats/doMdd (line 278)
    crit = chi2inv(pr,nPar);

    Error in poster/stats (line 217)
    Stat.mdd = doMdd();

    Error in estimate_params (line 217)
    s = stats(pos,theta,logpost)

    The lines of code have been pushed down because I had to adjust the "estimate" function to the new syntax. Any idea how to fix this problem?

    Also, when I run the filter_hist_data file, I get the following error (probably related to the estimate_params file):
    Undefined function or variable 'template'.

    Error in hdataobj.hdatafinal/doOneOutputArea (line 46)
    D.(Name).mse = template;

    Error in hdataobj.hdatafinal (line 23)
    doOneOutputArea('smooth');

    Error in model/mykalmanoutput (line 35)
    D = hdataobj.hdatafinal(Y,This,Range);

    Error in model/filter (line 252)
    [Y,~,PE,~,Outp] = mykalmanoutput(This,Y,xRange);

    Error in filter_hist_data (line 29)
    [ans,f,v,dl,pe] = filter(mest,d,starthist:endhist); %#ok

    Any assistance on this will be greatly appreciated.

    ReplyDelete
  2. Hi

    Re the first error message. To compute the marginal data density, you need the chi2 distribution function from the Statistics Toolbox. Apparently, you don't have the Statistics Toolbox installed. A simple workaround is to exclude the marginal data density from the requested output from the stats function. Modify line 217 in estimate_params as follows:

    s = stats(pos,theta,logpost,'mdd=',false);

    and you should be fine.

    Re the second error message. This was actually a typo in one of the previous versions. If you download the latest version of IRIS, it'll run OK.

    Best,
    Jaromir

    P/S It's a somewhat better idea to post questions of this kind on the discussion forum... But the call is yours :)

    ReplyDelete
  3. Hi Jaromir,

    I am an employee at Bank of Canada. Now I am planning to build a model in IRIS, can I do the following based on your example 3 on model languages:

    _____________________________________________
    !transition_variables

    !for ?v=x,y,z
    !do
    ?v,
    !end

    !transition_shocks

    epsilon

    !parameters

    rho

    !transition_equations
    !for ?v=x,y,z
    !do

    !if stationary == true %?condition?
    'eq label ?v' ?v = rho*?v{-1}...
    !if plus==true
    + epsilon;
    !else
    ;
    !end
    !else
    'eq label ?v' ?v - ?v{-1} = rho*(?v{-1} - ?v{-2}) + epsilon;
    !end
    !end
    _____________________________________________________________________________

    I thought the equations are all right in this way. But for the equation labels, I would like to change them dynamically based on different ?v, such 'eq label ?v', if ?v=x, then it is 'eq label x'. Could you kindly show me how to implement it?

    Thank you in advance,
    Xiaobin Tang

    ReplyDelete
  4. Hi Xiaobin

    Currently, this is not possible (i.e. the for-loop control variables do not apply to labels), but feel free to post a feature request, and I'll introduce this option for you.

    Best,
    Jaromir

    P/S It's better to post these kinds of questions on the discussion forum, not here on the blog...

    ReplyDelete
  5. Thank you for your quick response. Sorry for any confusion I made. I will post those kind of questions on the discussion forum later and post the feature request?

    Thanks again,

    ReplyDelete