first iteration of fix for nested parenthesis in matlab. #1201
parent
69306b5a82
commit
3b20d41a92
|
@ -2344,11 +2344,12 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia
|
||||||
if (output_type == oMatlabDynamicModel)
|
if (output_type == oMatlabDynamicModel)
|
||||||
{
|
{
|
||||||
// Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201
|
// Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201
|
||||||
testNestedParenthesis(model_output);
|
map<string, string> tmp_paren_vars;
|
||||||
testNestedParenthesis(model_local_vars_output);
|
fixNestedParenthesis(model_output, tmp_paren_vars);
|
||||||
testNestedParenthesis(jacobian_output);
|
fixNestedParenthesis(model_local_vars_output, tmp_paren_vars);
|
||||||
testNestedParenthesis(hessian_output);
|
fixNestedParenthesis(jacobian_output, tmp_paren_vars);
|
||||||
testNestedParenthesis(third_derivatives_output);
|
fixNestedParenthesis(hessian_output, tmp_paren_vars);
|
||||||
|
fixNestedParenthesis(third_derivatives_output, tmp_paren_vars);
|
||||||
|
|
||||||
DynamicOutput << "%" << endl
|
DynamicOutput << "%" << endl
|
||||||
<< "% Model equations" << endl
|
<< "% Model equations" << endl
|
||||||
|
|
|
@ -1293,25 +1293,116 @@ ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, const temporary_term
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ModelTree::testNestedParenthesis(const ostringstream &output) const
|
ModelTree::fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars) const
|
||||||
{
|
{
|
||||||
string str = output.str();
|
string str = output.str();
|
||||||
int open = 0;
|
int open = 0;
|
||||||
for (string::iterator it = str.begin(); it != str.end(); it++)
|
int first_open_paren = 0;
|
||||||
|
int matching_paren = 0;
|
||||||
|
bool hit_limit = false;
|
||||||
|
int i1 = 0;
|
||||||
|
map<string, string>::iterator it;
|
||||||
|
for (int i = 0; i < str.length(); i++)
|
||||||
{
|
{
|
||||||
if (*it == '(')
|
if (str.at(i) == '(')
|
||||||
open++;
|
|
||||||
else if (*it == ')')
|
|
||||||
open--;
|
|
||||||
if (open > 32)
|
|
||||||
{
|
{
|
||||||
cout << "Error: A .m file created by Dynare will have more than 32 nested parenthesis. Matlab cannot support this. "
|
if (open == 0)
|
||||||
<< "Please use the use_dll option of the model block to circumnavigate this problem." << endl
|
first_open_paren = i;
|
||||||
<< " If you have not yet set up a compiler on your system, see the Matlab documentation for doing so." << endl
|
open++;
|
||||||
<< " For Windows, see: https://www.mathworks.com/help/matlab/matlab_external/install-mingw-support-package.html" << endl;
|
}
|
||||||
exit(EXIT_FAILURE);
|
else if (str.at(i) == ')')
|
||||||
|
{
|
||||||
|
open--;
|
||||||
|
if (open == 0)
|
||||||
|
matching_paren = i;
|
||||||
|
}
|
||||||
|
if (open > 32)
|
||||||
|
hit_limit = true;
|
||||||
|
|
||||||
|
if (hit_limit && open == 0)
|
||||||
|
{
|
||||||
|
cerr << "Warning: A .m file created by Dynare will have more than 32 nested parenthesis. Matlab cannot support this. " << endl
|
||||||
|
<< " We are going to modify, albeit inefficiently, this output to have fewer than 32 nested parenthesis. " << endl
|
||||||
|
<< " It would hence behoove you to use the use_dll option of the model block to circumnavigate this problem." << endl
|
||||||
|
<< " If you have not yet set up a compiler on your system, see the Matlab documentation for doing so." << endl
|
||||||
|
<< " For Windows, see: https://www.mathworks.com/help/matlab/matlab_external/install-mingw-support-package.html" << endl << endl;
|
||||||
|
|
||||||
|
string str1 = str.substr(first_open_paren, matching_paren - first_open_paren + 1);
|
||||||
|
string repstr = "";
|
||||||
|
string varname;
|
||||||
|
while (testNestedParenthesis(str1))
|
||||||
|
{
|
||||||
|
int open_paren_idx = -1;
|
||||||
|
int match_paren_idx = -1;
|
||||||
|
int last_open_paren = -1;
|
||||||
|
for (int j = 0; j < str1.length(); j++)
|
||||||
|
{
|
||||||
|
if (str1.at(j) == '(')
|
||||||
|
{
|
||||||
|
// don't match, e.g. y(1)
|
||||||
|
size_t idx = str1.find_last_of("*/-+", j - 1);
|
||||||
|
if (j == 0 || (idx != string::npos && idx == j - 1))
|
||||||
|
open_paren_idx = j;
|
||||||
|
last_open_paren = j;
|
||||||
|
}
|
||||||
|
else if (str1.at(j) == ')')
|
||||||
|
{
|
||||||
|
// don't match, e.g. y(1)
|
||||||
|
size_t idx = str1.find_last_not_of("0123456789", j - 1);
|
||||||
|
if (idx != string::npos && idx != last_open_paren)
|
||||||
|
match_paren_idx = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open_paren_idx != -1 && match_paren_idx != -1)
|
||||||
|
{
|
||||||
|
string val = str1.substr(open_paren_idx, match_paren_idx - open_paren_idx + 1);
|
||||||
|
it = tmp_paren_vars.find(val);
|
||||||
|
if (it == tmp_paren_vars.end())
|
||||||
|
{
|
||||||
|
varname = "paren32_tmp_var_" + to_string(i1++);
|
||||||
|
repstr = repstr + varname + " = " + val + ";\n";
|
||||||
|
tmp_paren_vars[val] = varname;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
varname = it->second;
|
||||||
|
str1.replace(open_paren_idx, match_paren_idx - open_paren_idx + 1, varname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it = tmp_paren_vars.find(str1);
|
||||||
|
if (it == tmp_paren_vars.end())
|
||||||
|
{
|
||||||
|
varname = "paren32_tmp_var_" + to_string(i1++);
|
||||||
|
repstr = repstr + varname + " = " + str1 + ";\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
varname = it->second;
|
||||||
|
str.replace(first_open_paren, matching_paren - first_open_paren + 1, varname);
|
||||||
|
size_t insertLoc = str.find_last_of("\n", first_open_paren);
|
||||||
|
str.insert(insertLoc + 1, repstr);
|
||||||
|
hit_limit = false;
|
||||||
|
i = -1;
|
||||||
|
first_open_paren = matching_paren = open = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
output.str(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ModelTree::testNestedParenthesis(const string &str) const
|
||||||
|
{
|
||||||
|
int open = 0;
|
||||||
|
for (int i = 0; i < str.length(); i++)
|
||||||
|
{
|
||||||
|
if (str.at(i) == '(')
|
||||||
|
open++;
|
||||||
|
else if (str.at(i) == ')')
|
||||||
|
open--;
|
||||||
|
if (open > 32)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -190,8 +190,10 @@ protected:
|
||||||
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;
|
||||||
//! Adds informations for simulation in a binary file
|
//! Adds informations for simulation in a binary file
|
||||||
void Write_Inf_To_Bin_File(const string &basename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const;
|
void Write_Inf_To_Bin_File(const string &basename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const;
|
||||||
//! Checks for the number of nested parenthesis, issues error if > 32. Issue #1201
|
//! Fixes output when there are more than 32 nested parens, Issue #1201
|
||||||
void testNestedParenthesis(const ostringstream &output) const;
|
void fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars) const;
|
||||||
|
//! Tests if string contains more than 32 nested parens, Issue #1201
|
||||||
|
bool testNestedParenthesis(const string &str) const;
|
||||||
//! Writes model local variables
|
//! Writes model local variables
|
||||||
/*! 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 */
|
/*! 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 writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
|
||||||
|
|
|
@ -1399,11 +1399,12 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) c
|
||||||
if (output_type == oMatlabStaticModel)
|
if (output_type == oMatlabStaticModel)
|
||||||
{
|
{
|
||||||
// Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201
|
// Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201
|
||||||
testNestedParenthesis(model_output);
|
map<string, string> tmp_paren_vars;
|
||||||
testNestedParenthesis(model_local_vars_output);
|
fixNestedParenthesis(model_output, tmp_paren_vars);
|
||||||
testNestedParenthesis(jacobian_output);
|
fixNestedParenthesis(model_local_vars_output, tmp_paren_vars);
|
||||||
testNestedParenthesis(hessian_output);
|
fixNestedParenthesis(jacobian_output, tmp_paren_vars);
|
||||||
testNestedParenthesis(third_derivatives_output);
|
fixNestedParenthesis(hessian_output, tmp_paren_vars);
|
||||||
|
fixNestedParenthesis(third_derivatives_output, tmp_paren_vars);
|
||||||
|
|
||||||
StaticOutput << "residual = zeros( " << equations.size() << ", 1);" << endl << endl
|
StaticOutput << "residual = zeros( " << equations.size() << ", 1);" << endl << endl
|
||||||
<< "%" << endl
|
<< "%" << endl
|
||||||
|
|
Loading…
Reference in New Issue