Commit 164a6f30 authored by Sébastien Villemot's avatar Sébastien Villemot
Browse files

Fix bug in temporary terms array in the presence of model local variables

In the presence of MLVs, the temporary terms indexing was corrupted. The code
was using the implicit assumption that the ExprNodeLess ordering was giving the
same ordering as the temporary terms indexes ordering. But MLVs can be higher
in ExprNodeLess ordering than some other temporary terms, while they have the
lowest temporary terms index, hence the bug.

Fix this by no longer relying on the ExprNodeLess ordering, and rather use a
full map<ExprNode *, int> for ModelTree::temporary_terms_idxs. By the way,
simplify the code by removing a few useless data structures (e.g.
ModelTree::temporary_terms_idxs_*).
parent a9bfd122
......@@ -2310,24 +2310,19 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
deriv_node_temp_terms_t tef_terms;
temporary_terms_t temp_term_union;
temporary_terms_idxs_t temp_term_union_idxs;
for (map<expr_t, expr_t>::const_iterator it = temporary_terms_mlv.begin();
it != temporary_terms_mlv.end(); it++)
temp_term_union.insert(it->first);
writeModelLocalVariableTemporaryTerms(temp_term_union, temporary_terms_mlv,
temporary_terms_mlv_idxs,
model_tt_output, output_type, tef_terms);
temp_term_union_idxs = temporary_terms_mlv_idxs;
writeTemporaryTerms(temporary_terms_res, temporary_terms_res_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_res,
temp_term_union,
model_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_res.begin(), temporary_terms_res.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_res_idxs.begin(), temporary_terms_res_idxs.end());
writeModelEquations(model_output, output_type, temp_term_union, temp_term_union_idxs);
writeModelEquations(model_output, output_type, temp_term_union);
int nrows = equations.size();
int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr;
......@@ -2335,12 +2330,10 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
// Writing Jacobian
if (!first_derivatives.empty())
{
writeTemporaryTerms(temporary_terms_g1, temporary_terms_g1_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_g1,
temp_term_union,
jacobian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_g1_idxs.begin(), temporary_terms_g1_idxs.end());
for (first_derivatives_t::const_iterator it = first_derivatives.begin();
it != first_derivatives.end(); it++)
......@@ -2352,7 +2345,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
jacobianHelper(jacobian_output, eq, getDynJacobianCol(var), output_type);
jacobian_output << "=";
d1->writeOutput(jacobian_output, output_type,
temp_term_union, temp_term_union_idxs, tef_terms);
temp_term_union, temporary_terms_idxs, tef_terms);
jacobian_output << ";" << endl;
}
}
......@@ -2360,12 +2353,10 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
// Writing Hessian
if (!second_derivatives.empty())
{
writeTemporaryTerms(temporary_terms_g2, temporary_terms_g2_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_g2,
temp_term_union,
hessian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_g2_idxs.begin(), temporary_terms_g2_idxs.end());
int k = 0; // Keep the line of a 2nd derivative in v2
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
......@@ -2387,7 +2378,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
{
for_sym << "g2[" << eq + 1 << "," << col_nb + 1 << "]";
hessian_output << " @inbounds " << for_sym.str() << " = ";
d2->writeOutput(hessian_output, output_type, temp_term_union, temp_term_union_idxs, tef_terms);
d2->writeOutput(hessian_output, output_type, temp_term_union, temporary_terms_idxs, tef_terms);
hessian_output << endl;
}
else
......@@ -2400,7 +2391,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
sparseHelper(2, hessian_output, k, 2, output_type);
hessian_output << "=";
d2->writeOutput(hessian_output, output_type, temp_term_union, temp_term_union_idxs, tef_terms);
d2->writeOutput(hessian_output, output_type, temp_term_union, temporary_terms_idxs, tef_terms);
hessian_output << ";" << endl;
k++;
......@@ -2432,12 +2423,10 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
// Writing third derivatives
if (!third_derivatives.empty())
{
writeTemporaryTerms(temporary_terms_g3, temporary_terms_g3_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_g3,
temp_term_union,
third_derivatives_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_g3_idxs.begin(), temporary_terms_g3_idxs.end());
int k = 0; // Keep the line of a 3rd derivative in v3
for (third_derivatives_t::const_iterator it = third_derivatives.begin();
......@@ -2461,7 +2450,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
{
for_sym << "g3[" << eq + 1 << "," << ref_col + 1 << "]";
third_derivatives_output << " @inbounds " << for_sym.str() << " = ";
d3->writeOutput(third_derivatives_output, output_type, temp_term_union, temp_term_union_idxs, tef_terms);
d3->writeOutput(third_derivatives_output, output_type, temp_term_union, temporary_terms_idxs, tef_terms);
third_derivatives_output << endl;
}
else
......@@ -2474,7 +2463,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
sparseHelper(3, third_derivatives_output, k, 2, output_type);
third_derivatives_output << "=";
d3->writeOutput(third_derivatives_output, output_type, temp_term_union, temp_term_union_idxs, tef_terms);
d3->writeOutput(third_derivatives_output, output_type, temp_term_union, temporary_terms_idxs, tef_terms);
third_derivatives_output << ";" << endl;
}
......@@ -2530,7 +2519,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
init_output << "residual = zeros(" << nrows << ", 1);";
writeDynamicModelHelper(dynamic_basename + "_resid", "residual",
dynamic_basename + "_resid_tt",
temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size(),
temporary_terms_mlv.size() + temporary_terms_res.size(),
"", init_output, end_output,
model_output, model_tt_output);
......@@ -2539,7 +2528,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
init_output << "g1 = zeros(" << nrows << ", " << dynJacobianColsNbr << ");";
writeDynamicModelHelper(dynamic_basename + "_g1", "g1",
dynamic_basename + "_g1_tt",
temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() + temporary_terms_g1_idxs.size(),
temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size(),
dynamic_basename + "_resid_tt",
init_output, end_output,
jacobian_output, jacobian_tt_output);
......@@ -2556,8 +2545,8 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
init_output << "g2 = sparse([],[],[]," << nrows << "," << hessianColsNbr << ");";
writeDynamicModelHelper(dynamic_basename + "_g2", "g2",
dynamic_basename + "_g2_tt",
temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() + temporary_terms_g1_idxs.size()
+ temporary_terms_g2_idxs.size(),
temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size()
+ temporary_terms_g2.size(),
dynamic_basename + "_g1_tt",
init_output, end_output,
hessian_output, hessian_tt_output);
......@@ -2577,8 +2566,8 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
init_output << "g3 = sparse([],[],[]," << nrows << "," << ncols << ");";
writeDynamicModelHelper(dynamic_basename + "_g3", "g3",
dynamic_basename + "_g3_tt",
temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() + temporary_terms_g1_idxs.size()
+ temporary_terms_g2_idxs.size() + temporary_terms_g3_idxs.size(),
temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size()
+ temporary_terms_g2.size() + temporary_terms_g3.size(),
dynamic_basename + "_g2_tt",
init_output, end_output,
third_derivatives_output, third_derivatives_tt_output);
......@@ -2690,10 +2679,10 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
// Write the number of temporary terms
output << "tmp_nbr = zeros(Int,4)" << endl
<< "tmp_nbr[1] = " << temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() << "# Number of temporary terms for the residuals" << endl
<< "tmp_nbr[2] = " << temporary_terms_g1_idxs.size() << "# Number of temporary terms for g1 (jacobian)" << endl
<< "tmp_nbr[3] = " << temporary_terms_g2_idxs.size() << "# Number of temporary terms for g2 (hessian)" << endl
<< "tmp_nbr[4] = " << temporary_terms_g3_idxs.size() << "# Number of temporary terms for g3 (third order derivates)" << endl << endl;
<< "tmp_nbr[1] = " << temporary_terms_mlv.size() + temporary_terms_res.size() << "# Number of temporary terms for the residuals" << endl
<< "tmp_nbr[2] = " << temporary_terms_g1.size() << "# Number of temporary terms for g1 (jacobian)" << endl
<< "tmp_nbr[3] = " << temporary_terms_g2.size() << "# Number of temporary terms for g2 (hessian)" << endl
<< "tmp_nbr[4] = " << temporary_terms_g3.size() << "# Number of temporary terms for g3 (third order derivates)" << endl << endl;
// dynamicResidTT!
output << "function dynamicResidTT!(T::Vector{Float64}," << endl
......@@ -2707,7 +2696,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
output << "function dynamicResid!(T::Vector{Float64}, residual::Vector{Float64}," << endl
<< " y::Vector{Float64}, x::Matrix{Float64}, "
<< "params::Vector{Float64}, steady_state::Vector{Float64}, it_::Int, T_flag::Bool)" << endl
<< " @assert length(T) >= " << temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() << endl
<< " @assert length(T) >= " << temporary_terms_mlv.size() + temporary_terms_res.size() << endl
<< " @assert length(residual) == " << nrows << endl
<< " @assert length(y)+size(x, 2) == " << dynJacobianColsNbr << endl
<< " @assert length(params) == " << symbol_table.param_nbr() << endl
......@@ -2732,7 +2721,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
<< " y::Vector{Float64}, x::Matrix{Float64}, "
<< "params::Vector{Float64}, steady_state::Vector{Float64}, it_::Int, T_flag::Bool)" << endl
<< " @assert length(T) >= "
<< temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() + temporary_terms_g1_idxs.size() << endl
<< temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size() << endl
<< " @assert size(g1) == (" << nrows << ", " << dynJacobianColsNbr << ")" << endl
<< " @assert length(y)+size(x, 2) == " << dynJacobianColsNbr << endl
<< " @assert length(params) == " << symbol_table.param_nbr() << endl
......@@ -2757,7 +2746,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
output << "function dynamicG2!(T::Vector{Float64}, g2::Matrix{Float64}," << endl
<< " y::Vector{Float64}, x::Matrix{Float64}, "
<< "params::Vector{Float64}, steady_state::Vector{Float64}, it_::Int, T_flag::Bool)" << endl
<< " @assert length(T) >= " << temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() + temporary_terms_g1_idxs.size() + temporary_terms_g2_idxs.size() << endl
<< " @assert length(T) >= " << temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size() + temporary_terms_g2.size() << endl
<< " @assert size(g2) == (" << nrows << ", " << hessianColsNbr << ")" << endl
<< " @assert length(y)+size(x, 2) == " << dynJacobianColsNbr << endl
<< " @assert length(params) == " << symbol_table.param_nbr() << endl
......@@ -2784,7 +2773,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
<< " y::Vector{Float64}, x::Matrix{Float64}, "
<< "params::Vector{Float64}, steady_state::Vector{Float64}, it_::Int, T_flag::Bool)" << endl
<< " @assert length(T) >= "
<< temporary_terms_mlv_idxs.size() + temporary_terms_res_idxs.size() + temporary_terms_g1_idxs.size() + temporary_terms_g2_idxs.size() + temporary_terms_g3_idxs.size() << endl
<< temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size() + temporary_terms_g2.size() + temporary_terms_g3.size() << endl
<< " @assert size(g3) == (" << nrows << ", " << ncols << ")" << endl
<< " @assert length(y)+size(x, 2) == " << dynJacobianColsNbr << endl
<< " @assert length(params) == " << symbol_table.param_nbr() << endl
......@@ -2929,10 +2918,10 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
<< modstruct << "ndynamic = " << npred+nboth+nfwrd << ";" << endl;
if (!julia)
output << modstruct << "dynamic_tmp_nbr = zeros(4,1); % Number of temporaries used for the dynamic model" << endl
<< modstruct << "dynamic_tmp_nbr(1) = " << temporary_terms_res_idxs.size() << "; % Number of temporaries used for the evaluation of the residuals" << endl
<< modstruct << "dynamic_tmp_nbr(2) = " << temporary_terms_g1_idxs.size() << "; % Number of temporaries used for the evaluation of g1 (jacobian)" << endl
<< modstruct << "dynamic_tmp_nbr(3) = " << temporary_terms_g2_idxs.size() << "; % Number of temporaries used for the evaluation of g2 (hessian)" << endl
<< modstruct << "dynamic_tmp_nbr(4) = " << temporary_terms_g3_idxs.size() << "; % Number of temporaries used for the evaluation of g3 (third order derivatives)" << endl;
<< modstruct << "dynamic_tmp_nbr(1) = " << temporary_terms_res.size() << "; % Number of temporaries used for the evaluation of the residuals" << endl
<< modstruct << "dynamic_tmp_nbr(2) = " << temporary_terms_g1.size() << "; % Number of temporaries used for the evaluation of g1 (jacobian)" << endl
<< modstruct << "dynamic_tmp_nbr(3) = " << temporary_terms_g2.size() << "; % Number of temporaries used for the evaluation of g2 (hessian)" << endl
<< modstruct << "dynamic_tmp_nbr(4) = " << temporary_terms_g3.size() << "; % Number of temporaries used for the evaluation of g3 (third order derivatives)" << endl;
// Write equation tags
if (julia)
......
......@@ -373,7 +373,7 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<NumConstNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
else
output << datatree.num_constants.get(id);
......@@ -811,7 +811,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<VariableNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
}
return;
......@@ -2398,7 +2398,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<UnaryOpNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......@@ -4167,7 +4167,7 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<BinaryOpNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......@@ -5541,7 +5541,7 @@ TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<TrinaryOpNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......@@ -6751,7 +6751,7 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<ExternalFunctionNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......@@ -7023,7 +7023,7 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<FirstDerivExternalFunctionNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......@@ -7423,7 +7423,7 @@ SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<SecondDerivExternalFunctionNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......@@ -7749,7 +7749,7 @@ VarExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "T" << idx;
else
output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< temporary_terms_idxs[distance(temporary_terms.begin(), it)] + 1
<< temporary_terms_idxs.find(const_cast<VarExpectationNode *>(this))->second
<< RIGHT_ARRAY_SUBSCRIPT(output_type);
return;
}
......
......@@ -46,7 +46,7 @@ struct ExprNodeLess;
/*! They are ordered by index number thanks to ExprNodeLess */
typedef set<expr_t, ExprNodeLess> temporary_terms_t;
/*! Keeps track of array indices of temporary_terms for writing */
typedef vector<int> temporary_terms_idxs_t;
typedef map<expr_t, int> temporary_terms_idxs_t;
//! set of temporary terms used in a block
typedef set<int> temporary_terms_inuse_t;
......
......@@ -1169,102 +1169,54 @@ ModelTree::computeTemporaryTerms(bool is_matlab)
temp_terms_map,
is_matlab, eThirdDeriv);
int idx = 0;
for (map<NodeTreeReference, temporary_terms_t>::const_iterator it = temp_terms_map.begin();
it != temp_terms_map.end(); it++)
{
temporary_terms.insert(it->second.begin(), it->second.end());
temporary_terms_idxs.push_back(idx++);
}
temporary_terms_res = temp_terms_map[eResiduals];
temporary_terms_g1 = temp_terms_map[eFirstDeriv];
temporary_terms_g2 = temp_terms_map[eSecondDeriv];
temporary_terms_g3 = temp_terms_map[eThirdDeriv];
temporary_terms_mlv_idxs.clear();
temporary_terms_res_idxs.clear();
temporary_terms_g1_idxs.clear();
temporary_terms_g2_idxs.clear();
temporary_terms_g3_idxs.clear();
idx = 0;
int idx = 1;
for (map<expr_t, expr_t>::const_iterator it = temporary_terms_mlv.begin();
it != temporary_terms_mlv.end(); it++)
temporary_terms_mlv_idxs.push_back(idx++);
temporary_terms_idxs[it->first] = idx++;
for (temporary_terms_t::const_iterator it = temporary_terms_res.begin();
it != temporary_terms_res.end(); it++)
temporary_terms_res_idxs.push_back(idx++);
temporary_terms_idxs[*it] = idx++;
for (temporary_terms_t::const_iterator it = temporary_terms_g1.begin();
it != temporary_terms_g1.end(); it++)
temporary_terms_g1_idxs.push_back(idx++);
temporary_terms_idxs[*it] = idx++;
for (temporary_terms_t::const_iterator it = temporary_terms_g2.begin();
it != temporary_terms_g2.end(); it++)
temporary_terms_g2_idxs.push_back(idx++);
temporary_terms_idxs[*it] = idx++;
for (temporary_terms_t::const_iterator it = temporary_terms_g3.begin();
it != temporary_terms_g3.end(); it++)
temporary_terms_g3_idxs.push_back(idx++);
}
void
ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output,
ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const
{
temporary_terms_idxs_t tti, ttm1i;
writeTemporaryTerms(tt, tti, ttm1, ttm1i, output, output_type, tef_terms);
/*
// Local var used to keep track of temp nodes already written
temporary_terms_t tt2 = ttm1;
for (temporary_terms_t::const_iterator it = tt.begin();
it != tt.end(); it++)
if (ttm1.find(*it) == ttm1.end())
{
if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL)
(*it)->writeExternalFunctionOutput(output, output_type, tt2, tef_terms);
if (IS_C(output_type))
output << "double ";
else if (IS_JULIA(output_type))
output << " @inbounds const ";
(*it)->writeOutput(output, output_type, tt, tef_terms);
output << " = ";
(*it)->writeOutput(output, output_type, tt2, tef_terms);
if (IS_C(output_type) || IS_MATLAB(output_type))
output << ";";
output << endl;
// Insert current node into tt2
tt2.insert(*it);
}
*/
temporary_terms_idxs[*it] = idx++;
}
void
ModelTree::writeModelLocalVariableTemporaryTerms(const temporary_terms_t &tto, const map<expr_t, expr_t> &tt,
const temporary_terms_idxs_t &ttidxs,
ostream &output, ExprNodeOutputType output_type,
deriv_node_temp_terms_t &tef_terms) const
{
temporary_terms_t tt2;
temporary_terms_idxs_t tt2idxs;
int ttidx = 0;
for (map<expr_t, expr_t>::const_iterator it = tt.begin();
it != tt.end(); it++, ttidx++)
it != tt.end(); it++)
{
if (IS_C(output_type))
output << "double ";
else if (IS_JULIA(output_type))
output << " @inbounds const ";
it->first->writeOutput(output, output_type, tto, ttidxs, tef_terms);
it->first->writeOutput(output, output_type, tto, temporary_terms_idxs, tef_terms);
output << " = ";
it->second->writeOutput(output, output_type, tt2, tt2idxs, tef_terms);
it->second->writeOutput(output, output_type, tt2, temporary_terms_idxs, tef_terms);
if (IS_C(output_type) || IS_MATLAB(output_type))
output << ";";
......@@ -1272,33 +1224,30 @@ ModelTree::writeModelLocalVariableTemporaryTerms(const temporary_terms_t &tto, c
// Insert current node into tt2
tt2.insert(it->first);
tt2idxs.push_back(ttidxs[ttidx]);
}
}
void
ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_idxs_t &ttidxs,
const temporary_terms_t &ttm1, const temporary_terms_idxs_t &ttm1idxs,
ModelTree::writeTemporaryTerms(const temporary_terms_t &tt,
const temporary_terms_t &ttm1,
ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const
{
// Local var used to keep track of temp nodes already written
temporary_terms_t tt2 = ttm1;
temporary_terms_idxs_t tt2idxs = ttm1idxs;
int ttidx = 0;
for (temporary_terms_t::const_iterator it = tt.begin();
it != tt.end(); it++, ttidx++)
it != tt.end(); it++)
{
if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL)
(*it)->writeExternalFunctionOutput(output, output_type, tt2, tt2idxs, tef_terms);
(*it)->writeExternalFunctionOutput(output, output_type, tt2, temporary_terms_idxs, tef_terms);
if (IS_C(output_type))
output << "double ";
else if (IS_JULIA(output_type))
output << " @inbounds ";
(*it)->writeOutput(output, output_type, tt, ttidxs, tef_terms);
(*it)->writeOutput(output, output_type, tt, temporary_terms_idxs, tef_terms);
output << " = ";
(*it)->writeOutput(output, output_type, tt2, tt2idxs, tef_terms);
(*it)->writeOutput(output, output_type, tt2, temporary_terms_idxs, tef_terms);
if (IS_C(output_type) || IS_MATLAB(output_type))
output << ";";
......@@ -1306,7 +1255,6 @@ ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, const temporary_term
// Insert current node into tt2
tt2.insert(*it);
tt2idxs.push_back(ttidxs[ttidx]);
}
}
......@@ -1607,13 +1555,12 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type)
{
temporary_terms_t tt;
temporary_terms_idxs_t ttidxs;
writeModelEquations(output, output_type, tt, ttidxs);
writeModelEquations(output, output_type, tt);
}
void
ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
const temporary_terms_idxs_t &temporary_terms_idxs) const
const temporary_terms_t &temporary_terms) const
{
for (int eq = 0; eq < (int) equations.size(); eq++)
{
......
......@@ -143,11 +143,6 @@ protected:
temporary_terms_t temporary_terms_g3;
temporary_terms_idxs_t temporary_terms_idxs;
temporary_terms_idxs_t temporary_terms_mlv_idxs;
temporary_terms_idxs_t temporary_terms_res_idxs;
temporary_terms_idxs_t temporary_terms_g1_idxs;
temporary_terms_idxs_t temporary_terms_g2_idxs;
temporary_terms_idxs_t temporary_terms_g3_idxs;
//! Temporary terms for the file containing parameters derivatives
temporary_terms_t params_derivs_temporary_terms;
......@@ -191,9 +186,6 @@ protected:
void computeParamsDerivativesTemporaryTerms();
//! Writes temporary terms
void writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
void writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_idxs_t &ttidxs,
const temporary_terms_t &ttm1, const temporary_terms_idxs_t &ttm1idxs,
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;
//! 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;
......@@ -207,14 +199,12 @@ protected:
/*! No temporary term is used in the output, so that local parameters declarations can be safely put before temporary terms declaration in the output files */
void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
void writeModelLocalVariableTemporaryTerms(const temporary_terms_t &tto, const map<expr_t, expr_t> &tt,
const temporary_terms_idxs_t &ttidxs,
ostream &output, ExprNodeOutputType output_type,
deriv_node_temp_terms_t &tef_terms) const;
//! Writes model equations
void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
void writeModelEquations(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
const temporary_terms_idxs_t &temporary_terms_idxs) const;
const temporary_terms_t &temporary_terms) const;
//! Writes JSON model equations
//! if residuals = true, we are writing the dynamic/static model.
//! Otherwise, just the model equations (with line numbers, no tmp terms)
......
......@@ -1326,24 +1326,19 @@ StaticModel::writeStaticModel(const string &basename,
deriv_node_temp_terms_t tef_terms;
temporary_terms_t temp_term_union;
temporary_terms_idxs_t temp_term_union_idxs;
for (map<expr_t, expr_t>::const_iterator it = temporary_terms_mlv.begin();
it != temporary_terms_mlv.end(); it++)
temp_term_union.insert(it->first);
writeModelLocalVariableTemporaryTerms(temp_term_union, temporary_terms_mlv,
temporary_terms_mlv_idxs,
model_tt_output, output_type, tef_terms);
temp_term_union_idxs = temporary_terms_mlv_idxs;
writeTemporaryTerms(temporary_terms_res, temporary_terms_res_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_res,
temp_term_union,
model_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_res.begin(), temporary_terms_res.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_res_idxs.begin(), temporary_terms_res_idxs.end());
writeModelEquations(model_output, output_type, temp_term_union, temp_term_union_idxs);
writeModelEquations(model_output, output_type, temp_term_union);
int nrows = equations.size();
int JacobianColsNbr = symbol_table.endo_nbr();
......@@ -1352,12 +1347,10 @@ StaticModel::writeStaticModel(const string &basename,
// Write Jacobian w.r. to endogenous only
if (!first_derivatives.empty())
{
writeTemporaryTerms(temporary_terms_g1, temporary_terms_g1_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_g1,
temp_term_union,
jacobian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_g1_idxs.begin(), temporary_terms_g1_idxs.end());
}
for (first_derivatives_t::const_iterator it = first_derivatives.begin();
it != first_derivatives.end(); it++)
......@@ -1369,7 +1362,7 @@ StaticModel::writeStaticModel(const string &basename,
jacobianHelper(jacobian_output, eq, symbol_table.getTypeSpecificID(symb_id), output_type);
jacobian_output << "=";
d1->writeOutput(jacobian_output, output_type,
temp_term_union, temp_term_union_idxs, tef_terms);
temp_term_union, temporary_terms_idxs, tef_terms);
jacobian_output << ";" << endl;
}
......@@ -1377,12 +1370,10 @@ StaticModel::writeStaticModel(const string &basename,
// Write Hessian w.r. to endogenous only (only if 2nd order derivatives have been computed)
if (!second_derivatives.empty())
{
writeTemporaryTerms(temporary_terms_g2, temporary_terms_g2_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_g2,
temp_term_union,
hessian_tt_output, output_type, tef_terms);
temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end());
temp_term_union_idxs.insert(temp_term_union_idxs.end(),
temporary_terms_g2_idxs.begin(), temporary_terms_g2_idxs.end());
int k = 0; // Keep the line of a 2nd derivative in v2
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
......@@ -1448,12 +1439,10 @@ StaticModel::writeStaticModel(const string &basename,
// Writing third derivatives
if (!third_derivatives.empty())
{
writeTemporaryTerms(temporary_terms_g3, temporary_terms_g3_idxs,
temp_term_union, temp_term_union_idxs,
writeTemporaryTerms(temporary_terms_g3,
temp_term_union,
third_derivatives_tt_output, output_type, tef_terms);