Hello,
I have encountered a couple of problems coding up the Expectation operator which would be alleviated if you could answer the following questions:
1) In DataTree::AddVariable(int symb_id, int lag), why is there an "assert(lag==0);" at the beginning of this file and how can we add variables to the datatree with leads/lags?
2) I am a bit confused as to how negative numerial constants should be stored in the datatree. Should they be stored as a unaryOpNode of type oUminus pointing to a positive numConstNode (as is the case for MinusOne and MinusIninity)? Or should they be stored as a potentially negative number as in ParsingDriver::add_constant(string *constant)?
3) Is there a guideline for which types of potential errors to handle nicely (by printing a message to cerr and exiting) and which ones to simply allow to pass by? Say, for example (as I have not coded this fully yet), I would like to look up an oExpectation BinaryOpNode in the subst_table when replacing the oExpectation BinaryOpNode with a Variable node pointing to the associated auxiliary variable. This auxiliary variable would be provided if I had correctly inserted everything into the subst_table. If, on the other hand, there is a bug in my code, it will not return this and will break during processing. Though this will be tested for after the Expectation operator has been implemented, you can see that there are many such situations that could potentially arise. Hence, I was wondering if you have any advice as to when one should test for errors in processing (and print appropriate error messages) and when one should assume that everything has worked correctly. I hope this is clear and that I have not been too long-winded.
Best, Houtan
2009/9/17 Sébastien Villemot sebastien.villemot@ens.fr
Le mercredi 16 septembre 2009 à 20:39 -0400, houtan a écrit :
Just to make sure I understand completely, the reason you proposed the method above over the one outlined earlier (which seemed to replace the EXPECTATION operator as it was encountered, and is outlined below for reference) is that since we are declaring auxiliary variables on the fly, and since we are creating the modfile on the fly as well, we want to be certain that we do not declare a variable for our use (in this case aux*) that the user may have referenced at a later point in their .m file.
This is actually not the main reason for my proposing another solution. But this is a side effect, though.
If this is wrong and all of the symbols have in fact been declared in the SymbolTable by the time the parser begins to create expression trees, would the following be a valid procedure for implementing the Expectation operator?
Following the names EXPECTATION(iArg1)(iArg2),
in NodeID DataTree::AddExpectation(NodeID iArg1, NodeID iArg2)
- Create new auxiliary variable, auxvar(iArg1) via a separate
protected function (using addSymbol, addVariable) that will find a unique variable name
- Add equation: auxvar = iArg2(-iArg1) to the model tree
- return the NodeID of auxvar(iArg1) (as requested
here: http://www.dynare.org/DynareWiki/NewOperators )
If not, what is the advantage of the method proposed earlier over the one contained herein?
Because I want to clearly separate the parsing pass from the computing pass in the preprocessor. In my mind, parsing is only building an expression tree, exactly reflecting what the user has written. So I don't like the idea of doing this on-the-fly. I prefer to clearly separate things in several tasks. For the moment the preprocessor has 4 steps:
- parsing
- checking (ModFile::checkPass())
- computing (ModFile::computingPass())
- output writing (ModFile::writeOutputFiles())
All the treatment of the expectation operator (adding auxiliary variables and substituting the operator by the new variables) should be done at the beginning of the computing pass. The checking pass may be used to identify the set of expectation operators to be replaced (but only identifying, since it is meant to be "read-only").
Also note that, with Michel, we agreed on the fact that the auxiliary variable names should be meaningful for the user, because she will see it in the output of Dynare. The name needs also to be a valid MATLAB variable name, because we construct output structures with the endogenous names. So for example the auxiliary variable created by expression E(1)(x) could be called E_1_x, which is both meaningful and valid.
If it happens that this name collides with a variable declared by the user, then the preprocessor should exit with an error message, telling the user to use another name in order to avoid confusion (even for his own sake).
Also, why does the NewOperators page say we need to keep a list of new auxiliary variables? This wouldn't be necessary if the idea proposed herein is correct (but certainly would be if we were to follow the method proposed earlier).
It is up to you to decide if you need such a list in the implementation. My impression is that you don't need it, but I may be wrong.
Finally, the NewOperators page states "if the expression has not been encountered in the file, create a new auxiliary variable..." Shouldn't this new auxiliary variable be created, regardless of whether or not the expression has already been encountered?
This sentence was only meaningful in the context of an on-the-fly substitution. It is obsolete in the setting that I have in mind.
Best,
-- Sébastien Villemot
Dev mailing list Dev@dynare.org http://www.dynare.org/cgi-bin/mailman/listinfo/dev