Adds exceptions management on floating point operations using cfenv.h from gcc

time-shift
Ferhat MIHOUBI 2010-02-05 12:05:21 +01:00
parent 55c210ef47
commit 4a33777ef7
5 changed files with 339 additions and 85 deletions

View File

@ -16,6 +16,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _GLIBCXX_USE_C99_FENV_TR1 1
#include <cfenv>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include "Interpreter.hh" #include "Interpreter.hh"
@ -23,6 +26,10 @@
#define SMALL 1.0e-5; #define SMALL 1.0e-5;
//#define DEBUG //#define DEBUG
Interpreter::~Interpreter()
{
}
Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *x_arg, double *steady_y_arg, double *steady_x_arg, Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *x_arg, double *steady_y_arg, double *steady_x_arg,
double *direction_arg, int y_size_arg, double *direction_arg, int y_size_arg,
int nb_row_x_arg, int nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg, int nb_row_x_arg, int nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg,
@ -60,37 +67,35 @@ Interpreter::error_location()
{ {
string tmp; string tmp;
mxArray *M_; mxArray *M_;
double * P; char * P;
int R, C; unsigned int R, C;
M_ = mexGetVariable("global", "M_");
stringstream Error_loc("in "); stringstream Error_loc("in ");
switch(EQN_type) switch(EQN_type)
{ {
case TemporaryTerm: case TemporaryTerm:
if (EQN_block_number>1) if (EQN_block_number > 1)
Error_loc << "temporary term " << EQN_equation+1 << " in block " << EQN_block+1; Error_loc << "temporary term " << EQN_equation+1 << " in block " << EQN_block+1;
else else
Error_loc << "temporary term " << EQN_equation+1; Error_loc << "temporary term " << EQN_equation+1;
break; break;
case ModelEquation: case ModelEquation:
if (EQN_block_number>1) if (EQN_block_number > 1)
Error_loc << "equation " << EQN_equation+1 << " in block " << EQN_block+1; Error_loc << "equation " << EQN_equation+1 << " in block " << EQN_block+1;
else else
Error_loc << "equation " << EQN_equation+1; Error_loc << "equation " << EQN_equation+1;
break; break;
case FirstEndoDerivative: case FirstEndoDerivative:
if (EQN_block_number>1) M_ = mexGetVariable("global", "M_");
Error_loc << "first order derivative " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to endogenous variable "; 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 ";
else else
Error_loc << "first order derivative " << EQN_equation+1 << " with respect to endogenous variable "; Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to endogenous variable ";
R = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); C = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
C = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); R = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
P = (double*)mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); P = (char*) mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
if(EQN_dvar1<R) if (EQN_dvar1 < R)
{ for (unsigned int i = 0; i < C; i++)
for(int i = 0; i < C; i++) Error_loc << P[2*(EQN_dvar1+i*R)];
Error_loc << (char*)int(floor(P[EQN_dvar1*C+i]));
}
break; break;
default: default:
break; break;
@ -102,37 +107,57 @@ double
Interpreter::pow1(double a, double b) Interpreter::pow1(double a, double b)
{ {
double r = pow_(a, b); double r = pow_(a, b);
if (isnan(r) || isinf(r)) if (fetestexcept(FE_INVALID))
{ {
if (a < 0 && error_not_printed) if (error_not_printed)
{ {
mexPrintf("--------------------------------------\n Error: X^a with X=%5.15f\n in %s\n--------------------------------------\n", a,error_location().c_str()); mexPrintf("--------------------------------------\n Error: X^a with X=%5.15f\n in %s \n--------------------------------------\n", a,error_location().c_str());
error_not_printed = false; error_not_printed = false;
r = 0.0000000000000000000000001; r = 0.0000000000000000000000001;
} }
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN; res1 = NAN;
return (r); return r;
} }
else return r;
return r;
} }
double double
Interpreter::log1(double a) Interpreter::log1(double a)
{ {
double r = log(a); double r = log(a);
if (isnan(r) || isinf(r)) if (fetestexcept(FE_INVALID | FE_DIVBYZERO))
{ {
if (a <= 0 && error_not_printed) if (error_not_printed)
{ {
mexPrintf("--------------------------------------\n Error: log(X) with X=%5.15f\n in %s\n--------------------------------------\n", a,error_location().c_str()); mexPrintf("--------------------------------------\n Error: log(X) with X=%5.15f\n in %s \n--------------------------------------\n", a,error_location().c_str());
error_not_printed = false; error_not_printed = false;
r = 0.0000000000000000000000001;
} }
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN; res1 = NAN;
return (r); return r;
} }
else return r;
return r; }
double
Interpreter::log10_1(double a)
{
double r = log(a);
if (fetestexcept(FE_INVALID))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: log(X) with X=%5.15f\n in %s \n--------------------------------------\n", a,error_location().c_str());
error_not_printed = false;
r = 0.0000000000000000000000001;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
return r;
}
return r;
} }
void void
@ -144,6 +169,7 @@ Interpreter::compute_block_time(int Per_u_, bool evaluate, int block_num)
bool go_on = true; bool go_on = true;
double ll; double ll;
EQN_block = block_num; EQN_block = block_num;
//feclearexcept (FE_ALL_EXCEPT);
while (go_on) while (go_on)
{ {
switch (it_code->first) switch (it_code->first)
@ -622,7 +648,20 @@ Interpreter::compute_block_time(int Per_u_, bool evaluate, int block_num)
#endif #endif
break; break;
case oDivide: case oDivide:
Stack.push(v1 / v2); double r;
r = v1 / v2;
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero with %5.15f/%5.15f\n in %s \n--------------------------------------\n", v1, v2,error_location().c_str());
error_not_printed = false;
r = 1e70;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
Stack.push(r);
#ifdef DEBUG #ifdef DEBUG
tmp_out << " |" << v1 << "/" << v2 << "|"; tmp_out << " |" << v1 << "/" << v2 << "|";
#endif #endif
@ -713,7 +752,7 @@ Interpreter::compute_block_time(int Per_u_, bool evaluate, int block_num)
#endif #endif
break; break;
case oLog10: case oLog10:
Stack.push(log10(v1)); Stack.push(log10_1(v1));
#ifdef DEBUG #ifdef DEBUG
tmp_out << " |log10(" << v1 << ")|"; tmp_out << " |log10(" << v1 << ")|";
#endif #endif
@ -1042,6 +1081,16 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
if (cvg) if (cvg)
continue; continue;
y[Block_Contain[0].Variable] += -r[0]/g1[0]; y[Block_Contain[0].Variable] += -r[0]/g1[0];
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero with %5.15f/%5.15f\nSingularity in block %d\n--------------------------------------\n", r[0], g1[0], block_num);
error_not_printed = false;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1072,6 +1121,16 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
if (cvg) if (cvg)
continue; continue;
y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0]; y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0];
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero with %5.15f/%5.15f\nSingularity in block %d\n--------------------------------------\n", r[0], g1[0], block_num);
error_not_printed = false;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1103,6 +1162,16 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
if (cvg) if (cvg)
continue; continue;
y[Block_Contain[0].Variable] += -r[0]/g1[0]; y[Block_Contain[0].Variable] += -r[0]/g1[0];
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero with %5.15f/%5.15f\nSingularity in block %d\n--------------------------------------\n", r[0], g1[0], block_num);
error_not_printed = false;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1132,6 +1201,16 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
if (cvg) if (cvg)
continue; continue;
y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0]; y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0];
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero with %5.15f/%5.15f\nSingularity in block %d\n--------------------------------------\n", r[0], g1[0], block_num);
error_not_printed = false;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1186,8 +1265,13 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
cvg = false; cvg = false;
if (cvg) if (cvg)
continue; continue;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true); int prev_iter = iter;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true, EQN_block_number);
iter++; iter++;
if (iter > prev_iter)
{
}
} }
if (!cvg or !result) if (!cvg or !result)
{ {
@ -1204,7 +1288,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
error_not_printed = true; error_not_printed = true;
compute_block_time(0, false, block_num); compute_block_time(0, false, block_num);
cvg = false; cvg = false;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true); result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true, EQN_block_number);
if (!result) if (!result)
{ {
mexPrintf("Convergence not achieved in block %d\n", Block_Count); mexPrintf("Convergence not achieved in block %d\n", Block_Count);
@ -1253,7 +1337,8 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
cvg = false; cvg = false;
if (cvg) if (cvg)
continue; continue;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false); int prev_iter = iter;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false, EQN_block_number);
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1274,7 +1359,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
error_not_printed = true; error_not_printed = true;
compute_block_time(0, false, block_num); compute_block_time(0, false, block_num);
cvg = false; cvg = false;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false); result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false, EQN_block_number);
} }
} }
} }
@ -1326,7 +1411,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
cvg = false; cvg = false;
if (cvg) if (cvg)
continue; continue;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true); result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true, EQN_block_number);
iter++; iter++;
} }
if (!cvg or !result) if (!cvg or !result)
@ -1344,7 +1429,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
error_not_printed = true; error_not_printed = true;
compute_block_time(0, false, block_num); compute_block_time(0, false, block_num);
cvg = false; cvg = false;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true); result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true, EQN_block_number);
if (!result) if (!result)
{ {
mexPrintf("Convergence not achieved in block %d\n", Block_Count); mexPrintf("Convergence not achieved in block %d\n", Block_Count);
@ -1393,7 +1478,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
cvg = false; cvg = false;
if (cvg) if (cvg)
continue; continue;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false); result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false, EQN_block_number);
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1412,7 +1497,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
error_not_printed = true; error_not_printed = true;
compute_block_time(0, false, block_num); compute_block_time(0, false, block_num);
cvg = false; cvg = false;
result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false); result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false, EQN_block_number);
} }
} }
} }
@ -1485,7 +1570,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
else else
cvg = (max_res < solve_tolf); cvg = (max_res < solve_tolf);
u_count = u_count_saved; u_count = u_count_saved;
simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter, minimal_solving_periods); simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter, minimal_solving_periods, EQN_block_number);
iter++; iter++;
} }
if (!cvg) if (!cvg)
@ -1517,7 +1602,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name,
} }
} }
cvg = false; cvg = false;
simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter, minimal_solving_periods); simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter, minimal_solving_periods, EQN_block_number);
} }
mxFree(r); mxFree(r);
mxFree(y_save); mxFree(y_save);

