Commit 97664607 authored by Ferhat Mihoubi's avatar Ferhat Mihoubi

- external functions are compatible with block decomposition and/or bytecode

parent befa1b96
......@@ -139,6 +139,9 @@ double *u, *y, *ya;
double *steady_y, *steady_x;
double *g2, *g1, *r;
vector<mxArray*> jacobian_block, jacobian_other_endo_block, jacobian_exo_block, jacobian_det_exo_block;
map<unsigned int,double> TEF;
map<pair<unsigned int, unsigned int>, double > TEFD;
map<pair<unsigned int, pair<unsigned int, unsigned int> >, double > TEFDD;
ExpressionType EQN_type;
it_code_type it_code_expr;
......
This diff is collapsed.
This diff is collapsed.
......@@ -252,6 +252,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
unsigned int block_size = getBlockSize(block);
unsigned int block_mfs = getBlockMfs(block);
unsigned int block_recursive = block_size - block_mfs;
deriv_node_temp_terms_t tef_terms;
/*unsigned int block_exo_size = exo_block[block].size();
unsigned int block_exo_det_size = exo_det_block[block].size();
unsigned int block_other_endo_size = other_endo_block[block].size();*/
......@@ -475,10 +476,13 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin();
it != v_temporary_terms[block][i].end(); it++)
{
if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL)
(*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms);
output << " " << sps;
(*it)->writeOutput(output, local_output_type, local_temporary_terms);
(*it)->writeOutput(output, local_output_type, local_temporary_terms, tef_terms);
output << " = ";
(*it)->writeOutput(output, local_output_type, tt2);
(*it)->writeOutput(output, local_output_type, tt2, tef_terms);
// Insert current node into tt2
tt2.insert(*it);
output << ";" << endl;
......@@ -1070,6 +1074,7 @@ DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin
BinaryOpNode *eq_node;
Uff Uf[symbol_table.endo_nbr()];
map<expr_t, int> reference_count;
deriv_node_temp_terms_t tef_terms;
vector<int> feedback_variables;
bool file_open = false;
......@@ -1183,9 +1188,12 @@ DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin
for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin();
it != v_temporary_terms[block][i].end(); it++)
{
if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL)
(*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, true, false, tef_terms);
FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second));
fnumexpr.write(code_file, instruction_number);
(*it)->compile(code_file, instruction_number, false, tt2, map_idx, true, false);
(*it)->compile(code_file, instruction_number, false, tt2, map_idx, true, false, tef_terms);
FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second));
fstpt.write(code_file, instruction_number);
// Insert current node into tt2
......
This diff is collapsed.
This diff is collapsed.
......@@ -147,12 +147,6 @@ ModFile::checkPass()
exit(EXIT_FAILURE);
}
if (byte_code && (external_functions_table.get_total_number_of_unique_model_block_external_functions() > 0))
{
cerr << "ERROR: In 'model' block, use of external functions is not compatible with 'bytecode'" << endl;
exit(EXIT_FAILURE);
}
if (mod_file_struct.dsge_var_estimated)
if (!mod_file_struct.dsge_prior_weight_in_estimated_params)
{
......
......@@ -264,6 +264,10 @@ ModelTree::evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_m
{
val = Id->eval(eval_context);
}
catch (ExprNode::EvalExternalFunctionException &e)
{
val = 1;
}
catch (ExprNode::EvalException &e)
{
cerr << "ERROR: evaluation of Jacobian failed for equation " << eq+1 << " and variable " << symbol_table.getName(symb) << "(" << lag << ") [" << symb << "] !" << endl;
......@@ -271,7 +275,6 @@ ModelTree::evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_m
cerr << endl;
exit(EXIT_FAILURE);
}
if (fabs(val) < cutoff)
{
if (verbose)
......@@ -1115,12 +1118,19 @@ ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_n
{
// Local var used to keep track of temp nodes already written
temporary_terms_t tt2;
// To store the functions that have already been written in the form TEF* = ext_fun();
deriv_node_temp_terms_t tef_terms;
for (temporary_terms_t::const_iterator it = tt.begin();
it != tt.end(); it++)
{
if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL)
{
(*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic, tef_terms);
}
FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second));
fnumexpr.write(code_file, instruction_number);
(*it)->compile(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic);
(*it)->compile(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic, tef_terms);
if (dynamic)
{
FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second));
......
......@@ -1865,16 +1865,41 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in
double model_var_arg_dbl;
if (unaryNode == NULL)
{
model_var_arg = (int)numNode->eval(ectmp);
model_var_arg_dbl = numNode->eval(ectmp);
try
{
model_var_arg = (int)numNode->eval(ectmp);
}
catch (ExprNode::EvalException &e)
{
}
try
{
model_var_arg_dbl = numNode->eval(ectmp);
}
catch (ExprNode::EvalException &e)
{
}
}
else
if (unaryNode->get_op_code() != oUminus)
error("A model variable is being treated as if it were a function (i.e., takes an argument that is not an integer).");
else
{
model_var_arg = (int)unaryNode->eval(ectmp);
model_var_arg_dbl = unaryNode->eval(ectmp);
try
{
model_var_arg = (int)unaryNode->eval(ectmp);
}
catch (ExprNode::EvalException &e)
{
}
try
{
model_var_arg_dbl = unaryNode->eval(ectmp);
}
catch (ExprNode::EvalException &e)
{
}
}
if ((double) model_var_arg != model_var_arg_dbl) //make 100% sure int cast didn't lose info
......
......@@ -133,14 +133,9 @@ StaticModel::computeTemporaryTermsOrdered()
expr_t id = it->second.second;
id->computeTemporaryTerms(reference_count_local, temporary_terms_l, first_occurence_local, block, v_temporary_terms_local, block_size-1);
}
//temporary_terms_g.insert(temporary_terms_l.begin(), temporary_terms_l.end());
set<int> temporary_terms_in_use;
temporary_terms_in_use.clear();
v_temporary_terms_inuse[block] = temporary_terms_in_use;
/*for (int i = 0; i < (int) block_size; i++)
for (temporary_terms_t::const_iterator it = v_temporary_terms_local[block][i].begin();
it != v_temporary_terms_local[block][i].end(); it++)
(*it)->collectTemporary_terms(temporary_terms_g, temporary_terms_in_use, block);*/
computeTemporaryTermsMapping(temporary_terms_l, map_idx2[block]);
}
......@@ -222,6 +217,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
ofstream output;
int nze;
vector<int> feedback_variables;
deriv_node_temp_terms_t tef_terms;
ExprNodeOutputType local_output_type;
local_output_type = oMatlabStaticModelSparse;
......@@ -304,10 +300,13 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin();
it != v_temporary_terms[block][i].end(); it++)
{
if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL)
(*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms);
output << " " << sps;
(*it)->writeOutput(output, local_output_type, local_temporary_terms);
(*it)->writeOutput(output, local_output_type, local_temporary_terms, tef_terms);
output << " = ";
(*it)->writeOutput(output, local_output_type, tt2);
(*it)->writeOutput(output, local_output_type, tt2, tef_terms);
// Insert current node into tt2
tt2.insert(*it);
output << ";" << endl;
......@@ -602,6 +601,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
Uff Uf[symbol_table.endo_nbr()];
map<expr_t, int> reference_count;
vector<int> feedback_variables;
deriv_node_temp_terms_t tef_terms;
bool file_open = false;
string main_name = file_name;
......@@ -655,11 +655,6 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
fbeginblock.write(code_file, instruction_number);
// Get the current code_file position and jump if eval = true
streampos pos1 = code_file.tellp();
FJMPIFEVAL_ fjmp_if_eval(0);
fjmp_if_eval.write(code_file, instruction_number);
int prev_instruction_number = instruction_number;
for (i = 0; i < (int) block_size; i++)
{
//The Temporary terms
......@@ -670,9 +665,12 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin();
it != v_temporary_terms[block][i].end(); it++)
{
if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL)
(*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, false, false, tef_terms);
FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second));
fnumexpr.write(code_file, instruction_number);
(*it)->compile(code_file, instruction_number, false, tt2, map_idx, false, false);
(*it)->compile(code_file, instruction_number, false, tt2, map_idx, false, false, tef_terms);
FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second));
fstpst.write(code_file, instruction_number);
// Insert current node into tt2
......@@ -738,6 +736,13 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
}
FENDEQU_ fendequ;
fendequ.write(code_file, instruction_number);
// Get the current code_file position and jump if eval = true
streampos pos1 = code_file.tellp();
FJMPIFEVAL_ fjmp_if_eval(0);
fjmp_if_eval.write(code_file, instruction_number);
int prev_instruction_number = instruction_number;
// The Jacobian if we have to solve the block
if (simulation_type != EVALUATE_BACKWARD
&& simulation_type != EVALUATE_FORWARD)
......@@ -858,9 +863,14 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
for (temporary_terms_t::const_iterator it = v_temporary_terms_local[block][i].begin();
it != v_temporary_terms_local[block][i].end(); it++)
{
if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL)
(*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt3, map_idx2[block], false, false, tef_terms);
FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx2[block].find((*it)->idx)->second));
fnumexpr.write(code_file, instruction_number);
(*it)->compile(code_file, instruction_number, false, tt3, map_idx2[block], false, false);
(*it)->compile(code_file, instruction_number, false, tt3, map_idx2[block], false, false, tef_terms);
FSTPST_ fstpst((int)(map_idx2[block].find((*it)->idx)->second));
fstpst.write(code_file, instruction_number);
// Insert current node into tt2
......@@ -937,7 +947,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
FNUMEXPR_ fnumexpr(FirstEndoDerivative, 0, 0);
fnumexpr.write(code_file, instruction_number);
}
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), map_idx2[block], tt2);
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), map_idx2[block], tt2/*temporary_terms*/);
{
FSTPG2_ fstpg2(0,0);
fstpg2.write(code_file, instruction_number);
......@@ -957,7 +967,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr, 0);
fnumexpr.write(code_file, instruction_number);
compileChainRuleDerivative(code_file, instruction_number, eqr, varr, 0, map_idx2[block], tt2);
compileChainRuleDerivative(code_file, instruction_number, eqr, varr, 0, map_idx2[block], tt2/*temporary_terms*/);
FSTPG2_ fstpg2(eq,var);
fstpg2.write(code_file, instruction_number);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment