fix nested parens for params derivatives. closes #1201

time-shift
Houtan Bastani 2017-01-05 17:31:48 +01:00
parent a5d3ef21ad
commit 7fb7dd7ccc
2 changed files with 315 additions and 268 deletions

View File

@ -4016,6 +4016,133 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
&& !hessian_params_derivatives.size())
return;
ExprNodeOutputType output_type = (julia ? oJuliaDynamicModel : oMatlabDynamicModel);
ostringstream model_local_vars_output; // Used for storing model local vars
ostringstream model_output; // Used for storing model temp vars and equations
ostringstream jacobian_output; // Used for storing jacobian equations
ostringstream hessian_output; // Used for storing Hessian equations
ostringstream hessian1_output; // Used for storing Hessian equations
ostringstream third_derivs_output; // Used for storing third order derivatives equations
ostringstream third_derivs1_output; // Used for storing third order derivatives equations
deriv_node_temp_terms_t tef_terms;
writeModelLocalVariables(model_local_vars_output, output_type, tef_terms);
temporary_terms_t temp_terms_empty;
writeTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, output_type, tef_terms);
for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin();
it != residuals_params_derivatives.end(); it++)
{
int eq = it->first.first;
int param = it->first.second;
expr_t d1 = it->second;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
jacobian_output << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << param_col
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d1->writeOutput(jacobian_output, output_type, params_derivs_temporary_terms, tef_terms);
jacobian_output << ";" << endl;
}
for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin();
it != jacobian_params_derivatives.end(); it++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param = it->first.second.second;
expr_t d2 = it->second;
int var_col = getDynJacobianCol(var) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
hessian_output << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << var_col
<< ", " << param_col << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d2->writeOutput(hessian_output, output_type, params_derivs_temporary_terms, tef_terms);
hessian_output << ";" << endl;
}
int i = 1;
for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin();
it != residuals_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int param1 = it->first.second.first;
int param2 = it->first.second.second;
expr_t d2 = it->second;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
hessian1_output << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(hessian1_output, output_type, params_derivs_temporary_terms, tef_terms);
hessian1_output << ";" << endl;
}
i = 1;
for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin();
it != jacobian_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param1 = it->first.second.second.first;
int param2 = it->first.second.second.second;
expr_t d2 = it->second;
int var_col = getDynJacobianCol(var) + 1;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
third_derivs_output << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(third_derivs_output, output_type, params_derivs_temporary_terms, tef_terms);
third_derivs_output << ";" << endl;
}
i = 1;
for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin();
it != hessian_params_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var1 = it->first.second.first;
int var2 = it->first.second.second.first;
int param = it->first.second.second.second;
expr_t d2 = it->second;
int var1_col = getDynJacobianCol(var1) + 1;
int var2_col = getDynJacobianCol(var2) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
third_derivs1_output << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(third_derivs1_output, output_type, params_derivs_temporary_terms, tef_terms);
third_derivs1_output << ";" << endl;
}
string filename = julia ? basename + "DynamicParamsDerivs.jl" : basename + "_params_derivs.m";
ofstream paramsDerivsFile;
paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary);
@ -4025,9 +4152,18 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
exit(EXIT_FAILURE);
}
ExprNodeOutputType output_type = (julia ? oJuliaDynamicModel : oMatlabDynamicModel);
if (!julia)
{
// Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201
map<string, string> tmp_paren_vars;
bool message_printed = false;
fixNestedParenthesis(model_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(model_local_vars_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(jacobian_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(hessian_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(hessian1_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(third_derivs_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(third_derivs1_output, tmp_paren_vars, message_printed);
paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = " << basename << "_params_derivs(y, x, params, steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" << endl
<< "%" << endl
<< "% Compute the derivatives of the dynamic model with respect to the parameters" << endl
@ -4071,7 +4207,26 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
<< "%" << endl
<< "%" << endl
<< "% Warning : this file is generated automatically by Dynare" << endl
<< "% from model file (.mod)" << endl << endl;
<< "% from model file (.mod)" << endl << endl
<< model_local_vars_output.str()
<< model_output.str()
<< "rp = zeros(" << equation_number() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< jacobian_output.str()
<< "gp = zeros(" << equation_number() << ", " << dynJacobianColsNbr << ", " << symbol_table.param_nbr() << ");" << endl
<< hessian_output.str()
<< "if nargout >= 3" << endl
<< "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl
<< hessian1_output.str()
<< "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl
<< third_derivs_output.str()
<< "end" << endl
<< "if nargout >= 5" << endl
<< "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl
<< third_derivs1_output.str()
<< "end" << endl
<< "end" << endl;
}
else
paramsDerivsFile << "module " << basename << "DynamicParamsDerivs" << endl
<< "#" << endl
@ -4080,158 +4235,24 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
<< "#" << endl
<< "export params_derivs" << endl << endl
<< "function params_derivs(y, x, paramssteady_state, it_, "
<< "ss_param_deriv, ss_param_2nd_deriv)" << endl;
deriv_node_temp_terms_t tef_terms;
writeModelLocalVariables(paramsDerivsFile, output_type, tef_terms);
temporary_terms_t temp_terms_empty;
writeTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, paramsDerivsFile, output_type, tef_terms);
// Write parameter derivative
paramsDerivsFile << "rp = zeros(" << equation_number() << ", "
<< symbol_table.param_nbr() << ");" << endl;
for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin();
it != residuals_params_derivatives.end(); it++)
{
int eq = it->first.first;
int param = it->first.second;
expr_t d1 = it->second;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
paramsDerivsFile << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << param_col
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d1->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
// Write jacobian derivatives
paramsDerivsFile << "gp = zeros(" << equation_number() << ", " << dynJacobianColsNbr << ", "
<< symbol_table.param_nbr() << ");" << endl;
for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin();
it != jacobian_params_derivatives.end(); it++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param = it->first.second.second;
expr_t d2 = it->second;
int var_col = getDynJacobianCol(var) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
paramsDerivsFile << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << var_col
<< ", " << param_col << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
if (!julia)
// If nargout >= 3...
paramsDerivsFile << "if nargout >= 3" << endl;
// Write parameter second derivatives (only if nargout >= 3)
paramsDerivsFile << "rpp = zeros(" << residuals_params_second_derivatives.size()
<< ",4);" << endl;
int i = 1;
for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin();
it != residuals_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int param1 = it->first.second.first;
int param2 = it->first.second.second;
expr_t d2 = it->second;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
paramsDerivsFile << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
// Write jacobian second derivatives (only if nargout >= 3)
paramsDerivsFile << "gpp = zeros(" << jacobian_params_second_derivatives.size()
<< ",5);" << endl;
i = 1;
for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin();
it != jacobian_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param1 = it->first.second.second.first;
int param2 = it->first.second.second.second;
expr_t d2 = it->second;
int var_col = getDynJacobianCol(var) + 1;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
paramsDerivsFile << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
if (!julia)
// If nargout >= 5...
paramsDerivsFile << "end" << endl
<< "if nargout >= 5" << endl;
// Write hessian derivatives (only if nargout >= 5)
paramsDerivsFile << "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl;
i = 1;
for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin();
it != hessian_params_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var1 = it->first.second.first;
int var2 = it->first.second.second.first;
int param = it->first.second.second.second;
expr_t d2 = it->second;
int var1_col = getDynJacobianCol(var1) + 1;
int var2_col = getDynJacobianCol(var2) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
paramsDerivsFile << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
if (julia)
paramsDerivsFile << "(rp, gp, rpp, gpp, hp)" << endl;
paramsDerivsFile << "end" << endl
<< "ss_param_deriv, ss_param_2nd_deriv)" << endl
<< model_local_vars_output.str()
<< model_output.str()
<< "rp = zeros(" << equation_number() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< jacobian_output.str()
<< "gp = zeros(" << equation_number() << ", " << dynJacobianColsNbr << ", " << symbol_table.param_nbr() << ");" << endl
<< hessian_output.str()
<< "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl
<< hessian1_output.str()
<< "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl
<< third_derivs_output.str()
<< "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl
<< third_derivs1_output.str()
<< "(rp, gp, rpp, gpp, hp)" << endl
<< "end" << endl
<< "end" << endl;
paramsDerivsFile.close();
}

View File

@ -2181,8 +2181,139 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
&& !hessian_params_derivatives.size())
return;
string filename = julia ? basename + "StaticParamsDerivs.jl" : basename + "_static_params_derivs.m";
ExprNodeOutputType output_type = (julia ? oJuliaStaticModel : oMatlabStaticModel);
ostringstream model_local_vars_output; // Used for storing model local vars
ostringstream model_output; // Used for storing model
ostringstream jacobian_output; // Used for storing jacobian equations
ostringstream hessian_output; // Used for storing Hessian equations
ostringstream hessian1_output; // Used for storing Hessian equations
ostringstream third_derivs_output; // Used for storing third order derivatives equations
ostringstream third_derivs1_output; // Used for storing third order derivatives equations
deriv_node_temp_terms_t tef_terms;
writeModelLocalVariables(model_local_vars_output, output_type, tef_terms);
temporary_terms_t temp_terms_empty;
writeTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, output_type, tef_terms);
for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin();
it != residuals_params_derivatives.end(); it++)
{
int eq = it->first.first;
int param = it->first.second;
expr_t d1 = it->second;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
jacobian_output << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< eq+1 << ", " << param_col
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d1->writeOutput(jacobian_output, output_type, params_derivs_temporary_terms, tef_terms);
jacobian_output << ";" << endl;
}
for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin();
it != jacobian_params_derivatives.end(); it++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param = it->first.second.second;
expr_t d2 = it->second;
int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
hessian_output << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< eq+1 << ", " << var_col << ", " << param_col
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d2->writeOutput(hessian_output, output_type, params_derivs_temporary_terms, tef_terms);
hessian_output << ";" << endl;
}
int i = 1;
for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin();
it != residuals_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int param1 = it->first.second.first;
int param2 = it->first.second.second;
expr_t d2 = it->second;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
hessian1_output << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(hessian1_output, output_type, params_derivs_temporary_terms, tef_terms);
hessian1_output << ";" << endl;
}
i = 1;
for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin();
it != jacobian_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param1 = it->first.second.second.first;
int param2 = it->first.second.second.second;
expr_t d2 = it->second;
int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
third_derivs_output << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(third_derivs_output, output_type, params_derivs_temporary_terms, tef_terms);
third_derivs_output << ";" << endl;
}
i = 1;
for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin();
it != hessian_params_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var1 = it->first.second.first;
int var2 = it->first.second.second.first;
int param = it->first.second.second.second;
expr_t d2 = it->second;
int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1;
int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
third_derivs1_output << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(third_derivs1_output, output_type, params_derivs_temporary_terms, tef_terms);
third_derivs1_output << ";" << endl;
}
ofstream paramsDerivsFile;
string filename = julia ? basename + "StaticParamsDerivs.jl" : basename + "_static_params_derivs.m";
paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary);
if (!paramsDerivsFile.is_open())
{
@ -2190,9 +2321,19 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
exit(EXIT_FAILURE);
}
ExprNodeOutputType output_type = (julia ? oJuliaStaticModel : oMatlabStaticModel);
if (!julia)
{
// Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201
map<string, string> tmp_paren_vars;
bool message_printed = false;
fixNestedParenthesis(model_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(model_local_vars_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(jacobian_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(hessian_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(hessian1_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(third_derivs_output, tmp_paren_vars, message_printed);
fixNestedParenthesis(third_derivs1_output, tmp_paren_vars, message_printed);
paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = " << basename << "_static_params_derivs(y, x, params)" << endl
<< "%" << endl
<< "% Status : Computes derivatives of the static model with respect to the parameters" << endl
@ -2224,7 +2365,27 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
<< "%" << endl
<< "%" << endl
<< "% Warning : this file is generated automatically by Dynare" << endl
<< "% from model file (.mod)" << endl << endl;
<< "% from model file (.mod)" << endl << endl
<< model_local_vars_output.str()
<< model_output.str()
<< "rp = zeros(" << equation_number() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< jacobian_output.str()
<< "gp = zeros(" << equation_number() << ", " << symbol_table.endo_nbr() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< hessian_output.str()
<< "if nargout >= 3" << endl
<< "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl
<< hessian1_output.str()
<< "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl
<< third_derivs_output.str()
<< "end" << endl
<< "if nargout >= 5" << endl
<< "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl
<< third_derivs1_output.str()
<< "end" << endl
<< "end" << endl;
}
else
paramsDerivsFile << "module " << basename << "StaticParamsDerivs" << endl
<< "#" << endl
@ -2232,159 +2393,24 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
<< "# from " << basename << ".mod" << endl
<< "#" << endl
<< "export params_derivs" << endl << endl
<< "function params_derivs(y, x, params)" << endl;
deriv_node_temp_terms_t tef_terms;
writeModelLocalVariables(paramsDerivsFile, output_type, tef_terms);
temporary_terms_t temp_terms_empty;
writeTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, paramsDerivsFile, output_type, tef_terms);
// Write parameter derivative
paramsDerivsFile << "rp = zeros(" << equation_number() << ", "
<< symbol_table.param_nbr() << ");" << endl;
for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin();
it != residuals_params_derivatives.end(); it++)
{
int eq = it->first.first;
int param = it->first.second;
expr_t d1 = it->second;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
paramsDerivsFile << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< eq+1 << ", " << param_col
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d1->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
// Write jacobian derivatives
paramsDerivsFile << "gp = zeros(" << equation_number() << ", " << symbol_table.endo_nbr() << ", "
<< symbol_table.param_nbr() << ");" << endl;
for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin();
it != jacobian_params_derivatives.end(); it++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param = it->first.second.second;
expr_t d2 = it->second;
int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
paramsDerivsFile << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type)
<< eq+1 << ", " << var_col << ", " << param_col
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
if (!julia)
// If nargout >= 3...
paramsDerivsFile << "if nargout >= 3" << endl;
// Write parameter second derivatives (only if nargout >= 3)
paramsDerivsFile << "rpp = zeros(" << residuals_params_second_derivatives.size()
<< ",4);" << endl;
int i = 1;
for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin();
it != residuals_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int param1 = it->first.second.first;
int param2 = it->first.second.second;
expr_t d2 = it->second;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
paramsDerivsFile << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
// Write jacobian second derivatives (only if nargout >= 3)
paramsDerivsFile << "gpp = zeros(" << jacobian_params_second_derivatives.size()
<< ",5);" << endl;
i = 1;
for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin();
it != jacobian_params_second_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var = it->first.second.first;
int param1 = it->first.second.second.first;
int param2 = it->first.second.second.second;
expr_t d2 = it->second;
int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
paramsDerivsFile << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl
<< "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
if (!julia)
// If nargout >= 5...
paramsDerivsFile << "end" << endl
<< "if nargout >= 5" << endl;
// Write hessian derivatives (only if nargout >= 5)
paramsDerivsFile << "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl;
i = 1;
for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin();
it != hessian_params_derivatives.end(); ++it, i++)
{
int eq = it->first.first;
int var1 = it->first.second.first;
int var2 = it->first.second.second.first;
int param = it->first.second.second.second;
expr_t d2 = it->second;
int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1;
int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1;
int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
paramsDerivsFile << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl
<< "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5"
<< RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
d2->writeOutput(paramsDerivsFile, output_type, params_derivs_temporary_terms, tef_terms);
paramsDerivsFile << ";" << endl;
}
if (julia)
paramsDerivsFile << "(rp, gp, rpp, gpp, hp)" << endl;
paramsDerivsFile << "end" << endl
<< "function params_derivs(y, x, params)" << endl
<< model_local_vars_output.str()
<< model_output.str()
<< "rp = zeros(" << equation_number() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< jacobian_output.str()
<< "gp = zeros(" << equation_number() << ", " << symbol_table.endo_nbr() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< hessian_output.str()
<< "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl
<< hessian1_output.str()
<< "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl
<< third_derivs_output.str()
<< "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl
<< third_derivs1_output.str()
<< "(rp, gp, rpp, gpp, hp)" << endl
<< "end" << endl
<< "end" << endl;
paramsDerivsFile.close();
}