Temporary terms: various simplifications and added comments
parent
e89dd9cb8b
commit
3d2125287a
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,8 +1540,7 @@ 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])
|
for (const auto & first_derivative : derivatives[1])
|
||||||
{
|
{
|
||||||
int eq, var;
|
int eq, var;
|
||||||
|
@ -1558,6 +1554,7 @@ StaticModel::writeStaticModel(const string &basename,
|
||||||
temp_term_union, temporary_terms_idxs, tef_terms);
|
temp_term_union, temporary_terms_idxs, tef_terms);
|
||||||
jacobian_output << ";" << endl;
|
jacobian_output << ";" << endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr();
|
int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr();
|
||||||
// Write Hessian w.r. to endogenous only (only if 2nd order derivatives have been computed)
|
// Write Hessian w.r. to endogenous only (only if 2nd order derivatives have been computed)
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue