Temporary terms: various simplifications and added comments

issue#70
Sébastien Villemot 2018-11-16 16:53:07 +01:00
parent e89dd9cb8b
commit 3d2125287a
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
4 changed files with 49 additions and 56 deletions

View File

@ -2508,16 +2508,13 @@ DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput,
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
temporary_terms_t temp_term_union; temporary_terms_t temp_term_union;
for (auto it : temporary_terms_mlv) writeModelLocalVariableTemporaryTerms(temp_term_union,
temp_term_union.insert(it.first);
writeModelLocalVariableTemporaryTerms(temp_term_union, temporary_terms_mlv,
model_tt_output, output_type, tef_terms); model_tt_output, output_type, tef_terms);
writeTemporaryTerms(temporary_terms_derivatives[0], writeTemporaryTerms(temporary_terms_derivatives[0],
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
model_tt_output, output_type, tef_terms); model_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[0].begin(), temporary_terms_derivatives[0].end());
writeModelEquations(model_output, output_type, temp_term_union); writeModelEquations(model_output, output_type, temp_term_union);
@ -2531,7 +2528,6 @@ DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput,
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
jacobian_tt_output, output_type, tef_terms); jacobian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[1].begin(), temporary_terms_derivatives[1].end());
for (const auto & first_derivative : derivatives[1]) for (const auto & first_derivative : derivatives[1])
{ {
@ -2554,7 +2550,6 @@ DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput,
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
hessian_tt_output, output_type, tef_terms); hessian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[2].begin(), temporary_terms_derivatives[2].end());
int k = 0; // Keep the line of a 2nd derivative in v2 int k = 0; // Keep the line of a 2nd derivative in v2
for (const auto & second_derivative : derivatives[2]) for (const auto & second_derivative : derivatives[2])
@ -2623,7 +2618,6 @@ DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput,
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
third_derivatives_tt_output, output_type, tef_terms); third_derivatives_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[3].begin(), temporary_terms_derivatives[3].end());
int k = 0; // Keep the line of a 3rd derivative in v3 int k = 0; // Keep the line of a 3rd derivative in v3
for (const auto & third_derivative : derivatives[3]) for (const auto & third_derivative : derivatives[3])
@ -5389,9 +5383,10 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
ostringstream third_derivs_output; // Used for storing third order derivatives equations ostringstream third_derivs_output; // Used for storing third order derivatives equations
ostringstream third_derivs1_output; // Used for storing third order derivatives equations ostringstream third_derivs1_output; // Used for storing third order derivatives equations
temporary_terms_t temp_term_union;
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
writeTemporaryTerms(params_derivs_temporary_terms, {}, params_derivs_temporary_terms_idxs, model_output, output_type, tef_terms); writeTemporaryTerms(params_derivs_temporary_terms, temp_term_union, params_derivs_temporary_terms_idxs, model_output, output_type, tef_terms);
for (const auto & residuals_params_derivative : params_derivatives.find({ 0, 1 })->second) for (const auto & residuals_params_derivative : params_derivatives.find({ 0, 1 })->second)
{ {

View File

@ -1361,17 +1361,18 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms)
temporary_terms_derivatives.clear(); temporary_terms_derivatives.clear();
temporary_terms_derivatives.resize(4); temporary_terms_derivatives.resize(4);
// Collect all model local variables appearing in equations. See #101 /* Collect all model local variables appearing in equations (and only those,
// All used model local variables are automatically set as temporary variables because printing unused model local variables can lead to a crash,
see Dynare/dynare#101).
Then store them in a dedicated structure (temporary_terms_mlv), that will
be treated as the rest of temporary terms. */
set<int> used_local_vars; set<int> used_local_vars;
for (auto & equation : equations) for (auto & equation : equations)
equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars); equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars);
for (int used_local_var : used_local_vars) for (int used_local_var : used_local_vars)
{ {
VariableNode *v = AddVariable(used_local_var); VariableNode *v = AddVariable(used_local_var);
temporary_terms_mlv[v] = local_variables_table.find(used_local_var)->second; temporary_terms_mlv[v] = local_variables_table.find(used_local_var)->second;
reference_count[v] = { ExprNode::min_cost(is_matlab)+1, NodeTreeReference::residuals };
} }
map<NodeTreeReference, temporary_terms_t> temp_terms_map; map<NodeTreeReference, temporary_terms_t> temp_terms_map;
@ -1413,9 +1414,8 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms)
temporary_terms_derivatives[3] = temp_terms_map[NodeTreeReference::thirdDeriv]; temporary_terms_derivatives[3] = temp_terms_map[NodeTreeReference::thirdDeriv];
int idx = 0; int idx = 0;
for (map<expr_t, expr_t, ExprNodeLess>::const_iterator it = temporary_terms_mlv.begin(); for (auto &it : temporary_terms_mlv)
it != temporary_terms_mlv.end(); it++) temporary_terms_idxs[it.first] = idx++;
temporary_terms_idxs[it->first] = idx++;
for (auto it : temporary_terms_derivatives[0]) for (auto it : temporary_terms_derivatives[0])
temporary_terms_idxs[it] = idx++; temporary_terms_idxs[it] = idx++;
@ -1431,56 +1431,57 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms)
} }
void void
ModelTree::writeModelLocalVariableTemporaryTerms(const temporary_terms_t &tto, const map<expr_t, expr_t, ExprNodeLess> &tt, ModelTree::writeModelLocalVariableTemporaryTerms(temporary_terms_t &temp_term_union,
ostream &output, ExprNodeOutputType output_type, ostream &output, ExprNodeOutputType output_type,
deriv_node_temp_terms_t &tef_terms) const deriv_node_temp_terms_t &tef_terms) const
{ {
temporary_terms_t tt2; temporary_terms_t tto;
for (auto it : tt) for (auto it : temporary_terms_mlv)
tto.insert(it.first);
for (auto &it : temporary_terms_mlv)
{ {
if (isJuliaOutput(output_type)) if (isJuliaOutput(output_type))
output << " @inbounds const "; output << " @inbounds const ";
it.first->writeOutput(output, output_type, tto, temporary_terms_idxs, tef_terms); it.first->writeOutput(output, output_type, tto, temporary_terms_idxs, tef_terms);
output << " = "; output << " = ";
it.second->writeOutput(output, output_type, tt2, temporary_terms_idxs, tef_terms); it.second->writeOutput(output, output_type, temp_term_union, temporary_terms_idxs, tef_terms);
if (isCOutput(output_type) || isMatlabOutput(output_type)) if (isCOutput(output_type) || isMatlabOutput(output_type))
output << ";"; output << ";";
output << endl; output << endl;
// Insert current node into tt2 /* We put in temp_term_union the VariableNode corresponding to the MLV,
tt2.insert(it.first); not its definition, so that when equations use the MLV,
T(XXX) is printed instead of the MLV name */
temp_term_union.insert(it.first);
} }
} }
void void
ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, ModelTree::writeTemporaryTerms(const temporary_terms_t &tt,
const temporary_terms_t &ttm1, temporary_terms_t &temp_term_union,
const temporary_terms_idxs_t &tt_idxs, const temporary_terms_idxs_t &tt_idxs,
ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const
{ {
// Local var used to keep track of temp nodes already written for (auto it : tt)
temporary_terms_t tt2 = ttm1;
for (auto it = tt.begin();
it != tt.end(); it++)
{ {
if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != nullptr) if (dynamic_cast<AbstractExternalFunctionNode *>(it) != nullptr)
(*it)->writeExternalFunctionOutput(output, output_type, tt2, tt_idxs, tef_terms); it->writeExternalFunctionOutput(output, output_type, temp_term_union, tt_idxs, tef_terms);
if (isJuliaOutput(output_type)) if (isJuliaOutput(output_type))
output << " @inbounds "; output << " @inbounds ";
(*it)->writeOutput(output, output_type, tt, tt_idxs, tef_terms); it->writeOutput(output, output_type, tt, tt_idxs, tef_terms);
output << " = "; output << " = ";
(*it)->writeOutput(output, output_type, tt2, tt_idxs, tef_terms); it->writeOutput(output, output_type, temp_term_union, tt_idxs, tef_terms);
if (isCOutput(output_type) || isMatlabOutput(output_type)) if (isCOutput(output_type) || isMatlabOutput(output_type))
output << ";"; output << ";";
output << endl; output << endl;
// Insert current node into tt2 temp_term_union.insert(it);
tt2.insert(*it);
} }
} }