View File

@ -54,6 +54,7 @@ private:
protected: protected:
double pow1(double a, double b); double pow1(double a, double b);
double log1(double a); double log1(double a);
double log10_1(double a);
string error_location(); string error_location();
void compute_block_time(int Per_u_, bool evaluate, int block_num); void compute_block_time(int Per_u_, bool evaluate, int block_num);
void evaluate_a_block(const int size, const int type, string bin_basename, bool steady_state, int block_num, void evaluate_a_block(const int size, const int type, string bin_basename, bool steady_state, int block_num,
@ -77,7 +78,7 @@ private:
string filename; string filename;
int minimal_solving_periods; int minimal_solving_periods;
public: public:
~Interpreter();
Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *x_arg, double *steady_y_arg, double *steady_x_arg, Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *x_arg, double *steady_y_arg, double *steady_x_arg,
double *direction_arg, int y_size_arg, int nb_row_x_arg, double *direction_arg, int y_size_arg, int nb_row_x_arg,
int nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg, int maxit_arg_, double solve_tolf_arg, int size_o_direction_arg, int nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg, int maxit_arg_, double solve_tolf_arg, int size_o_direction_arg,

View File

@ -17,6 +17,9 @@
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _GLIBCXX_USE_C99_FENV_TR1 1
#include <cfenv>
#include <cstring> #include <cstring>
#include <ctime> #include <ctime>
#include <sstream> #include <sstream>
@ -994,7 +997,7 @@ SparseMatrix::simple_bksub(int it_, int Size, double slowc_l)
} }
bool bool
SparseMatrix::simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state) SparseMatrix::simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state, int Block_number)
{ {
int i, j, k; int i, j, k;
int pivj = 0, pivk = 0; int pivj = 0, pivk = 0;
@ -1082,7 +1085,12 @@ SparseMatrix::simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax,
} }
} }
} }
#ifdef GLOBAL_CONVERGENCE
if (iter == 1)
#else
slowc_save /= 2; slowc_save /= 2;
#endif
mexPrintf("Error: Simulation diverging, trying to correct it using slowc=%f\n", slowc_save); mexPrintf("Error: Simulation diverging, trying to correct it using slowc=%f\n", slowc_save);
for (i = 0; i < y_size; i++) for (i = 0; i < y_size; i++)
y[i+it_*y_size] = ya[i+it_*y_size] + slowc_save*direction[i+it_*y_size]; y[i+it_*y_size] = ya[i+it_*y_size] + slowc_save*direction[i+it_*y_size];
@ -1152,42 +1160,12 @@ SparseMatrix::simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax,
} }
first = first->NZE_C_N; first = first->NZE_C_N;
} }
double markovitz = 0, markovitz_max = -9e70;
if (!one)
{
for (j = 0; j < l; j++)
{
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max)));
if (markovitz > markovitz_max)
{
piv = piv_v[j];
pivj = pivj_v[j]; //Line number
pivk = pivk_v[j]; //positi
markovitz_max = markovitz;
}
}
}
else
{
for (j = 0; j < l; j++)
{
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max)));
if (markovitz > markovitz_max && NR[j] == 1)
{
piv = piv_v[j];
pivj = pivj_v[j]; //Line number
pivk = pivk_v[j]; //positi
markovitz_max = markovitz;
}
}
}
pivot[i] = pivj;
pivotk[i] = pivk;
pivotv[i] = piv;
line_done[pivj] = true;
if (piv_abs < eps) if (piv_abs < eps)
{ {
mexPrintf("Error: singular system in Simulate_NG in block %d\n", blck+1); if (Block_number > 1)
mexPrintf("Error: singular system in Simulate_NG in block %d\n", blck+1);
else
mexPrintf("Error: singular system in Simulate_NG\n");
mexEvalString("drawnow;"); mexEvalString("drawnow;");
mxFree(piv_v); mxFree(piv_v);
mxFree(pivj_v); mxFree(pivj_v);
@ -1203,6 +1181,98 @@ SparseMatrix::simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax,
mexErrMsgTxt(filename.c_str()); mexErrMsgTxt(filename.c_str());
} }
} }
double markovitz = 0, markovitz_max = -9e70;
int NR_max = 0;
//mexPrintf("l=%d\n",l);
if (!one)
{
for (j = 0; j < l; j++)
{
if (N_max > 0 && NR[j] > 0)
{
if (fabs(piv_v[j]) > 0)
{
if (markowitz_c > 0)
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max)));
else
markovitz = fabs(piv_v[j])/piv_abs;
}
else
markovitz = 0;
}
else
markovitz = fabs(piv_v[j])/piv_abs;
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero in simul_NG(1) piv_abs=%f and N_max=%d \n--------------------------------------\n", piv_abs, N_max);
error_not_printed = false;
markovitz = 1e70;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
//mexPrintf("piv_v[j]=%f NR[j]=%d markovitz=%f markovitz_max=%f\n", piv_v[j], NR[j], markovitz, markovitz_max);
if (markovitz > markovitz_max)
{
piv = piv_v[j];
pivj = pivj_v[j]; //Line number
pivk = pivk_v[j]; //positi
markovitz_max = markovitz;
NR_max = NR[j];
}
}
}
else
{
for (j = 0; j < l; j++)
{
if (N_max > 0 && NR[j] > 0)
{
if (fabs(piv_v[j]) > 0)
{
if (markowitz_c > 0)
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max)));
else
markovitz = fabs(piv_v[j])/piv_abs;
}
else
markovitz = 0;
}
else
markovitz = fabs(piv_v[j])/piv_abs;
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero in simul_NG(2) piv_abs=%f and N_max=%d \n--------------------------------------\n", piv_abs, N_max);
error_not_printed = false;
markovitz = 1e70;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
if (/*markovitz > markovitz_max &&*/ NR[j] == 1)
{
piv = piv_v[j];
pivj = pivj_v[j]; //Line number
pivk = pivk_v[j]; //positi
markovitz_max = markovitz;
NR_max = NR[j];
//mexPrintf("forced piv = %f NR_max =%d\n",piv, NR_max);
}
}
}
if (fabs(piv) < eps)
mexPrintf("==> Error NR_max=%d, N_max=%d and piv=%f, piv_abs=%f, markovitz_max=%f\n",NR_max, N_max, piv, piv_abs, markovitz_max);
if (NR_max == 0)
mexPrintf("==> Error NR_max=0 and piv=%f, markovitz_max=%f\n",piv, markovitz_max);
pivot[i] = pivj;
pivotk[i] = pivk;
pivotv[i] = piv;
line_done[pivj] = true;
/*divide all the non zeros elements of the line pivj by the max_pivot*/ /*divide all the non zeros elements of the line pivj by the max_pivot*/
int nb_var = At_Row(pivj, &first); int nb_var = At_Row(pivj, &first);
for (j = 0; j < nb_var; j++) for (j = 0; j < nb_var; j++)
@ -1426,7 +1496,7 @@ SparseMatrix::Check_the_Solution(int periods, int y_kmin, int y_kmax, int Size,
} }
int int
SparseMatrix::simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, bool cvg, int &iter, int minimal_solving_periods) SparseMatrix::simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, bool cvg, int &iter, int minimal_solving_periods, int Block_number)
{ {
/*Triangularisation at each period of a block using a simple gaussian Elimination*/ /*Triangularisation at each period of a block using a simple gaussian Elimination*/
t_save_op_s *save_op_s; t_save_op_s *save_op_s;
@ -1606,17 +1676,45 @@ SparseMatrix::simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax
first = first->NZE_C_N; first = first->NZE_C_N;
} }
double markovitz = 0, markovitz_max = -9e70; double markovitz = 0, markovitz_max = -9e70;
int NR_max = 0;
//mexPrintf("l=%d\n",l);
if (!one) if (!one)
{ {
for (j = 0; j < l; j++) for (j = 0; j < l; j++)
{ {
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max))); if (N_max > 0 && NR[j] > 0)
{
if (fabs(piv_v[j]) > 0)
{
if (markowitz_c > 0)
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max)));
else
markovitz = fabs(piv_v[j])/piv_abs;
}
else
markovitz = 0;
}
else
markovitz = fabs(piv_v[j])/piv_abs;
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero in simul_NG(1) piv_abs=%f and N_max=%d \n--------------------------------------\n", piv_abs, N_max);
error_not_printed = false;
markovitz = 1e70;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
//mexPrintf("piv_v[j]=%f NR[j]=%d markovitz=%f markovitz_max=%f\n", piv_v[j], NR[j], markovitz, markovitz_max);
if (markovitz > markovitz_max) if (markovitz > markovitz_max)
{ {
piv = piv_v[j]; piv = piv_v[j];
pivj = pivj_v[j]; //Line number pivj = pivj_v[j]; //Line number
pivk = pivk_v[j]; //positi pivk = pivk_v[j]; //positi
markovitz_max = markovitz; markovitz_max = markovitz;
NR_max = NR[j];
} }
} }
} }
@ -1624,16 +1722,46 @@ SparseMatrix::simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax
{ {
for (j = 0; j < l; j++) for (j = 0; j < l; j++)
{ {
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log((double)(NR[j]/N_max))); if (N_max > 0 && NR[j] > 0)
if (markovitz > markovitz_max && NR[j] == 1) {
if (fabs(piv_v[j]) > 0)
{
if (markowitz_c > 0)
markovitz = exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(double (NR[j])/double (N_max)));
else
markovitz = fabs(piv_v[j])/piv_abs;
}
else
markovitz = 0;
}
else
markovitz = fabs(piv_v[j])/piv_abs;
if (fetestexcept(FE_DIVBYZERO))
{
if (error_not_printed)
{
mexPrintf("--------------------------------------\n Error: Divide by zero in simul_NG(2) piv_abs=%f and N_max=%d \n--------------------------------------\n", piv_abs, N_max);
error_not_printed = false;
markovitz = 1e70;
}
feclearexcept (FE_ALL_EXCEPT);
res1 = NAN;
}
if (/*markovitz > markovitz_max &&*/ NR[j] == 1)
{ {
piv = piv_v[j]; piv = piv_v[j];
pivj = pivj_v[j]; //Line number pivj = pivj_v[j]; //Line number
pivk = pivk_v[j]; //position pivk = pivk_v[j]; //positi
markovitz_max = markovitz; markovitz_max = markovitz;
NR_max = NR[j];
//mexPrintf("forced piv = %f NR_max =%d\n",piv, NR_max);
} }
} }
} }
if (fabs(piv) < eps)
mexPrintf("==> Error NR_max=%d, N_max=%d and piv=%f, piv_abs=%f, markovitz_max=%f\n",NR_max, N_max, piv, piv_abs, markovitz_max);
if (NR_max == 0)
mexPrintf("==> Error NR_max=0 and piv=%f, markovitz_max=%f\n",piv, markovitz_max);
pivot[i] = pivj; pivot[i] = pivj;
pivot_save[i] = pivj; pivot_save[i] = pivj;
pivotk[i] = pivk; pivotk[i] = pivk;
@ -1667,7 +1795,10 @@ SparseMatrix::simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax
} }
if (piv_abs < eps) if (piv_abs < eps)
{ {
mexPrintf("Error: singular system in Simulate_NG1\n"); if (Block_number>1)
mexPrintf("Error: singular system in Simulate_NG1 in block %d\n", blck);
else
mexPrintf("Error: singular system in Simulate_NG1\n");
mexEvalString("drawnow;"); mexEvalString("drawnow;");
filename += " stopped"; filename += " stopped";
mexErrMsgTxt(filename.c_str()); mexErrMsgTxt(filename.c_str());

View File

@ -99,8 +99,8 @@ class SparseMatrix
{ {
public: public:
SparseMatrix(); SparseMatrix();
int simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, bool cvg, int &iter, int minimal_solving_periods); int simulate_NG1(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, bool cvg, int &iter, int minimal_solving_periods, int Block_number);
bool simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state); bool simulate_NG(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state, int Block_number);
void Direct_Simulate(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, int iter); void Direct_Simulate(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, int iter);
void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1); void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1);
void Read_SparseMatrix(string file_name, const int Size, int periods, int y_kmin, int y_kmax, bool steady_state, bool two_boundaries); void Read_SparseMatrix(string file_name, const int Size, int periods, int y_kmin, int y_kmax, bool steady_state, bool two_boundaries);
@ -182,6 +182,7 @@ protected:
int start_compare; int start_compare;
int restart; int restart;
bool error_not_printed; bool error_not_printed;
double g_lambda1, g_lambda2, gp_0;
}; };
#endif #endif

