preprocessor: add model_local_variable declaration for declaring model local variables with tex names. Closes #563

time-shift
Houtan Bastani 2017-08-28 15:14:11 +02:00
parent a8073a8d31
commit 628c4cf27b
9 changed files with 109 additions and 50 deletions

View File

@ -1539,6 +1539,24 @@ a variable with a multiplicative trend).
@end deffn
@anchor{model_local_variable}
@deffn Command model_local_variable @var{VARIABLE_NAME} [$@var{LATEX_NAME}$] @dots{};
@descriptionhead
This optional command declares a model local variable. @xref{Conventions}, for
the syntax of @var{VARIABLE_NAME}. As you can create model local variables on
the fly in the model block (@pxref{model_local_variables_in_model_block}), the
interest of this command is primarily to assign a @var{LATEX_NAME} to the model
local variable.
@examplehead
@example
model_local_variable GDP_US $GDPUS$;
@end example
@end deffn
@node Expressions
@section Expressions
@ -1918,16 +1936,19 @@ equation. A homogenous equation looks like:
@var{MODEL_EXPRESSION};
@end example
@anchor{model_local_variables_in_model_block}
Inside the model block, Dynare allows the creation of @emph{model-local
variables}, which constitute a simple way to share a common expression
between several equations. The syntax consists of a pound sign
(@code{#}) followed by the name of the new model local variable (which
must @strong{not} be declared as in @ref{Variable declarations}), an equal
sign, and the expression for which this new variable will stand. Later
on, every time this variable appears in the model, Dynare will
substitute it by the expression assigned to the variable. Note that the
scope of this variable is restricted to the model block; it cannot be
used outside. A model local variable declaration looks like:
variables}, which constitute a simple way to share a common expression between
several equations. The syntax consists of a pound sign (@code{#}) followed by
the name of the new model local variable (which must @strong{not} be declared
as in @ref{Variable declarations}, but may have been declared by
@ref{model_local_variable}), an equal sign, and the expression for which this
new variable will stand. Later on, every time this variable appears in the
model, Dynare will substitute it by the expression assigned to the
variable. Note that the scope of this variable is restricted to the model
block; it cannot be used outside. To assign a @LaTeX{} name to the model local
variable, use the declaration syntax outlined by @ref{model_local_variable}. A
model local variable declaration looks like:
@example
# @var{VARIABLE_NAME} = @var{MODEL_EXPRESSION};
@end example

View File

@ -507,6 +507,7 @@ DataTree::AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableExcept
throw LocalVariableException(symbol_table.getName(symb_id));
local_variables_table[symb_id] = value;
local_variables_vector.push_back(symb_id);
}
expr_t

View File

@ -84,6 +84,8 @@ protected:
//! Stores local variables value (maps symbol ID to corresponding node)
map<int, expr_t> local_variables_table;
//! Stores the order of appearance of local variables in the model block. Needed following change in #563
vector<int> local_variables_vector;
//! Internal implementation of AddVariable(), without the check on the lag
VariableNode *AddVariableInternal(int symb_id, int lag);

View File

@ -3728,9 +3728,9 @@ DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const
assert(&symbol_table == &dynamic_model.symbol_table);
// Convert model local variables (need to be done first)
for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
dynamic_model.AddLocalVariable(it->first, it->second->cloneDynamic(dynamic_model));
for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_vector.end(); it++)
dynamic_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->cloneDynamic(dynamic_model));
// Convert equations
for (size_t i = 0; i < equations.size(); i++)
@ -3853,9 +3853,9 @@ DynamicModel::toStatic(StaticModel &static_model) const
assert(&symbol_table == &static_model.symbol_table);
// Convert model local variables (need to be done first)
for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
static_model.AddLocalVariable(it->first, it->second->toStatic(static_model));
for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_vector.end(); it++)
static_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->toStatic(static_model));
// Convert equations
int static_only_index = 0;

View File

@ -129,7 +129,7 @@ class ParsingDriver;
%token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL
%token <string_val> TEX_NAME
%token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
%token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES PLOT_SHOCK_DECOMPOSITION
%token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE
%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL
%token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP QOQ YOY AOA
%left COMMA
@ -203,6 +203,7 @@ statement : parameters
| varexo
| varexo_det
| predetermined_variables
| model_local_variable
| change_type
| periods
| model
@ -381,6 +382,8 @@ predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list '
parameters : PARAMETERS parameter_list ';';
model_local_variable : MODEL_LOCAL_VARIABLE model_local_variable_list ';';
named_var_elem : symbol EQUAL QUOTED_STRING
{
pair<string *, string *> *pr = new pair<string *, string *>($1, $3);
@ -525,6 +528,20 @@ predetermined_variables_list : predetermined_variables_list symbol
{ driver.add_predetermined_variable($1); }
;
model_local_variable_list : model_local_variable_list symbol
{ driver.declare_model_local_variable($2); }
| model_local_variable_list COMMA symbol
{ driver.declare_model_local_variable($3); }
| symbol
{ driver.declare_model_local_variable($1); }
| model_local_variable_list symbol TEX_NAME
{ driver.declare_model_local_variable($2, $3); }
| model_local_variable_list COMMA symbol TEX_NAME
{ driver.declare_model_local_variable($3, $4); }
| symbol TEX_NAME
{ driver.declare_model_local_variable($1, $2); }
;
change_type : CHANGE_TYPE '(' change_type_arg ')' change_type_var_list ';'
{ driver.change_type($3, $5); }
;

View File

@ -111,6 +111,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>log_trend_var {BEGIN DYNARE_STATEMENT; return token::LOG_TREND_VAR;}
<INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;}
<INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;}
<INITIAL>model_local_variable {BEGIN DYNARE_STATEMENT; return token::MODEL_LOCAL_VARIABLE;}
<INITIAL>periods {BEGIN DYNARE_STATEMENT; return token::PERIODS;}
<INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;}
<INITIAL>estimation {BEGIN DYNARE_STATEMENT; return token::ESTIMATION;}