View File

@ -107,10 +107,11 @@ protected:
the derivation IDs of endogenous, then the IDs of parameters */ the derivation IDs of endogenous, then the IDs of parameters */
map<pair<int,int>, map<vector<int>, expr_t>> params_derivatives; map<pair<int,int>, map<vector<int>, expr_t>> params_derivatives;
//! Temporary terms for the static/dynamic file (those which will be noted T[x]) //! Storage for temporary terms in block/bytecode mode
temporary_terms_t temporary_terms; temporary_terms_t temporary_terms;
//! Temporary terms for model local variables //! Used model local variables, that will be treated as temporary terms
/*! See the comments in ModelTree::computeTemporaryTerms() */
map<expr_t, expr_t, ExprNodeLess> temporary_terms_mlv; map<expr_t, expr_t, ExprNodeLess> temporary_terms_mlv;
//! Temporary terms for residuals and derivatives //! Temporary terms for residuals and derivatives
@ -164,7 +165,7 @@ protected:
//! Computes temporary terms for the file containing parameters derivatives //! Computes temporary terms for the file containing parameters derivatives
void computeParamsDerivativesTemporaryTerms(); void computeParamsDerivativesTemporaryTerms();
//! Writes temporary terms //! Writes temporary terms
void writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, const temporary_terms_idxs_t &tt_idxs, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const; void writeTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, const temporary_terms_idxs_t &tt_idxs, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
void writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, deriv_node_temp_terms_t &tef_terms, string &concat) const; void writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, deriv_node_temp_terms_t &tef_terms, string &concat) const;
//! Compiles temporary terms //! Compiles temporary terms
void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const; void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const;
@ -174,7 +175,7 @@ protected:
void fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars, bool &message_printed) const; void fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars, bool &message_printed) const;
//! Tests if string contains more than 32 nested parens, Issue #1201 //! Tests if string contains more than 32 nested parens, Issue #1201
bool testNestedParenthesis(const string &str) const; bool testNestedParenthesis(const string &str) const;
void writeModelLocalVariableTemporaryTerms(const temporary_terms_t &tto, const map<expr_t, expr_t, ExprNodeLess> &tt, void writeModelLocalVariableTemporaryTerms(temporary_terms_t &temp_term_union,
ostream &output, ExprNodeOutputType output_type, ostream &output, ExprNodeOutputType output_type,
deriv_node_temp_terms_t &tef_terms) const; deriv_node_temp_terms_t &tef_terms) const;
//! Writes model equations //! Writes model equations

