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

time-shift
Ferhat Mihoubi 2010-12-10 11:50:27 +01:00
parent befa1b966b
commit 97664607b2
10 changed files with 1167 additions and 87 deletions

View File

@ -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;

View File

@ -160,6 +160,9 @@ Interpreter::compute_block_time(int Per_u_, bool evaluate, int block_num, int si
#endif
EQN_type = TemporaryTerm;
EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation();
#ifdef DEBUG
mexPrintf("EQN_equation=%d\n",EQN_equation);mexEvalString("drawnow;");
#endif
break;
case ModelEquation:
#ifdef DEBUG
@ -1058,6 +1061,339 @@ Interpreter::compute_block_time(int Per_u_, bool evaluate, int block_num, int si
}
break;
case FPUSH:
break;
case FCALL:
{
#ifdef DEBUG
mexPrintf("------------------------------\n");
mexPrintf("CALL ");mexEvalString("drawnow;");
#endif
FCALL_ *fc = (FCALL_ *) it_code->second;
string function_name = fc->get_function_name();
#ifdef DEBUG
mexPrintf("function_name=%s ", function_name.c_str());mexEvalString("drawnow;");
#endif
unsigned int nb_input_arguments = fc->get_nb_input_arguments();
#ifdef DEBUG
mexPrintf("nb_input_arguments=%d ", nb_input_arguments);mexEvalString("drawnow;");
#endif
unsigned int nb_output_arguments = fc->get_nb_output_arguments();
#ifdef DEBUG
mexPrintf("nb_output_arguments=%d\n", nb_output_arguments);mexEvalString("drawnow;");
#endif
mxArray *output_arguments[3];
string arg_func_name = fc->get_arg_func_name();
#ifdef DEBUG
mexPrintf("arg_func_name.length() = %d\n",arg_func_name.length());
mexPrintf("arg_func_name.c_str() = %s\n",arg_func_name.c_str());
#endif
unsigned int nb_add_input_arguments = fc->get_nb_add_input_arguments();
external_function_type function_type = fc->get_function_type();
#ifdef DEBUG
mexPrintf("function_type=%d ExternalFunctionWithoutDerivative=%d\n",function_type, ExternalFunctionWithoutDerivative);
mexEvalString("drawnow;");
#endif
mxArray **input_arguments;
switch (function_type)
{
case ExternalFunctionWithoutDerivative:
case ExternalFunctionWithFirstDerivative:
case ExternalFunctionWithFirstandSecondDerivative:
{
input_arguments = (mxArray**)mxMalloc(nb_input_arguments * sizeof(mxArray*));
#ifdef DEBUG
mexPrintf("Stack.size()=%d\n",Stack.size());
mexEvalString("drawnow;");
#endif
for (unsigned int i = 0; i < nb_input_arguments ; i++)
{
mxArray *vv = mxCreateDoubleScalar(Stack.top());
input_arguments[nb_input_arguments - i - 1] = vv;
Stack.pop();
}
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
double *rr = mxGetPr(output_arguments[0]);
Stack.push(*rr);
if (function_type == ExternalFunctionWithFirstDerivative || function_type == ExternalFunctionWithFirstandSecondDerivative)
{
unsigned int indx = fc->get_indx();
double *FD1 = mxGetPr(output_arguments[1]);
unsigned int rows = mxGetN(output_arguments[1]);
for(unsigned int i = 0; i < rows; i++)
TEFD[make_pair(indx, i)] = FD1[i];
}
if (function_type == ExternalFunctionWithFirstandSecondDerivative)
{
unsigned int indx = fc->get_indx();
double *FD2 = mxGetPr(output_arguments[2]);
unsigned int rows = mxGetM(output_arguments[2]);
unsigned int cols = mxGetN(output_arguments[2]);
unsigned int k = 0;
for (unsigned int j = 0; j < cols; j++)
for (unsigned int i = 0; i < rows; i++)
TEFDD[make_pair(indx, make_pair(i, j))] = FD2[k++];
}
}
break;
case ExternalFunctionNumericalFirstDerivative:
{
input_arguments = (mxArray**)mxMalloc((nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray*));
mxArray *vv = mxCreateString(arg_func_name.c_str());
input_arguments[0] = vv;
vv = mxCreateDoubleScalar(fc->get_row());
input_arguments[1] = vv;
vv = mxCreateCellMatrix(1, nb_add_input_arguments);
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
{
double rr = Stack.top();
#ifdef DEBUG
mexPrintf("i=%d rr = %f Stack.size()=%d\n",i, rr, Stack.size());
#endif
mxSetCell(vv, nb_add_input_arguments - (i+1), mxCreateDoubleScalar(rr));
Stack.pop();
}
input_arguments[nb_input_arguments+nb_add_input_arguments] = vv;
#ifdef DEBUG
mexCallMATLAB(0, NULL, 1, & input_arguments[0], "disp");
mexCallMATLAB(0, NULL, 1, & input_arguments[1], "disp");
mexCallMATLAB(0, NULL, 1, & input_arguments[2], "celldisp");
mexPrintf("OK\n");
mexEvalString("drawnow;");
#endif
nb_input_arguments = 3;
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
double *rr = mxGetPr(output_arguments[0]);
#ifdef DEBUG
mexPrintf("*rr=%f\n",*rr);
#endif
Stack.push(*rr);
}
break;
case ExternalFunctionFirstDerivative:
{
input_arguments = (mxArray**)mxMalloc(nb_input_arguments * sizeof(mxArray*));
for (unsigned int i = 0; i < nb_input_arguments; i++)
{
mxArray *vv = mxCreateDoubleScalar(Stack.top());
input_arguments[(nb_input_arguments - 1) - i] = vv;
Stack.pop();
}
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
unsigned int indx = fc->get_indx();
double *FD1 = mxGetPr(output_arguments[0]);
//mexPrint
unsigned int rows = mxGetN(output_arguments[0]);
for (unsigned int i = 0; i < rows; i++)
TEFD[make_pair(indx, i)] = FD1[i];
}
break;
case ExternalFunctionNumericalSecondDerivative:
{
input_arguments = (mxArray**)mxMalloc((nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray*));
mxArray *vv = mxCreateString(arg_func_name.c_str());
input_arguments[0] = vv;
vv = mxCreateDoubleScalar(fc->get_row());
input_arguments[1] = vv;
vv = mxCreateDoubleScalar(fc->get_col());
input_arguments[2] = vv;
vv = mxCreateCellMatrix(1, nb_add_input_arguments);
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
{
double rr = Stack.top();
mexPrintf("i=%d rr = %f\n",i, rr);
mxSetCell(vv, (nb_add_input_arguments - 1) - i, mxCreateDoubleScalar(rr));
Stack.pop();
}
input_arguments[nb_input_arguments+nb_add_input_arguments] = vv;
mexCallMATLAB(0, NULL, 1, & input_arguments[0], "disp");
mexCallMATLAB(0, NULL, 1, & input_arguments[1], "disp");
mexCallMATLAB(0, NULL, 1, & input_arguments[2], "celldisp");
mexPrintf("OK\n");
mexEvalString("drawnow;");
nb_input_arguments = 3;
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
double *rr = mxGetPr(output_arguments[0]);
Stack.push(*rr);
}
break;
case ExternalFunctionSecondDerivative:
{
input_arguments = (mxArray**)mxMalloc(nb_input_arguments * sizeof(mxArray*));
for (unsigned int i = 0; i < nb_input_arguments ; i++)
{
mxArray *vv = mxCreateDoubleScalar(Stack.top());
input_arguments[i] = vv;
Stack.pop();
}
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
unsigned int indx = fc->get_indx();
double *FD2 = mxGetPr(output_arguments[2]);
unsigned int rows = mxGetM(output_arguments[0]);
unsigned int cols = mxGetN(output_arguments[0]);
unsigned int k = 0;
for (unsigned int j = 0; j < cols; j++)
for (unsigned int i = 0; i < rows; i++)
TEFDD[make_pair(indx, make_pair(i, j))] = FD2[k++];
}
break;
}
/*if (f)
{
input_arguments = (mxArray**)mxMalloc((nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray*));
//the called function is jacob_element or hess_element
mxArray *vv = mxCreateString(arg_func_name.c_str());
input_arguments[0] = vv;
vv = mxCreateDoubleScalar(fc->get_indx());
input_arguments[1] = vv;
start_input_arg += 2;
}
else
input_arguments = (mxArray**)mxMalloc(nb_input_arguments * sizeof(mxArray*));
for (unsigned int i = start_input_arg; i < nb_input_arguments + start_input_arg; i++)
{
mxArray *vv = mxCreateDoubleScalar(Stack.top());
input_arguments[i] = vv;
Stack.pop();
}
mexPrintf("nb_add_input_arguments=%d Stack.size()=%d\n",nb_add_input_arguments, Stack.size());mexEvalString("drawnow;");
if (arg_func_name.length() > 0)
{
mxArray *vv = mxCreateCellArray(1, &nb_add_input_arguments);
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
{
double rr = Stack.top();
mexPrintf("i=%d rr = %f\n",i, rr);
mxSetCell(vv, i, mxCreateDoubleScalar(rr));
Stack.pop();
}
input_arguments[nb_input_arguments+nb_add_input_arguments] = vv;
mexCallMATLAB(0, NULL, 1, & input_arguments[0], "disp");
mexCallMATLAB(0, NULL, 1, & input_arguments[1], "disp");
mexCallMATLAB(0, NULL, 1, & input_arguments[2], "celldisp");
mexPrintf("OK\n");
mexEvalString("drawnow;");
nb_input_arguments = 3;
}
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
double *rr = mxGetPr(output_arguments[0]);
Stack.push(*rr);
if (nb_output_arguments >= 2) //its the return of a TEF
{
unsigned int indx = fc->get_indx();
double *FD1 = mxGetPr(output_arguments[1]);
unsigned int rows = mxGetM(output_arguments[1]);
for(unsigned int i = 0; i < rows; i++)
TEFD[make_pair(indx, i)] = FD1[i];
if (nb_output_arguments == 3)
{
double *FD2 = mxGetPr(output_arguments[2]);
unsigned int rows = mxGetM(output_arguments[2]);
unsigned int cols = mxGetN(output_arguments[2]);
unsigned int k = 0;
for (unsigned int j = 0; j < cols; j++)
for (unsigned int i = 0; i < rows; i++)
TEFDD[make_pair(indx, make_pair(i, j))] = FD2[k++];
}
}
else*/
/*
#ifdef DEBUG
mexPrintf("Stack.size()=%d, *rr=%f\n",Stack.size(), *rr);
mexPrintf("done\n");
mexEvalString("drawnow;");
#endif*/
}
break;
case FSTPTEF:
var = ((FSTPTEF_ *) it_code->second)->get_number();
#ifdef DEBUG
mexPrintf("FSTPTEF\n");
mexPrintf("var=%d Stack.size()=%d\n",var, Stack.size());
#endif
TEF[var-1] = Stack.top();
#ifdef DEBUG
mexPrintf("FSTP TEF[var-1]=%f done\n",TEF[var-1]);
mexEvalString("drawnow;");
#endif
Stack.pop();
break;
case FLDTEF:
var = ((FLDTEF_ *) it_code->second)->get_number();
#ifdef DEBUG
mexPrintf("FLDTEF\n");
mexPrintf("var=%d Stack.size()=%d\n",var, Stack.size());
mexPrintf("FLD TEF[var-1]=%f done\n",TEF[var-1]);
mexEvalString("drawnow;");
#endif
Stack.push(TEF[var-1]);
break;
case FSTPTEFD:
{
unsigned int indx = ((FSTPTEFD_ *) it_code->second)->get_indx();
unsigned int row = ((FSTPTEFD_ *) it_code->second)->get_row();
#ifdef DEBUG
mexPrintf("FSTPTEFD\n");
mexPrintf("indx=%d Stack.size()=%d\n",indx, Stack.size());
#endif
TEFD[make_pair(indx, row-1)] = Stack.top();
#ifdef DEBUG
mexPrintf("FSTP TEFD[make_pair(indx, row)]=%f done\n",TEFD[make_pair(indx, row-1)]);
mexEvalString("drawnow;");
#endif
Stack.pop();
}
break;
case FLDTEFD:
{
unsigned int indx = ((FLDTEFD_ *) it_code->second)->get_indx();
unsigned int row = ((FLDTEFD_ *) it_code->second)->get_row();
#ifdef DEBUG
mexPrintf("FLDTEFD\n");
mexPrintf("indx=%d row=%d Stack.size()=%d\n",indx, row, Stack.size());
mexPrintf("FLD TEFD[make_pair(indx, row)]=%f done\n",TEFD[make_pair(indx, row-1)]);
mexEvalString("drawnow;");
#endif
Stack.push(TEFD[make_pair(indx, row-1)]);
}
break;
case FSTPTEFDD:
{
unsigned int indx = ((FSTPTEFDD_ *) it_code->second)->get_indx();
unsigned int row = ((FSTPTEFDD_ *) it_code->second)->get_row();
unsigned int col = ((FSTPTEFDD_ *) it_code->second)->get_col();
#ifdef DEBUG
mexPrintf("FSTPTEFD\n");
mexPrintf("indx=%d Stack.size()=%d\n",indx, Stack.size());
#endif
TEFDD[make_pair(indx, make_pair(row-1, col-1))] = Stack.top();
#ifdef DEBUG
mexPrintf("FSTP TEFDD[make_pair(indx, make_pair(row, col))]=%f done\n",TEFDD[make_pair(indx, make_pair(row, col))]);
mexEvalString("drawnow;");
#endif
Stack.pop();
}
break;
case FLDTEFDD:
{
unsigned int indx = ((FLDTEFDD_ *) it_code->second)->get_indx();
unsigned int row = ((FLDTEFDD_ *) it_code->second)->get_row();
unsigned int col = ((FSTPTEFDD_ *) it_code->second)->get_col();
#ifdef DEBUG
mexPrintf("FLDTEFD\n");
mexPrintf("indx=%d Stack.size()=%d\n",indx, Stack.size());
mexPrintf("FLD TEFD[make_pair(indx, make_pair(row, col))]=%f done\n",TEFDD[make_pair(indx, make_pair(row, col))]);
mexEvalString("drawnow;");
#endif
Stack.push(TEFDD[make_pair(indx, make_pair(row-1, col-1))]);
}
break;
case FCUML:
v1 = Stack.top();
Stack.pop();

View File

@ -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;

View File

@ -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

View File

@ -157,6 +157,16 @@ ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const tem
writeOutput(output, output_type, temporary_terms, tef_terms);
}
void
ExprNode::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
{
deriv_node_temp_terms_t tef_terms;
compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
}
void
ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -165,6 +175,16 @@ ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output
// Nothing to do
}
void
ExprNode::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
{
// Nothing to do
}
VariableNode *
ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
@ -294,13 +314,16 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
}
double
NumConstNode::eval(const eval_context_t &eval_context) const throw (EvalException)
NumConstNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
return (datatree.num_constants.getDouble(id));
}
void
NumConstNode::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
NumConstNode::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
{
FLDC_ fldc(datatree.num_constants.getDouble(id));
fldc.write(CompileCode, instruction_number);
@ -710,7 +733,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
}
double
VariableNode::eval(const eval_context_t &eval_context) const throw (EvalException)
VariableNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
eval_context_t::const_iterator it = eval_context.find(symb_id);
if (it == eval_context.end())
@ -720,10 +743,13 @@ VariableNode::eval(const eval_context_t &eval_context) const throw (EvalExceptio
}
void
VariableNode::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
VariableNode::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
{
if (type == eModelLocalVariable || type == eModFileLocalVariable)
datatree.local_variables_table[symb_id]->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
datatree.local_variables_table[symb_id]->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
else
{
int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
@ -1593,8 +1619,19 @@ UnaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType out
arg->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
}
void
UnaryOpNode::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
{
arg->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
}
double
UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException)
UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException)
{
switch (op_code)
{
@ -1644,7 +1681,7 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException)
}
double
UnaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException)
UnaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
double v = arg->eval(eval_context);
@ -1652,7 +1689,10 @@ UnaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException
}
void
UnaryOpNode::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
UnaryOpNode::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
{
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
if (it != temporary_terms.end())
@ -1672,10 +1712,10 @@ UnaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, boo
return;
}
if (op_code == oSteadyState)
arg->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, true);
arg->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, true, tef_terms);
else
{
arg->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
arg->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
FUNARY_ funary(op_code);
funary.write(CompileCode, instruction_number);
}
@ -2331,7 +2371,7 @@ BinaryOpNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
}
double
BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException)
BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException, EvalExternalFunctionException)
{
switch (op_code)
{
@ -2375,7 +2415,7 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (Eva
}
double
BinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException)
BinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
double v1 = arg1->eval(eval_context);
double v2 = arg2->eval(eval_context);
@ -2384,7 +2424,10 @@ BinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalExceptio
}
void
BinaryOpNode::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
BinaryOpNode::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
{
// If current node is a temporary term
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
@ -2404,8 +2447,8 @@ BinaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, bo
}
return;
}
arg1->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
arg2->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
arg1->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
arg2->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
FBINARY_ fbinary(op_code);
fbinary.write(CompileCode, instruction_number);
}
@ -2593,6 +2636,18 @@ BinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType ou
arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
}
void
BinaryOpNode::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
{
arg1->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
arg2->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
}
void
BinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@ -3342,7 +3397,7 @@ TrinaryOpNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
}
double
TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException)
TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException)
{
switch (op_code)
{
@ -3356,7 +3411,7 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v
}
double
TrinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException)
TrinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
double v1 = arg1->eval(eval_context);
double v2 = arg2->eval(eval_context);
@ -3366,7 +3421,10 @@ TrinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalExcepti
}
void
TrinaryOpNode::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
TrinaryOpNode::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
{
// If current node is a temporary term
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this));
@ -3386,9 +3444,9 @@ TrinaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, b
}
return;
}
arg1->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
arg2->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
arg3->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic);
arg1->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
arg2->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
arg3->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms);
FTRINARY_ ftrinary(op_code);
ftrinary.write(CompileCode, instruction_number);
}
@ -3485,6 +3543,20 @@ TrinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType o
arg3->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
}
void
TrinaryOpNode::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
{
arg1->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
arg2->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
arg3->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
}
void
TrinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@ -3751,8 +3823,12 @@ ExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
expr_t
ExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables)
{
cerr << "ExternalFunctionNode::getChainRuleDerivative: operation impossible!" << endl;
exit(EXIT_FAILURE);
assert(datatree.external_functions_table.getNargs(symb_id) > 0);
vector<expr_t> dargs;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
dargs.push_back((*it)->getChainRuleDerivative(deriv_id, recursive_variables));
return composeDerivatives(dargs);
}
void
@ -3822,6 +3898,56 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ
output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms);
}
unsigned int
ExternalFunctionNode::compileExternalFunctionArguments(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
{
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx,
dynamic, steady_dynamic, tef_terms);
return(arguments.size());
}
void
ExternalFunctionNode::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
{
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this));
if (it != temporary_terms.end())
{
if (dynamic)
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDT_ fldt(ii->second);
fldt.write(CompileCode, instruction_number);
}
else
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDST_ fldst(ii->second);
fldst.write(CompileCode, instruction_number);
}
return;
}
if (!lhs_rhs)
{
FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms));
fldtef.write(CompileCode, instruction_number);
}
else
{
FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms));
fstptef.write(CompileCode, instruction_number);
}
}
void
ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -3899,6 +4025,57 @@ ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutpu
}
}
void
ExternalFunctionNode::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
{
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
if (!alreadyWrittenAsTefTerm(symb_id, tef_terms))
{
tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size();
int indx = getIndxInTefTerms(symb_id, tef_terms);
int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
unsigned int nb_output_arguments = 0;
if (symb_id == first_deriv_symb_id &&
symb_id == second_deriv_symb_id)
nb_output_arguments = 3;
else if (symb_id == first_deriv_symb_id)
nb_output_arguments = 2;
else
nb_output_arguments = 1;
unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx);
switch(nb_output_arguments)
{
case 1:
fcall.set_function_type(ExternalFunctionWithoutDerivative);
break;
case 2:
fcall.set_function_type(ExternalFunctionWithFirstDerivative);
break;
case 3:
fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative);
break;
}
fcall.write(CompileCode, instruction_number);
FSTPTEF_ fstptef(indx);
fstptef.write(CompileCode, instruction_number);
}
}
void
ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
@ -3907,8 +4084,10 @@ ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const
{
cerr << "ExternalFunctionNode::computeTemporaryTerms: not implemented" << endl;
exit(EXIT_FAILURE);
expr_t this2 = const_cast<ExternalFunctionNode *>(this);
temporary_terms.insert(this2);
first_occurence[this2] = make_pair(Curr_block, equation);
v_temporary_terms[Curr_block][equation].insert(this2);
}
void
@ -3927,22 +4106,18 @@ ExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_
temporary_terms_inuse.insert(idx);
else
{
//arg->collectTemporary_terms(temporary_terms, result);
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
}
}
double
ExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException)
ExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
throw EvalException();
throw EvalExternalFunctionException();
}
void
ExternalFunctionNode::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
{
cerr << "ExternalFunctionNode::compile: operation impossible!" << endl;
exit(EXIT_FAILURE);
}
pair<int, expr_t>
ExternalFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
@ -4176,8 +4351,10 @@ FirstDerivExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &referenc
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const
{
cerr << "FirstDerivExternalFunctionNode::computeTemporaryTerms: not implemented" << endl;
exit(EXIT_FAILURE);
expr_t this2 = const_cast<FirstDerivExternalFunctionNode *>(this);
temporary_terms.insert(this2);
first_occurence[this2] = make_pair(Curr_block, equation);
v_temporary_terms[Curr_block][equation].insert(this2);
}
expr_t
@ -4233,6 +4410,45 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType
<< LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndx << RIGHT_ARRAY_SUBSCRIPT(output_type);
}
void
FirstDerivExternalFunctionNode::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
{
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<FirstDerivExternalFunctionNode *>(this));
if (it != temporary_terms.end())
{
if (dynamic)
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDT_ fldt(ii->second);
fldt.write(CompileCode, instruction_number);
}
else
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDST_ fldst(ii->second);
fldst.write(CompileCode, instruction_number);
}
return;
}
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
int tmpIndx = inputIndex;
if (!lhs_rhs)
{
FLDTEFD_ fldtefd(getIndxInTefTerms(symb_id, tef_terms), tmpIndx);
fldtefd.write(CompileCode, instruction_number);
}
else
{
FSTPTEFD_ fstptefd(getIndxInTefTerms(symb_id, tef_terms), tmpIndx);
fstptefd.write(CompileCode, instruction_number);
}
}
void
FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -4326,6 +4542,51 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp
}
}
void
FirstDerivExternalFunctionNode::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
{
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
if (first_deriv_symb_id == symb_id || alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms))
return;
unsigned int nb_add_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
if (first_deriv_symb_id == eExtFunNotSet)
{
unsigned int nb_input_arguments = 0;
unsigned int nb_output_arguments = 1;
unsigned int indx = getIndxInTefTerms(symb_id, tef_terms);
FCALL_ fcall(nb_output_arguments, nb_input_arguments, "jacob_element", indx);
fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
fcall.set_row(inputIndex);
fcall.set_nb_add_input_arguments(nb_add_input_arguments);
fcall.set_function_type(ExternalFunctionNumericalFirstDerivative);
fcall.write(CompileCode, instruction_number);
FSTPTEFD_ fstptefd(indx, inputIndex);
fstptefd.write(CompileCode, instruction_number);
}
else
{
tef_terms[make_pair(first_deriv_symb_id, arguments)] = (int) tef_terms.size();
int indx = getIndxInTefTerms(symb_id, tef_terms);
int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
unsigned int nb_output_arguments = 1;
FCALL_ fcall(nb_output_arguments, nb_add_input_arguments, datatree.symbol_table.getName(first_deriv_symb_id), indx);
fcall.set_function_type(ExternalFunctionFirstDerivative);
fcall.write(CompileCode, instruction_number);
}
}
SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg,
int top_level_symb_id_arg,
const vector<expr_t> &arguments_arg,
@ -4355,8 +4616,10 @@ SecondDerivExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &referen
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const
{
cerr << "SecondDerivExternalFunctionNode::computeTemporaryTerms: not implemented" << endl;
exit(EXIT_FAILURE);
expr_t this2 = const_cast<SecondDerivExternalFunctionNode *>(this);
temporary_terms.insert(this2);
first_occurence[this2] = make_pair(Curr_block, equation);
v_temporary_terms[Curr_block][equation].insert(this2);
}
expr_t

View File

@ -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,
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,
@ -719,8 +746,13 @@ 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;
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 );
unsigned int compileExternalFunctionArguments(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 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);
@ -763,9 +795,17 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
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 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;
};
class SecondDerivExternalFunctionNode : public ExternalFunctionNode

View File

@ -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)
{

View File

@ -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));

View File

@ -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

View File

@ -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);