View File

@ -1418,24 +1418,25 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t
for (size_t i = 0; i < equations.size(); i++)
equations[i]->collectVariables(eModelLocalVariable, used_local_vars);
for (set<int>::const_iterator it = used_local_vars.begin();
it != used_local_vars.end(); ++it)
{
int id = *it;
expr_t value = local_variables_table.find(id)->second;
value->writeExternalFunctionOutput(output, output_type, tt, tef_terms);
for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_vector.end(); it++)
if (used_local_vars.find(*it) != used_local_vars.end())
{
int id = *it;
expr_t value = local_variables_table.find(id)->second;
value->writeExternalFunctionOutput(output, output_type, tt, tef_terms);
if (IS_C(output_type))
output << "double ";
else if (IS_JULIA(output_type))
output << " @inbounds ";
if (IS_C(output_type))
output << "double ";
else if (IS_JULIA(output_type))
output << " @inbounds ";
/* We append underscores to avoid name clashes with "g1" or "oo_" (see
also VariableNode::writeOutput) */
output << symbol_table.getName(id) << "__ = ";
value->writeOutput(output, output_type, tt, tef_terms);
output << ";" << endl;
}
/* We append underscores to avoid name clashes with "g1" or "oo_" (see
also VariableNode::writeOutput) */
output << symbol_table.getName(id) << "__ = ";
value->writeOutput(output, output_type, tt, tef_terms);
output << ";" << endl;
}
}
void
@ -1468,21 +1469,26 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t
}
output << "]"
<< ", \"model_local_variables\": [";
for (set<int>::const_iterator it = used_local_vars.begin();
it != used_local_vars.end(); ++it)
{
if (it != used_local_vars.begin())
output << ", ";
int id = *it;
expr_t value = local_variables_table.find(id)->second;
bool printed = false;
for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_vector.end(); it++)
if (used_local_vars.find(*it) != used_local_vars.end())
{
int id = *it;
expr_t value = local_variables_table.find(id)->second;
/* We append underscores to avoid name clashes with "g1" or "oo_" (see
also VariableNode::writeOutput) */
output << "{\"variable\": \"" << symbol_table.getName(id) << "__\""
<< ", \"value\": \"";
value->writeJsonOutput(output, tt, tef_terms);
output << "\"}" << endl;
}
if (printed)
output << ", ";
else
printed = true;
/* We append underscores to avoid name clashes with "g1" or "oo_" (see
also VariableNode::writeOutput) */
output << "{\"variable\": \"" << symbol_table.getName(id) << "__\""
<< ", \"value\": \"";
value->writeJsonOutput(output, tt, tef_terms);
output << "\"}" << endl;
}
output << "]";
}
@ -1660,11 +1666,11 @@ ModelTree::writeLatexModelFile(const string &basename, ExprNodeOutputType output
<< "\\footnotesize" << endl;
// Write model local variables
for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_vector.end(); it++)
{
int id = it->first;
expr_t value = it->second;
int id = *it;
expr_t value = local_variables_table.find(id)->second;
content_output << "\\begin{dmath*}" << endl
<< symbol_table.getTeXName(id) << " = ";

View File

@ -2226,6 +2226,15 @@ ParsingDriver::add_model_equal_with_zero_rhs(expr_t arg)
return add_model_equal(arg, model_tree->Zero);
}
void
ParsingDriver::declare_model_local_variable(string *name, string *tex_name)
{
declare_symbol(name, eModelLocalVariable, tex_name, NULL);
delete name;
if (tex_name != NULL)
delete tex_name;
}
void
ParsingDriver::declare_and_init_model_local_variable(string *name, expr_t rhs)
{

View File

@ -303,6 +303,8 @@ public:
void declare_exogenous_det(string *name, string *tex_name = NULL, vector<pair<string *, string *> *> *partition_value = NULL);
//! Declares a parameter
void declare_parameter(string *name, string *tex_name = NULL, vector<pair<string *, string *> *> *partition_value = NULL);
//! Declares a model local variable
void declare_model_local_variable(string *name, string *tex_name = NULL);
//! Declares a statement local variable
void declare_statement_local_variable(string *name);
//! Completes a subsample statement