2216 lines
79 KiB
C++
2216 lines
79 KiB
C++
/*
|
||
* Copyright (C) 2007-2015 Dynare Team
|
||
*
|
||
* This file is part of Dynare.
|
||
*
|
||
* Dynare is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* Dynare is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef ERROR_HANDLING
|
||
#define ERROR_HANDLING
|
||
|
||
#include <cstring>
|
||
#include <iostream>
|
||
#include <sstream>
|
||
#include <map>
|
||
#define BYTE_CODE
|
||
#include "CodeInterpreter.hh"
|
||
#ifdef DEBUG_EX
|
||
# include <math.h>
|
||
# include "mex_interface.hh"
|
||
#endif
|
||
|
||
#ifdef OCTAVE_MEX_FILE
|
||
# define CHAR_LENGTH 1
|
||
#else
|
||
# define CHAR_LENGTH 2
|
||
#endif
|
||
|
||
#ifdef _MSC_VER
|
||
#include <limits>
|
||
#define M_E 2.71828182845904523536
|
||
#define M_LOG2E 1.44269504088896340736
|
||
#define M_LOG10E 0.434294481903251827651
|
||
#define M_LN2 0.693147180559945309417
|
||
#define M_LN10 2.30258509299404568402
|
||
#define M_PI 3.14159265358979323846
|
||
#define M_PI_2 1.57079632679489661923
|
||
#define M_PI_4 0.785398163397448309616
|
||
#define M_1_PI 0.318309886183790671538
|
||
#define M_2_PI 0.636619772367581343076
|
||
#define M_1_SQRTPI 0.564189583547756286948
|
||
#define M_2_SQRTPI 1.12837916709551257390
|
||
#define M_SQRT2 1.41421356237309504880
|
||
#define M_SQRT_2 0.707106781186547524401
|
||
#define NAN numeric_limits<double>::quiet_NaN()
|
||
|
||
#define isnan(x) _isnan(x)
|
||
#define isinf(x) (!_finite(x))
|
||
#define fpu_error(x) (isinf(x) || isnan(x))
|
||
|
||
#define finite(x) _finite(x)
|
||
|
||
class MSVCpp_missings
|
||
{
|
||
public:
|
||
inline double
|
||
asinh(double x) const
|
||
{
|
||
if(x==0.0)
|
||
return 0.0;
|
||
double ax = abs(x);
|
||
return log(x+ax*sqrt(1.+1./(ax*ax)));
|
||
}
|
||
|
||
inline double
|
||
acosh(double x) const
|
||
{
|
||
if(x==0.0)
|
||
return 0.0;
|
||
double ax = abs(x);
|
||
return log(x+ax*sqrt(1.-1./(ax*ax)));
|
||
}
|
||
|
||
inline double
|
||
atanh(double x) const
|
||
{
|
||
return log((1+x)/(1-x))/2;
|
||
}
|
||
|
||
inline double
|
||
erf(double x) const
|
||
{
|
||
const double a1 = -1.26551223, a2 = 1.00002368,
|
||
a3 = 0.37409196, a4 = 0.09678418,
|
||
a5 = -0.18628806, a6 = 0.27886807,
|
||
a7 = -1.13520398, a8 = 1.48851587,
|
||
a9 = -0.82215223, a10 = 0.17087277;
|
||
double v = 1;
|
||
double z = abs(x);
|
||
if (z <= 0)
|
||
return v;
|
||
double t = 1 / (1 + 0.5 * z);
|
||
v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
|
||
if (x < 0)
|
||
v = 2 - v;
|
||
return 1 - v;
|
||
}
|
||
|
||
inline double
|
||
nearbyint(double x) const
|
||
{
|
||
return floor(x + 0.5);
|
||
}
|
||
|
||
inline double
|
||
fmax(double x, double y) const
|
||
{
|
||
if (x > y)
|
||
return x;
|
||
else
|
||
return y;
|
||
}
|
||
|
||
inline double
|
||
fmin(double x, double y) const
|
||
{
|
||
if (x < y)
|
||
return x;
|
||
else
|
||
return y;
|
||
}
|
||
|
||
};
|
||
#endif
|
||
|
||
|
||
//#define DEBUG
|
||
using namespace std;
|
||
|
||
const int NO_ERROR_ON_EXIT = 0;
|
||
const int ERROR_ON_EXIT = 1;
|
||
|
||
|
||
typedef vector<pair<Tags, void * > > code_liste_type;
|
||
typedef code_liste_type::const_iterator it_code_type;
|
||
|
||
|
||
class GeneralExceptionHandling
|
||
{
|
||
string ErrorMsg;
|
||
public:
|
||
#ifdef _MSC_VER
|
||
~GeneralExceptionHandling()
|
||
{
|
||
FreeLibrary(hinstLib);
|
||
};
|
||
#endif
|
||
GeneralExceptionHandling(string ErrorMsg_arg) : ErrorMsg(ErrorMsg_arg)
|
||
{
|
||
};
|
||
inline string
|
||
GetErrorMsg()
|
||
{
|
||
return ErrorMsg;
|
||
}
|
||
inline void
|
||
completeErrorMsg(string ErrorMsg_arg)
|
||
{
|
||
ErrorMsg += ErrorMsg_arg;
|
||
}
|
||
};
|
||
|
||
class FloatingPointExceptionHandling : public GeneralExceptionHandling
|
||
{
|
||
public:
|
||
FloatingPointExceptionHandling(string value) : GeneralExceptionHandling(string("Floating point error in bytecode: " + value))
|
||
{
|
||
};
|
||
};
|
||
|
||
class LogExceptionHandling : public FloatingPointExceptionHandling
|
||
{
|
||
double value;
|
||
public:
|
||
LogExceptionHandling(double value_arg) : FloatingPointExceptionHandling("log(X)"),
|
||
value(value_arg)
|
||
{
|
||
ostringstream tmp;
|
||
tmp << " with X=" << value << "\n";
|
||
completeErrorMsg(tmp.str());
|
||
};
|
||
};
|
||
|
||
class Log10ExceptionHandling : public FloatingPointExceptionHandling
|
||
{
|
||
double value;
|
||
public:
|
||
Log10ExceptionHandling(double value_arg) : FloatingPointExceptionHandling("log10(X)"),
|
||
value(value_arg)
|
||
{
|
||
ostringstream tmp;
|
||
tmp << " with X=" << value << "\n";
|
||
completeErrorMsg(tmp.str());
|
||
};
|
||
};
|
||
|
||
class DivideExceptionHandling : public FloatingPointExceptionHandling
|
||
{
|
||
double value1, value2;
|
||
public:
|
||
DivideExceptionHandling(double value1_arg, double value2_arg) : FloatingPointExceptionHandling("a/X"),
|
||
value1(value1_arg),
|
||
value2(value2_arg)
|
||
{
|
||
ostringstream tmp;
|
||
tmp << " with X=" << value2 << "\n";
|
||
completeErrorMsg(tmp.str());
|
||
};
|
||
};
|
||
|
||
class PowExceptionHandling : public FloatingPointExceptionHandling
|
||
{
|
||
double value1, value2;
|
||
public:
|
||
PowExceptionHandling(double value1_arg, double value2_arg) : FloatingPointExceptionHandling("X^a"),
|
||
value1(value1_arg),
|
||
value2(value2_arg)
|
||
{
|
||
ostringstream tmp;
|
||
if (abs(value1) > 1e-10 )
|
||
tmp << " with X=" << value1 << "\n";
|
||
else
|
||
tmp << " with X=" << value1 << " and a=" << value2 << "\n";
|
||
completeErrorMsg(tmp.str());
|
||
};
|
||
};
|
||
|
||
class UserExceptionHandling : public GeneralExceptionHandling
|
||
{
|
||
double value;
|
||
public:
|
||
UserExceptionHandling() : GeneralExceptionHandling("Fatal error in bytecode:")
|
||
{
|
||
completeErrorMsg(" User break\n");
|
||
};
|
||
};
|
||
|
||
class FatalExceptionHandling : public GeneralExceptionHandling
|
||
{
|
||
public:
|
||
FatalExceptionHandling(string ErrorMsg_arg) : GeneralExceptionHandling("Fatal error in bytecode:")
|
||
{
|
||
completeErrorMsg(ErrorMsg_arg);
|
||
};
|
||
FatalExceptionHandling() : GeneralExceptionHandling("")
|
||
{
|
||
};
|
||
};
|
||
|
||
struct s_plan
|
||
{
|
||
string var, exo;
|
||
int var_num, exo_num;
|
||
vector<pair<int, double> > per_value;
|
||
vector<double> value;
|
||
};
|
||
|
||
struct table_conditional_local_type
|
||
{
|
||
bool is_cond;
|
||
int var_exo, var_endo;
|
||
double constrained_value;
|
||
};
|
||
typedef vector<table_conditional_local_type> vector_table_conditional_local_type;
|
||
typedef map< int, vector_table_conditional_local_type > table_conditional_global_type;
|
||
#ifdef MATLAB_MEX_FILE
|
||
extern "C" bool utIsInterruptPending();
|
||
#endif
|
||
|
||
#ifdef _MSC_VER
|
||
class ErrorMsg : public MSVCpp_missings
|
||
#else
|
||
class ErrorMsg
|
||
#endif
|
||
{
|
||
private:
|
||
bool is_load_variable_list;
|
||
|
||
public:
|
||
double *y, *ya;
|
||
int y_size;
|
||
double *T;
|
||
int nb_row_xd, nb_row_x, col_x;
|
||
int y_kmin, y_kmax, periods;
|
||
double *x, *params;
|
||
double *u;
|
||
double *steady_y, *steady_x;
|
||
double *g2, *g1, *r, *res;
|
||
vector<s_plan> splan, spfplan;
|
||
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;
|
||
/*unsigned int*/size_t nb_endo, nb_exo, nb_param;
|
||
char *P_endo_names, *P_exo_names, *P_param_names;
|
||
size_t/*unsigned int*/ endo_name_length, exo_name_length, param_name_length;
|
||
unsigned int EQN_equation, EQN_block, EQN_block_number;
|
||
unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3;
|
||
vector<pair<string, pair<SymbolType, unsigned int> > > Variable_list;
|
||
|
||
inline
|
||
ErrorMsg()
|
||
{
|
||
mxArray *M_ = mexGetVariable("global", "M_");
|
||
if (mxGetFieldNumber(M_, "endo_names") == -1)
|
||
{
|
||
nb_endo = 0;
|
||
endo_name_length = 0;
|
||
P_endo_names = NULL;
|
||
}
|
||
else
|
||
{
|
||
nb_endo = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
|
||
endo_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
|
||
P_endo_names = (char *) mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
|
||
}
|
||
if (mxGetFieldNumber(M_, "exo_names") == -1)
|
||
{
|
||
nb_exo = 0;
|
||
exo_name_length = 0;
|
||
P_exo_names = NULL;
|
||
}
|
||
else
|
||
{
|
||
nb_exo = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")));
|
||
exo_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")));
|
||
P_exo_names = (char *) mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")));
|
||
}
|
||
if (mxGetFieldNumber(M_, "param_names") == -1)
|
||
{
|
||
nb_param = 0;
|
||
param_name_length = 0;
|
||
P_param_names = NULL;
|
||
}
|
||
else
|
||
{
|
||
nb_param = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
|
||
param_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
|
||
P_param_names = (char *) mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
|
||
}
|
||
is_load_variable_list = false;
|
||
}
|
||
|
||
inline string
|
||
add_underscore_to_fpe(const string &str)
|
||
{
|
||
string temp;
|
||
int pos1 = -1, pos2 = -1;
|
||
string tmp_n(str.length(), ' ');
|
||
string dollar, pound, tilde;
|
||
dollar = "$";
|
||
pound = "<EFBFBD>";
|
||
tilde = "~";
|
||
for (unsigned int i = 0; i < str.length(); i++)
|
||
{
|
||
if (dollar.compare(&str[i]) != 0 && pound.compare(&str[i]) != 0)
|
||
temp += str[i];
|
||
else
|
||
{
|
||
if (dollar.compare(&str[i]) == 0)
|
||
pos1 = int(temp.length());
|
||
else
|
||
pos2 = int(temp.length());
|
||
if (pos1 >= 0 && pos2 >= 0)
|
||
{
|
||
tmp_n.erase(pos1, pos2-pos1+1);
|
||
tmp_n.insert(pos1, pos2-pos1, tilde[0]);
|
||
pos1 = pos2 = -1;
|
||
}
|
||
}
|
||
}
|
||
temp += "\n" + tmp_n;
|
||
return temp;
|
||
}
|
||
|
||
inline void
|
||
load_variable_list()
|
||
{
|
||
ostringstream res;
|
||
for (unsigned int variable_num = 0; variable_num < (unsigned int)nb_endo; variable_num++)
|
||
{
|
||
for (unsigned int i = 0; i < endo_name_length; i++)
|
||
if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ')
|
||
res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)];
|
||
Variable_list.push_back(make_pair(res.str(), make_pair(eEndogenous, variable_num)));
|
||
}
|
||
for (unsigned int variable_num = 0; variable_num < (unsigned int)nb_exo; variable_num++)
|
||
{
|
||
for (unsigned int i = 0; i < exo_name_length; i++)
|
||
if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ')
|
||
res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)];
|
||
Variable_list.push_back(make_pair(res.str(), make_pair(eExogenous, variable_num)));
|
||
}
|
||
}
|
||
|
||
inline int
|
||
get_ID(const string variable_name, SymbolType *variable_type)
|
||
{
|
||
if (!is_load_variable_list)
|
||
{
|
||
load_variable_list();
|
||
is_load_variable_list = true;
|
||
}
|
||
size_t n = Variable_list.size();
|
||
int i = 0;
|
||
bool notfound = true;
|
||
while (notfound && i < (int) n)
|
||
{
|
||
if (variable_name == Variable_list[i].first)
|
||
{
|
||
notfound = false;
|
||
*variable_type = Variable_list[i].second.first;
|
||
return Variable_list[i].second.second;
|
||
}
|
||
i++;
|
||
}
|
||
return(-1);
|
||
}
|
||
|
||
inline string
|
||
get_variable(const SymbolType variable_type, const unsigned int variable_num) const
|
||
{
|
||
ostringstream res;
|
||
switch (variable_type)
|
||
{
|
||
case eEndogenous:
|
||
if (variable_num <= nb_endo)
|
||
{
|
||
for (unsigned int i = 0; i < endo_name_length; i++)
|
||
if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ')
|
||
res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)];
|
||
}
|
||
else
|
||
mexPrintf("=> Unknown endogenous variable # %d", variable_num);
|
||
break;
|
||
case eExogenous:
|
||
case eExogenousDet:
|
||
if (variable_num <= nb_exo)
|
||
{
|
||
for (unsigned int i = 0; i < exo_name_length; i++)
|
||
if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ')
|
||
res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)];
|
||
}
|
||
else
|
||
mexPrintf("=> Unknown exogenous variable # %d", variable_num);
|
||
break;
|
||
case eParameter:
|
||
if (variable_num <= nb_param)
|
||
{
|
||
for (unsigned int i = 0; i < param_name_length; i++)
|
||
if (P_param_names[CHAR_LENGTH*(variable_num+i*nb_param)] != ' ')
|
||
res << P_param_names[CHAR_LENGTH*(variable_num+i*nb_param)];
|
||
}
|
||
else
|
||
mexPrintf("=> Unknown parameter # %d", variable_num);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return (res.str());
|
||
}
|
||
|
||
inline string
|
||
error_location(bool evaluate, bool steady_state, int size, int block_num, int it_, int Per_u_)
|
||
{
|
||
stringstream Error_loc("");
|
||
if (!steady_state)
|
||
switch (EQN_type)
|
||
{
|
||
case TemporaryTerm:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "temporary term " << EQN_equation+1 << " in block " << EQN_block+1 << " at time " << it_;
|
||
else
|
||
Error_loc << "temporary term " << EQN_equation+1 << " at time " << it_;
|
||
break;
|
||
case ModelEquation:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "equation " << EQN_equation+1 << " in block " << EQN_block+1 << " at time " << it_;
|
||
else
|
||
Error_loc << "equation " << EQN_equation+1 << " at time " << it_;
|
||
break;
|
||
case FirstEndoDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to endogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to endogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
break;
|
||
case FirstOtherEndoDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to other endogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to other endogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
break;
|
||
case FirstExoDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to exogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to exogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
break;
|
||
case FirstExodetDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to deterministic exogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to deterministic exogenous variable " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
break;
|
||
case FirstParamDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to parameter " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to parameter " << get_variable(eEndogenous, EQN_dvar1) << " at time " << it_;
|
||
break;
|
||
default:
|
||
return ("???");
|
||
}
|
||
else
|
||
switch (EQN_type)
|
||
{
|
||
case TemporaryTerm:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "temporary term " << EQN_equation+1 << " in block " << EQN_block+1;
|
||
else
|
||
Error_loc << "temporary term " << EQN_equation+1;
|
||
break;
|
||
case ModelEquation:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "equation " << EQN_equation+1 << " in block " << EQN_block+1;
|
||
else
|
||
Error_loc << "equation " << EQN_equation+1;
|
||
break;
|
||
case FirstEndoDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to endogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to endogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
break;
|
||
case FirstOtherEndoDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to other endogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to other endogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
break;
|
||
case FirstExoDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to exogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to exogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
break;
|
||
case FirstExodetDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to deterministic exogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to deterministic exogenous variable " << get_variable(eEndogenous, EQN_dvar1);
|
||
break;
|
||
case FirstParamDerivative:
|
||
if (EQN_block_number > 1)
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to parameter " << get_variable(eEndogenous, EQN_dvar1);
|
||
else
|
||
Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to parameter " << get_variable(eEndogenous, EQN_dvar1);
|
||
break;
|
||
default:
|
||
return ("???");
|
||
}
|
||
it_code_type it_code_ret;
|
||
Error_loc << endl << add_underscore_to_fpe(" " + print_expression(it_code_expr, evaluate, size, block_num, steady_state, Per_u_, it_, it_code_ret, true));
|
||
return (Error_loc.str());
|
||
}
|
||
|
||
inline string
|
||
print_expression(it_code_type it_code, bool evaluate, int size, int block_num, bool steady_state, int Per_u_, int it_, it_code_type &it_code_ret, bool compute) const
|
||
{
|
||
int var, lag = 0, op, eq;
|
||
stack<string> Stack;
|
||
stack<double> Stackf;
|
||
ostringstream tmp_out, tmp_out2;
|
||
string v1, v2, v3;
|
||
double v1f, v2f, v3f = 0.0;
|
||
bool go_on = true;
|
||
double ll;
|
||
ExpressionType equation_type = TemporaryTerm;
|
||
size_t found;
|
||
double *jacob = NULL, *jacob_other_endo = NULL, *jacob_exo = NULL, *jacob_exo_det = NULL;
|
||
external_function_type function_type = ExternalFunctionWithoutDerivative;
|
||
|
||
if (evaluate)
|
||
{
|
||
jacob = mxGetPr(jacobian_block[block_num]);
|
||
if (!steady_state)
|
||
{
|
||
jacob_other_endo = mxGetPr(jacobian_other_endo_block[block_num]);
|
||
jacob_exo = mxGetPr(jacobian_exo_block[block_num]);
|
||
jacob_exo_det = mxGetPr(jacobian_det_exo_block[block_num]);
|
||
}
|
||
}
|
||
|
||
while (go_on)
|
||
{
|
||
#ifdef MATLAB_MEX_FILE
|
||
if ( utIsInterruptPending() )
|
||
throw UserExceptionHandling();
|
||
#endif
|
||
switch (it_code->first)
|
||
{
|
||
case FNUMEXPR:
|
||
switch (((FNUMEXPR_ *) it_code->second)->get_expression_type())
|
||
{
|
||
case TemporaryTerm:
|
||
equation_type = TemporaryTerm;
|
||
break;
|
||
case ModelEquation:
|
||
equation_type = ModelEquation;
|
||
break;
|
||
case FirstEndoDerivative:
|
||
equation_type = FirstEndoDerivative;
|
||
break;
|
||
case FirstOtherEndoDerivative:
|
||
equation_type = FirstOtherEndoDerivative;
|
||
break;
|
||
case FirstExoDerivative:
|
||
equation_type = FirstExoDerivative;
|
||
break;
|
||
case FirstExodetDerivative:
|
||
equation_type = FirstExodetDerivative;
|
||
break;
|
||
case FirstParamDerivative:
|
||
equation_type = FirstParamDerivative;
|
||
break;
|
||
case SecondEndoDerivative:
|
||
equation_type = SecondEndoDerivative;
|
||
break;
|
||
case SecondExoDerivative:
|
||
equation_type = SecondExoDerivative;
|
||
break;
|
||
case SecondExodetDerivative:
|
||
equation_type = SecondExodetDerivative;
|
||
break;
|
||
case SecondParamDerivative:
|
||
equation_type = SecondExodetDerivative;
|
||
break;
|
||
case ThirdEndoDerivative:
|
||
equation_type = ThirdEndoDerivative;
|
||
break;
|
||
case ThirdExoDerivative:
|
||
equation_type = ThirdExoDerivative;
|
||
break;
|
||
case ThirdExodetDerivative:
|
||
equation_type = ThirdExodetDerivative;
|
||
break;
|
||
case ThirdParamDerivative:
|
||
equation_type = ThirdExodetDerivative;
|
||
break;
|
||
default:
|
||
ostringstream tmp;
|
||
tmp << " in print_expression, expression type " << ((FNUMEXPR_ *) it_code->second)->get_expression_type() << " not implemented yet\n";
|
||
throw FatalExceptionHandling(tmp.str());
|
||
}
|
||
break;
|
||
case FLDV:
|
||
//load a variable in the processor
|
||
switch (((FLDV_ *) it_code->second)->get_type())
|
||
{
|
||
case eParameter:
|
||
var = ((FLDV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDV_ Param var=%d\n", var);
|
||
mexPrintf("get_variable(eParameter, var)=%s\n",get_variable(eParameter, var).c_str());
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
Stack.push(get_variable(eParameter, var));
|
||
if (compute)
|
||
Stackf.push(params[var]);
|
||
break;
|
||
case eEndogenous:
|
||
var = ((FLDV_ *) it_code->second)->get_pos();
|
||
lag = ((FLDV_ *) it_code->second)->get_lead_lag();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDV_ endo var=%d, lag=%d\n", var, lag);
|
||
mexPrintf("get_variable(eEndogenous, var)=%s, compute=%d\n",get_variable(eEndogenous, var).c_str(), compute);
|
||
mexPrintf("it_=%d, lag=%d, y_size=%d, var=%d, y=%x\n", it_, lag, y_size, var, y);
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
tmp_out.str("");
|
||
if (lag > 0)
|
||
tmp_out << get_variable(eEndogenous, var) << "(+" << lag << ")";
|
||
else if (lag < 0)
|
||
tmp_out << get_variable(eEndogenous, var) << "(" << lag << ")";
|
||
else
|
||
tmp_out << get_variable(eEndogenous, var);
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
{
|
||
if (evaluate)
|
||
Stackf.push(ya[(it_+lag)*y_size+var]);
|
||
else
|
||
Stackf.push(y[(it_+lag)*y_size+var]);
|
||
}
|
||
break;
|
||
case eExogenous:
|
||
var = ((FLDV_ *) it_code->second)->get_pos();
|
||
lag = ((FLDV_ *) it_code->second)->get_lead_lag();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDV_ exo var=%d, lag=%d", var, lag);
|
||
#endif
|
||
tmp_out.str("");
|
||
if (lag != 0)
|
||
tmp_out << get_variable(eExogenous, var) << "(" << lag << ")";
|
||
else
|
||
tmp_out << get_variable(eExogenous, var);
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(x[it_+lag+var*nb_row_x]);
|
||
break;
|
||
case eExogenousDet:
|
||
var = ((FLDV_ *) it_code->second)->get_pos();
|
||
lag = ((FLDV_ *) it_code->second)->get_lead_lag();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDV_ exo_det var=%d, lag=%d", var, lag);
|
||
#endif
|
||
tmp_out.str("");
|
||
if (lag != 0)
|
||
tmp_out << get_variable(eExogenousDet, var) << "(" << lag << ")";
|
||
else
|
||
tmp_out << get_variable(eExogenousDet, var);
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(x[it_+lag+var*nb_row_xd]);
|
||
break;
|
||
case eModelLocalVariable:
|
||
break;
|
||
default:
|
||
mexPrintf("FLDV: Unknown variable type\n");
|
||
}
|
||
break;
|
||
case FLDSV:
|
||
case FLDVS:
|
||
//load a variable in the processor
|
||
switch (((FLDSV_ *) it_code->second)->get_type())
|
||
{
|
||
case eParameter:
|
||
var = ((FLDSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDSV_ param var=%d", var);
|
||
#endif
|
||
Stack.push(get_variable(eParameter, var));
|
||
if (compute)
|
||
Stackf.push(params[var]);
|
||
break;
|
||
case eEndogenous:
|
||
var = ((FLDSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDSV_ endo var=%d", var);
|
||
#endif
|
||
Stack.push(get_variable(eEndogenous, var));
|
||
if (compute)
|
||
{
|
||
if (it_code->first == FLDSV)
|
||
{
|
||
if (evaluate)
|
||
Stackf.push(ya[var]);
|
||
else
|
||
Stackf.push(y[var]);
|
||
}
|
||
else
|
||
Stackf.push(steady_y[var]);
|
||
}
|
||
break;
|
||
case eExogenous:
|
||
var = ((FLDSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDSV_ exo var=%d", var);
|
||
#endif
|
||
Stack.push(get_variable(eExogenous, var));
|
||
#ifdef DEBUG
|
||
mexPrintf("oka var=%d, Stack.size()=%d x=%x\n", var, Stack.size(), x);
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(x[var]);
|
||
break;
|
||
case eExogenousDet:
|
||
var = ((FLDSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDSV_ exo_det var=%d", var);
|
||
#endif
|
||
Stack.push(get_variable(eExogenousDet, var));
|
||
if (compute)
|
||
Stackf.push(x[var]);
|
||
break;
|
||
case eModelLocalVariable:
|
||
break;
|
||
default:
|
||
mexPrintf("FLDSV: Unknown variable type\n");
|
||
}
|
||
break;
|
||
case FLDT:
|
||
//load a temporary variable in the processor
|
||
var = ((FLDT_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDT_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "T" << var+1;
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(T[var*(periods+y_kmin+y_kmax)+it_]);
|
||
break;
|
||
case FLDST:
|
||
//load a temporary variable in the processor
|
||
var = ((FLDST_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDST_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "T" << var+1;
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(T[var]);
|
||
break;
|
||
case FLDU:
|
||
//load u variable in the processor
|
||
var = ((FLDU_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDU_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "u(" << var+1 << " + it_)";
|
||
Stack.push(tmp_out.str());
|
||
var += Per_u_;
|
||
if (compute)
|
||
Stackf.push(u[var]);
|
||
break;
|
||
case FLDSU:
|
||
//load u variable in the processor
|
||
var = ((FLDSU_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDSU_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "u(" << var+1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(u[var]);
|
||
break;
|
||
case FLDR:
|
||
var = ((FLDR_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDSR_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "residual(" << var+1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(r[var]);
|
||
break;
|
||
case FLDZ:
|
||
//load 0 in the processor
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDZ_");
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << 0;
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(0.0);
|
||
break;
|
||
case FLDC:
|
||
//load a numerical constant in the processor
|
||
ll = ((FLDC_ *) it_code->second)->get_value();
|
||
tmp_out.str("");
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDC_ ll=%f", ll);
|
||
#endif
|
||
tmp_out << ll;
|
||
Stack.push(tmp_out.str());
|
||
if (compute)
|
||
Stackf.push(ll);
|
||
break;
|
||
case FSTPV:
|
||
//load a variable in the processor
|
||
go_on = false;
|
||
switch (((FSTPV_ *) it_code->second)->get_type())
|
||
{
|
||
case eParameter:
|
||
var = ((FSTPV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPV_ param var=%d", var);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eParameter, var) << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
params[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case eEndogenous:
|
||
var = ((FSTPV_ *) it_code->second)->get_pos();
|
||
lag = ((FSTPV_ *) it_code->second)->get_lead_lag();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPV_ endo var=%d, lag=%d", var, lag);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eEndogenous, var);
|
||
if (lag > 0)
|
||
tmp_out << "(+" << lag << ")";
|
||
else if (lag < 0)
|
||
tmp_out << "(" << lag << ")";
|
||
tmp_out << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
y[(it_+lag)*y_size+var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case eExogenous:
|
||
var = ((FSTPV_ *) it_code->second)->get_pos();
|
||
lag = ((FSTPV_ *) it_code->second)->get_lead_lag();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPV_ exo var=%d, lag=%d", var, lag);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eExogenous, var);
|
||
if (lag != 0)
|
||
tmp_out << "(" << lag << ")";
|
||
tmp_out << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
x[it_+lag+var*nb_row_x] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case eExogenousDet:
|
||
var = ((FSTPV_ *) it_code->second)->get_pos();
|
||
lag = ((FSTPV_ *) it_code->second)->get_lead_lag();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPV_ exodet var=%d, lag=%d", var, lag);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eExogenousDet, var);
|
||
if (lag != 0)
|
||
tmp_out << "(" << lag << ")";
|
||
tmp_out << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
x[it_+lag+var*nb_row_xd] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
default:
|
||
mexPrintf("FSTPV: Unknown variable type\n");
|
||
}
|
||
break;
|
||
case FSTPSV:
|
||
go_on = false;
|
||
//load a variable in the processor
|
||
switch (((FSTPSV_ *) it_code->second)->get_type())
|
||
{
|
||
case eParameter:
|
||
var = ((FSTPSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPSV_ param var=%d", var);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eParameter, var);
|
||
tmp_out << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
params[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case eEndogenous:
|
||
var = ((FSTPSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPSV_ endo var=%d", var);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eEndogenous, var);
|
||
tmp_out << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
y[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case eExogenous:
|
||
case eExogenousDet:
|
||
var = ((FSTPSV_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPSV_ exo var=%d", var);
|
||
#endif
|
||
tmp_out2.str("");
|
||
tmp_out2 << Stack.top();
|
||
tmp_out.str("");
|
||
tmp_out << get_variable(eExogenous, var);
|
||
tmp_out << " = " << tmp_out2.str();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
x[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
default:
|
||
mexPrintf("FSTPSV: Unknown variable type\n");
|
||
}
|
||
break;
|
||
case FSTPT:
|
||
go_on = false;
|
||
//store in a temporary variable from the processor
|
||
var = ((FSTPT_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPT_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "T" << var+1 << " = " << Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
T[var*(periods+y_kmin+y_kmax)+it_] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPST:
|
||
go_on = false;
|
||
//store in a temporary variable from the processor
|
||
var = ((FSTPST_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPST_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "T" << var+1 << " = " << Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
T[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPU:
|
||
go_on = false;
|
||
//store in u variable from the processor
|
||
var = ((FSTPU_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPU_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "u(" << var+1 << " + it_) = " << Stack.top();
|
||
var += Per_u_;
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
u[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPSU:
|
||
go_on = false;
|
||
//store in u variable from the processor
|
||
var = ((FSTPSU_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPSU_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "u(" << var+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
u[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPR:
|
||
go_on = false;
|
||
//store in residual variable from the processor
|
||
var = ((FSTPR_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPR_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "residual(" << var+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
r[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPG:
|
||
go_on = false;
|
||
//store in derivative (g) variable from the processor
|
||
var = ((FSTPG_ *) it_code->second)->get_pos();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTG_ var=%d", var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "g1[" << var+1 << "] = " << Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
g1[var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPG2:
|
||
go_on = false;
|
||
//store in derivative (g) variable from the processor
|
||
eq = ((FSTPG2_ *) it_code->second)->get_row();
|
||
var = ((FSTPG2_ *) it_code->second)->get_col();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTG2_ eq=%d var=%d", eq, var);
|
||
#endif
|
||
tmp_out.str("");
|
||
tmp_out << "/*jacob(" << eq << ", " << var << ")*/ jacob(" << eq+size*var+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
jacob[eq + size*var] = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
break;
|
||
case FSTPG3:
|
||
//store in derivative (g) variable from the processor
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPG3\n");
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
double r;
|
||
unsigned int pos_col;
|
||
go_on = false;
|
||
if (compute)
|
||
{
|
||
r = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
eq = ((FSTPG3_ *) it_code->second)->get_row();
|
||
var = ((FSTPG3_ *) it_code->second)->get_col();
|
||
lag = ((FSTPG3_ *) it_code->second)->get_lag();
|
||
pos_col = ((FSTPG3_ *) it_code->second)->get_col_pos();
|
||
switch (equation_type)
|
||
{
|
||
case FirstEndoDerivative:
|
||
#ifdef DEBUG
|
||
mexPrintf("Endo eq=%d, pos_col=%d, size=%d\n", eq, pos_col, size);
|
||
#endif
|
||
if (compute)
|
||
jacob[eq + size*pos_col] = r;
|
||
tmp_out.str("");
|
||
tmp_out << "/*jacob(" << eq << ", " << pos_col << " var= " << var << ")*/ jacob(" << eq+size*pos_col+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
break;
|
||
case FirstOtherEndoDerivative:
|
||
if (compute)
|
||
jacob_other_endo[eq + size*pos_col] = r;
|
||
tmp_out.str("");
|
||
tmp_out << "jacob_other_endo(" << eq+size*pos_col+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
break;
|
||
case FirstExoDerivative:
|
||
#ifdef DEBUG
|
||
mexPrintf("Exo eq=%d, pos_col=%d, size=%d\n", eq, pos_col, size);
|
||
#endif
|
||
if (compute)
|
||
jacob_exo[eq + size*pos_col] = r;
|
||
tmp_out.str("");
|
||
tmp_out << "/*jacob_exo(" << eq << ", " << pos_col << " var=" << var << ")*/ jacob_exo(" << eq+size*pos_col+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
break;
|
||
case FirstExodetDerivative:
|
||
if (compute)
|
||
jacob_exo_det[eq + size*pos_col] = r;
|
||
tmp_out.str("");
|
||
tmp_out << "/*jacob_exo_det(" << eq << ", " << pos_col << " var=" << var << ")*/ jacob_exo_det(" << eq+size*pos_col+1 << ") = " << Stack.top();
|
||
Stack.pop();
|
||
break;
|
||
default:
|
||
ostringstream tmp;
|
||
tmp << " in compute_block_time, variable " << EQN_type << " not used yet\n";
|
||
//throw FatalExceptionHandling(tmp.str());
|
||
mexPrintf("%s", tmp.str().c_str());
|
||
}
|
||
#ifdef DEBUG
|
||
tmp_out << "=>";
|
||
mexPrintf(" g1[%d](%f)=%s\n", var, g1[var], tmp_out.str().c_str());
|
||
tmp_out.str("");
|
||
#endif
|
||
break;
|
||
case FBINARY:
|
||
op = ((FBINARY_ *) it_code->second)->get_op_type();
|
||
v2 = Stack.top();
|
||
Stack.pop();
|
||
v1 = Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
v2f = Stackf.top();
|
||
Stackf.pop();
|
||
v1f = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
switch (op)
|
||
{
|
||
case oPlus:
|
||
#ifdef DEBUG
|
||
mexPrintf("+");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(v1f + v2f);
|
||
tmp_out.str("");
|
||
tmp_out << v1 << " + " << v2;
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oMinus:
|
||
#ifdef DEBUG
|
||
mexPrintf("-");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(v1f - v2f);
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " - ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oTimes:
|
||
#ifdef DEBUG
|
||
mexPrintf("*");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(v1f * v2f);
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " * ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oDivide:
|
||
#ifdef DEBUG
|
||
mexPrintf("/");
|
||
#endif
|
||
if (compute)
|
||
{
|
||
r = v1f / v2f;
|
||
Stackf.push(r);
|
||
}
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
if (compute)
|
||
{
|
||
if (isinf(r))
|
||
tmp_out << "$";
|
||
tmp_out << " / ";
|
||
if (isinf(r))
|
||
tmp_out << "<EFBFBD>";
|
||
}
|
||
else
|
||
tmp_out << " / ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oLess:
|
||
#ifdef DEBUG
|
||
mexPrintf("<");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(double (v1f < v2f));
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " < ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oGreater:
|
||
#ifdef DEBUG
|
||
mexPrintf(">");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(double (v1f > v2f));
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " > ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oLessEqual:
|
||
#ifdef DEBUG
|
||
mexPrintf("<=");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(double (v1f <= v2f));
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " <= ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oGreaterEqual:
|
||
#ifdef DEBUG
|
||
mexPrintf(">=");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(double (v1f >= v2f));
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " >= ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oEqualEqual:
|
||
#ifdef DEBUG
|
||
mexPrintf("==");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(double (v1f == v2f));
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " == ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oDifferent:
|
||
#ifdef DEBUG
|
||
mexPrintf("!=");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(double (v1f != v2f));
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
tmp_out << " != ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oPower:
|
||
#ifdef DEBUG
|
||
mexPrintf("^");
|
||
#endif
|
||
if (compute)
|
||
{
|
||
r = pow(v1f, v2f);
|
||
Stackf.push(r);
|
||
}
|
||
tmp_out.str("");
|
||
found = v1.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v1;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
if (compute)
|
||
{
|
||
if (isnan(r))
|
||
tmp_out << "$ ^ " << "<EFBFBD>";
|
||
else
|
||
tmp_out << " ^ ";
|
||
}
|
||
else
|
||
tmp_out << " ^ ";
|
||
found = v2.find(" ");
|
||
if (found != string::npos)
|
||
tmp_out << "(";
|
||
tmp_out << v2;
|
||
if (found != string::npos)
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oPowerDeriv:
|
||
{
|
||
v3 = Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
int derivOrder = int(nearbyint(Stackf.top()));
|
||
Stackf.pop();
|
||
if (fabs(v1f) < NEAR_ZERO && v2f > 0
|
||
&& derivOrder > v2f
|
||
&& fabs(v2f-nearbyint(v2f)) < NEAR_ZERO)
|
||
{
|
||
r = 0.0;
|
||
Stackf.push(r);
|
||
}
|
||
else
|
||
{
|
||
double dxp = pow(v1f, v2f-derivOrder);
|
||
for (int i = 0; i < derivOrder; i++)
|
||
dxp *= v2f--;
|
||
Stackf.push(dxp);
|
||
r = dxp;
|
||
}
|
||
}
|
||
tmp_out.str("");
|
||
if (compute)
|
||
{
|
||
if (isnan(r))
|
||
tmp_out << "$ PowerDeriv " << "<EFBFBD>";
|
||
else
|
||
tmp_out << "PowerDeriv";
|
||
}
|
||
else
|
||
tmp_out << "PowerDeriv";
|
||
tmp_out << "(" << v1 << ", " << v2 << ", " << v3 << ")";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
#ifdef DEBUG
|
||
tmp_out << " |PowerDeriv(" << v1 << ", " << v2 << v3 << ")|";
|
||
#endif
|
||
break;
|
||
case oMax:
|
||
#ifdef DEBUG
|
||
mexPrintf("max");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(max(v1f, v2f));
|
||
tmp_out.str("");
|
||
tmp_out << "max(" << v1 << ", " << v2 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oMin:
|
||
#ifdef DEBUG
|
||
mexPrintf("min");
|
||
#endif
|
||
if (compute)
|
||
Stackf.push(min(v1f, v2f));
|
||
tmp_out.str("");
|
||
tmp_out << "min(" << v1 << ", " << v2 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oEqual:
|
||
default:
|
||
mexPrintf("Error unknown Unary operator=%d\n", op); mexEvalString("drawnow;");
|
||
;
|
||
}
|
||
break;
|
||
case FUNARY:
|
||
op = ((FUNARY_ *) it_code->second)->get_op_type();
|
||
v1 = Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
v1f = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
switch (op)
|
||
{
|
||
case oUminus:
|
||
if (compute)
|
||
Stackf.push(-v1f);
|
||
tmp_out.str("");
|
||
tmp_out << " -" << v1;
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oExp:
|
||
if (compute)
|
||
Stackf.push(exp(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "exp(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oLog:
|
||
if (compute)
|
||
{
|
||
r = log(v1f);
|
||
Stackf.push(r);
|
||
}
|
||
tmp_out.str("");
|
||
if (compute)
|
||
{
|
||
if (isnan(r))
|
||
tmp_out << "$log" << "<EFBFBD>" << "(" << v1 << ")";
|
||
else
|
||
tmp_out << "log(" << v1 << ")";
|
||
}
|
||
else
|
||
tmp_out << "log(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oLog10:
|
||
if (compute)
|
||
{
|
||
r = log10(v1f);
|
||
Stackf.push(r);
|
||
}
|
||
tmp_out.str("");
|
||
if (compute)
|
||
{
|
||
if (isnan(r))
|
||
tmp_out << "$log10" << "<EFBFBD>" << "(" << v1 << ")";
|
||
else
|
||
tmp_out << "log10(" << v1 << ")";
|
||
}
|
||
else
|
||
tmp_out << "log10(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oCos:
|
||
if (compute)
|
||
Stackf.push(cos(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "cos(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oSin:
|
||
if (compute)
|
||
Stackf.push(sin(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "sin(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oTan:
|
||
if (compute)
|
||
Stackf.push(tan(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "tan(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oAcos:
|
||
if (compute)
|
||
Stackf.push(acos(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "acos(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oAsin:
|
||
if (compute)
|
||
Stackf.push(asin(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "asin(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oAtan:
|
||
if (compute)
|
||
Stackf.push(atan(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "atan(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oCosh:
|
||
if (compute)
|
||
Stackf.push(cosh(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "cosh(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oSinh:
|
||
if (compute)
|
||
Stackf.push(sinh(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "sinh(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oTanh:
|
||
if (compute)
|
||
Stackf.push(tanh(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "tanh(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oAcosh:
|
||
if (compute)
|
||
Stackf.push(acosh(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "acosh(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oAsinh:
|
||
if (compute)
|
||
Stackf.push(asinh(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "asinh(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oAtanh:
|
||
if (compute)
|
||
Stackf.push(atanh(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "atanh(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oSqrt:
|
||
if (compute)
|
||
Stackf.push(sqrt(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "sqrt(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oErf:
|
||
if (compute)
|
||
Stackf.push(erf(v1f));
|
||
tmp_out.str("");
|
||
tmp_out << "erf(" << v1 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
default:
|
||
mexPrintf("Error unknown Binary operator=%d\n", op); mexEvalString("drawnow;");
|
||
;
|
||
}
|
||
break;
|
||
case FTRINARY:
|
||
op = ((FTRINARY_ *) it_code->second)->get_op_type();
|
||
v3 = Stack.top();
|
||
Stack.pop();
|
||
v2 = Stack.top();
|
||
Stack.pop();
|
||
v1 = Stack.top();
|
||
Stack.pop();
|
||
if (compute)
|
||
{
|
||
v3f = Stackf.top();
|
||
Stackf.pop();
|
||
v2f = Stackf.top();
|
||
Stackf.pop();
|
||
v1f = Stackf.top();
|
||
Stackf.pop();
|
||
}
|
||
switch (op)
|
||
{
|
||
case oNormcdf:
|
||
if (compute)
|
||
Stackf.push(0.5*(1+erf((v1f-v2f)/v3f/M_SQRT2)));
|
||
tmp_out.str("");
|
||
tmp_out << "normcdf(" << v1 << ", " << v2 << ", " << v3 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case oNormpdf:
|
||
if (compute)
|
||
Stackf.push(1/(v3f*sqrt(2*M_PI)*exp(pow((v1f-v2f)/v3f, 2)/2)));
|
||
tmp_out.str("");
|
||
tmp_out << "normpdf(" << v1 << ", " << v2 << ", " << v3 << ")";
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
default:
|
||
mexPrintf("Error unknown Trinary operator=%d\n", op); mexEvalString("drawnow;");
|
||
}
|
||
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();
|
||
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:
|
||
{
|
||
if (compute)
|
||
{
|
||
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(Stackf.top());
|
||
input_arguments[nb_input_arguments - i - 1] = vv;
|
||
Stackf.pop();
|
||
}
|
||
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
|
||
double *rr = mxGetPr(output_arguments[0]);
|
||
Stackf.push(*rr);
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << function_name << "(";
|
||
vector<string> ss(nb_input_arguments);
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
ss[nb_input_arguments-i-1] = Stack.top();
|
||
Stack.pop();
|
||
}
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
tmp_out << ss[i];
|
||
if (i < nb_input_arguments - 1)
|
||
tmp_out << ", ";
|
||
}
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
case ExternalFunctionNumericalFirstDerivative:
|
||
{
|
||
if (compute)
|
||
{
|
||
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 = Stackf.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));
|
||
Stackf.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
|
||
Stackf.push(*rr);
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << function_name << "(";
|
||
tmp_out << arg_func_name.c_str() << ", " << fc->get_row() << ", {";
|
||
vector<string> ss(nb_input_arguments);
|
||
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
|
||
{
|
||
ss[nb_add_input_arguments-i-1] = Stack.top();
|
||
Stack.pop();
|
||
}
|
||
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
|
||
{
|
||
tmp_out << ss[i];
|
||
if (i < nb_add_input_arguments - 1)
|
||
tmp_out << ", ";
|
||
}
|
||
tmp_out << "})";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
case ExternalFunctionFirstDerivative:
|
||
{
|
||
if (compute)
|
||
{
|
||
input_arguments = (mxArray **) mxMalloc(nb_input_arguments * sizeof(mxArray *));
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
mxArray *vv = mxCreateDoubleScalar(Stackf.top());
|
||
input_arguments[(nb_input_arguments - 1) - i] = vv;
|
||
Stackf.pop();
|
||
}
|
||
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << function_name << "(";
|
||
vector<string> ss(nb_input_arguments);
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
ss[nb_input_arguments-i-1] = Stack.top();
|
||
Stack.pop();
|
||
}
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
tmp_out << ss[i];
|
||
if (i < nb_input_arguments - 1)
|
||
tmp_out << ", ";
|
||
}
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
case ExternalFunctionNumericalSecondDerivative:
|
||
{
|
||
if (compute)
|
||
{
|
||
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 = Stackf.top();
|
||
#ifdef DEBUG
|
||
mexPrintf("i=%d rr = %f\n", i, rr);
|
||
#endif
|
||
mxSetCell(vv, (nb_add_input_arguments - 1) - i, mxCreateDoubleScalar(rr));
|
||
Stackf.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]);
|
||
Stackf.push(*rr);
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << function_name << "(";
|
||
tmp_out << arg_func_name.c_str() << ", " << fc->get_row() << ", " << fc->get_col() << ", {";
|
||
vector<string> ss(nb_input_arguments);
|
||
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
|
||
{
|
||
ss[nb_add_input_arguments-i-1] = Stack.top();
|
||
Stack.pop();
|
||
}
|
||
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
|
||
{
|
||
tmp_out << ss[i];
|
||
if (i < nb_add_input_arguments - 1)
|
||
tmp_out << ", ";
|
||
}
|
||
tmp_out << "})";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
case ExternalFunctionSecondDerivative:
|
||
{
|
||
if (compute)
|
||
{
|
||
input_arguments = (mxArray **) mxMalloc(nb_input_arguments * sizeof(mxArray *));
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
mxArray *vv = mxCreateDoubleScalar(Stackf.top());
|
||
input_arguments[i] = vv;
|
||
Stackf.pop();
|
||
}
|
||
mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str());
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << function_name << "(";
|
||
vector<string> ss(nb_input_arguments);
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
ss[nb_input_arguments-i-1] = Stack.top();
|
||
Stack.pop();
|
||
}
|
||
for (unsigned int i = 0; i < nb_input_arguments; i++)
|
||
{
|
||
tmp_out << ss[i];
|
||
if (i < nb_input_arguments - 1)
|
||
tmp_out << ", ";
|
||
}
|
||
tmp_out << ")";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
}
|
||
#ifdef DEBUG
|
||
mexPrintf("end CALL\n");
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
break;
|
||
}
|
||
case FSTPTEF:
|
||
go_on = false;
|
||
var = ((FSTPTEF_ *) it_code->second)->get_number();
|
||
#ifdef DEBUG
|
||
mexPrintf("FSTPTEF\n");
|
||
mexPrintf("var=%d Stack.size()=%d\n", var, Stack.size());
|
||
#endif
|
||
if (compute)
|
||
{
|
||
#ifdef DEBUG
|
||
double rr = Stackf.top();
|
||
mexPrintf("FSTP TEF(var-1)=%f done\n", rr);
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
Stackf.pop();
|
||
}
|
||
tmp_out.str("");
|
||
switch (function_type)
|
||
{
|
||
case ExternalFunctionWithoutDerivative:
|
||
tmp_out << "TEF(" << var << ") = " << Stack.top();
|
||
break;
|
||
case ExternalFunctionWithFirstDerivative:
|
||
tmp_out << "[TEF(" << var << "), TEFD(" << var << ") ]= " << Stack.top();
|
||
break;
|
||
case ExternalFunctionWithFirstandSecondDerivative:
|
||
tmp_out << "[TEF(" << var << "), TEFD(" << var << "), TEFDD(" << var << ") ]= " << Stack.top();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
Stack.pop();
|
||
#ifdef DEBUG
|
||
mexPrintf("end FSTPEF\n");
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
break;
|
||
case FLDTEF:
|
||
var = ((FLDTEF_ *) it_code->second)->get_number();
|
||
#ifdef DEBUG
|
||
mexPrintf("FLDTEF\n");
|
||
mexPrintf("var=%d Stack.size()=%d\n", var, Stackf.size());
|
||
{
|
||
map<unsigned int, double>::const_iterator it = TEF.find(var-1);
|
||
mexPrintf("FLD TEF[var-1]=%f done\n", it->second);
|
||
}
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
if (compute)
|
||
{
|
||
map<unsigned int, double>::const_iterator it = TEF.find(var-1);
|
||
Stackf.push(it->second);
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << "TEF(" << var << ")";
|
||
Stack.push(tmp_out.str());
|
||
#ifdef DEBUG
|
||
mexPrintf("end FLDTEF\n");
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
|
||
break;
|
||
case FSTPTEFD:
|
||
{
|
||
go_on = false;
|
||
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
|
||
if (compute)
|
||
{
|
||
#ifdef DEBUG
|
||
double rr = Stackf.top();
|
||
mexPrintf("FSTP TEFD[make_pair(indx, row)]=%f done\n", rr);
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
Stackf.pop();
|
||
}
|
||
tmp_out.str("");
|
||
if (function_type == ExternalFunctionNumericalFirstDerivative)
|
||
tmp_out << "TEFD(" << indx << ", " << row << ") = " << Stack.top();
|
||
else if (function_type == ExternalFunctionFirstDerivative)
|
||
tmp_out << "TEFD(" << indx << ") = " << Stack.top();
|
||
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());
|
||
map<pair<unsigned int, unsigned int>, double>::const_iterator it = TEFD.find(make_pair(indx, row-1));
|
||
mexPrintf("FLD TEFD[make_pair(indx, row)]=%f done\n", it->second);
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
if (compute)
|
||
{
|
||
map<pair<unsigned int, unsigned int>, double>::const_iterator it = TEFD.find(make_pair(indx, row-1));
|
||
Stackf.push(it->second);
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << "TEFD(" << indx << ", " << row << ")";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
case FSTPTEFDD:
|
||
{
|
||
go_on = false;
|
||
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
|
||
if (compute)
|
||
{
|
||
#ifdef DEBUG
|
||
double rr = Stackf.top();
|
||
mexPrintf("rr=%f\n", rr);
|
||
map<pair<unsigned int, pair<unsigned int, unsigned int> >, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1)));
|
||
mexPrintf("FSTP TEFDD[make_pair(indx, make_pair(row, col))]=%f done\n", it->second);
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
Stackf.pop();
|
||
}
|
||
tmp_out.str("");
|
||
if (function_type == ExternalFunctionNumericalSecondDerivative)
|
||
tmp_out << "TEFDD(" << indx << ", " << row << ", " << col << ") = " << Stack.top();
|
||
else if (function_type == ExternalFunctionSecondDerivative)
|
||
tmp_out << "TEFDD(" << indx << ") = " << Stack.top();
|
||
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());
|
||
map<pair<unsigned int, pair<unsigned int, unsigned int> >, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1)));
|
||
mexPrintf("FLD TEFD[make_pair(indx, make_pair(row, col))]=%f done\n", it->second);
|
||
mexEvalString("drawnow;");
|
||
#endif
|
||
if (compute)
|
||
{
|
||
map<pair<unsigned int, pair<unsigned int, unsigned int> >, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1)));
|
||
Stackf.push(it->second);
|
||
}
|
||
tmp_out.str("");
|
||
tmp_out << "TEFDD(" << indx << ", " << row << ", " << col << ")";
|
||
Stack.push(tmp_out.str());
|
||
}
|
||
break;
|
||
case FJMPIFEVAL:
|
||
tmp_out.str("");
|
||
tmp_out << "if (~evaluate)";
|
||
go_on = false;
|
||
break;
|
||
case FJMP:
|
||
tmp_out.str("");
|
||
tmp_out << "else";
|
||
go_on = false;
|
||
break;
|
||
case FCUML:
|
||
if (compute)
|
||
{
|
||
v1f = Stackf.top();
|
||
Stackf.pop();
|
||
v2f = Stackf.top();
|
||
Stackf.pop();
|
||
Stackf.push(v1f+v2f);
|
||
}
|
||
v1 = Stack.top();
|
||
Stack.pop();
|
||
v2 = Stack.top();
|
||
Stack.pop();
|
||
tmp_out.str("");
|
||
tmp_out << v1 << " + " << v2;
|
||
Stack.push(tmp_out.str());
|
||
break;
|
||
case FENDBLOCK:
|
||
case FENDEQU:
|
||
go_on = false;
|
||
break;
|
||
case FOK:
|
||
break;
|
||
default:
|
||
ostringstream tmp;
|
||
mexPrintf("Error it_code->first=%d unknown\n", it_code->first); mexEvalString("drawnow;");
|
||
tmp << " in print_expression, unknown opcode " << it_code->first << "!! FENDEQU=" << FENDEQU << "\n";
|
||
throw FatalExceptionHandling(tmp.str());
|
||
}
|
||
it_code++;
|
||
}
|
||
#ifdef DEBUG
|
||
mexPrintf("print_expression end tmp_out.str().c_str()=%s\n", tmp_out.str().c_str()); mexEvalString("drawnow;");
|
||
#endif
|
||
it_code_ret = it_code;
|
||
return (tmp_out.str());
|
||
}
|
||
|
||
};
|
||
|
||
#endif
|