View File

@ -21,9 +21,11 @@
// simulate.cc // // simulate.cc //
// simulate file designed for GNU GCC C++ compiler // // simulate file designed for GNU GCC C++ compiler //
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define _GLIBCXX_USE_C99_FENV_TR1 1
#include <cfenv>
#include <cstring> #include <cstring>
#include "Interpreter.hh" #include "Interpreter.hh"
#ifndef DEBUG_EX #ifndef DEBUG_EX
# include "mex.h" # include "mex.h"
@ -33,10 +35,12 @@
#include "Mem_Mngr.hh" #include "Mem_Mngr.hh"
#ifdef DEBUG_EX #ifdef DEBUG_EX
using namespace std; using namespace std;
# include <sstream> # include <sstream>
string string
Get_Argument(const char *argv) Get_Argument(const char *argv)
{ {
@ -213,6 +217,30 @@ Get_Argument(const mxArray *prhs)
return f; return f;
} }
void fpe_handler(int) {
int e;
mexPrintf("caught FPE, exiting.\n");
e = fetestexcept(FE_ALL_EXCEPT);
if (!e) {
mexPrintf("no exception information set\n");
}
if (e & FE_DIVBYZERO) {
mexPrintf("divide by zero\n");
}
if (e & FE_INVALID) {
mexPrintf("invalide operand\n");
}
if (e & FE_UNDERFLOW) {
mexPrintf("underflow\n");
}
if (e & FE_OVERFLOW) {
mexPrintf("overflow\n");
}
exit(1);
}
/* The gateway routine */ /* The gateway routine */
void void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
@ -225,6 +253,14 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
double *direction; double *direction;
bool steady_state = false; bool steady_state = false;
bool evaluate = false; bool evaluate = false;
fexcept_t *flagp;
flagp = (fexcept_t*) mxMalloc(sizeof(fexcept_t));
if(fegetexceptflag(flagp, FE_ALL_EXCEPT))
mexPrintf("fegetexceptflag failed\n");
if(fesetexceptflag(flagp,FE_INVALID | FE_DIVBYZERO))
mexPrintf("fesetexceptflag failed\n");
mxFree(flagp);
feclearexcept (FE_ALL_EXCEPT);
for (i = 0; i < nrhs; i++) for (i = 0; i < nrhs; i++)
{ {
if (Get_Argument(prhs[i]) == "static") if (Get_Argument(prhs[i]) == "static")