View File

@ -1519,16 +1519,13 @@ StaticModel::writeStaticModel(const string &basename,
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
temporary_terms_t temp_term_union; temporary_terms_t temp_term_union;
for (auto it : temporary_terms_mlv) writeModelLocalVariableTemporaryTerms(temp_term_union,
temp_term_union.insert(it.first);
writeModelLocalVariableTemporaryTerms(temp_term_union, temporary_terms_mlv,
model_tt_output, output_type, tef_terms); model_tt_output, output_type, tef_terms);
writeTemporaryTerms(temporary_terms_derivatives[0], writeTemporaryTerms(temporary_terms_derivatives[0],
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
model_tt_output, output_type, tef_terms); model_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[0].begin(), temporary_terms_derivatives[0].end());
writeModelEquations(model_output, output_type, temp_term_union); writeModelEquations(model_output, output_type, temp_term_union);
@ -1543,20 +1540,20 @@ StaticModel::writeStaticModel(const string &basename,
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
jacobian_tt_output, output_type, tef_terms); jacobian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[1].begin(), temporary_terms_derivatives[1].end());
}
for (const auto & first_derivative : derivatives[1])
{
int eq, var;
tie(eq, var) = vectorToTuple<2>(first_derivative.first);
expr_t d1 = first_derivative.second;
int symb_id = getSymbIDByDerivID(var);
jacobianHelper(jacobian_output, eq, symbol_table.getTypeSpecificID(symb_id), output_type); for (const auto & first_derivative : derivatives[1])
jacobian_output << "="; {
d1->writeOutput(jacobian_output, output_type, int eq, var;
temp_term_union, temporary_terms_idxs, tef_terms); tie(eq, var) = vectorToTuple<2>(first_derivative.first);
jacobian_output << ";" << endl; expr_t d1 = first_derivative.second;
int symb_id = getSymbIDByDerivID(var);
jacobianHelper(jacobian_output, eq, symbol_table.getTypeSpecificID(symb_id), output_type);
jacobian_output << "=";
d1->writeOutput(jacobian_output, output_type,
temp_term_union, temporary_terms_idxs, tef_terms);
jacobian_output << ";" << endl;
}
} }
int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr(); int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr();
@ -1567,7 +1564,6 @@ StaticModel::writeStaticModel(const string &basename,
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
hessian_tt_output, output_type, tef_terms); hessian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[2].begin(), temporary_terms_derivatives[2].end());
int k = 0; // Keep the line of a 2nd derivative in v2 int k = 0; // Keep the line of a 2nd derivative in v2
for (const auto & second_derivative : derivatives[2]) for (const auto & second_derivative : derivatives[2])
@ -1638,7 +1634,6 @@ StaticModel::writeStaticModel(const string &basename,
temp_term_union, temp_term_union,
temporary_terms_idxs, temporary_terms_idxs,
third_derivatives_tt_output, output_type, tef_terms); third_derivatives_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_derivatives[3].begin(), temporary_terms_derivatives[3].end());
int k = 0; // Keep the line of a 3rd derivative in v3 int k = 0; // Keep the line of a 3rd derivative in v3
for (const auto & third_derivative : derivatives[3]) for (const auto & third_derivative : derivatives[3])
@ -2653,9 +2648,10 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
ostringstream third_derivs_output; // Used for storing third order derivatives equations ostringstream third_derivs_output; // Used for storing third order derivatives equations
ostringstream third_derivs1_output; // Used for storing third order derivatives equations ostringstream third_derivs1_output; // Used for storing third order derivatives equations
temporary_terms_t temp_term_union;
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
writeTemporaryTerms(params_derivs_temporary_terms, {}, params_derivs_temporary_terms_idxs, model_output, output_type, tef_terms); writeTemporaryTerms(params_derivs_temporary_terms, temp_term_union, params_derivs_temporary_terms_idxs, tt_output, output_type, tef_terms);
for (const auto & residuals_params_derivative : params_derivatives.find({ 0, 1 })->second) for (const auto & residuals_params_derivative : params_derivatives.find({ 0, 1 })->second)
{ {