Commit 751c0da2 authored by Ferhat Mihoubi's avatar Ferhat Mihoubi
Browse files

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

parent d0b7e9e5
......@@ -93,7 +93,17 @@ enum Tags
FOK, //!< Used for debugging purpose - 21 (33)
FNUMEXPR //!< Store the expression type and references - 22 (34)
FNUMEXPR, //!< Store the expression type and references - 22 (34)
FCALL, //!< Call an external function - 23 (35)
FPUSH, //!< Push a double in the stack - 24 (36)
FPOP, //!< Pop a double from the stack - 25 (37)
FLDTEF, //!< Stores the result of an external function in the stack - 26 (38)
FSTPTEF, //!< Loads the result of an external function from the stack- 27 (39)
FLDTEFD, //!< Stores the result of an external function in the stack - 28 (40)
FSTPTEFD, //!< Loads the result of an external function from the stack- 29 (41)
FLDTEFDD, //!< Stores the result of an external function in the stack - 28 (42)
FSTPTEFDD //!< Loads the result of an external function from the stack- 29 (43)
};
......@@ -207,6 +217,17 @@ enum TrinaryOpcode
oNormpdf
};
enum external_function_type
{
ExternalFunctionWithoutDerivative,
ExternalFunctionWithFirstDerivative,
ExternalFunctionWithFirstandSecondDerivative,
ExternalFunctionNumericalFirstDerivative,
ExternalFunctionFirstDerivative,
ExternalFunctionNumericalSecondDerivative,
ExternalFunctionSecondDerivative
};
struct Block_contain_type
{
int Equation, Variable, Own_Derivative;
......@@ -362,6 +383,24 @@ public:
};
};
class FPUSH_ : public TagWithoutArgument
{
public:
inline FPUSH_() : TagWithoutArgument(FPUSH)
{
};
};
class FPOP_ : public TagWithoutArgument
{
public:
inline FPOP_() : TagWithoutArgument(FPOP)
{
};
};
class FDIMT_ : public TagWithOneArgument<unsigned int>
{
public:
......@@ -734,6 +773,136 @@ public:
}
};
class FLDTEF_ : public TagWithOneArgument<unsigned int>
{
public:
inline FLDTEF_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDTEF)
{
};
inline FLDTEF_(unsigned int number) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDTEF, number)
{
};
inline unsigned int
get_number()
{
return arg1;
}
};
class FSTPTEF_ : public TagWithOneArgument<unsigned int>
{
public:
inline FSTPTEF_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPTEF)
{
};
inline FSTPTEF_(unsigned int number) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPTEF, number)
{
};
inline unsigned int
get_number()
{
return arg1;
}
};
class FLDTEFD_ : public TagWithTwoArguments<unsigned int, unsigned int>
{
public:
inline FLDTEFD_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FLDTEFD)
{
};
inline FLDTEFD_(unsigned int indx, unsigned int row) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FLDTEFD, indx, row)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
};
class FSTPTEFD_ : public TagWithTwoArguments<unsigned int, unsigned int>
{
public:
inline FSTPTEFD_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPTEFD)
{
};
inline FSTPTEFD_(unsigned int indx, unsigned int row) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPTEFD, indx, row)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
};
class FLDTEFDD_ : public TagWithThreeArguments<unsigned int, unsigned int, unsigned int>
{
public:
inline FLDTEFDD_() : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FLDTEFDD)
{
};
inline FLDTEFDD_(unsigned int indx, unsigned int row, unsigned int col) : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FLDTEFDD, indx, row, col)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
inline unsigned int
get_col()
{
return arg3;
};
};
class FSTPTEFDD_ : public TagWithThreeArguments<unsigned int, unsigned int, unsigned int>
{
public:
inline FSTPTEFDD_() : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FSTPTEFDD)
{
};
inline FSTPTEFDD_(unsigned int indx, unsigned int row, unsigned int col) : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FSTPTEF, indx, row, col)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
inline unsigned int
get_col()
{
return arg3;
};
};
class FLDVS_ : public TagWithTwoArguments<uint8_t, unsigned int>
{
public:
......@@ -861,6 +1030,156 @@ public:
};
};
class FCALL_ : public TagWithFourArguments<unsigned int, unsigned int, string, unsigned int>
{
string func_name;
string arg_func_name;
unsigned int add_input_arguments, row, col;
external_function_type function_type;
public:
inline FCALL_() : TagWithFourArguments<unsigned int, unsigned int, string, unsigned int>::TagWithFourArguments(FCALL)
{
arg_func_name = "";
add_input_arguments = 0;
row = 0;
col = 0;
function_type = ExternalFunctionWithoutDerivative;
};
inline FCALL_(unsigned int nb_output_arguments, unsigned int nb_input_arguments, string f_name, unsigned int indx) :
TagWithFourArguments<unsigned int, unsigned int, string, unsigned int>::TagWithFourArguments(FCALL, nb_output_arguments, nb_input_arguments, f_name, indx)
{
arg_func_name = "";
add_input_arguments = 0;
row = 0;
col = 0;
function_type = ExternalFunctionWithoutDerivative;
func_name = f_name;
};
inline string
get_function_name()
{
//printf("get_function_name => func_name=%s\n",func_name.c_str());fflush(stdout);
return func_name;
};
inline unsigned int
get_nb_output_arguments()
{
return arg1;
};
inline unsigned int
get_nb_input_arguments()
{
return arg2;
};
inline unsigned int
get_indx()
{
return arg4;
};
inline void
set_arg_func_name(string arg_arg_func_name)
{
arg_func_name = arg_arg_func_name;
};
inline string
get_arg_func_name()
{
return arg_func_name;
};
inline void
set_nb_add_input_arguments(unsigned int arg_add_input_arguments)
{
add_input_arguments = arg_add_input_arguments;
};
inline unsigned int
get_nb_add_input_arguments()
{
return add_input_arguments;
};
inline void
set_row(unsigned int arg_row)
{
row = arg_row;
};
inline unsigned int
get_row()
{
return row;
}
inline void
set_col(unsigned int arg_col)
{
col = arg_col;
};
inline unsigned int
get_col()
{
return col;
};
inline void
set_function_type(external_function_type arg_function_type)
{
function_type = arg_function_type;
};
inline external_function_type
get_function_type()
{
return(function_type);
}
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(&op_code), sizeof(op_code));
CompileCode.write(reinterpret_cast<char *>(&arg1), sizeof(arg1));
CompileCode.write(reinterpret_cast<char *>(&arg2), sizeof(arg2));
CompileCode.write(reinterpret_cast<char *>(&arg4), sizeof(arg4));
CompileCode.write(reinterpret_cast<char *>(&add_input_arguments), sizeof(add_input_arguments));
CompileCode.write(reinterpret_cast<char *>(&row), sizeof(row));
CompileCode.write(reinterpret_cast<char *>(&col), sizeof(col));
CompileCode.write(reinterpret_cast<char *>(&function_type), sizeof(function_type));
int size = func_name.size();
CompileCode.write(reinterpret_cast<char *>(&size), sizeof(int));
const char *name = func_name.c_str();
CompileCode.write(reinterpret_cast<const char *>(name), func_name.size());
size = arg_func_name.size();
CompileCode.write(reinterpret_cast<char *>(&size), sizeof(int));
name = arg_func_name.c_str();
CompileCode.write(reinterpret_cast<const char *>(name), arg_func_name.size());
instruction_number++;
};
#ifdef BYTE_CODE
inline uint8_t *
load(uint8_t *code)
{
op_code = FCALL; code += sizeof(op_code);
memcpy(&arg1, code, sizeof(arg1)); code += sizeof(arg1);
memcpy(&arg2, code, sizeof(arg2)); code += sizeof(arg2);
memcpy(&arg4, code, sizeof(arg4)); code += sizeof(arg4);
memcpy(&add_input_arguments, code, sizeof(add_input_arguments)); code += sizeof(add_input_arguments);
memcpy(&row, code, sizeof(row)); code += sizeof(row);
memcpy(&col, code, sizeof(col)); code += sizeof(col);
memcpy(&function_type, code, sizeof(function_type)); code += sizeof(function_type);
int size;
memcpy(&size, code, sizeof(size)); code += sizeof(size);
char* name = (char*)mxMalloc((size+1)*sizeof(char));
memcpy(name, code, size); code += size;
name[size] = NULL;
func_name = name;
mxFree(name);
memcpy(&size, code, sizeof(size)); code += sizeof(size);
name = (char*)mxMalloc((size+1)*sizeof(char));
memcpy(name, code, size); code += size;
name[size] = NULL;
arg_func_name = name;
mxFree(name);
return code;
}
#endif
};
class FNUMEXPR_ : public TagWithOneArgument<ExpressionType>
{
private:
......@@ -1473,6 +1792,78 @@ public:
tags_liste.push_back(make_pair(FJMP, code));
code += sizeof(FJMP_);
break;
case FCALL:
{
# ifdef DEBUGL
mexPrintf("FCALL\n");
# endif
FCALL_ *fcall = new FCALL_;
code = fcall->load(code);
tags_liste.push_back(make_pair(FCALL, fcall));
# ifdef DEBUGL
mexPrintf("FCALL finish\n");mexEvalString("drawnow;");
mexPrintf("-- *code=%d\n",*code);mexEvalString("drawnow;");
# endif
}
break;
case FPUSH:
# ifdef DEBUGL
mexPrintf("FPUSH\n");
# endif
tags_liste.push_back(make_pair(FPUSH, code));
code += sizeof(FPUSH_);
break;
case FPOP:
# ifdef DEBUGL
mexPrintf("FPOP\n");
# endif
tags_liste.push_back(make_pair(FPOP, code));
code += sizeof(FPOP_);
break;
case FLDTEF:
# ifdef DEBUGL
mexPrintf("FLDTEF\n");
# endif
tags_liste.push_back(make_pair(FLDTEF, code));
code += sizeof(FLDTEF_);
break;
case FSTPTEF:
# ifdef DEBUGL
mexPrintf("FSTPTEF\n");
# endif
tags_liste.push_back(make_pair(FSTPTEF, code));
code += sizeof(FSTPTEF_);
break;
case FLDTEFD:
# ifdef DEBUGL
mexPrintf("FLDTEFD\n");
# endif
tags_liste.push_back(make_pair(FLDTEFD, code));
code += sizeof(FLDTEFD_);
break;
case FSTPTEFD:
# ifdef DEBUGL
mexPrintf("FSTPTEFD\n");
# endif
tags_liste.push_back(make_pair(FSTPTEFD, code));
code += sizeof(FSTPTEFD_);
break;
case FLDTEFDD:
# ifdef DEBUGL
mexPrintf("FLDTEFDD\n");
# endif
tags_liste.push_back(make_pair(FLDTEFDD, code));
code += sizeof(FLDTEFDD_);
break;
case FSTPTEFDD:
# ifdef DEBUGL
mexPrintf("FSTPTEFDD\n");
# endif
tags_liste.push_back(make_pair(FSTPTEFDD, code));
code += sizeof(FSTPTEFDD_);
break;
default:
mexPrintf("Unknown Tag value=%d code=%x\n", *code, code);
done = true;
......
......@@ -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.
......@@ -196,6 +196,11 @@ public:
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const;
//! Computes the set of all variables of a given symbol type in the expression
/*!
Variables are stored as integer pairs of the form (symb_id, lag).
......@@ -241,8 +246,14 @@ public:
{
};
virtual double eval(const eval_context_t &eval_context) const throw (EvalException) = 0;
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const = 0;
class EvalExternalFunctionException : public EvalException
{
};
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException ) = 0;
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const = 0;
void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
//! Creates a static version of this node
/*!
This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
......@@ -403,8 +414,8 @@ public:
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException);
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException );
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
......@@ -449,8 +460,8 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException);
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException );
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
SymbolType
get_type() const
......@@ -506,6 +517,10 @@ public:
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &first_occurence,
......@@ -514,9 +529,9 @@ public:
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException);
virtual double eval(const eval_context_t &eval_context) const throw (EvalException);
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException );
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException );
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
//! Returns operand
expr_t
get_arg() const
......@@ -573,6 +588,10 @@ public:
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &first_occurence,
......@@ -581,9 +600,9 @@ public:
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException);
virtual double eval(const eval_context_t &eval_context) const throw (EvalException);
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException, EvalExternalFunctionException );
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException );
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const;
//! Returns first operand
expr_t
......@@ -648,6 +667,10 @@ public:
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &first_occurence,
......@@ -656,9 +679,9 @@ public:
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException);
virtual double eval(const eval_context_t &eval_context) const throw (EvalException);
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException );
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException );
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
......@@ -711,6 +734,10 @@ public:
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,