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 @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 @node Expressions
@section Expressions @section Expressions
@ -1918,16 +1936,19 @@ equation. A homogenous equation looks like:
@var{MODEL_EXPRESSION}; @var{MODEL_EXPRESSION};
@end example @end example
@anchor{model_local_variables_in_model_block}
Inside the model block, Dynare allows the creation of @emph{model-local Inside the model block, Dynare allows the creation of @emph{model-local
variables}, which constitute a simple way to share a common expression variables}, which constitute a simple way to share a common expression between
between several equations. The syntax consists of a pound sign several equations. The syntax consists of a pound sign (@code{#}) followed by
(@code{#}) followed by the name of the new model local variable (which the name of the new model local variable (which must @strong{not} be declared
must @strong{not} be declared as in @ref{Variable declarations}), an equal as in @ref{Variable declarations}, but may have been declared by
sign, and the expression for which this new variable will stand. Later @ref{model_local_variable}), an equal sign, and the expression for which this
on, every time this variable appears in the model, Dynare will new variable will stand. Later on, every time this variable appears in the
substitute it by the expression assigned to the variable. Note that the model, Dynare will substitute it by the expression assigned to the
scope of this variable is restricted to the model block; it cannot be variable. Note that the scope of this variable is restricted to the model
used outside. A model local variable declaration looks like: 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 @example
# @var{VARIABLE_NAME} = @var{MODEL_EXPRESSION}; # @var{VARIABLE_NAME} = @var{MODEL_EXPRESSION};
@end example @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)); throw LocalVariableException(symbol_table.getName(symb_id));
local_variables_table[symb_id] = value; local_variables_table[symb_id] = value;
local_variables_vector.push_back(symb_id);
} }
expr_t expr_t

View File

@ -84,6 +84,8 @@ protected:
//! Stores local variables value (maps symbol ID to corresponding node) //! Stores local variables value (maps symbol ID to corresponding node)
map<int, expr_t> local_variables_table; 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 //! Internal implementation of AddVariable(), without the check on the lag
VariableNode *AddVariableInternal(int symb_id, int 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); assert(&symbol_table == &dynamic_model.symbol_table);
// Convert model local variables (need to be done first) // Convert model local variables (need to be done first)
for (map<int, expr_t>::const_iterator it = local_variables_table.begin(); for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_table.end(); it++) it != local_variables_vector.end(); it++)
dynamic_model.AddLocalVariable(it->first, it->second->cloneDynamic(dynamic_model)); dynamic_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->cloneDynamic(dynamic_model));
// Convert equations // Convert equations
for (size_t i = 0; i < equations.size(); i++) 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); assert(&symbol_table == &static_model.symbol_table);
// Convert model local variables (need to be done first) // Convert model local variables (need to be done first)
for (map<int, expr_t>::const_iterator it = local_variables_table.begin(); for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_table.end(); it++) it != local_variables_vector.end(); it++)
static_model.AddLocalVariable(it->first, it->second->toStatic(static_model)); static_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->toStatic(static_model));
// Convert equations // Convert equations
int static_only_index = 0; 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 TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL
%token <string_val> TEX_NAME %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 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 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 %token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP QOQ YOY AOA
%left COMMA %left COMMA
@ -203,6 +203,7 @@ statement : parameters
| varexo | varexo
| varexo_det | varexo_det
| predetermined_variables | predetermined_variables
| model_local_variable
| change_type | change_type
| periods | periods
| model | model
@ -381,6 +382,8 @@ predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list '
parameters : PARAMETERS parameter_list ';'; parameters : PARAMETERS parameter_list ';';
model_local_variable : MODEL_LOCAL_VARIABLE model_local_variable_list ';';
named_var_elem : symbol EQUAL QUOTED_STRING named_var_elem : symbol EQUAL QUOTED_STRING
{ {
pair<string *, string *> *pr = new pair<string *, string *>($1, $3); 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); } { 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 ';' change_type : CHANGE_TYPE '(' change_type_arg ')' change_type_var_list ';'
{ driver.change_type($3, $5); } { 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>log_trend_var {BEGIN DYNARE_STATEMENT; return token::LOG_TREND_VAR;}
<INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;} <INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;}
<INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;} <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>periods {BEGIN DYNARE_STATEMENT; return token::PERIODS;}
<INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;} <INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;}
<INITIAL>estimation {BEGIN DYNARE_STATEMENT; return token::ESTIMATION;} <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++) for (size_t i = 0; i < equations.size(); i++)
equations[i]->collectVariables(eModelLocalVariable, used_local_vars); equations[i]->collectVariables(eModelLocalVariable, used_local_vars);
for (set<int>::const_iterator it = used_local_vars.begin(); for (vector<int>::const_iterator it = local_variables_vector.begin();
it != used_local_vars.end(); ++it) 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; int id = *it;
value->writeExternalFunctionOutput(output, output_type, tt, tef_terms); expr_t value = local_variables_table.find(id)->second;
value->writeExternalFunctionOutput(output, output_type, tt, tef_terms);
if (IS_C(output_type)) if (IS_C(output_type))
output << "double "; output << "double ";
else if (IS_JULIA(output_type)) else if (IS_JULIA(output_type))
output << " @inbounds "; output << " @inbounds ";
/* We append underscores to avoid name clashes with "g1" or "oo_" (see /* We append underscores to avoid name clashes with "g1" or "oo_" (see
also VariableNode::writeOutput) */ also VariableNode::writeOutput) */
output << symbol_table.getName(id) << "__ = "; output << symbol_table.getName(id) << "__ = ";
value->writeOutput(output, output_type, tt, tef_terms); value->writeOutput(output, output_type, tt, tef_terms);
output << ";" << endl; output << ";" << endl;
} }
} }
void void
@ -1468,21 +1469,26 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t
} }
output << "]" output << "]"
<< ", \"model_local_variables\": ["; << ", \"model_local_variables\": [";
for (set<int>::const_iterator it = used_local_vars.begin(); bool printed = false;
it != used_local_vars.end(); ++it) for (vector<int>::const_iterator it = local_variables_vector.begin();
{ it != local_variables_vector.end(); it++)
if (it != used_local_vars.begin()) if (used_local_vars.find(*it) != used_local_vars.end())
output << ", "; {
int id = *it; int id = *it;
expr_t value = local_variables_table.find(id)->second; expr_t value = local_variables_table.find(id)->second;
/* We append underscores to avoid name clashes with "g1" or "oo_" (see if (printed)
also VariableNode::writeOutput) */ output << ", ";
output << "{\"variable\": \"" << symbol_table.getName(id) << "__\"" else
<< ", \"value\": \""; printed = true;
value->writeJsonOutput(output, tt, tef_terms);
output << "\"}" << endl; /* 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 << "]"; output << "]";
} }
@ -1660,11 +1666,11 @@ ModelTree::writeLatexModelFile(const string &basename, ExprNodeOutputType output
<< "\\footnotesize" << endl; << "\\footnotesize" << endl;
// Write model local variables // Write model local variables
for (map<int, expr_t>::const_iterator it = local_variables_table.begin(); for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_table.end(); it++) it != local_variables_vector.end(); it++)
{ {
int id = it->first; int id = *it;
expr_t value = it->second; expr_t value = local_variables_table.find(id)->second;
content_output << "\\begin{dmath*}" << endl content_output << "\\begin{dmath*}" << endl
<< symbol_table.getTeXName(id) << " = "; << 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); 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 void
ParsingDriver::declare_and_init_model_local_variable(string *name, expr_t rhs) 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); void declare_exogenous_det(string *name, string *tex_name = NULL, vector<pair<string *, string *> *> *partition_value = NULL);
//! Declares a parameter //! Declares a parameter
void declare_parameter(string *name, string *tex_name = NULL, vector<pair<string *, string *> *> *partition_value = NULL); 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 //! Declares a statement local variable
void declare_statement_local_variable(string *name); void declare_statement_local_variable(string *name);
//! Completes a subsample statement //! Completes a subsample statement