diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m
index 8e3128b5fb380d374766a9fb4daae30ce973fe1a..42b41b8160530042ec84287b75bdeab3ba18b919 100644
--- a/matlab/global_initialization.m
+++ b/matlab/global_initialization.m
@@ -224,4 +224,7 @@ function global_initialization()
   
   % block decomposition + minimum feedback set for steady state computation
   options_.block_mfs = 0;
-  
\ No newline at end of file
+
+  % block decomposition + minimum feedback set for steady state computation
+  % using simulate.dll
+  options_.block_mfs_dll = 0;
diff --git a/matlab/model_info.m b/matlab/model_info.m
index a0b3d6cbd530f0e24d972a89ec43bc8560228d8e..7d6b986699234c53412ab19554212c8675b4146b 100644
--- a/matlab/model_info.m
+++ b/matlab/model_info.m
@@ -24,23 +24,23 @@ function model_info;
  if(isfield(M_,'block_structure'))
    nb_blocks=length(M_.block_structure.block);
    fprintf('The model has %d equations and is decomposed in %d blocks as follow:\n',M_.endo_nbr,nb_blocks);
-   fprintf('==============================================================================================================\n');
-   fprintf('| %10s | %10s | %30s | %14s | %30s |\n','Block n�','Size','Block Type','Equation','Dependent variable');
-   fprintf('|============|============|================================|================|================================|\n');
+   fprintf('===============================================================================================================\n');
+   fprintf('| %10s | %10s | %30s | %14s | %31s |\n','Block n�','Size','Block Type','E   quation','Dependent variable');
+   fprintf('|============|============|================================|================|=================================|\n');
    for i=1:nb_blocks
        size_block=length(M_.block_structure.block(i).equation);
        if(i>1)
-         fprintf('|------------|------------|--------------------------------|----------------|--------------------------------|\n');
+         fprintf('|------------|------------|--------------------------------|----------------|---------------------------------|\n');
        end;
        for j=1:size_block
            if(j==1)
-               fprintf('| %3d (%4d) | %10d | %30s | %14d | %30s |\n',i,M_.block_structure.block(i).num,size_block,Sym_type(M_.block_structure.block(i).Simulation_Type),M_.block_structure.block(i).equation(j),M_.endo_names(M_.block_structure.block(i).variable(j),:));
+               fprintf('| %3d (%4d) | %10d | %30s | %14d | %-6d %24s |\n',i,M_.block_structure.block(i).num,size_block,Sym_type(M_.block_structure.block(i).Simulation_Type),M_.block_structure.block(i).equation(j),M_.block_structure.block(i).variable(j),M_.endo_names(M_.block_structure.block(i).variable(j),:));
            else
-               fprintf('| %10s | %10s | %30s | %14d | %30s |\n','','','',M_.block_structure.block(i).equation(j),M_.endo_names(M_.block_structure.block(i).variable(j),:));
+               fprintf('| %10s | %10s | %30s | %14d | %-6d %24s |\n','','','',M_.block_structure.block(i).equation(j),M_.block_structure.block(i).variable(j),M_.endo_names(M_.block_structure.block(i).variable(j),:));
            end;
        end;
    end;
-   fprintf('==============================================================================================================\n');
+   fprintf('===============================================================================================================\n');
    fprintf('\n');
    for k=1:M_.maximum_endo_lag+M_.maximum_endo_lead+1
        if(k==M_.maximum_endo_lag+1)
diff --git a/matlab/resid.m b/matlab/resid.m
index 8a3b1d41f445a0f3c7b776aa9f95038ba1392bd0..5287b8812f0cca496a5ef8d3255472c942c386bc 100644
--- a/matlab/resid.m
+++ b/matlab/resid.m
@@ -53,12 +53,12 @@ function resid(period)
       addpath(M_.fname);
   end;
   for it_=M_.maximum_lag+1:period+M_.maximum_lag
-    if(options_.model_mode == 1 || options_.model_mode == 3)
-        z(:,it_-M_.maximum_lag) = feval(fh,oo_.endo_simul',oo_.exo_simul, M_.params, it_);
-    else
+    %if(options_.model_mode == 1 || options_.model_mode == 3)
+    %    z(:,it_-M_.maximum_lag) = feval(fh,oo_.endo_simul',oo_.exo_simul, M_.params, it_);
+    %else
         z(:,it_-M_.maximum_lag) = feval(fh,y(iyr0),oo_.exo_simul, M_.params, it_);
         iyr0 = iyr0 + n;
-    end;
+    %end;
   end
   if(options_.model_mode == 1 || options_.model_mode == 3)
       rmpath(M_.fname);
diff --git a/matlab/solve_one_boundary.m b/matlab/solve_one_boundary.m
index 0596745fbd4d6ef6af3be74ea302a2ad0c67b6c8..b5430d1a649e267494828af95af9642b2013e540 100644
--- a/matlab/solve_one_boundary.m
+++ b/matlab/solve_one_boundary.m
@@ -100,8 +100,42 @@ function [y, info] = solve_one_boundary(fname, y, x, params, y_index_eq, nze, pe
               max_res=max(max(abs(r)));
            end;
            %['max_res=' num2str(max_res) ' Block_Num=' int2str(Block_Num) ' it_=' int2str(it_)]
+           disp(['iteration : ' int2str(iter+1) ' => ' num2str(max_res) ' time = ' int2str(it_)]);
+           
+%     fjac = zeros(Blck_size, Blck_size);
+%     disp(['Blck_size=' int2str(Blck_size) ' it_=' int2str(it_)]);
+%     dh = max(abs(y(it_, y_index_eq)),options_.gstep*ones(1, Blck_size))*eps^(1/3);
+%     fvec = r;
+%       for j = 1:Blck_size
+%     	  ydh = y ;
+%           ydh(it_, y_index_eq(j)) = ydh(it_, y_index_eq(j)) + dh(j)  ;
+%           [t, y1, g11, g21, g31]=feval(fname, ydh, x, params, it_, 0);
+%           fjac(:,j) = (t - fvec)./dh(j) ;
+%       end;
+%     diff = g1 -fjac;
+%     diff
+%     disp('g1');
+%     disp([num2str(g1,'%4.5f')]);
+%     disp('fjac');
+%     disp([num2str(fjac,'%4.5f')]);
+%     [c_max, i_c_max] = max(abs(diff));
+%     [l_c_max, i_r_max] = max(c_max);
+%     disp(['maximum element row=' int2str(i_c_max(i_r_max)) ' and column=' int2str(i_r_max) ' value = ' num2str(l_c_max)]);
+%     equation = i_c_max(i_r_max);
+%     variable = i_r_max;
+%     variable
+%     mod(variable, Blck_size)
+%     disp(['equation ' int2str(equation) ' and variable ' int2str(y_index_eq(variable)) ' ' M_.endo_names(y_index_eq(variable), :)]);
+%     disp(['g1(' int2str(equation) ', ' int2str(variable) ')=' num2str(g1(equation, variable),'%3.10f') ' fjac(' int2str(equation) ', ' int2str(variable) ')=' num2str(fjac(equation, variable), '%3.10f') ' y(' int2str(it_) ', ' int2str(variable) ')=' num2str(y(it_, variable))]);
+%     %return;
+%     %g1 = fjac;
+
+           
+           
+           
+           
            if(verbose==1)
-             disp(['iteration : ' int2str(iter) ' => ' num2str(max_res) ' time = ' int2str(it_)]);
+             disp(['iteration : ' int2str(iter+1) ' => ' num2str(max_res) ' time = ' int2str(it_)]);
              if(is_dynamic)
                disp([M_.endo_names(y_index_eq,:) num2str([y(it_,y_index_eq)' r g1])]);
              else
@@ -118,7 +152,7 @@ function [y, info] = solve_one_boundary(fname, y, x, params, y_index_eq, nze, pe
            if(~cvg)
              if(iter>0)
                if(~isreal(max_res) | isnan(max_res) | (max_resa<max_res && iter>1))
-                 if(isnan(max_res))
+                 if(isnan(max_res)| (max_resa<max_res && iter>0))
                    detJ=det(g1a);
                    if(abs(detJ)<1e-7)
                      max_factor=max(max(abs(g1a)));
@@ -198,15 +232,23 @@ function [y, info] = solve_one_boundary(fname, y, x, params, y_index_eq, nze, pe
                else
                   info = -Block_Num*10;
                end
-             elseif(~is_dynamic & options_.solve_algo==2)
+             elseif((~is_dynamic & options_.solve_algo==2) || (is_dynamic & options_.solve_algo==4))
                 lambda=1;
                 stpmx = 100 ;
-                stpmax = stpmx*max([sqrt(y'*y);size(y_index_eq,2)]);
+                if (is_dynamic)
+                    stpmax = stpmx*max([sqrt(y*y');size(y_index_eq,2)]);
+                else
+                    stpmax = stpmx*max([sqrt(y'*y);size(y_index_eq,2)]);
+                end;
                 nn=1:size(y_index_eq,2);
                 g = (r'*g1)';
                 f = 0.5*r'*r;
                 p = -g1\r ;
-                [y,f,r,check]=lnsrch1(y,f,g,p,stpmax,fname,nn,y_index_eq,x, params, 0);
+                if (is_dynamic)
+                    [y,f,r,check]=lnsrch1(y,f,g,p,stpmax,fname,nn,y_index_eq,x, params, it_, 0);
+                else
+                    [y,f,r,check]=lnsrch1(y,f,g,p,stpmax,fname,nn,y_index_eq,x, params, 0);
+                end;
                 dx = ya - y(y_index_eq);
              elseif(~is_dynamic & options_.solve_algo==3)
                  [yn,info] = csolve(@local_fname, y(y_index_eq),@local_fname,1e-6,500, x, params, y, y_index_eq, fname, 1);
@@ -283,6 +325,7 @@ function [y, info] = solve_one_boundary(fname, y, x, params, y_index_eq, nze, pe
                  return;
              end;
              iter=iter+1;
+             max_resa = max_res;
            end
        end
        if cvg==0
diff --git a/matlab/solve_two_boundaries.m b/matlab/solve_two_boundaries.m
index b34efe742d6ff2b750c59e55c39f5fcc20a6c40c..b03e1244276b421838d2133bece3c1fd0b0b9527 100644
--- a/matlab/solve_two_boundaries.m
+++ b/matlab/solve_two_boundaries.m
@@ -58,7 +58,7 @@ function y = solve_two_boundaries(fname, y, x, params, y_index, nze, periods, y_
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 
-  global oo_ M_ T9025 T1149 T11905;
+  global options_ oo_ M_ T9025 T1149 T11905;
   cvg=0;
   iter=0;
   Per_u_=0;
@@ -73,11 +73,48 @@ function y = solve_two_boundaries(fname, y, x, params, y_index, nze, periods, y_
   reduced = 0;
   while ~(cvg==1 | iter>maxit_),
     [r, y, g1, g2, g3, b]=feval(fname, y, x, params, periods, 0, y_kmin, Blck_size);
+
+%     fjac = zeros(Blck_size, Blck_size*(y_kmin_l+1+y_kmax_l));
+%     disp(['Blck_size=' int2str(Blck_size) ' size(y_index)=' int2str(size(y_index,2))]);
+%     dh = max(abs(y(y_kmin+1-y_kmin_l:y_kmin+1+y_kmax_l, y_index)),options_.gstep*ones(y_kmin_l+1+y_kmax_l, Blck_size))*eps^(1/3);
+%     fvec = r;
+%     %for i = y_kmin+1-y_kmin_l:y_kmin+1+y_kmax_l
+%     i = y_kmin+1;
+%       i
+%       for j = 1:Blck_size
+%     	  ydh = y ;
+%           ydh(i, y_index(j)) = ydh(i, y_index(j)) + dh(i, j)  ;
+%           if(j==11 && i==2)
+%               disp(['y(i,y_index(11)=' int2str(y_index(11)) ')= ' num2str(y(i,y_index(11))) ' ydh(i, y_index(j))=' num2str(ydh(i, y_index(j))) ' dh(i,j)= ' num2str(dh(i,j))]);
+%           end;
+%           [t, y1, g11, g21, g31, b1]=feval(fname, ydh, x, params, periods, 0, y_kmin, Blck_size);
+%           fjac(:,j+(i-(y_kmin+1-y_kmin_l))*Blck_size) = (t(:, 1+y_kmin) - fvec(:, 1+y_kmin))./dh(i, j) ;
+%           if(j==11 && i==2)
+%                disp(['fjac(:,' int2str(j+(i-(y_kmin+1-y_kmin_l))*Blck_size) ')=']);
+%                disp([num2str(fjac(:,j+(i-(y_kmin+1-y_kmin_l))*Blck_size))]);
+%           end;
+%       end;
+% %    end
+%     %diff = g1(1:Blck_size, 1:Blck_size*(y_kmin_l+1+y_kmax_l)) -fjac;
+%     diff = g1(1:Blck_size, y_kmin_l*Blck_size+1:(y_kmin_l+1)*Blck_size) -fjac(1:Blck_size, y_kmin_l*Blck_size+1:(y_kmin_l+1)*Blck_size);
+%     disp(diff);
+%     [c_max, i_c_max] = max(abs(diff));
+%     [l_c_max, i_r_max] = max(c_max);
+%     disp(['maximum element row=' int2str(i_c_max(i_r_max)) ' and column=' int2str(i_r_max) ' value = ' num2str(l_c_max)]);
+%     equation = i_c_max(i_r_max);
+%     variable = i_r_max;
+%     variable
+%     disp(['equation ' int2str(equation) ' and variable ' int2str(y_index(mod(variable, Blck_size))) ' ' M_.endo_names(y_index(mod(variable, Blck_size)), :)]);
+%     disp(['g1(' int2str(equation) ', ' int2str(variable) ')=' num2str(g1(equation, y_kmin_l*Blck_size+variable),'%3.10f') ' fjac(' int2str(equation) ', ' int2str(variable) ')=' num2str(fjac(equation, y_kmin_l*Blck_size+variable), '%3.10f')]);
+%     return;
+
+
+
 %     for i=1:periods;
 %       disp([sprintf('%5.14f ',[T9025(i) T1149(i) T11905(i)])]);
 %     end;
 %     return;
-    residual = r(:,y_kmin+1:y_kmin+1+y_kmax_l);
+    %residual = r(:,y_kmin+1:y_kmin+1+y_kmax_l);
     %num2str(residual,' %1.6f')
     %jac_ = g1(1:(y_kmin)*Blck_size, 1:(y_kmin+1+y_kmax_l)*Blck_size);
     %jac_
@@ -87,15 +124,15 @@ function y = solve_two_boundaries(fname, y, x, params, y_index, nze, periods, y_
     term2 = g1(:, (periods+y_kmin_l)*Blck_size+1:(periods+y_kmin_l+y_kmax_l)*Blck_size)*reshape(y(periods+y_kmin+1:periods+y_kmin+y_kmax_l,y_index)',1,y_kmax_l*Blck_size)';
     b = b - term1 - term2;
     
-%     fid = fopen(['result' num2str(iter)],'w');
-%     fg1a = full(g1a);
-%     fprintf(fid,'%d\n',size(fg1a,1));
-%     fprintf(fid,'%d\n',size(fg1a,2));
-%     fprintf(fid,'%5.14f\n',fg1a);
-%     fprintf(fid,'%d\n',size(b,1));
-%     fprintf(fid,'%5.14f\n',b);
-%     fclose(fid);
-%     return;
+%      fid = fopen(['result' num2str(iter)],'w');
+%      fg1a = full(g1a);
+%      fprintf(fid,'%d\n',size(fg1a,1));
+%      fprintf(fid,'%d\n',size(fg1a,2));
+%      fprintf(fid,'%5.14f\n',fg1a);
+%      fprintf(fid,'%d\n',size(b,1));
+%      fprintf(fid,'%5.14f\n',b);
+%      fclose(fid);
+%      return;
     %ipconfigb_ = b(1:(1+y_kmin)*Blck_size);
     %b_ 
     
diff --git a/matlab/steady_.m b/matlab/steady_.m
index 4062e6f5d5027990056a38470595b95adf977b86..269838de9ac56534a41e4f1a7062594c64b7bc6a 100644
--- a/matlab/steady_.m
+++ b/matlab/steady_.m
@@ -79,6 +79,8 @@ function steady_()
                           [oo_.exo_steady_state; ...
                           oo_.exo_det_steady_state], M_.params);
     end
+  elseif options_.block_mfs_dll
+      [oo_.steady_state,check] = simulate('steady_state');
   else
     [oo_.steady_state,check] = dynare_solve([M_.fname '_static'],...
 				     oo_.steady_state,...
diff --git a/mex/sources/simulate/Interpreter.cc b/mex/sources/simulate/Interpreter.cc
index 5cf8e255d6f50dcc6724ce17b599837c3c87d83f..e455d14ef1560dd5521b7f8b615e19e55907e015 100644
--- a/mex/sources/simulate/Interpreter.cc
+++ b/mex/sources/simulate/Interpreter.cc
@@ -16,9 +16,13 @@
  * You should have received a copy of the GNU General Public License
  * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
  */
-//#define DEBUGC
 #include <cstring>
+#include <sstream>
 #include "Interpreter.hh"
+#define BIG 1.0e+8;
+#define SMALL 1.0e-5;
+//#define DEBUG
+
 
 Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *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,
@@ -45,202 +49,249 @@ Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, doub
   markowitz_c=markowitz_c_arg;
   filename=filename_arg;
   T=NULL;
-  //GaussSeidel=true;
+  error_not_printed = true;
 }
 
 double
 Interpreter::pow1(double a, double b)
 {
-  double r=pow_(a,b);
+	/*double r;
+	if(a>=0)
+    r=pow_(a,b);
+	else
+	  {
+	     //r=0;
+	     //max_res=res1=res2=BIG;
+	     if(error_not_printed)
+	       {
+	         mexPrintf("Error: X^a with X<0\n");
+	         error_not_printed = false;
+	       }
+	     //r = BIG;
+	     //r = -pow_(-a, b);
+	     //r = 0;
+	     //r = SMALL;
+	     //r = pow_(-a, b);
+	  }*/
+	double r = pow_(a, b);
   if (isnan(r) || isinf(r))
     {
-      //mexPrintf("pow(%f, %f)=%f\n",a, b, r);
-      max_res=res1=res2=r;
+    	if(a<0 && error_not_printed)
+	       {
+	         mexPrintf("Error: X^a with X=%5.25f\n",a);
+	         error_not_printed = false;
+	         r = 0.0000000000000000000000001;
+	       }
+      //res1=NAN;
       return(r);
     }
   else
     return r;
 }
 
+double
+Interpreter::log1(double a)
+{
+	/*double r;
+	if(a>=0)
+    r=pow_(a,b);
+	else
+	  {
+	     //r=0;
+	     //max_res=res1=res2=BIG;
+	     if(error_not_printed)
+	       {
+	         mexPrintf("Error: X^a with X<0\n");
+	         error_not_printed = false;
+	       }
+	     //r = BIG;
+	     //r = -pow_(-a, b);
+	     //r = 0;
+	     //r = SMALL;
+	     //r = pow_(-a, b);
+	  }*/
+	double r = log(a);
+  if (isnan(r) || isinf(r))
+    {
+    	if(a<=0 && error_not_printed)
+	       {
+	         mexPrintf("Error: log(X) with X<=0\n");
+	         error_not_printed = false;
+	       }
+      res1=NAN;
+      return(r);
+    }
+  else
+    return r;
+}
+
+
 
 void
 Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
 {
   int var, lag, op;
+  ostringstream tmp_out;
   double v1, v2;
   char/*uint8_t*/ cc;
   bool go_on=true;
   double *ll;
   while (go_on)
     {
-      //mexPrintf("it_=%d",it_);
       switch (cc=get_code_char)
         {
           case FLDV :
             //load a variable in the processor
-#ifdef DEBUGC
-            if(Block_Count==2)
-              {
-                mexPrintf("FLDV\n");
-                mexEvalString("drawnow;");
-              }
-#endif
             switch (get_code_char)
               {
                 case eParameter :
                   var=get_code_int;
-#ifdef DEBUGC
-                  if(Block_Count==2)
-                    {
-                      mexPrintf(" params[%d]=%f\n",var,params[var]);
-                      mexEvalString("drawnow;");
-                    }
-#endif
                   Stack.push(params[var]);
+#ifdef DEBUG
+                  tmp_out << " params[" << var << "](" << params[var] << ")";
+#endif
                   break;
                 case eEndogenous :
                   var=get_code_int;
                   lag=get_code_int;
-#ifdef DEBUGC
-                  if(Block_Count==2)
-                    {
-                      mexPrintf("y[%d, %d]=%f\n",it_+lag, var+1, y[(it_+lag)*y_size+var]);
-                    }
-#endif
                   Stack.push(y[(it_+lag)*y_size+var]);
+#ifdef DEBUG
+                  tmp_out << " y[" << it_+lag << ", " << var << "](" << y[(it_+lag)*y_size+var] << ")";
+#endif
                   break;
                 case eExogenous :
-#ifdef DEBUGC
-                  mexPrintf("Exogenous\n");
-#endif
                   var=get_code_int;
                   lag=get_code_int;
-#ifdef DEBUGC
-                  if(Block_Count==2)
-                    {
-                      mexPrintf("x[%d, %d]\n",it_+lag, var+1);
-                    }
-#endif
                   Stack.push(x[it_+lag+var*nb_row_x]);
+#ifdef DEBUG
+                  tmp_out << " x[" << it_+lag << ", " << var << "](" << x[it_+lag+var*nb_row_x] << ")";
+#endif
                   break;
                 case eExogenousDet :
-#ifdef DEBUGC
-                  mexPrintf("ExogenousDet\n");
-#endif
-
                   var=get_code_int;
                   lag=get_code_int;
-#ifdef DEBUGC
-                  mexPrintf(" x(det)[%d]=%f\n",it_+lag+var*nb_row_xd,x[it_+lag+var*nb_row_xd]);
-                  mexEvalString("drawnow;");
-#endif
                   Stack.push(x[it_+lag+var*nb_row_xd]);
                   break;
                 default:
                   mexPrintf("Unknown variable type\n");
               }
             break;
+          case FLDSV :
+            //load a variable in the processor
+            switch (get_code_char)
+              {
+                case eParameter :
+                  var=get_code_int;
+                  Stack.push(params[var]);
+#ifdef DEBUG
+                  tmp_out << " params[" << var << "](" << params[var] << ")";
+#endif
+                  break;
+                case eEndogenous :
+                  var=get_code_int;
+                  Stack.push(y[var]);
+#ifdef DEBUG
+                  tmp_out << " y[" << var << "](" << y[var] << ")";
+#endif
+                  break;
+                case eExogenous :
+                  var=get_code_int;
+                  Stack.push(x[var]);
+#ifdef DEBUG
+                  tmp_out << " x[" << var << "](" << x[var] << ")";
+#endif
+                  break;
+                case eExogenousDet :
+                  var=get_code_int;
+                  Stack.push(x[var]);
+                  break;
+                default:
+                  mexPrintf("Unknown variable type\n");
+              }
+            break;
           case FLDT :
             //load a temporary variable in the processor
             var=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("FLDT %d [%d]=%f Stack.size()=%d\n",var,var*(periods+y_kmin+y_kmax)+it_,T[var*(periods+y_kmin+y_kmax)+it_], Stack.size());
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+            tmp_out << " T[" << it_ << ", " << var << "](" << T[var*(periods+y_kmin+y_kmax)+it_] << ")";
 #endif
             Stack.push(T[var*(periods+y_kmin+y_kmax)+it_]);
             break;
+          case FLDST :
+            //load a temporary variable in the processor
+            var=get_code_int;
+#ifdef DEBUG
+            tmp_out << " T[" << var << "](" << T[var] << ")";
+#endif
+            Stack.push(T[var]);
+            break;
           case FLDU :
             //load u variable in the processor
-#ifdef DEBUGC
-            mexPrintf("FLDU\n");
-            mexEvalString("drawnow;");
-#endif
             var=get_code_int;
             var+=Per_u_;
+#ifdef DEBUG
+            tmp_out << " u[" << var << "](" << u[var] << ")";
+#endif
             Stack.push(u[var]);
             break;
-          case FLDR :
+          case FLDSU :
             //load u variable in the processor
             var=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("FLDR r[%d]=%f\n",var, r[var] );
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+            tmp_out << " u[" << var << "](" << u[var] << ")";
 #endif
+            Stack.push(u[var]);
+            break;
+          case FLDR :
+            //load u variable in the processor
+            var=get_code_int;
             Stack.push(r[var]);
             break;
           case FLDZ :
             //load 0 in the processor
-#ifdef DEBUGC
-            mexPrintf("FLDZ\n");
-            mexEvalString("drawnow;");
-#endif
             Stack.push(0);
+#ifdef DEBUG
+            tmp_out << " 0";
+#endif
             break;
           case FLDC :
             //load a numerical constant in the processor
             /*asm("fld\n\t"
                 "fstp %%st" : "=t" (ll) : "0" ((double)(*Code)));*/
             ll=get_code_pdouble;
-#ifdef DEBUGC
-            mexPrintf("FLDC %f\n",*ll);
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+            tmp_out << " " << *ll;
 #endif
+
             Stack.push(*ll);
             break;
           case FSTPV :
             //load a variable in the processor
-#ifdef DEBUGC
-            mexPrintf("FSTPV\n");
-            mexEvalString("drawnow;");
-#endif
             switch (get_code_char)
               {
                 case eParameter :
                   var=get_code_int;
                   params[var] = Stack.top();
-#ifdef DEBUGC
-                  mexPrintf("FSTP params[%d]=%f\n", var, params[var]);
-                  mexEvalString("drawnow;");
-#endif
                   Stack.pop();
                   break;
                 case eEndogenous :
-#ifdef DEBUGC
-                  mexPrintf("FSTP Endogenous\n");
-#endif
                   var=get_code_int;
                   lag=get_code_int;
-#ifdef DEBUGC
-                  //mexPrintf("y[%d(it_=%d, lag=%d, y_size=%d, var=%d)](%d)=",(it_+lag)*y_size+var,it_, lag, y_size, var, Stack.size());
-                  mexPrintf("FSTP y[it_=%d, lag=%d, y_size=%d, var=%d, block=%d)]=",it_, lag, y_size, var+1, Block_Count+1);
-                  mexEvalString("drawnow;");
-#endif
                   y[(it_+lag)*y_size+var] = Stack.top();
-#ifdef DEBUGC
-                  mexPrintf("%f\n",y[(it_+lag)*y_size+var]);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << "=>";
+                  //mexPrintf(" y[%d, %d](%f)=%s\n", it_+lag, var, y[(it_+lag)*y_size+var], tmp_out.str().c_str());
+                  tmp_out.str("");
 #endif
                   Stack.pop();
                   break;
                 case eExogenous :
-#ifdef DEBUGC
-                  mexPrintf("Exogenous\n");
-#endif
-                  //var=get_code_int;
                   var=get_code_int;
                   lag=get_code_int;
-                  /*mexPrintf("FSTP x[it_=%d, lag=%d, y_size=%d, var=%d, block=%d)]=",it_, lag, y_size, var+1, Block_Count+1);
-                  mexEvalString("drawnow;");*/
                   x[it_+lag+var*nb_row_x]  = Stack.top();
                   Stack.pop();
-                  /*mexPrintf("%f\n",x[it_+lag+var*nb_row_x]);
-                  mexEvalString("drawnow;");*/
                   break;
                 case eExogenousDet :
-#ifdef DEBUGC
-                  mexPrintf("ExogenousDet\n");
-#endif
-                  var=get_code_int;
                   var=get_code_int;
                   lag=get_code_int;
                   x[it_+lag+var*nb_row_xd] = Stack.top();
@@ -249,69 +300,110 @@ Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
                 default:
                   mexPrintf("Unknown vraibale type\n");
               }
+            break;
+					case FSTPSV :
+            //load a variable in the processor
+            switch (get_code_char)
+              {
+                case eParameter :
+                  var=get_code_int;
+                  params[var] = Stack.top();
+                  Stack.pop();
+                  break;
+                case eEndogenous :
+                  var=get_code_int;
+                  y[var] = Stack.top();
+#ifdef DEBUG
+                  tmp_out << "=>";
+                  //mexPrintf(" y%d](%f)=%s\n", var, y[var], tmp_out.str().c_str());
+                  tmp_out.str("");
+#endif
+                  Stack.pop();
+                  break;
+                case eExogenous :
+                  var=get_code_int;
+                  x[var]  = Stack.top();
+                  Stack.pop();
+                  break;
+                case eExogenousDet :
+                  var=get_code_int;
+                  x[var] = Stack.top();
+                  Stack.pop();
+                  break;
+                default:
+                  mexPrintf("Unknown vraibale type\n");
+              }
             break;
           case FSTPT :
-            //load a temporary variable in the processor
+            //store in a temporary variable from the processor
             var=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("FSTPT T[(var=%d, it_=%d, periods=%d, y_kmin=%d, y_kmax=%d)%d]=", var, it_, periods, y_kmin, y_kmax, var*(periods+y_kmin+y_kmax)+it_);
-            mexEvalString("drawnow;");
-#endif
             T[var*(periods+y_kmin+y_kmax)+it_] = Stack.top();
-#ifdef DEBUGC
-            mexPrintf("%f\n",T[var*(periods+y_kmin+y_kmax)+it_]);
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+						tmp_out << "=>";
+            //mexPrintf(" T[%d, %d](%f)=%s\n", it_, var, T[var*(periods+y_kmin+y_kmax)+it_], tmp_out.str().c_str());
+            tmp_out.str("");
+#endif
+            Stack.pop();
+            break;
+          case FSTPST :
+            //store in a temporary variable from the processor
+            var=get_code_int;
+            T[var] = Stack.top();
+#ifdef DEBUG
+						tmp_out << "=>";
+            //mexPrintf(" T%d](%f)=%s\n", var, T[var], tmp_out.str().c_str());
+            tmp_out.str("");
 #endif
             Stack.pop();
             break;
           case FSTPU :
-            //load u variable in the processor
+            //store in u variable from the processor
             var=get_code_int;
             var+=Per_u_;
-#ifdef DEBUGC
-            mexPrintf("FSTPU u[%d]",var);
-            mexEvalString("drawnow;");
+            u[var] = Stack.top();
+#ifdef DEBUG
+						tmp_out << "=>";
+						if(var==308)
+              mexPrintf(" u[%d](%f)=%s\n", var, u[var], tmp_out.str().c_str());
+            tmp_out.str("");
 #endif
+            Stack.pop();
+            break;
+          case FSTPSU :
+            //store in u variable from the processor
+            var=get_code_int;
             u[var] = Stack.top();
-#ifdef DEBUGC
-            mexPrintf("=%f\n",u[var]);
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+						tmp_out << "=>";
+						if(var==308)
+              mexPrintf(" u[%d](%f)=%s\n", var, u[var], tmp_out.str().c_str());
+            tmp_out.str("");
 #endif
             Stack.pop();
             break;
           case FSTPR :
-            //load u variable in the processor
+            //store in residual variable from the processor
             var=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("FSTPR residual[%d]=",var);
-            mexEvalString("drawnow;");
-#endif
             r[var] = Stack.top();
-#ifdef DEBUGC
-            mexPrintf("%f\n",r[var]);
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+            tmp_out << "=>";
+            //mexPrintf(" r[%d](%f)=%s\n", var, r[var], tmp_out.str().c_str());
+            tmp_out.str("");
 #endif
             Stack.pop();
             break;
           case FSTPG :
-            //load u variable in the processor
+            //store in derivative (g) variable from the processor
             var=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("FSTPG g1[%d]=",var);
-            mexEvalString("drawnow;");
-#endif
             g1[var] = Stack.top();
-#ifdef DEBUGC
-            mexPrintf("%f\n",g1[var]);
-            mexEvalString("drawnow;");
+#ifdef DEBUG
+            tmp_out << "=>";
+            //mexPrintf(" r[%d](%f)=%s\n", var, r[var], tmp_out.str().c_str());
+            tmp_out.str("");
 #endif
             Stack.pop();
             break;
           case FBINARY :
-#ifdef DEBUGC
-            mexPrintf("FBINARY\n");
-            mexEvalString("drawnow;");
-#endif
             op=get_code_int;
             v2=Stack.top();
             Stack.pop();
@@ -321,93 +413,80 @@ Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
               {
                 case oPlus:
                   Stack.push(v1 + v2);
-#ifdef DEBUGC
-                  mexPrintf("+\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "+" << v2 << "|";
 #endif
                   break;
                 case oMinus:
                   Stack.push(v1 - v2);
-#ifdef DEBUGC
-                  mexPrintf("-\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "-" << v2 << "|";
 #endif
                   break;
                 case oTimes:
                   Stack.push(v1 * v2);
-#ifdef DEBUGC
-                  mexPrintf("*\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "*" << v2 << "|";
 #endif
                   break;
                 case oDivide:
                   Stack.push(v1 / v2);
-#ifdef DEBUGC
-                  mexPrintf("/\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "/" << v2 << "|";
 #endif
                   break;
                 case oLess:
                   Stack.push(double(v1<v2));
-#ifdef DEBUGC
-                  mexPrintf("%f < %f\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "<" << v2 << "|";
 #endif
                   break;
                 case oGreater:
                   Stack.push(double(v1>v2));
-#ifdef DEBUGC
-                  mexPrintf("%f > %f\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << ">" << v2 << "|";
 #endif
                   break;
                 case oLessEqual:
                   Stack.push(double(v1<=v2));
-#ifdef DEBUGC
-                  mexPrintf("%f <= %f\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "<=" << v2 << "|";
 #endif
                   break;
                 case oGreaterEqual:
                   Stack.push(double(v1>=v2));
-#ifdef DEBUGC
-                  mexPrintf("%f >= %f\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << ">=" << v2 << "|";
 #endif
                   break;
                 case oEqualEqual:
                   Stack.push(double(v1==v2));
-#ifdef DEBUGC
-                  mexPrintf("%f == %f\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "==" << v2 << "|";
 #endif
                   break;
                 case oDifferent:
                   Stack.push(double(v1!=v2));
-#ifdef DEBUGC
-                  mexPrintf("%f > %f\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "!=" << v2 << "|";
 #endif
                   break;
                 case oPower:
-#ifdef DEBUGC
-                  mexPrintf("pow(%f, %f)\n",v1,v2);
-                  mexEvalString("drawnow;");
-#endif
                   Stack.push(pow1(v1, v2));
+#ifdef DEBUG
+                  tmp_out << " |" << v1 << "^" << v2 << "|";
+#endif
                   break;
                 case oMax:
                   Stack.push(max(v1, v2));
-#ifdef DEBUGC
-                  mexPrintf("max(%f, %f)\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |max(" << v1 << "," << v2 << ")|";
 #endif
                   break;
                 case oMin:
                   Stack.push(min(v1, v2));
-#ifdef DEBUGC
-                  mexPrintf("min(%f, %f)\n",v1,v2);
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |min(" << v1 << "," << v2 << ")|";
 #endif
                   break;
                 case oEqual:
@@ -417,132 +496,112 @@ Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
               }
             break;
           case FUNARY :
-#ifdef DEBUGC
-            mexPrintf("FUNARY\n");
-            mexEvalString("drawnow;");
-#endif
             op=get_code_int;
-               v1=Stack.top();
+            v1=Stack.top();
             Stack.pop();
             switch (op)
               {
                 case oUminus:
                   Stack.push(-v1);
-#ifdef DEBUGC
-                  mexPrintf("-\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |-(" << v1 << ")|";
 #endif
+
                   break;
                 case oExp:
                   Stack.push(exp(v1));
-#ifdef DEBUGC
-                  mexPrintf("exp\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |exp(" << v1 << ")|";
 #endif
                   break;
                 case oLog:
-                  Stack.push(log(v1));
-#ifdef DEBUGC
-                  mexPrintf("log\n");
-                  mexEvalString("drawnow;");
+                  Stack.push(log1(v1));
+#ifdef DEBUG
+                  tmp_out << " |log(" << v1 << ")|";
 #endif
                   break;
                 case oLog10:
                   Stack.push(log10(v1));
-#ifdef DEBUGC
-                  mexPrintf("log10\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |log10(" << v1 << ")|";
 #endif
                   break;
                 case oCos:
                   Stack.push(cos(v1));
-#ifdef DEBUGC
-                  mexPrintf("cos\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |cos(" << v1 << ")|";
 #endif
                   break;
                 case oSin:
                   Stack.push(sin(v1));
-#ifdef DEBUGC
-                  mexPrintf("sin\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |sin(" << v1 << ")|";
 #endif
                   break;
                 case oTan:
                   Stack.push(tan(v1));
-#ifdef DEBUGC
-                  mexPrintf("tan\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |tan(" << v1 << ")|";
 #endif
                   break;
                 case oAcos:
                   Stack.push(acos(v1));
-#ifdef DEBUGC
-                  mexPrintf("acos\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |acos(" << v1 << ")|";
 #endif
                   break;
                 case oAsin:
                   Stack.push(asin(v1));
-#ifdef DEBUGC
-                  mexPrintf("asin\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |asin(" << v1 << ")|";
 #endif
                   break;
                 case oAtan:
                   Stack.push(atan(v1));
-#ifdef DEBUGC
-                  mexPrintf("atan\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |atan(" << v1 << ")|";
 #endif
                   break;
                 case oCosh:
                   Stack.push(cosh(v1));
-#ifdef DEBUGC
-                  mexPrintf("cosh\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |cosh(" << v1 << ")|";
 #endif
                   break;
                 case oSinh:
                   Stack.push(sinh(v1));
-#ifdef DEBUGC
-                  mexPrintf("sinh\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |sinh(" << v1 << ")|";
 #endif
                   break;
                 case oTanh:
                   Stack.push(tanh(v1));
-#ifdef DEBUGC
-                  mexPrintf("tanh\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |tanh(" << v1 << ")|";
 #endif
                   break;
                 case oAcosh:
                   Stack.push(acosh(v1));
-#ifdef DEBUGC
-                  mexPrintf("acosh\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |acosh(" << v1 << ")|";
 #endif
                   break;
                 case oAsinh:
                   Stack.push(asinh(v1));
-#ifdef DEBUGC
-                  mexPrintf("asinh\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |asinh(" << v1 << ")|";
 #endif
                   break;
                 case oAtanh:
                   Stack.push(atanh(v1));
-#ifdef DEBUGC
-                  mexPrintf("atanh\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |atanh(" << v1 << ")|";
 #endif
                   break;
                 case oSqrt:
                   Stack.push(sqrt(v1));
-#ifdef DEBUGC
-                  mexPrintf("sqrt\n");
-                  mexEvalString("drawnow;");
+#ifdef DEBUG
+                  tmp_out << " |sqrt(" << v1 << ")|";
 #endif
                   break;
                 default:
@@ -551,10 +610,6 @@ Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
               }
             break;
           case FCUML :
-#ifdef DEBUGC
-            mexPrintf("FCUML\n");
-            mexEvalString("drawnow;");
-#endif
             v1=Stack.top();
             Stack.pop();
             v2=Stack.top();
@@ -563,30 +618,12 @@ Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
             break;
           case FENDBLOCK :
             //it's the block end
-#ifdef DEBUGC
-            //mexPrintf("FENDBLOCK\n");
-            //mexEvalString("drawnow;");
-#endif
-            //Block[Block_Count].end=get_code_pos;
             go_on=false;
             break;
           case FENDEQU :
-#ifdef DEBUGC
-            mexPrintf("FENDEQU\n");
-            mexEvalString("drawnow;");
-#endif
-            /*if (GaussSeidel)
-              return;*/
             break;
           case FOK :
-#ifdef DEBUGC
-            mexPrintf("FOK\n");
-            mexEvalString("drawnow;");
-#endif
             op=get_code_int;
-#ifdef DEBUGC
-               mexPrintf("var=%d\n",op);
-#endif
             if (Stack.size()>0)
               {
                 mexPrintf("error: Stack not empty!\n");
@@ -603,12 +640,9 @@ Interpreter::compute_block_time(int Per_u_) /*throw(EvalException)*/
     }
 }
 
-void
-Interpreter::simulate_a_block(int size,int type, string file_name, string bin_basename, bool Gaussian_Elimination)
+bool
+Interpreter::simulate_a_block(int size,int type, string file_name, string bin_basename, bool Gaussian_Elimination, bool steady_state, int block_num)
 {
-  /*mexPrintf("simulate_a_block\n");
-  mexEvalString("drawnow;");*/
-
   char *begining;
   int i;
   bool is_linear, cvg;
@@ -618,254 +652,305 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
   int Block_List_Max_Lead;
   int giter;
   int u_count_int;
+  bool result = true;
   double *y_save;
-#ifdef LINBCG
-  LinBCG linbcg;
-  Mat_DP a;
-  Vec_INT indx;
-#endif
-    //SparseMatrix sparse_matrix;
-
-  //int nb_endo, u_count_init;
 
-
-  //mexPrintf("simulate_a_block\n");
-  //mexEvalString("drawnow;");
-  //mexPrintf("%d\n",debile);
-
-  //GaussSeidel=false;
-  //slowc_save=slowc/2;
-  //mexPrintf("simulate_a_block size=%d type=%d\n",size,type);
   switch (type)
     {
       case EVALUATE_FORWARD :
-      //case EVALUATE_FORWARD_R :
-#ifdef DEBUGC
-        mexPrintf("EVALUATE_FORWARD\n");
-        mexEvalString("drawnow;");
-#endif
-        begining=get_code_pointer;
-        //mexPrintf("y_kmin=%d periods=%d",y_kmin, periods);
-        for (it_=y_kmin;it_<periods+y_kmin;it_++)
-          {
-            //mexPrintf("begining=%x\n",begining);
-            set_code_pointer(begining);
-            Per_y_=it_*y_size;
-            //mexPrintf("bef compute_block_time()\n");
-            compute_block_time(0);
-            //mexPrintf("x(%d, 638)=%1.14f/x(%d, 116)=%1.14f=%1.14f\n",it_,x[it_+638*nb_row_x],it_,x[it_+116*nb_row_x],x[it_+638*nb_row_x]/x[it_+116*nb_row_x]);
-#ifdef PRINT_OUT
-            for (int j = 0; j<size; j++)
-              mexPrintf("y[%d, %d] = %1.14f\n", Block_Contain[j].Variable, it_, y[Per_y_ + Block_Contain[j].Variable]);
-#endif
-          }
+        if(steady_state)
+					compute_block_time(0);
+				else
+				  {
+            begining=get_code_pointer;
+            for (it_=y_kmin;it_<periods+y_kmin;it_++)
+              {
+                set_code_pointer(begining);
+                Per_y_=it_*y_size;
+                compute_block_time(0);
+              }
+				  }
         break;
       case EVALUATE_BACKWARD :
-      //case EVALUATE_BACKWARD_R :
-#ifdef DEBUGC
-        mexPrintf("EVALUATE_BACKWARD\n");
-        mexEvalString("drawnow;");
-#endif
-        begining=get_code_pointer;
-        for (it_=periods+y_kmin-1;it_>=y_kmin;it_--)
-          {
-            set_code_pointer(begining);
-            Per_y_=it_*y_size;
-            compute_block_time(0);
-#ifdef PRINT_OUT
-            for (int j = 0; j<size; j++)
-              mexPrintf("y[%d, %d] = %1.14f\n", Block_Contain[j].Variable, it_, y[Per_y_ + Block_Contain[j].Variable]);
-#endif
-          }
+        if(steady_state)
+          compute_block_time(0);
+				else
+				  {
+            begining=get_code_pointer;
+            for (it_=periods+y_kmin-1;it_>=y_kmin;it_--)
+              {
+                set_code_pointer(begining);
+                Per_y_=it_*y_size;
+                compute_block_time(0);
+              }
+				  }
         break;
       case SOLVE_FORWARD_SIMPLE :
-#ifdef DEBUGC
-        mexPrintf("SOLVE_FORWARD_SIMPLE\n");
-        mexEvalString("drawnow;");
-#endif
         g1=(double*)mxMalloc(size*size*sizeof(double));
-        r=(double*)mxMalloc(size*sizeof(double));
-        begining=get_code_pointer;
-        for (it_=y_kmin;it_<periods+y_kmin;it_++)
+				r=(double*)mxMalloc(size*sizeof(double));
+				begining=get_code_pointer;
+        if(steady_state)
           {
-            cvg=false;
+          	cvg=false;
             iter=0;
-            Per_y_=it_*y_size;
             while (!(cvg||(iter>maxit_)))
               {
                 set_code_pointer(begining);
                 Per_y_=it_*y_size;
-                compute_block_time(0);
-                y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0];
-                //mexPrintf("y[%d] += -r[0] (%f) / g1[0] (%f) = %f\n",Per_y_+Block_Contain[0].Variable,r[0],g1[0],y[Per_y_+Block_Contain[0].Variable]);
-                double rr;
-                rr=r[0]/(1+y[Per_y_+Block_Contain[0].Variable]);
-                cvg=((rr*rr)<solve_tolf);
-                iter++;
-              }
-            if (!cvg)
-              {
-                mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n",Block_Count,it_,iter);
-                mexEvalString("st=fclose('all');clear all;");
-                mexErrMsgTxt("End of simulate");
+                    compute_block_time(0);
+                    y[Block_Contain[0].Variable] += -r[0]/g1[0];
+                    double rr;
+							    	rr=r[0];
+                    cvg=((rr*rr)<solve_tolf);
+                    iter++;
+                  }
+                if (!cvg)
+                  {
+                    mexPrintf("Convergence not achieved in block %d, after %d iterations\n",Block_Count,iter);
+                    /*mexEvalString("st=fclose('all');clear all;");
+                    mexErrMsgTxt("End of simulate");*/
+                    return false;
+                  }
               }
-#ifdef PRINT_OUT
-            mexPrintf("y[%d, %d]=%f \n",it_, Block_Contain[0].Variable ,y[Per_y_ + Block_Contain[0].Variable]);
-#endif
-          }
+				   else
+				     {
+                for (it_=y_kmin;it_<periods+y_kmin;it_++)
+                  {
+                    cvg=false;
+                    iter=0;
+                    Per_y_=it_*y_size;
+                    while (!(cvg||(iter>maxit_)))
+                      {
+                        set_code_pointer(begining);
+                        Per_y_=it_*y_size;
+                        compute_block_time(0);
+                        y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0];
+                        double rr;
+                        if(fabs(1+y[Per_y_+Block_Contain[0].Variable])>eps)
+				    					    rr=r[0]/(1+y[Per_y_+Block_Contain[0].Variable]);
+						    		    else
+								    	    rr=r[0];
+                        cvg=((rr*rr)<solve_tolf);
+                        iter++;
+                      }
+                    if (!cvg)
+                      {
+                        mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n",Block_Count,it_,iter);
+                        mexEvalString("st=fclose('all');clear all;");
+                        mexErrMsgTxt("End of simulate");
+                     }
+								}
+					 }
         mxFree(g1);
         mxFree(r);
         break;
       case SOLVE_BACKWARD_SIMPLE :
-#ifdef DEBUGC
-        mexPrintf("SOLVE_BACKWARD_SIMPLE\n");
-        mexEvalString("drawnow;");
-#endif
         g1=(double*)mxMalloc(size*size*sizeof(double));
-        r=(double*)mxMalloc(size*sizeof(double));
-        begining=get_code_pointer;
-        for (it_=periods+y_kmin;it_>y_kmin;it_--)
+				r=(double*)mxMalloc(size*sizeof(double));
+				begining=get_code_pointer;
+        if(steady_state)
           {
-            cvg=false;
+          	cvg=false;
             iter=0;
-            Per_y_=it_*y_size;
             while (!(cvg||(iter>maxit_)))
               {
                 set_code_pointer(begining);
                 Per_y_=it_*y_size;
-                compute_block_time(0);
-                /*mexPrintf("Compute_block_time=> in SOLVE_BACKWARD_SIMPLE : OK\n");
-                mexEvalString("drawnow;");*/
-                y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0];
-                double rr;
-                rr=r[0]/(1+y[Per_y_+Block_Contain[0].Variable]);
-                cvg=((rr*rr)<solve_tolf);
-                iter++;
-              }
-            if (!cvg)
-              {
-                mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n",Block_Count,it_,iter);
-                mexEvalString("st=fclose('all');clear all;");
-                mexErrMsgTxt("End of simulate");
+                    compute_block_time(0);
+                    y[Block_Contain[0].Variable] += -r[0]/g1[0];
+                    double rr;
+    					    	rr=r[0];
+                    cvg=((rr*rr)<solve_tolf);
+                    iter++;
+                  }
+                if (!cvg)
+                  {
+                    mexPrintf("Convergence not achieved in block %d, after %d iterations\n",Block_Count,iter);
+                    return false;
+                    /*mexEvalString("st=fclose('all');clear all;");
+                    mexErrMsgTxt("End of simulate");*/
+                  }
               }
-#ifdef PRINT_OUT
-            mexPrintf("y[%d, %d]=%f \n",it_, Block_Contain[0].Variable ,y[Per_y_ + Block_Contain[0].Variable]);
-#endif
-          }
+				    else
+				      {
+                for (it_=periods+y_kmin;it_>y_kmin;it_--)
+                  {
+                    cvg=false;
+                    iter=0;
+                    Per_y_=it_*y_size;
+                    while (!(cvg||(iter>maxit_)))
+                      {
+                        set_code_pointer(begining);
+                        Per_y_=it_*y_size;
+                        compute_block_time(0);
+                        y[Per_y_+Block_Contain[0].Variable] += -r[0]/g1[0];
+                        double rr;
+                        if(fabs(1+y[Per_y_+Block_Contain[0].Variable])>eps)
+				    					    rr=r[0]/(1+y[Per_y_+Block_Contain[0].Variable]);
+						    		    else
+								    	    rr=r[0];
+                        cvg=((rr*rr)<solve_tolf);
+                        iter++;
+                      }
+                    if (!cvg)
+                      {
+                        mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n",Block_Count,it_,iter);
+                        mexEvalString("st=fclose('all');clear all;");
+                        mexErrMsgTxt("End of simulate");
+                      }
+                  }
+            }
         mxFree(g1);
         mxFree(r);
         break;
       case SOLVE_FORWARD_COMPLETE :
-#ifdef DEBUGC
-        mexPrintf("SOLVE FORWARD_COMPLETE\n");
-        mexEvalString("drawnow;");
-#endif
         is_linear=get_code_bool;
-        /*mexPrintf("is_linear=%d\n",is_linear);
-        mexEvalString("drawnow;");*/
         max_lag_plus_max_lead_plus_1=get_code_int;
-        /*mexPrintf("max_lag_plus_max_lead_plus_1=%d\n",max_lag_plus_max_lead_plus_1);
-        mexEvalString("drawnow;");*/
         symbol_table_endo_nbr=get_code_int;
-        /*mexPrintf("symbol_table_endo_nbr=%d\n",symbol_table_endo_nbr);
-        mexEvalString("drawnow;");*/
         Block_List_Max_Lag=get_code_int;
-        /*mexPrintf("Block_List_Max_Lag=%d\n",Block_List_Max_Lag);
-        mexEvalString("drawnow;");*/
         Block_List_Max_Lead=get_code_int;
-        /*mexPrintf("Block_List_Max_Lead=%d\n",Block_List_Max_Lead);
-        mexEvalString("drawnow;");*/
         u_count_int=get_code_int;
-        /*mexPrintf("u_count_int=%d\n",u_count_int);
-        mexEvalString("drawnow;");*/
         fixe_u(&u, u_count_int, u_count_int);
-        //Read_file(file_name, periods, 0, symbol_table_endo_nbr, Block_List_Max_Lag, Block_List_Max_Lead, nb_endo, u_count, u_count_init, u);
-        //sparse_matrix.initialize(periods, nb_endo, y_kmin, y_kmax, y_size, u_count, u_count_init, u, y, ya, slowc, y_decal, markowitz_c, res1, res2, max_res);
-        Read_SparseMatrix(bin_basename, size, 1, 0, 0);
-        //mexPrintf("size=%d\n",size);
+        Read_SparseMatrix(bin_basename, size, 1, 0, 0, steady_state);
         g1=(double*)mxMalloc(size*size*sizeof(double));
         r=(double*)mxMalloc(size*sizeof(double));
         begining=get_code_pointer;
         Per_u_ = 0;
-
-        if (!is_linear)
-          {
-            max_res_idx=0;
-            for (it_=y_kmin;it_<periods+y_kmin;it_++)
+				if(steady_state)
+				  {
+			      if (!is_linear)
               {
+                max_res_idx=0;
                 cvg=false;
                 iter=0;
-                Per_y_=it_*y_size;
+                //Per_y_=it_*y_size;
                 while (!(cvg||(iter>maxit_)))
                   {
+                 	  /*for (int j = 0; j < y_size; j++)
+              	    mexPrintf("   variable %d at time %d and %d = %f\n", j+1, it_, it_+1, y[j+it_*y_size]);*/
                     set_code_pointer(begining);
-                    compute_block_time(0);
-                    /*mexPrintf("Compute_block_time=> in SOLVE_FORWARD_COMPLETE : OK it_%d\n",it_);
-                    mexEvalString("drawnow;");*/
-                    //Direct_Simulate(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, 0, false, iter);
-                    simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter);
+                    error_not_printed = true;
                     res2=0;
-                    res1=0;
+						    		res1=0;
                     max_res=0;
-                    for (i=0; i<size ;i++)
-                      {
-                        double rr;
-                        rr=r[i]/(1+y[Per_y_+Block_Contain[i].Variable]);
-                        if (max_res<fabs(rr))
+                    compute_block_time(0);
+                    /*if (isnan(res1)||isinf(res1))
+                    {
+                    memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
+                    }*/
+                    if (!(isnan(res1)||isinf(res1)))
+										  {
+                        for (i=0; i<size ;i++)
                           {
-                            max_res=fabs(rr);
-                            max_res_idx=i;
-                          }
-                        res2+=rr*rr;
-                        res1+=fabs(rr);
-                      }
-                    cvg=(max_res<solve_tolf);
+                            double rr;
+                            rr=r[i];
+                            if (max_res<fabs(rr))
+                              {
+                                max_res=fabs(rr);
+                                max_res_idx=i;
+                              }
+                            res2+=rr*rr;
+                            res1+=fabs(rr);
+													}
+
+                        cvg=(max_res<solve_tolf);
+											}
+		    						else
+				    					cvg=false;
+                    result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true);
                     iter++;
                   }
                 if (!cvg)
                   {
                     mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n", Block_Count, it_, iter);
-                    mexEvalString("st=fclose('all');clear all;");
-                    mexErrMsgTxt("End of simulate");
+                    /*mexEvalString("st=fclose('all');clear all;");
+                    mexErrMsgTxt("End of simulate");*/
+                    return false;
                   }
               }
-          }
-        else
-          {
-            for (it_=y_kmin;it_<periods+y_kmin;it_++)
+            else
               {
                 set_code_pointer(begining);
                 Per_y_=it_*y_size;
                 iter = 0;
                 res1=res2=max_res=0;max_res_idx=0;
-                /*mexPrintf("Compute_block_time=> in SOLVE_FORWARD_COMPLETE before compute_block_time OK\n");
-                mexEvalString("drawnow;");*/
+                error_not_printed = true;
                 compute_block_time(0);
-                //mexPrintf("Compute_block_time=> in SOLVE_FORWARD_COMPLETE : OK\n");
-                /*mexPrintf("Compute_block_time=> in SOLVE_FORWARD_COMPLETE : %d OK\n",it_);
-                mexEvalString("drawnow;");*/
-                //Direct_Simulate(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, 0, false, iter);
-                //Direct_Simulate(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, 0, false, iter);
-                //simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, 0, /*true*/false, cvg, iter);
                 cvg=false;
-                /*mexPrintf("Compute_block_time=> in SOLVE_FORWARD_COMPLETE : OK it_%d\n",it_);
-                mexEvalString("drawnow;");*/
-                simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter);
-                /*mexPrintf("End of simulate_NG\n");
-                mexEvalString("drawnow;");*/
-                //simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter);
+                result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true);
               }
-            /*mexPrintf("solve forward complete simulation\n");
-            for (it_=y_kmin;it_<periods+y_kmin;it_++)
+				  }
+				else
+				  {
+			      if (!is_linear)
               {
-                mexPrintf("it_=%d ",it_);
-                for(i=0; i<y_size; i++)
-                  mexPrintf(" %f",y[i+it_*y_size]);
-                mexPrintf("\n");
-              }*/
-          }
-        /*mexPrintf("end of forward solve\n");
-        mexEvalString("drawnow;");*/
+                max_res_idx=0;
+                for (it_=y_kmin;it_<periods+y_kmin;it_++)
+                 {
+                    cvg=false;
+                    iter=0;
+                    Per_y_=it_*y_size;
+                    while (!(cvg||(iter>maxit_)))
+                      {
+                      	/*for (int j = 0; j < y_size; j++)
+                  	    	mexPrintf("   variable %d at time %d and %d = %f\n", j+1, it_, it_+1, y[j+it_*y_size]);*/
+                        set_code_pointer(begining);
+                        error_not_printed = true;
+                        res2=0;
+						    				res1=0;
+                        max_res=0;
+                        compute_block_time(0);
+                        /*if (isnan(res1)||isinf(res1))
+                          {
+                            memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
+                          }*/
+                        if (!(isnan(res1)||isinf(res1)))
+										      {
+                            for (i=0; i<size ;i++)
+                              {
+                                double rr;
+                                if(fabs(1+y[Per_y_+Block_Contain[i].Variable])>eps)
+                                  rr=r[i]/(1+y[Per_y_+Block_Contain[i].Variable]);
+                                else
+                                  rr=r[i];
+                                if (max_res<fabs(rr))
+                                  {
+                                    max_res=fabs(rr);
+                                    max_res_idx=i;
+                                  }
+                                res2+=rr*rr;
+                                res1+=fabs(rr);
+                              }
+                            cvg=(max_res<solve_tolf);
+    										  }
+		    								else
+				    						  cvg=false;
+                        result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false);
+                        iter++;
+                      }
+                    if (!cvg)
+                      {
+                        mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n", Block_Count, it_, iter);
+                        mexEvalString("st=fclose('all');clear all;");
+                        mexErrMsgTxt("End of simulate");
+                      }
+                  }
+              }
+            else
+              {
+                for (it_=y_kmin;it_<periods+y_kmin;it_++)
+                  {
+                    set_code_pointer(begining);
+                    Per_y_=it_*y_size;
+                    iter = 0;
+                    res1=res2=max_res=0;max_res_idx=0;
+                    error_not_printed = true;
+                    compute_block_time(0);
+                    cvg=false;
+                    result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false);
+                  }
+              }
+				  }
         mxFree(index_equa);
         mxFree(index_vara);
         memset(direction,0,size_of_direction);
@@ -874,89 +959,147 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
         mxFree(u);
         break;
       case SOLVE_BACKWARD_COMPLETE :
-#ifdef DEBUGC
-        mexPrintf("SOLVE_BACKWARD_COMPLETE\n");
-        mexEvalString("drawnow;");
-#endif
         is_linear=get_code_bool;
-        //mexPrintf("is_linear=%d\n",is_linear);
-        //mexEvalString("drawnow;");
         max_lag_plus_max_lead_plus_1=get_code_int;
-        //mexPrintf("max_lag_plus_max_lead_plus_1=%d\n",max_lag_plus_max_lead_plus_1);
-        //mexEvalString("drawnow;");
         symbol_table_endo_nbr=get_code_int;
-        //mexPrintf("symbol_table_endo_nbr=%d\n",symbol_table_endo_nbr);
-        //mexEvalString("drawnow;");
         Block_List_Max_Lag=get_code_int;
-        //mexPrintf("Block_List_Max_Lag=%d\n",Block_List_Max_Lag);
-        //mexEvalString("drawnow;");
         Block_List_Max_Lead=get_code_int;
-        //mexPrintf("Block_List_Max_Lead=%d\n",Block_List_Max_Lead);
-        //mexEvalString("drawnow;");
         u_count_int=get_code_int;
-        /*mexPrintf("u_count_int=%d\n",u_count_int);
-        mexEvalString("drawnow;");*/
         fixe_u(&u, u_count_int, u_count_int);
-        Read_SparseMatrix(bin_basename, size, 1, 0, 0);
-        //mexPrintf("size=%d\n",size);
-        //mexEvalString("drawnow;");
+        Read_SparseMatrix(bin_basename, size, 1, 0, 0, steady_state);
         g1=(double*)mxMalloc(size*size*sizeof(double));
         r=(double*)mxMalloc(size*sizeof(double));
         begining=get_code_pointer;
-        if (!is_linear)
-          {
-            max_res_idx=0;
-            for (it_=periods+y_kmin;it_>y_kmin;it_--)
+        if(steady_state)
+				  {
+			      if (!is_linear)
               {
+                max_res_idx=0;
                 cvg=false;
                 iter=0;
-                Per_y_=it_*y_size;
+                //Per_y_=it_*y_size;
                 while (!(cvg||(iter>maxit_)))
                   {
+                 	  /*for (int j = 0; j < y_size; j++)
+              	    mexPrintf("   variable %d at time %d and %d = %f\n", j+1, it_, it_+1, y[j+it_*y_size]);*/
                     set_code_pointer(begining);
-                    compute_block_time(0);
-                    /*mexPrintf("Compute_block_time=> in SOLVE_BACKWARD_COMPLETE : OK\n");
-                    mexEvalString("drawnow;");*/
-                    //Direct_Simulate(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, 0, false, iter);
-                    simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter);
+                    error_not_printed = true;
                     res2=0;
-                    res1=0;
+						    		res1=0;
                     max_res=0;
-                    for (i=0; i<size ;i++)
-                      {
-                        double rr;
-                        rr=r[i]/(1+y[Per_y_+Block_Contain[i].Variable]);
-                        if (max_res<fabs(rr))
+                    compute_block_time(0);
+                    /*if (isnan(res1)||isinf(res1))
+                    {
+                    memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
+                    }*/
+                    if (!(isnan(res1)||isinf(res1)))
+										  {
+                        for (i=0; i<size ;i++)
                           {
-                            max_res=fabs(rr);
-                            max_res_idx=i;
-                          }
-                        res2+=rr*rr;
-                        res1+=fabs(rr);
-                      }
-                    cvg=(max_res<solve_tolf);
+                            double rr;
+                            rr=r[i];
+                            if (max_res<fabs(rr))
+                              {
+                                max_res=fabs(rr);
+                                max_res_idx=i;
+                              }
+                            res2+=rr*rr;
+                            res1+=fabs(rr);
+													}
+                        cvg=(max_res<solve_tolf);
+											}
+		    						else
+				    					cvg=false;
+                    result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true);
                     iter++;
                   }
                 if (!cvg)
                   {
                     mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n", Block_Count, it_, iter);
-                    mexEvalString("st=fclose('all');clear all;");
-                    mexErrMsgTxt("End of simulate");
+                    /*mexEvalString("st=fclose('all');clear all;");
+                    mexErrMsgTxt("End of simulate");*/
+                    return false;
                   }
               }
-          }
-        else
-          {
-            for (it_=periods+y_kmin;it_>y_kmin;it_--)
+            else
               {
                 set_code_pointer(begining);
                 Per_y_=it_*y_size;
+                iter = 0;
+                res1=res2=max_res=0;max_res_idx=0;
+                error_not_printed = true;
                 compute_block_time(0);
                 cvg=false;
-                //Direct_Simulate(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, 1, false, iter);
-                simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter);
+                result = simulate_NG(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, false, cvg, iter, true);
               }
-          }
+				  }
+				else
+				 {
+            if (!is_linear)
+              {
+                max_res_idx=0;
+                for (it_=periods+y_kmin;it_>y_kmin;it_--)
+                  {
+                    cvg=false;
+                    iter=0;
+                    Per_y_=it_*y_size;
+                    while (!(cvg||(iter>maxit_)))
+                      {
+                        set_code_pointer(begining);
+                        error_not_printed = true;
+                        res2=0;
+                        res1=0;
+                        max_res=0;
+                        compute_block_time(0);
+                        /*if (isnan(res1)||isinf(res1))
+                          {
+                            memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
+                          }*/
+										    if (!(isnan(res1)||isinf(res1)))
+										      {
+                            for (i=0; i<size ;i++)
+                              {
+																double rr;
+                                if(fabs(1+y[Per_y_+Block_Contain[i].Variable])>eps)
+                                  rr=r[i]/(1+y[Per_y_+Block_Contain[i].Variable]);
+                                else
+                                  rr=r[i];
+                                if (max_res<fabs(rr))
+                                  {
+                                    max_res=fabs(rr);
+                                    max_res_idx=i;
+                                  }
+                                res2+=rr*rr;
+                                res1+=fabs(rr);
+                              }
+												    cvg=(max_res<solve_tolf);
+										      }
+										    else
+										      cvg=false;
+										    result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false);
+                        iter++;
+                      }
+                    if (!cvg)
+                      {
+                        mexPrintf("Convergence not achieved in block %d, at time %d after %d iterations\n", Block_Count, it_, iter);
+                        mexEvalString("st=fclose('all');clear all;");
+                        mexErrMsgTxt("End of simulate");
+                      }
+                  }
+              }
+            else
+              {
+                for (it_=periods+y_kmin;it_>y_kmin;it_--)
+                  {
+                    set_code_pointer(begining);
+                    Per_y_=it_*y_size;
+                    error_not_printed = true;
+                    compute_block_time(0);
+                    cvg=false;
+                    result = simulate_NG(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, false, cvg, iter, false);
+                  }
+              }
+				  }
 				mxFree(index_equa);
         mxFree(index_vara);
         memset(direction,0,size_of_direction);
@@ -966,92 +1109,30 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
         break;
       case SOLVE_TWO_BOUNDARIES_SIMPLE :
       case SOLVE_TWO_BOUNDARIES_COMPLETE:
-#if GNUVER >= 432
-        //mexPrintf("omp_get_max_threads=%d\n",omp_get_max_threads());
-#endif
-#ifdef DEBUGC
-        mexPrintf("SOLVE_TWO_BOUNDARIES_COMPLETE\n");
-        mexEvalString("drawnow;");
-#endif
+        if(steady_state)
+          {
+            mexPrintf("SOLVE_TXO_BOUNDARIES in a steady state model: impossible case\n");
+            return false;
+          }
         is_linear=get_code_bool;
-#ifdef DEBUGC
-        mexPrintf("is_linear=%d\n",is_linear);
-        mexEvalString("drawnow;");
-#endif
         max_lag_plus_max_lead_plus_1=get_code_int;
-#ifdef DEBUGC
-        mexPrintf("max_lag_plus_max_lead_plus_1=%d\n",max_lag_plus_max_lead_plus_1);
-        mexEvalString("drawnow;");
-#endif
         symbol_table_endo_nbr=get_code_int;
-#ifdef DEBUGC
-        mexPrintf("symbol_table_endo_nbr=%d\n",symbol_table_endo_nbr);
-        mexEvalString("drawnow;");
-#endif
         Block_List_Max_Lag=get_code_int;
-#ifdef DEBUGC
-        mexPrintf("Block_List_Max_Lag=%d\n",Block_List_Max_Lag);
-        mexEvalString("drawnow;");
-#endif
         Block_List_Max_Lead=get_code_int;
-#ifdef DEBUGC
-        mexPrintf("Block_List_Max_Lead=%d\n",Block_List_Max_Lead);
-        mexEvalString("drawnow;");
-#endif
         u_count_int=get_code_int;
-#ifdef DEBUGC
-        mexPrintf("u_count_int=%d\n",u_count_int);
-        mexPrintf("periods=%d\n",periods);
-        mexEvalString("drawnow;");
-#endif
-
-        //sparse_matrix.initialize(periods, nb_endo, y_kmin, y_kmax, y_size, u_count, u_count_init, u, y, ya, slowc, y_decal, markowitz_c, res1, res2, max_res);
-
-        //fixe_u(&u, u_count_int, max_lag_plus_max_lead_plus_1);
         fixe_u(&u, u_count_int, u_count_int);
-#ifdef DEBUGC
-        mexPrintf("u=%x\n",u);
-        mexPrintf("size=%d\n",size);
-#endif
-        Read_SparseMatrix(bin_basename, size, periods, y_kmin, y_kmax);
-#ifdef DEBUGC
-        mexPrintf("size=%d\n",size);
-        mexEvalString("drawnow;");
-#endif
-        //mexPrintf("aft reading_sparse_matrix\n");
-        //mexEvalString("drawnow;");
+        Read_SparseMatrix(bin_basename, size, periods, y_kmin, y_kmax, steady_state);
         u_count=u_count_int*(periods+y_kmax+y_kmin);
-        //g1=(double*)mxMalloc(size*size*sizeof(double));
-        //mexPrintf("r=(double*)mxMalloc(%d)=",size*sizeof(double));
         r=(double*)mxMalloc(size*sizeof(double));
-        //mexPrintf("%x\n",r);
         y_save=(double*)mxMalloc(y_size*sizeof(double)*(periods+y_kmax+y_kmin));
-#ifdef DEBUGC
-        mexPrintf("u_count=%d\n",u_count);
-        mexEvalString("drawnow;");
-#endif
         begining=get_code_pointer;
         if(!Gaussian_Elimination)
           {
-#ifdef LINBCG
-            it_=y_kmin;
-            Per_u_=0;
-            Per_y_=it_*y_size;
-            set_code_pointer(begining);
-            compute_block_time(0);
-            linbcg.Initialize(filename, res1, res2, max_res, slowc, ya, direction, iter);
-            linbcg.Preconditioner(periods, y_kmin, y_kmax, size, IM_i, index_vara, index_equa, y_size, y, true, 0, a, indx);
-#endif
           }
-        //GaussSeidel=false;
         giter=0;
         iter=0;
-        //mexPrintf("2 boudaries problem\n");
-        //mexEvalString("drawnow;");
-        //mexPrintf("GaussSeidel=%d\n",GaussSeidel);
         if (!is_linear)
           {
-            //double res1a=0;
             cvg=false;
             int u_count_saved=u_count;
             while (!(cvg||(iter>maxit_)))
@@ -1061,26 +1142,12 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
                 max_res=0;
                 max_res_idx=0;
                 memcpy(y_save, y, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
-                //double res[size][13];
                 for (it_=y_kmin;it_<periods+y_kmin;it_++)
                   {
-                    Per_u_=(it_-y_kmin)*/*max_lag_plus_max_lead_plus_1*/u_count_int;
-                    //mexPrintf("Per_u_=%d\n",Per_u_);
+                    Per_u_=(it_-y_kmin)*u_count_int;
                     Per_y_=it_*y_size;
-                    //mexPrintf("ok\n");
-                    /*mexPrintf("compute_block_time it_=%d periods=%d y_kmin=%d\n",it_, periods, y_kmin);
-                    mexEvalString("drawnow;");*/
                     set_code_pointer(begining);
                     compute_block_time(Per_u_);
-                    /*mexPrintf("periods it_=%d ",it_);
-                    for (i=0; i< size; i++)
-                      mexPrintf(" %f ",r[i]);
-								    mexPrintf("\n");*/
-                    /*mexPrintf("end of compute_block_time it_=%d\n",it_);*/
-                    /*if(Gaussian_Elimination)
-                      initialize(periods, nb_endo, y_kmin, y_kmax, y_size, u_count, u_count_init, u, y, ya, slowc, y_decal, markowitz_c, res1, res2, max_res);*/
-                    //mexPrintf("ok1\n");
-                    /*mexEvalString("drawnow;");*/
                     if (isnan(res1)||isinf(res1))
                       {
                         memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
@@ -1088,17 +1155,11 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
                       }
                     for (i=0; i< size; i++)
                       {
-                      	/*if(it_<13)
-													res[i][it_-y_kmin]=r[i];*/
                         double rr;
-                        /*if(fabs(y[Per_y_+Block_Contain[i].Variable])>solve_tolf)*/
-                        //mexPrintf("res[%d]=%f\n",i,r[i]);
                         if(fabs(1+y[Per_y_+Block_Contain[i].Variable])>eps)
                           rr=r[i]/(1+y[Per_y_+Block_Contain[i].Variable]);
                         else
                           rr=r[i];
-                        /*else
-                          rr=r[i];*/
                         if (max_res<fabs(rr))
                           {
                             max_res=fabs(rr);
@@ -1106,54 +1167,14 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
                           }
                         res2+=rr*rr;
                         res1+=fabs(rr);
-                        /*if (GaussSeidel && giter)
-                          {
-                            //mexPrintf("y[%d]-=r[%d]/u[%d]\n",Block_Contain[i].Variable,i,Block_Contain[i].Own_Derivative,);
-                            y[Per_y_+Block_Contain[i].Variable]-=r[i]/u[Per_u_+Block_Contain[i].Own_Derivative];
-                            //mexPrintf("y[%d]-=r[%d](%f)/u[%d](%f)=%f\n",Block_Contain[i].Variable,i,r[i],Block_Contain[i].Own_Derivative,u[Per_u_+Block_Contain[i].Own_Derivative], y[Per_y_+Block_Contain[i].Variable]);
-                          }*/
-                        /*mexPrintf("r[%d] (i=%d)",i+size*(it_-y_kmin),i);
-                        mexPrintf("=%f\n",r[i]);*/
-											  //mexPrintf("u[b[%d]=%d]=%f\n",i+(it_-y_kmin)*u_count_int,b[i+(it_-y_kmin)*u_count_int],u[b[i+(it_-y_kmin)*u_count_int]]);
                       }
-										//mexPrintf("---------------------------------------------------------------------------------\n");
-                    //mexPrintf("(log(y(%d, 151))) - (x(%d, 338)=%f\n",it_, it_,y[Per_y_+ 150] - exp(x[it_+337*nb_row_x]));
-                  }
-								/*for(i=0;i<size;i++)
-								  {
-    							   for(int j=0;j<5;j++)
-									     mexPrintf(" % 1.6f ",res[i][j]);
-										 mexPrintf("\n");
-								  }*/
-                cvg=(max_res<solve_tolf);
-                //mexPrintf("it_=%d\n",it_);
-                if(Gaussian_Elimination)
-                  {
-                    /*mexPrintf("bef simulate_NG1\n");
-                    mexEvalString("drawnow;");*/
-                    u_count=u_count_saved;
-                    /*mexPrintf("u_count=%d &u_count=%x\n",u_count,&u_count);
-                    mexEvalString("drawnow;");*/
-                    /*for(int t=0;t<periods;t++)
-											{
-				  	            mexPrintf("%5.14f %5.14f %5.14f %5.14f \n",T[437*(periods+y_kmin+y_kmax)+t], T[72*(periods+y_kmin+y_kmax)+t], T[473*(periods+y_kmin+y_kmax)+t],
-				  	            T[437*(periods+y_kmin+y_kmax)+t] * T[72*(periods+y_kmin+y_kmax)+t] * T[473*(periods+y_kmin+y_kmax)+t]);
-				              }
-										filename=" stopped";
-                    mexErrMsgTxt(filename.c_str());*/
-                    simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter);
-                    /*mexPrintf("after simulate_NG1\n");
-                    mexEvalString("drawnow;");*/
-                    /*mexPrintf("aft simulate_NG1\n");
-                    mexEvalString("drawnow;");*/
-                  }
-                else
-                  {
-#ifdef LINBCG
-                    linbcg.Initialize(filename, res1, res2, max_res, slowc, ya, direction, iter);
-                    linbcg.SolveLinear(periods, y_kmin, y_kmax, size, IM_i, index_vara, index_equa,y_size,y, true, cvg, a, indx);
-#endif
                   }
+								if (isnan(res1)||isinf(res1))
+								  cvg = false;
+								else
+                  cvg=(max_res<solve_tolf);
+                u_count=u_count_saved;
+                simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter);
                 iter++;
               }
             if (!cvg)
@@ -1168,87 +1189,32 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
           	res1=res2=max_res=0;max_res_idx=0;
             for (it_=y_kmin;it_<periods+y_kmin;it_++)
               {
-                Per_u_=(it_-y_kmin)*/*max_lag_plus_max_lead_plus_1*/u_count_int;
+                Per_u_=(it_-y_kmin)*u_count_int;
                 Per_y_=it_*y_size;
                 set_code_pointer(begining);
                 compute_block_time(Per_u_);
-                /*mexPrintf("periods it_=%d ",it_);
                 for (i=0; i< size; i++)
-                  mexPrintf(" %f ",r[i]);
-								mexPrintf("\n");*/
-#ifdef PRINT_OUT
-                for (j=0; j<max_lag_plus_max_lead_plus_1; j++)
                   {
-                    mexPrintf(" %f",u[Per_u_+j]);
-                  }
-                mexPrintf("\n");
-#endif
-                /*mexPrintf("it_=%d ",it_);
-                for(i=0; i<y_size; i++)
-                  mexPrintf(" %f",y[i]);
-                mexPrintf("\n");*/
-                for (i=0; i< size; i++)
-                {
-                  double rr;
-                  /*if(fabs(y[Per_y_+Block_Contain[i].Variable])>solve_tolf)*/
-                  //mexPrintf("res[%d]=%f\n",i,r[i]);
-                  /*if(fabs(1+y[Per_y_+Block_Contain[i].Variable])>eps)
-                    rr=r[i]/(1+y[Per_y_+Block_Contain[i].Variable]);
-                  else*/
+                    double rr;
                     rr=r[i];
-                  /*else
-                    rr=r[i];*/
-                  if (max_res<fabs(rr))
-                    {
-                      max_res=fabs(rr);
-                      max_res_idx=i;
-                    }
-                  res2+=rr*rr;
-                  res1+=fabs(rr);
-                }
+                    if (max_res<fabs(rr))
+                      {
+                        max_res=fabs(rr);
+                        max_res_idx=i;
+                      }
+                    res2+=rr*rr;
+                    res1+=fabs(rr);
+                  }
               }
-            //res1=res2=max_res=0;max_res_idx=0;
-
             cvg = false;
-            //mexPrintf("it_=%d\n",it_);
-            if(Gaussian_Elimination)
-              {
-                simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter);
-                /*mexPrintf("after simulate_NG1\n");
-                mexEvalString("drawnow;");*/
-              }
-            else
-              {
-#ifdef LINBCG
-                linbcg.Initialize(filename, res1, res2, max_res, slowc, ya, direction, iter);
-                linbcg.SolveLinear(periods, y_kmin, y_kmax, size, IM_i, index_vara, index_equa, y_size, y, true, cvg, a, indx);
-#endif
-              }
-            /*mexPrintf("Two boundaries simulation\n");
-            for (it_=y_kmin;it_<periods+y_kmin;it_++)
-              {
-                mexPrintf("it_=%d ",it_);
-                for(i=0; i<y_size; i++)
-                  mexPrintf(" %f",y[i+it_*y_size]);
-                mexPrintf("\n");
-              }*/
+            simulate_NG1(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, periods, true, cvg, iter);
           }
-#ifdef  DEBUGC
-        //mexErrMsgTxt("End of simulate");
-#endif
-
-        //mxFree(g1);
-        /*mexPrintf("end of simulate_a_block\n");
-        mexEvalString("drawnow;");*/
         mxFree(r);
         mxFree(y_save);
         mxFree(u);
         mxFree(index_vara);
         mxFree(index_equa);
         memset(direction,0,size_of_direction);
-        /*mexPrintf("after free\n");
-        mexEvalString("drawnow;");*/
-        //GaussSeidel=false;
         break;
       default:
         mexPrintf("Unknow type =%d\n",type);
@@ -1256,17 +1222,20 @@ Interpreter::simulate_a_block(int size,int type, string file_name, string bin_ba
         mexEvalString("drawnow;");
         mexErrMsgTxt("End of simulate");
     }
-  /*mexPrintf("finish simulate_a_block\n");
-  mexEvalString("drawnow;");*/
+	return true;
 }
 
-void
-Interpreter::compute_blocks(string file_name, string bin_basename)
+bool
+Interpreter::compute_blocks(string file_name, string bin_basename, bool steady_state)
 {
   ifstream CompiledCode;
+  bool result = true;
   int Code_Size, var;
-  //printf("open(%s)\n",(file_name + ".cod").c_str());
-  //First read and store inn memory the code
+  if(steady_state)
+    file_name += "_static";
+	else
+	  file_name += "_dynamic";
+  //First read and store in memory the code
   CompiledCode.open((file_name + ".cod").c_str(),std::ios::in | std::ios::binary| std::ios::ate);
   if (!CompiledCode.is_open())
     {
@@ -1278,10 +1247,7 @@ Interpreter::compute_blocks(string file_name, string bin_basename)
       mexErrMsgTxt(filename.c_str());
     }
   Code_Size=CompiledCode.tellg();
-#ifdef DEBUGC
-  mexPrintf("Code_Size=%d\n",Code_Size);
-  mexEvalString("drawnow;");
-#endif
+
   CompiledCode.seekg(std::ios::beg);
   Code=(char*)mxMalloc(Code_Size);
   CompiledCode.seekg(0);
@@ -1294,16 +1260,7 @@ Interpreter::compute_blocks(string file_name, string bin_basename)
   bool go_on=true;
   while (go_on)
     {
-#ifdef DEBUGC
-      mexPrintf("pos=%d\n",int(get_code_pos)-int(Init_Code));
-      mexEvalString("drawnow;");
-#endif
       char code=get_code_char;
-#ifdef DEBUGC
-      int icode=(int)code;
-      mexPrintf("code=%d\n",icode);
-      mexEvalString("drawnow;");
-#endif
       switch (code)
         {
           case FBEGINBLOCK :
@@ -1314,69 +1271,35 @@ Interpreter::compute_blocks(string file_name, string bin_basename)
             Block.clear();
             Block_Contain.clear();
             Block_contain_type lBlock_Contain;
-#ifdef DEBUGC
-            mexPrintf("FBEGINBLOCK\n");
-            mexEvalString("drawnow;");
-#endif
-            /*uint64_t *Init_Code_64;
-            memcpy(Init_Code_64, Init_Code, sizeof(*Init_Code_64));*/
             lBlock.begin=get_code_pos-(uint64_t)Init_Code;
-#ifdef DEBUGC
-            mexPrintf("Block[%d].begin=%d\n",Block_Count, lBlock.begin);
-            mexEvalString("drawnow;");
-#endif
             lBlock.size=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("Block[Block_Count].size=%d\n",lBlock.size);
-            mexEvalString("drawnow;");
-#endif
             lBlock.type=get_code_int;
-#ifdef DEBUGC
-            mexPrintf("Block[Block_Count].type=%d\n",lBlock.type);
-            mexEvalString("drawnow;");
-#endif
             Block.push_back(lBlock);
-            for (int i=0;i</*Block[Block_Count].size*/lBlock.size;i++)
+            for (int i=0;i<lBlock.size;i++)
               {
                 lBlock_Contain.Variable=get_code_int;
-#ifdef DEBUGC
-                mexPrintf("Block_Contain[%d].Variable=%d\n",i,lBlock_Contain.Variable);
-                mexEvalString("drawnow;");
-#endif
                 lBlock_Contain.Equation=get_code_int;
-#ifdef DEBUGC
-                mexPrintf("Block_Contain[%d].Equation=%d\n",i,lBlock_Contain.Equation);
-                mexEvalString("drawnow;");
-#endif
                 lBlock_Contain.Own_Derivative=get_code_int;
-                //mexPrintf("Block_Contain[%d].Own_Derivative=%d\n",i,lBlock_Contain.Own_Derivative);
                 Block_Contain.push_back(lBlock_Contain);
               }
-#ifdef DEBUGC
-            mexPrintf("Block Completed\n");
-            mexEvalString("drawnow;");
-#endif
-            simulate_a_block(lBlock.size,lBlock.type, file_name, bin_basename,true);
-            /*mexPrintf("after simulate_a_block\n");
-            mexEvalString("drawnow;");*/
-            //simulate_a_block(lBlock.size,lBlock.type, file_name, bin_basename,false);
+            result = simulate_a_block(lBlock.size,lBlock.type, file_name, bin_basename,true, steady_state, Block_Count);
+            if(!result)
+              go_on = false;
             break;
           case FEND :
-#ifdef DEBUGC
-            mexPrintf("FEND\n");
-            mexEvalString("drawnow;");
-#endif
             go_on=false;
             break;
           case FDIMT :
             var=get_code_int;
-#ifdef DEBUGC
-                mexPrintf("FDIMT var=%d mxMalloc(%d)\n",var,var*(periods+y_kmin+y_kmax)*sizeof(double));
-                mexEvalString("drawnow;");
-#endif
             if(T)
               mxFree(T);
             T=(double*)mxMalloc(var*(periods+y_kmin+y_kmax)*sizeof(double));
+            break;
+					case FDIMST :
+            var=get_code_int;
+            if(T)
+              mxFree(T);
+            T=(double*)mxMalloc(var*sizeof(double));
             break;
           default :
             mexPrintf("Unknow command : %d at pos %d !!\n",(long int)(code),(uint64_t*)(get_code_pos)-(uint64_t*)(Init_Code));
@@ -1389,6 +1312,5 @@ Interpreter::compute_blocks(string file_name, string bin_basename)
   mxFree(Init_Code);
   if(T)
     mxFree(T);
-  /*mexPrintf("compute_blocks\n");
-  mexEvalString("drawnow;");*/
+	return result;
 }
diff --git a/mex/sources/simulate/Interpreter.hh b/mex/sources/simulate/Interpreter.hh
index f7ee2b0ac3cce0b9c1dd4b7e83ffaf1c5ea282d4..66d7592cd7b5bb045d61514ac7acb1ebc6b7f586 100644
--- a/mex/sources/simulate/Interpreter.hh
+++ b/mex/sources/simulate/Interpreter.hh
@@ -67,8 +67,9 @@ class Interpreter : SparseMatrix
 {
   protected :
     double pow1(double a, double b);
+    double log1(double a);
     void compute_block_time(int Per_u_);
-    void simulate_a_block(int size,int type, string file_name, string bin_basename, bool Gaussian_Elimination);
+    bool simulate_a_block(int size,int type, string file_name, string bin_basename, bool Gaussian_Elimination, bool steady_state, int block_num);
     double *T;
     vector<Block_contain_type> Block_Contain;
     vector<Block_type> Block;
@@ -83,6 +84,7 @@ class Interpreter : SparseMatrix
     double *x, *params;
     //double *y, *ya, *x, *direction;
     map<pair<pair<int, int> ,int>, int> IM_i;
+    int equation, derivative_equation, derivative_variable;
     string filename;
   public :
     //ReadBinFile read_bin_file;
@@ -90,7 +92,7 @@ class Interpreter : SparseMatrix
     Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *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,
                 double slowc_arg, int y_decal_arg, double markowitz_c_arg, string &filename_arg);
-    void compute_blocks(string file_name, string bin_basename);
+    bool compute_blocks(string file_name, string bin_basename, bool steady_state);
 };
 
 
diff --git a/mex/sources/simulate/Mem_Mngr.hh b/mex/sources/simulate/Mem_Mngr.hh
index e1246a981f49d4015e19fab4b0aa101a1c557245..5d113960898c4f70d5418ff5c3b922cfe3c79201 100644
--- a/mex/sources/simulate/Mem_Mngr.hh
+++ b/mex/sources/simulate/Mem_Mngr.hh
@@ -34,7 +34,7 @@ struct NonZeroElem
   {
     int u_index;
     int r_index, c_index, lag_index;
-    NonZeroElem *NZE_R_N, *NZE_C_N;
+    NonZeroElem *NZE_R_N, *NZE_C_N/*, *NZE_C_P*/;
   };
 
 typedef vector<NonZeroElem*> v_NonZeroElem;
diff --git a/mex/sources/simulate/SparseMatrix.cc b/mex/sources/simulate/SparseMatrix.cc
index 2044db163e2be34d338bf76b5af4dc7b3f92a2d7..20fa39b9807e41322c4b1d975b79786ff8e3ebcc 100644
--- a/mex/sources/simulate/SparseMatrix.cc
+++ b/mex/sources/simulate/SparseMatrix.cc
@@ -18,44 +18,46 @@
  */
 
 #include <cstring>
+#include <ctime>
 #include <sstream>
 #include "SparseMatrix.hh"
 
+using namespace std;
+
 SparseMatrix::SparseMatrix()
 {
-  pivotva=NULL;
-  g_save_op=NULL;
-  g_nop_all=0;
+  pivotva = NULL;
+  g_save_op = NULL;
+  g_nop_all = 0;
   mem_mngr.init_Mem();
-  symbolic=true;
-  alt_symbolic=false;
-  alt_symbolic_count=0;
-  max_u=0;
-  min_u=0x7FFFFFFF;
-  res1a=9.0e60;
-  tbreak_g=0;
-  start_compare=0;
+  symbolic = true;
+  alt_symbolic = false;
+  alt_symbolic_count = 0;
+  max_u = 0;
+  min_u = 0x7FFFFFFF;
+  res1a = 9.0e60;
+  tbreak_g = 0;
+  start_compare = 0;
   restart = 0;
+  IM_i.clear();
 }
 
-
-//
-
-
-int SparseMatrix::NRow(int r)
+int
+SparseMatrix::NRow(int r)
 {
   return NbNZRow[r];
 }
 
-int SparseMatrix::NCol(int c)
+int
+SparseMatrix::NCol(int c)
 {
   return NbNZCol[c];
 }
 
-
-int SparseMatrix::At_Row(int r, NonZeroElem **first)
+int
+SparseMatrix::At_Row(int r, NonZeroElem **first)
 {
-  (*first)=FNZE_R[r];
+  (*first) = FNZE_R[r];
   return NbNZRow[r];
 }
 
@@ -63,30 +65,30 @@ int
 SparseMatrix::Union_Row(int row1, int row2)
 {
   NonZeroElem *first1, *first2;
-  int n1=At_Row(row1, &first1);
-  int n2=At_Row(row2, &first2);
-  int i1=0, i2=0, nb_elem=0;
-  while (i1<n1 && i2<n2)
+  int n1 = At_Row(row1, &first1);
+  int n2 = At_Row(row2, &first2);
+  int i1 = 0, i2 = 0, nb_elem = 0;
+  while (i1 < n1 && i2 < n2)
     {
-      if (first1->c_index==first2->c_index)
+      if (first1->c_index == first2->c_index)
         {
           nb_elem++;
           i1++;
           i2++;
-          first1=first1->NZE_R_N;
-          first2=first2->NZE_R_N;
+          first1 = first1->NZE_R_N;
+          first2 = first2->NZE_R_N;
         }
-      else if (first1->c_index<first2->c_index)
+      else if (first1->c_index < first2->c_index)
         {
           nb_elem++;
           i1++;
-          first1=first1->NZE_R_N;
+          first1 = first1->NZE_R_N;
         }
       else
         {
           nb_elem++;
           i2++;
-          first2=first2->NZE_R_N;
+          first2 = first2->NZE_R_N;
         }
     }
   return nb_elem;
@@ -95,834 +97,588 @@ SparseMatrix::Union_Row(int row1, int row2)
 int
 SparseMatrix::At_Pos(int r, int c, NonZeroElem **first)
 {
-  (*first)=FNZE_R[r];
-  while ((*first)->c_index!=c /*&& (*first)->NZE_R_N*/)
-    {
-#ifdef PRINT_OUT
-      mexPrintf("looking not CRS [%d, %d]\n",(*first)->r_index,(*first)->c_index);
-#endif
-      (*first)=(*first)->NZE_R_N;
-    }
-  /*if ((*first)->c_index!=c)
-    mexPrintf("-----------------------  cannot find M[%d, %d]\n",r,c);*/
+  (*first) = FNZE_R[r];
+  while ((*first)->c_index != c)
+    (*first) = (*first)->NZE_R_N;
   return NbNZRow[r];
 }
 
-
-int SparseMatrix::At_Col(int c, NonZeroElem **first)
+int
+SparseMatrix::At_Col(int c, NonZeroElem **first)
 {
-  (*first)=FNZE_C[c];
+  (*first) = FNZE_C[c];
   return NbNZCol[c];
 }
 
-int SparseMatrix::At_Col(int c, int lag, NonZeroElem **first)
+int
+SparseMatrix::At_Col(int c, int lag, NonZeroElem **first)
 {
-  (*first)=FNZE_C[c];
-  int i=0;
-  while ((*first)->lag_index!=lag && (*first))
-    {
-#ifdef PRINT_OUT
-      mexPrintf("first->lag_index(%d) != %d\n",(*first)->lag_index,lag);
-#endif
-      (*first)=(*first)->NZE_C_N;
-    }
+  (*first) = FNZE_C[c];
+  int i = 0;
+  while ((*first)->lag_index != lag && (*first))
+    (*first) = (*first)->NZE_C_N;
   if ((*first))
     {
-#ifdef PRINT_OUT
-      mexPrintf("first=%x\n",(*first));
-#endif
-      NonZeroElem* firsta=(*first);
+      NonZeroElem *firsta = (*first);
       if (!firsta->NZE_C_N)
         i++;
       else
         {
-          while (firsta->lag_index==lag && firsta->NZE_C_N)
+          while (firsta->lag_index == lag && firsta->NZE_C_N)
             {
-#ifdef PRINT_OUT
-              mexPrintf("firsta->lag_index(%d) == %d, eq=%d, var=%d\n",firsta->lag_index,lag, firsta->r_index, firsta->c_index);
-#endif
-              firsta=firsta->NZE_C_N;
+              firsta = firsta->NZE_C_N;
               i++;
             }
-          if (firsta->lag_index==lag) i++;
+          if (firsta->lag_index == lag) i++;
         }
     }
-#ifdef PRINT_OUT
-  mexPrintf("i=%d\n",i);
-#endif
   return i;
 }
 
-#ifdef PROFILER
-double tdelete1=0, tdelete2=0, tdelete21=0, tdelete22=0, tdelete221=0, tdelete222=0, tcompare=0;
-#endif
-
-void SparseMatrix::Delete(const int r,const int c, const int Size)
+void
+SparseMatrix::Delete(const int r, const int c)
 {
-	//mexPrintf("Delete r=%d c=%d\n",r,c);
-  NonZeroElem *first=FNZE_R[r], *firsta=NULL;
-#ifdef PROFILER
-  clock_t td0, td1, td2;
-  td0=clock();
-#endif
-  while (first->c_index!=c)
+	NonZeroElem *first = FNZE_R[r], *firsta = NULL;
+
+	//mexPrintf("Delete r=%d, c=%d\n", r, c);
+	/*map<pair<int, int>,NonZeroElem*>::const_iterator it;
+	it = Mapped_Array.find(make_pair(r, c));
+	if(it==Mapped_Array.end())
+	  mexPrintf("Not Found\n");
+  first = it->second;
+  if(it != Mapped_Array.begin())
     {
-      firsta=first;
-      first=first->NZE_R_N;
+      it--;
+			if(it->first.first == r)
+        firsta = it->second;
+			else
+			  firsta = NULL;
     }
-#ifdef PRINT_OUT
-      mexPrintf("CRS [%d, %d]=c(%d)\n",first->r_index,first->c_index,c);
-      mexEvalString("drawnow;");
-#endif
-  if (firsta!=NULL)
-    firsta->NZE_R_N=first->NZE_R_N;
-  if (first==FNZE_R[r])
-    FNZE_R[r]=first->NZE_R_N;
+	else
+	  firsta = NULL;
+  Mapped_Array.erase(make_pair(r, c));*/
+
+  while (first->c_index != c)
+    {
+      firsta = first;
+      first = first->NZE_R_N;
+    }
+  if (firsta != NULL)
+    firsta->NZE_R_N = first->NZE_R_N;
+  if (first == FNZE_R[r])
+    FNZE_R[r] = first->NZE_R_N;
   NbNZRow[r]--;
-#ifdef PROFILER
-  tdelete1+=clock()-td0;
-  td0=clock();
-  td1=clock();
-#endif
-  first=FNZE_C[c];
-  firsta=NULL;
-  while (first->r_index!=r)
+
+  first = FNZE_C[c];
+  firsta = NULL;
+  while (first->r_index != r)
     {
-      firsta=first;
-      first=first->NZE_C_N;
+      firsta = first;
+      first = first->NZE_C_N;
     }
-#ifdef PRINT_OUT
-  mexPrintf("CSS [%d, %d]=r(%d)\n",first->r_index,first->c_index,r);
-  mexEvalString("drawnow;");
-#endif
-#ifdef PROFILER
-  tdelete21+=clock()-td1;
-  td1=clock();
-#endif
-  if (firsta!=NULL)
-    firsta->NZE_C_N=first->NZE_C_N;
-  if (first==FNZE_C[c])
-    FNZE_C[c]=first->NZE_C_N;
-#ifdef PROFILER
-  td2=clock();
-#endif
+	//firsta = first->NZE_C_P;
+
+	/*if(first->NZE_C_N != NULL)
+	  {
+	  	//mexPrintf("ultime\n");
+      (first->NZE_C_N)->NZE_C_P = firsta;
+	  }*/
+  //mexPrintf("ok1\n");
+
+  if (firsta != NULL)
+    firsta->NZE_C_N = first->NZE_C_N;
+  if (first == FNZE_C[c])
+		FNZE_C[c] = first->NZE_C_N;
+
   u_liste.push_back(first->u_index);
-#ifdef PROFILER
-  tdelete221+=clock()-td2;
-  td2=clock();
-#endif
-#ifdef NEW_ALLOC
   mem_mngr.mxFree_NZE(first);
-#else
-  mxFree(first);
-#endif
   NbNZCol[c]--;
-#ifdef PROFILER
-  tdelete222+=clock()-td2;
-#endif
-#ifdef PROFILER
-  tdelete22+=clock()-td1;
-  tdelete2+=clock()-td0;
-#endif
   /*Check the deletition*/
   /*int nb_var=NbNZRow[r];
   first=FNZE_R[r];
   for(int j=0;j<nb_var;j++)
     {
-    	if(!first)
-    	  mexPrintf("Error in Delete (Row) r=%d and c=%d \n",r,c);
+      if(!first)
+        mexPrintf("Error in Delete (Row) r=%d and c=%d \n",r,c);
       first=first->NZE_R_N;
     }
-	nb_var=NbNZCol[c];
+  nb_var=NbNZCol[c];
   first=FNZE_C[c];
   for(int j=0;j<nb_var;j++)
     {
-    	if(!first)
-    	  mexPrintf("Error in Delete (Col) r=%d and c=%d \n",r,c);
+      if(!first)
+        mexPrintf("Error in Delete (Col) r=%d and c=%d \n",r,c);
       first=first->NZE_C_N;
     }*/
+	//mexPrintf("done\n");
 }
 
-
-void SparseMatrix::Print(int Size, int *b)
+void
+SparseMatrix::Print(int Size, int *b)
 {
-  int a,i,j,k,l;
+  int a, i, j, k, l;
   mexPrintf("   ");
-  for (k=0;k<Size*periods;k++)
-    mexPrintf("%-2d ",k);
+  for (k = 0; k < Size*periods; k++)
+    mexPrintf("%-2d ", k);
   mexPrintf("    |    ");
-  for (k=0;k<Size*periods;k++)
-    mexPrintf("%8d",k);
+  for (k = 0; k < Size*periods; k++)
+    mexPrintf("%8d", k);
   mexPrintf("\n");
-  for (i=0;i<Size*periods;i++)
+  for (i = 0; i < Size*periods; i++)
     {
-      NonZeroElem *first=FNZE_R[i];
-      j=NbNZRow[i];
-      mexPrintf("%-2d ",i);
-      a=0;
-      for (k=0;k<j;k++)
+      NonZeroElem *first = FNZE_R[i];
+      j = NbNZRow[i];
+      mexPrintf("%-2d ", i);
+      a = 0;
+      for (k = 0; k < j; k++)
         {
-          for (l=0;l<(first->c_index-a);l++)
+          for (l = 0; l < (first->c_index-a); l++)
             mexPrintf("   ");
-          mexPrintf("%-2d ",first->u_index);
-          a=first->c_index+1;
-          first=first->NZE_R_N;
+          mexPrintf("%-2d ", first->u_index);
+          a = first->c_index+1;
+          first = first->NZE_R_N;
         }
-      for (k=a;k<Size*periods;k++)
+      for (k = a; k < Size*periods; k++)
         mexPrintf("   ");
-      mexPrintf("%-2d ",b[i]);
+      mexPrintf("%-2d ", b[i]);
 
-      first=FNZE_R[i];
-      j=NbNZRow[i];
-      mexPrintf(" | %-2d ",i);
-      a=0;
-      for (k=0;k<j;k++)
+      first = FNZE_R[i];
+      j = NbNZRow[i];
+      mexPrintf(" | %-2d ", i);
+      a = 0;
+      for (k = 0; k < j; k++)
         {
-          for (l=0;l<(first->c_index-a);l++)
+          for (l = 0; l < (first->c_index-a); l++)
             mexPrintf("        ");
-          mexPrintf("%8.4f",double(u[first->u_index]));
-          a=first->c_index+1;
-          first=first->NZE_R_N;
+          mexPrintf("%8.4f", double (u[first->u_index]));
+          a = first->c_index+1;
+          first = first->NZE_R_N;
         }
-      for (k=a;k<Size*periods;k++)
+      for (k = a; k < Size*periods; k++)
         mexPrintf("        ");
-      mexPrintf("%8.4f",double(u[b[i]]));
+      mexPrintf("%8.4f", double (u[b[i]]));
       mexPrintf("\n");
     }
 }
 
-
-
-void SparseMatrix::Insert(const int r, const int c, const int u_index, const int lag_index)
+void
+SparseMatrix::Insert(const int r, const int c, const int u_index, const int lag_index)
 {
-	//mexPrintf("Insert r=%d c=%d\n",r,c);
-#ifdef PRINT_OUT
-  mexPrintf("In Insert r=%d, c=%d, u=%d, lag=%d \n",r,c,u_index,lag_index);
-#endif
-  NonZeroElem *firstn, *first, *firsta;
-  /*if (first)
-    {*/
-#ifdef NEW_ALLOC
-  firstn=mem_mngr.mxMalloc_NZE();
-#else
-  firstn=(NonZeroElem*)mxMalloc(sizeof(NonZeroElem));
-#endif
-  first=FNZE_R[r];
-  firsta=NULL;
-#ifdef PRINT_OUT
-  mexPrintf("first->c_index=%d, first->NZE_R_N=%x\n",first->c_index, first->NZE_R_N);
-#endif
-  while (first->c_index<c && first->NZE_R_N)
+  NonZeroElem *firstn, *first, *firsta, *a;
+  firstn = mem_mngr.mxMalloc_NZE();
+  first = FNZE_R[r];
+  firsta = NULL;
+  while (first->c_index < c && (a = first->NZE_R_N))
     {
-      firsta=first;
-#ifdef PRINT_OUT
-      mexPrintf("drop first->c_index=%d c=%d\n",first->c_index,c);
-#endif
-      first=first->NZE_R_N;
+      firsta = first;
+      first = a;
     }
-#ifdef PRINT_OUT
-  mexPrintf("retain first->c_index=%d c=%d\n",first->c_index,c);
-#endif
-  firstn->u_index=u_index;
-  firstn->r_index=r;
-  firstn->c_index=c;
-  firstn->lag_index=lag_index;
-  if (first->c_index>c)
+  firstn->u_index = u_index;
+  firstn->r_index = r;
+  firstn->c_index = c;
+  firstn->lag_index = lag_index;
+  if (first->c_index > c)
     {
-      if (first==FNZE_R[r])
-        FNZE_R[r]=firstn;
-      if (firsta!=NULL)
-        firsta->NZE_R_N=firstn;
-      firstn->NZE_R_N=first;
+      if (first == FNZE_R[r])
+        FNZE_R[r] = firstn;
+      if (firsta != NULL)
+        firsta->NZE_R_N = firstn;
+      firstn->NZE_R_N = first;
     }
   else /*first.c_index<c*/
     {
-    	/*if(first->c_index==c)
-    	  mexPrintf("Error in Insert (r=%d, c=%d -Row-) already exist!!\n");*/
-      first->NZE_R_N=firstn;
-      firstn->NZE_R_N=NULL;
+      first->NZE_R_N = firstn;
+      firstn->NZE_R_N = NULL;
     }
   NbNZRow[r]++;
-  first=FNZE_C[c];
-  firsta=NULL;
-  while (first->r_index<r && first->NZE_C_N)
+  first = FNZE_C[c];
+  firsta = NULL;
+  while (first->r_index < r && (a = first->NZE_C_N))
     {
-      firsta=first;
-      first=first->NZE_C_N;
+      firsta = first;
+      first = a;
     }
-  if (first->r_index>r)
+  if (first->r_index > r)
     {
-      if (first==FNZE_C[c])
-        FNZE_C[c]=firstn;
-      if (firsta!=NULL)
-        firsta->NZE_C_N=firstn;
-      firstn->NZE_C_N=first;
+      if (first == FNZE_C[c])
+        FNZE_C[c] = firstn;
+      if (firsta != NULL)
+        firsta->NZE_C_N = firstn;
+      firstn->NZE_C_N = first;
     }
   else /*first.r_index<r*/
     {
-    	/*if(first->r_index==r)
-    	  mexPrintf("Error in Insert (r=%d, c=%d -Col-) already exist!!\n");*/
-      first->NZE_C_N=firstn;
-      firstn->NZE_C_N=NULL;
+      first->NZE_C_N = firstn;
+      firstn->NZE_C_N = NULL;
     }
+
+	//if (firsta != NULL)
+	/*firstn->NZE_C_P = firsta;
+	if(first != NULL)
+	  first->NZE_C_P = firstn;*/
+
   NbNZCol[c]++;
+  //Mapped_Array[make_pair(r, c)] = firstn;
   /*Check the insertion*/
   /*int nb_var=NbNZRow[r];
-  first=FNZE_R[r];
-  for(int j=0;j<nb_var;j++)
-    {
-    	if(!first)
-    	  mexPrintf("Error in insert (Row) r=%d and c=%d \n",r,c);
+     first=FNZE_R[r];
+     for(int j=0;j<nb_var;j++)
+     {
+        if(!first)
+          mexPrintf("Error in insert (Row) r=%d and c=%d \n",r,c);
       first=first->NZE_R_N;
-    }
-	nb_var=NbNZCol[c];
-  first=FNZE_C[c];
-  for(int j=0;j<nb_var;j++)
-    {
-    	if(!first)
-    	  mexPrintf("Error in insert (Col) r=%d and c=%d \n",r,c);
+     }
+        nb_var=NbNZCol[c];
+     first=FNZE_C[c];
+     for(int j=0;j<nb_var;j++)
+     {
+        if(!first)
+          mexPrintf("Error in insert (Col) r=%d and c=%d \n",r,c);
       first=first->NZE_C_N;
-    }*/
+     }*/
 }
 
-void SparseMatrix::Read_SparseMatrix(string file_name, int Size, int periods, int y_kmin, int y_kmax)
+void
+SparseMatrix::Read_SparseMatrix(string file_name, int Size, int periods, int y_kmin, int y_kmax, bool steady_state)
 {
-  int i,j,eq,var,lag;
-  filename=file_name;
+  int i, j, eq, var, lag;
+  filename = file_name;
   mem_mngr.fixe_file_name(file_name);
   if (!SaveCode.is_open())
     {
-#ifdef PRINT_OUT
-      mexPrintf("file opened\n");
-#endif
-      SaveCode.open((file_name + ".bin").c_str(), std::ios::in | std::ios::binary);
+    	if(steady_state)
+        SaveCode.open((file_name + "_static.bin").c_str(), ios::in | ios::binary);
+			else
+			  SaveCode.open((file_name + "_dynamic.bin").c_str(), ios::in | ios::binary);
       if (!SaveCode.is_open())
         {
-          mexPrintf("Error : Can't open file \"%s\" for reading\n", (file_name + ".bin").c_str());
+        	if(steady_state)
+            mexPrintf("Error : Can't open file \"%s\" for reading\n", (file_name + "_static.bin").c_str());
+					else
+					  mexPrintf("Error : Can't open file \"%s\" for reading\n", (file_name + "_dynamic.bin").c_str());
           mexEvalString("st=fclose('all');clear all;");
           mexErrMsgTxt("Exit from Dynare");
         }
-#ifdef PRINT_OUT
-      mexPrintf("done\n");
-#endif
     }
   IM_i.clear();
-  //mexPrintf("u_count_init=%d\n",u_count_init);
-  for (i=0;i<u_count_init;i++)
+  for (i = 0; i < u_count_init; i++)
     {
       SaveCode.read(reinterpret_cast<char *>(&eq), sizeof(eq));
       SaveCode.read(reinterpret_cast<char *>(&var), sizeof(var));
       SaveCode.read(reinterpret_cast<char *>(&lag), sizeof(lag));
       SaveCode.read(reinterpret_cast<char *>(&j), sizeof(j));
-      //mexPrintf("eq=%d var=%d lag=%d j=%d\n",eq, var, lag, j);
-      IM_i[std::make_pair(std::make_pair(eq, var), lag)] = j;
-    }
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("index_vara=(int*)mxMalloc(%d*sizeof(int))\n",Size*(periods+y_kmin+y_kmax));
-#endif
-  index_vara=(int*)mxMalloc(Size*(periods+y_kmin+y_kmax)*sizeof(int));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("ok\n");
-#endif
-  for (j=0;j<Size;j++)
-    {
-      SaveCode.read(reinterpret_cast<char *>(&index_vara[j]), sizeof(*index_vara));
+      IM_i[make_pair(make_pair(eq, var), lag)] = j;
     }
-  if(periods+y_kmin+y_kmax>1)
+  index_vara = (int *) mxMalloc(Size*(periods+y_kmin+y_kmax)*sizeof(int));
+  for (j = 0; j < Size; j++)
+    SaveCode.read(reinterpret_cast<char *>(&index_vara[j]), sizeof(*index_vara));
+  if (periods+y_kmin+y_kmax > 1)
     {
-      for (i=1;i<periods+y_kmin+y_kmax;i++)
+      for (i = 1; i < periods+y_kmin+y_kmax; i++)
         {
-          for (j=0;j<Size;j++)
-           {
-   #ifdef PRINT_OUT
-              mexPrintf("index_vara[%d]=index_vara[%d]+y_size=",j+Size*i,j+Size*(i-1));
-   #endif
-             index_vara[j+Size*i]=index_vara[j+Size*(i-1)]+y_size;
-   #ifdef PRINT_OUT
-             mexPrintf("%d\n",index_vara[j+Size*i]);
-  #endif
-           }
-       }
+          for (j = 0; j < Size; j++)
+            {
+              index_vara[j+Size*i] = index_vara[j+Size*(i-1)]+y_size;
+            }
+        }
     }
-  index_equa=(int*)mxMalloc(Size*sizeof(int));
-  for(j=0;j<Size;j++)
+  index_equa = (int *) mxMalloc(Size*sizeof(int));
+  for (j = 0; j < Size; j++)
     {
       SaveCode.read(reinterpret_cast<char *>(&index_equa[j]), sizeof(*index_equa));
     }
 }
 
-
-
-void SparseMatrix::Simple_Init(int it_, int y_kmin, int y_kmax, int Size, std::map<std::pair<std::pair<int, int> ,int>, int> &IM)
+void
+SparseMatrix::Simple_Init(int it_, int y_kmin, int y_kmax, int Size, map<pair<pair<int, int>, int>, int> &IM)
 {
   int i, eq, var, lag;
-  //double tmp_b=0.0;
-  std::map<std::pair<std::pair<int, int> ,int>, int>::iterator it4;
-  NonZeroElem* first;
-  //mexPrintf("periods=%d, y_kmin=%d, y_kmax=%d, SizeInit=%d, IM.size()=%d\n",periods, y_kmin, y_kmax, Size, IM.size());
-  pivot=(int*)mxMalloc(Size*sizeof(int));
-  pivot_save=(int*)mxMalloc(Size*sizeof(int));
-  pivotk=(int*)mxMalloc(Size*sizeof(int));
-  pivotv=(double*)mxMalloc(Size*sizeof(double));
-  pivotva=(double*)mxMalloc(Size*sizeof(double));
-  b=(int*)mxMalloc(Size*sizeof(int));
-  line_done=(bool*)mxMalloc(Size*sizeof(bool));
-  //memset(line_done, 0, Size*sizeof(*line_done));
+  map<pair<pair<int, int>, int>, int>::iterator it4;
+  NonZeroElem *first;
+  pivot = (int *) mxMalloc(Size*sizeof(int));
+  pivot_save = (int *) mxMalloc(Size*sizeof(int));
+  pivotk = (int *) mxMalloc(Size*sizeof(int));
+  pivotv = (double *) mxMalloc(Size*sizeof(double));
+  pivotva = (double *) mxMalloc(Size*sizeof(double));
+  b = (int *) mxMalloc(Size*sizeof(int));
+  line_done = (bool *) mxMalloc(Size*sizeof(bool));
 
   mem_mngr.init_CHUNK_BLCK_SIZE(u_count);
-  g_save_op=NULL;
-  g_nop_all=0;
-  i=Size*sizeof(NonZeroElem*);
-  FNZE_R=(NonZeroElem**)mxMalloc(i);
-  FNZE_C=(NonZeroElem**)mxMalloc(i);
-  //memset(FNZE_R, 0, i);
-  //memset(FNZE_C, 0, i);
-  NonZeroElem** temp_NZE_R=(NonZeroElem**)mxMalloc(i);
-  NonZeroElem** temp_NZE_C=(NonZeroElem**)mxMalloc(i);
-  //memset(temp_NZE_R, 0, i);
-  //memset(temp_NZE_C, 0, i);
-  i=Size*sizeof(int);
-  NbNZRow=(int*)mxMalloc(i);
-  NbNZCol=(int*)mxMalloc(i);
-  //memset(NbNZRow, 0, i);
-  //memset(NbNZCol, 0, i);
-  i=Size*sizeof(*b);
-  //memset(b,0,i);
-  it4=IM.begin();
-  eq=-1;
-  double tmp_b[Size];
-  #pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
-  for(i=0; i< Size;i++)
+  g_save_op = NULL;
+  g_nop_all = 0;
+  i = Size*sizeof(NonZeroElem *);
+  FNZE_R = (NonZeroElem **) mxMalloc(i);
+  FNZE_C = (NonZeroElem **) mxMalloc(i);
+  NonZeroElem **temp_NZE_R = (NonZeroElem **) mxMalloc(i);
+  NonZeroElem **temp_NZE_C = (NonZeroElem **) mxMalloc(i);
+  i = Size*sizeof(int);
+  NbNZRow = (int *) mxMalloc(i);
+  NbNZCol = (int *) mxMalloc(i);
+  i = Size*sizeof(*b);
+  it4 = IM.begin();
+  eq = -1;
+  //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
+  for (i = 0; i < Size; i++)
     {
-      tmp_b[i]=0;//u[i];
-      b[i]=0;
-      line_done[i]=0;
-      FNZE_C[i]=0;
-      FNZE_R[i]=0;
-      temp_NZE_C[i]=0;
-      temp_NZE_R[i]=0;
-      NbNZRow[i]=0;
-      NbNZCol[i]=0;
+      b[i] = 0;
+      line_done[i] = 0;
+      FNZE_C[i] = 0;
+      FNZE_R[i] = 0;
+      temp_NZE_C[i] = 0;
+      temp_NZE_R[i] = 0;
+      NbNZRow[i] = 0;
+      NbNZCol[i] = 0;
     }
-  int u_count1=Size;
-  while (it4!=IM.end())
+  int u_count1 = Size;
+  while (it4 != IM.end())
     {
-      var=it4->first.first.second;
-      /*if (eq!=it4->first.first.first)
-        tmp_b=0;*/
-      eq=it4->first.first.first;
-      lag=it4->first.second;
-      if (lag==0)   /*Build the index for sparse matrix containing the jacobian : u*/
+      var = it4->first.first.second;
+      eq = it4->first.first.first;
+      lag = it4->first.second;
+      if (lag == 0)   /*Build the index for sparse matrix containing the jacobian : u*/
         {
-          //mexPrintf("Add eq=%d, var=%d, lag=%d at it_=%d u=%f\n",eq,var,lag, it_, u[u_count1]);
-          //mexPrintf("    u_index=%d\n",/*it4->second+u_count_init*it_*/u_count1);
           NbNZRow[eq]++;
           NbNZCol[var]++;
-#ifdef NEW_ALLOC
-          first=mem_mngr.mxMalloc_NZE();
-#else
-          first=(NonZeroElem*)mxMalloc(sizeof(NonZeroElem));
-#endif
-          first->NZE_C_N=NULL;
-          first->NZE_R_N=NULL;
-          first->u_index=u_count1/*it4->second+u_count_init*it_*/;
-          first->r_index=eq;
-          first->c_index=var;
-          first->lag_index=lag;
-          //mexPrintf("  u[%d](%f)*y[%d](%f)=%f\n",u_count1, u[u_count1], index_vara[var]+it_*y_size, y[index_vara[var]+it_*y_size], u[u_count1]*y[index_vara[var]+it_*y_size]);
-          tmp_b[eq] += u[u_count1]*y[index_vara[var]+it_*y_size];
-          if (FNZE_R[eq]==NULL)
-            {
-              FNZE_R[eq]=first;
-            }
-          if (FNZE_C[var]==NULL)
-            FNZE_C[var]=first;
-          if (temp_NZE_R[eq]!=NULL)
-            temp_NZE_R[eq]->NZE_R_N=first;
-          if (temp_NZE_C[var]!=NULL)
-            temp_NZE_C[var]->NZE_C_N=first;
-          temp_NZE_R[eq]=first;
-          temp_NZE_C[var]=first;
+          first = mem_mngr.mxMalloc_NZE();
+          first->NZE_C_N = NULL;
+          first->NZE_R_N = NULL;
+          first->u_index = u_count1 /*it4->second+u_count_init*it_*/;
+          first->r_index = eq;
+          first->c_index = var;
+          first->lag_index = lag;
+          if (FNZE_R[eq] == NULL)
+            FNZE_R[eq] = first;
+          if (FNZE_C[var] == NULL)
+            FNZE_C[var] = first;
+          if (temp_NZE_R[eq] != NULL)
+            temp_NZE_R[eq]->NZE_R_N = first;
+          if (temp_NZE_C[var] != NULL)
+            temp_NZE_C[var]->NZE_C_N = first;
+          temp_NZE_R[eq] = first;
+          temp_NZE_C[var] = first;
+          //Mapped_Array[make_pair(eq,var)]=first;
           u_count1++;
         }
       it4++;
     }
-  #pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
-  for(i=0;i<Size;i++)
-    {
-      b[i]=u_count1+i;
-      u[b[i]]=-tmp_b[i];
-    }
-  //mexEvalString("Init");
+  //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
+  for (i = 0; i < Size; i++)
+		b[i] = i;
   mxFree(temp_NZE_R);
   mxFree(temp_NZE_C);
-  /*mexPrintf("end of Simple_Init\n");
-  mexEvalString("drawnow;");*/
+  u_count = u_count1/*+Size*/;
 }
 
-
-void SparseMatrix::Init(int periods, int y_kmin, int y_kmax, int Size, std::map<std::pair<std::pair<int, int> ,int>, int> &IM)
+void
+SparseMatrix::Init(int periods, int y_kmin, int y_kmax, int Size, map<pair<pair<int, int>, int>, int> &IM)
 {
-  int t,i, eq, var, lag, ti_y_kmin, ti_y_kmax;
-  double tmp_b=0.0;
-  std::map<std::pair<std::pair<int, int> ,int>, int>::iterator it4;
-  NonZeroElem* first;
-  //mexPrintf("periods=%d, y_kmin=%d, y_kmax=%d, SizeInit=%d, IM.size()=%d\n",periods, y_kmin, y_kmax, Size, IM.size());
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("pivot=(int*)mxMalloc(%d*sizeof(int))\n",Size*periods);
-#endif
-  pivot=(int*)mxMalloc(Size*periods*sizeof(int));
-  pivot_save=(int*)mxMalloc(Size*periods*sizeof(int));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("pivota=(int*)mxMalloc(%d*sizeof(int))\n",Size*periods);
-#endif
-  pivotk=(int*)mxMalloc(Size*periods*sizeof(int));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("pivotv=(double*)mxMalloc(%d*sizeof(double))\n",Size*periods);
-#endif
-  pivotv=(double*)mxMalloc(Size*periods*sizeof(double));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("pivotva=(double*)mxMalloc(%d*sizeof(double))\n",Size*periods);
-#endif
-  pivotva=(double*)mxMalloc(Size*periods*sizeof(double));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("b=(int*)mxMalloc(%d*sizeof(int))\n",Size*periods);
-#endif
-  b=(int*)mxMalloc(Size*periods*sizeof(int));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("line_done=(bool*)mxMalloc(%d*sizeof(bool))\n",Size*periods);
-#endif
-  line_done=(bool*)mxMalloc(Size*periods*sizeof(bool));
-  //memset(line_done, 0, periods*Size*sizeof(*line_done));
+  int t, i, eq, var, lag, ti_y_kmin, ti_y_kmax;
+  double tmp_b = 0.0;
+  map<pair<pair<int, int>, int>, int>::iterator it4;
+  NonZeroElem *first;
+  pivot = (int *) mxMalloc(Size*periods*sizeof(int));
+  pivot_save = (int *) mxMalloc(Size*periods*sizeof(int));
+  pivotk = (int *) mxMalloc(Size*periods*sizeof(int));
+  pivotv = (double *) mxMalloc(Size*periods*sizeof(double));
+  pivotva = (double *) mxMalloc(Size*periods*sizeof(double));
+  b = (int *) mxMalloc(Size*periods*sizeof(int));
+  line_done = (bool *) mxMalloc(Size*periods*sizeof(bool));
   mem_mngr.init_CHUNK_BLCK_SIZE(u_count);
-  g_save_op=NULL;
-  g_nop_all=0;
-#ifdef PRINT_OUT
-  mexPrintf("sizeof(NonZeroElem)=%d sizeof(NonZeroElem*)=%d\n",sizeof(NonZeroElem),sizeof(NonZeroElem*));
-#endif
-  i=(periods+y_kmax+1)*Size*sizeof(NonZeroElem*);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("FNZE_R=(NonZeroElem**)mxMalloc(%d)\n",i);
-#endif
-  FNZE_R=(NonZeroElem**)mxMalloc(i);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("FNZE_C=(NonZeroElem**)mxMalloc(%d)\n",i);
-#endif
-  FNZE_C=(NonZeroElem**)mxMalloc(i);
-  //memset(FNZE_R, 0, i);
-  //memset(FNZE_C, 0, i);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("temp_NZE_R=(NonZeroElem**)(%d)\n",i);
-#endif
-  NonZeroElem** temp_NZE_R=(NonZeroElem**)mxMalloc(i);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("temp_NZE_R=(NonZeroElem**)(%d)\n",i);
-#endif
-  NonZeroElem** temp_NZE_C=(NonZeroElem**)mxMalloc(i);
-  //memset(temp_NZE_R, 0, i);
-  //memset(temp_NZE_C, 0, i);
-  i=(periods+y_kmax+1)*Size*sizeof(int);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("NbNZRow=(int*)mxMalloc(%d)\n",i);
-#endif
-  NbNZRow=(int*)mxMalloc(i);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("NbNZCol=(int*)mxMalloc(%d)\n",i);
-#endif
-  NbNZCol=(int*)mxMalloc(i);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("ok\n");
-#endif
-  //memset(NbNZRow, 0, i);
-  //memset(NbNZCol, 0, i);
-  //i=periods*Size*sizeof(*b);
-  //memset(b,0,i);
-
-  #pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
-  for(i=0; i< periods*Size;i++)
+  g_save_op = NULL;
+  g_nop_all = 0;
+  i = (periods+y_kmax+1)*Size*sizeof(NonZeroElem*);
+  FNZE_R = (NonZeroElem **) mxMalloc(i);
+  FNZE_C = (NonZeroElem **) mxMalloc(i);
+  NonZeroElem **temp_NZE_R = (NonZeroElem **) mxMalloc(i);
+  NonZeroElem **temp_NZE_C = (NonZeroElem **) mxMalloc(i);
+  i = (periods+y_kmax+1)*Size*sizeof(int);
+  NbNZRow = (int *) mxMalloc(i);
+  NbNZCol = (int *) mxMalloc(i);
+
+  //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
+  for (i = 0; i < periods*Size; i++)
     {
-      b[i]=0;
-      line_done[i]=0;
+      b[i] = 0;
+      line_done[i] = 0;
     }
-  #pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
-  for(i=0; i< (periods+y_kmax+1)*Size;i++)
+  //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
+  for (i = 0; i < (periods+y_kmax+1)*Size; i++)
     {
-      FNZE_C[i]=0;
-      FNZE_R[i]=0;
-      temp_NZE_C[i]=0;
-      temp_NZE_R[i]=0;
-      NbNZRow[i]=0;
-      NbNZCol[i]=0;
+      FNZE_C[i] = 0;
+      FNZE_R[i] = 0;
+      temp_NZE_C[i] = NULL;
+      temp_NZE_R[i] = NULL;
+      NbNZRow[i] = 0;
+      NbNZCol[i] = 0;
     }
 
-#ifdef PRINT_OUT
-  mexPrintf("Now looping\n");
-  mexEvalString("drawnow;");
-#endif
-  ///#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) ordered private(it4, ti_y_kmin, ti_y_kmax, eq, var, lag) schedule(dynamic)
-  for (t=0;t<periods;t++)
+  //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) ordered private(it4, ti_y_kmin, ti_y_kmax, eq, var, lag) schedule(dynamic)
+  for (t = 0; t < periods; t++)
     {
-#ifdef PRINT_OUT
-      mexPrintf("t=%d\n",t);
-#endif
-      ti_y_kmin=-min( t            , y_kmin);
-      ti_y_kmax= min( periods-(t+1), y_kmax);
-      it4=IM.begin();
-      eq=-1;
-      ///#pragma omp ordered
-      while (it4!=IM.end())
+      ti_y_kmin = -min(t, y_kmin);
+      ti_y_kmax = min(periods-(t+1), y_kmax);
+      it4 = IM.begin();
+      eq = -1;
+      //#pragma omp ordered
+      while (it4 != IM.end())
         {
-          var=it4->first.first.second;
-          if (eq!=it4->first.first.first+Size*t)
-            tmp_b=0;
-          eq=it4->first.first.first+Size*t;
-          lag=it4->first.second;
-#ifdef PRINT_OUT
-					mexPrintf("=) eq=%d var=%d lag=%d t=%d\n",eq,var, lag, t);
-          mexPrintf("eq=%d, var=%d",eq,var);
-          mexEvalString("drawnow;");
-#endif
-          if (var<(periods+y_kmax)*Size)
+          var = it4->first.first.second;
+          if (eq != it4->first.first.first+Size*t)
+            tmp_b = 0;
+          eq = it4->first.first.first+Size*t;
+          lag = it4->first.second;
+          if (var < (periods+y_kmax)*Size)
             {
-              lag=it4->first.second;
-#ifdef PRINT_OUT
-              mexPrintf(", lag =%d, ti_y_kmin=%d, ti_y_kmax=%d ", lag, ti_y_kmin, ti_y_kmax);
-#endif
-              if (lag<=ti_y_kmax && lag>=ti_y_kmin)   /*Build the index for sparse matrix containing the jacobian : u*/
+              lag = it4->first.second;
+              if (lag <= ti_y_kmax && lag >= ti_y_kmin)   /*Build the index for sparse matrix containing the jacobian : u*/
                 {
-                  var+=Size*t;
+                  var += Size*t;
                   NbNZRow[eq]++;
                   NbNZCol[var]++;
-#ifdef NEW_ALLOC
-                  first=mem_mngr.mxMalloc_NZE();
-#else
-                  first=(NonZeroElem*)mxMalloc(sizeof(NonZeroElem));
-#endif
-								  //mexPrintf("=> eq=%d var=%d lag=%d u=%d\n",eq,var, lag, it4->second+u_count_init*t);
-                  first->NZE_C_N=NULL;
-                  first->NZE_R_N=NULL;
-                  first->u_index=it4->second+u_count_init*t;
-                  first->r_index=eq;
-                  first->c_index=var;
-                  first->lag_index=lag;
-                  /*if(eq==0 && var==0)
-                    mexPrintf("alloc FNZE_R[0]=%x\n",first);*/
-                  if (FNZE_R[eq]==NULL)
-                    FNZE_R[eq]=first;
-                  if (FNZE_C[var]==NULL)
-                    FNZE_C[var]=first;
-                  if (temp_NZE_R[eq]!=NULL)
-                    temp_NZE_R[eq]->NZE_R_N=first;
-                  if (temp_NZE_C[var]!=NULL)
-                    temp_NZE_C[var]->NZE_C_N=first;
-                  temp_NZE_R[eq]=first;
-                  temp_NZE_C[var]=first;
-#ifdef PRINT_OUT
-                  mexPrintf("=> ");
-#endif
+                  first = mem_mngr.mxMalloc_NZE();
+                  //first->NZE_C_P = temp_NZE_C[var];
+                  first->NZE_C_N = NULL;
+                  first->NZE_R_N = NULL;
+                  first->u_index = it4->second+u_count_init*t;
+                  first->r_index = eq;
+                  first->c_index = var;
+                  first->lag_index = lag;
+                  if (FNZE_R[eq] == NULL)
+                    FNZE_R[eq] = first;
+                  if (FNZE_C[var] == NULL)
+                    FNZE_C[var] = first;
+                  if (temp_NZE_R[eq] != NULL)
+                    temp_NZE_R[eq]->NZE_R_N = first;
+                  if (temp_NZE_C[var] != NULL)
+                    temp_NZE_C[var]->NZE_C_N = first;
+                  temp_NZE_R[eq] = first;
+                  temp_NZE_C[var] = first;
+                  //Mapped_Array[make_pair(eq,var)]=first;
                 }
               else       /*Build the additive terms ooutside the simulation periods related to the first lags and the last leads...*/
                 {
-                	if(lag<ti_y_kmin)
-                	  {
-#ifdef PRINT_OUT
-                      mexPrintf("nn var=%d, Size=%d, t=%d, y_kmin=%d, y_kmax=%d\n", var, Size, t, y_kmin, y_kmax);
-                      mexPrintf("   tmp_b+=u[%d]*y[index_var[%d]]\n", it4->second+u_count_init*t, var+Size*(y_kmin+t));
-                      mexPrintf("   tmp_b+=u[%d](%f)*y[%d(%d)](f)\n", it4->second+u_count_init*t, u[it4->second+u_count_init*t], index_vara[var+Size*(y_kmin+t)],var+Size*(y_kmin+t)/*,y[index_vara[var+Size*(y_kmin+t)]]*/);
-                      mexEvalString("drawnow;");
-#endif
-                      tmp_b+=u[it4->second+u_count_init*t]*y[index_vara[var+Size*(y_kmin+t)]];
-                	  }
-									else
-									  {
-#ifdef PRINT_OUT
-									  	var -= Size;
-                      mexPrintf("nn var=%d, Size=%d, t=%d, y_kmin=%d, y_kmax=%d\n", var, Size, t, y_kmin, y_kmax);
-                      mexPrintf("   tmp_b+=u[%d]*y[index_var[%d]]\n", it4->second+u_count_init*t, var+Size*(y_kmin+t));
-                      mexPrintf("   tmp_b+=u[%d](%f)*y[%d(%d)](f)\n", it4->second+u_count_init*t, u[it4->second+u_count_init*t], index_vara[var+Size*(y_kmin+t)],var+Size*(y_kmin+t)/*,y[index_vara[var+Size*(y_kmin+t)]]*/);
-                      mexEvalString("drawnow;");
-#endif
-                      tmp_b+=u[it4->second+u_count_init*t]*y[index_vara[var+Size*(y_kmin+t)]];
+                  if (lag < ti_y_kmin)
+                    {
+                      tmp_b += u[it4->second+u_count_init*t]*y[index_vara[var+Size*(y_kmin+t)]];
+                    }
+                  else
+                    {
+                      tmp_b += u[it4->second+u_count_init*t]*y[index_vara[var+Size*(y_kmin+t)]];
 
-									  }
+                    }
                 }
             }
           else           /* ...and store it in the u vector*/
             {
-#ifdef PRINT_OUT
-              mexPrintf("");
-#endif
-              b[eq]=it4->second+u_count_init*t;
-              u[b[eq]]+=tmp_b;
+              b[eq] = it4->second+u_count_init*t;
+              u[b[eq]] += tmp_b;
               tmp_b = 0;
-              //mexPrintf("u[%d]=%f corr=%f\n",b[eq],u[b[eq]],tmp_b);
-#ifdef PRINT_OUT
-              mexPrintf("=> u[b[%d]=%d]=%f\n", eq, b[eq], u[b[eq]]);
-              mexEvalString("drawnow;");
-#endif
             }
-#ifdef PRINT_OUT
-          mexPrintf(" u[%d] = %e\n",it4->second+u_count_init*t,double(u[it4->second+u_count_init*t]));
-          mexEvalString("drawnow;");
-#endif
           it4++;
         }
     }
-#ifdef PRINT_OUT
-  mexPrintf("end of Init\n");
-  mexEvalString("drawnow;");
-#endif
   mxFree(temp_NZE_R);
   mxFree(temp_NZE_C);
 }
 
-void SparseMatrix::ShortInit(int periods, int y_kmin, int y_kmax, int Size, std::map<std::pair<std::pair<int, int> ,int>, int> &IM)
+void
+SparseMatrix::ShortInit(int periods, int y_kmin, int y_kmax, int Size, map<pair<pair<int, int>, int>, int> &IM)
 {
   int t, eq, var, lag, ti_y_kmin, ti_y_kmax;
-  double tmp_b=0.0;
-  std::map<std::pair<std::pair<int, int> ,int>, int>::iterator it4;
+  double tmp_b = 0.0;
+  map<pair<pair<int, int>, int>, int>::iterator it4;
   //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) ordered private(it4, ti_y_kmin, ti_y_kmax, eq, var, lag, tmp_b) schedule(dynamic)
-  for (t=0;t<periods;t++)
+  for (t = 0; t < periods; t++)
     {
-#ifdef PRINT_OUT
-      mexPrintf("t=%d\n",t);
-#endif
-      ti_y_kmin=-min( t            , y_kmin);
-      ti_y_kmax= min( periods-(t+1), y_kmax);
-      it4=IM.begin();
-      eq=-1;
-      while (it4!=IM.end())
+      ti_y_kmin = -min(t, y_kmin);
+      ti_y_kmax = min(periods-(t+1), y_kmax);
+      it4 = IM.begin();
+      eq = -1;
+      while (it4 != IM.end())
         {
-          var=it4->first.first.second;
-          if (eq!=it4->first.first.first+Size*t)
-            tmp_b=0;
-          eq=it4->first.first.first+Size*t;
-#ifdef PRINT_OUT
-          mexPrintf("eq=%d, var=%d",eq,var);
-#endif
-          if (var<(periods+y_kmax)*Size)
+          var = it4->first.first.second;
+          if (eq != it4->first.first.first+Size*t)
+            tmp_b = 0;
+          eq = it4->first.first.first+Size*t;
+          if (var < (periods+y_kmax)*Size)
             {
-              lag=it4->first.second;
-#ifdef PRINT_OUT
-              mexPrintf(", lag =%d, ti_y_kmin=%d, ti_y_kmax=%d ", lag, ti_y_kmin, ti_y_kmax);
-#endif
-              if (lag<=ti_y_kmax && lag>=ti_y_kmin)
+              lag = it4->first.second;
+              if (lag <= ti_y_kmax && lag >= ti_y_kmin)
                 {
-                  var+=Size*t;
+                  var += Size*t;
                 }
               else
                 {
-#ifdef PRINT_OUT
-                  mexPrintf("nn ");
-                  mexPrintf("tmp_b+=u[%d]*y[index_var[%d]]\n",it4->second+u_count_init*t,var+Size*(y_kmin+t));
-                  mexPrintf("tmp_b+=u[%d](%f)*y[%d(%d)](%f)",it4->second+u_count_init*t,u[it4->second+u_count_init*t], index_vara[var+Size*(y_kmin+t)],var+Size*(y_kmin+t),y[index_vara[var+Size*(y_kmin+t)]]);
-#endif
-                  tmp_b+=u[it4->second+u_count_init*t]*y[index_vara[var+Size*(y_kmin+t)]];
+                  tmp_b += u[it4->second+u_count_init*t]*y[index_vara[var+Size*(y_kmin+t)]];
                 }
             }
           else
             {
-#ifdef PRINT_OUT
-              mexPrintf("");
-#endif
-              b[eq]=it4->second+u_count_init*t;
-              u[b[eq]]+=tmp_b;
-              //mexPrintf("u[%d]=%f\n",b[eq],u[b[eq]]);
-#ifdef PRINT_OUT
-              mexPrintf("=> b[%d]=%f\n", eq, u[b[eq]]);
-#endif
+              b[eq] = it4->second+u_count_init*t;
+              u[b[eq]] += tmp_b;
             }
-#ifdef PRINT_OUT
-          mexPrintf(" u[%d] = %e\n",it4->second+u_count_init*t,double(u[it4->second+u_count_init*t]));
-#endif
           it4++;
         }
     }
 }
 
-
-
-int SparseMatrix::Get_u()
+int
+SparseMatrix::Get_u()
 {
   if (!u_liste.empty())
     {
-      int i=u_liste.back();
+      int i = u_liste.back();
       u_liste.pop_back();
-#ifdef PRINT_OUT
-      mexPrintf("Get_u=%d\n",i);
-#endif
       return i;
     }
   else
     {
-      if (u_count<u_count_alloc)
+      if (u_count < u_count_alloc)
         {
-          int i=u_count;
+          int i = u_count;
           u_count++;
-#ifdef PRINT_OUT
-          mexPrintf("Get_u=%d\n",i);
-#endif
           return i;
         }
       else
         {
-          u_count_alloc+=5*u_count_alloc_save;
-#ifdef MEM_ALLOC_CHK
-          mexPrintf("u=(double*)mxRealloc(u,%d*sizeof(double))\n",u_count_alloc);
-#endif
-          u=(double*)mxRealloc(u,u_count_alloc*sizeof(double));
-#ifdef MEM_ALLOC_CHK
-          mexPrintf("ok\n");
-#endif
+          u_count_alloc += 5*u_count_alloc_save;
+          u = (double *) mxRealloc(u, u_count_alloc*sizeof(double));
           if (!u)
             {
-              mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n",u_count_alloc*sizeof(double));
+              mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n", u_count_alloc*sizeof(double));
               mexEvalString("st=fclose('all');clear all;");
               mexErrMsgTxt("Exit from Dynare");
             }
-          int i=u_count;
+          int i = u_count;
           u_count++;
           return i;
         }
     }
 }
 
-void SparseMatrix::Delete_u(int pos)
+void
+SparseMatrix::Delete_u(int pos)
 {
-#ifdef PRINT_OUT
-  mexPrintf("Delete_u=%d\n",pos);
-#endif
   u_liste.push_back(pos);
-
 }
 
-void SparseMatrix::Clear_u()
+void
+SparseMatrix::Clear_u()
 {
   u_liste.clear();
 }
 
-void SparseMatrix::Print_u()
+void
+SparseMatrix::Print_u()
 {
-  for (unsigned int i=0;i<u_liste.size();i++)
-    mexPrintf("%d ",u_liste[i]);
+  for (unsigned int i = 0; i < u_liste.size(); i++)
+    mexPrintf("%d ", u_liste[i]);
 }
 
-void SparseMatrix::End(int Size)
+void
+SparseMatrix::End(int Size)
 {
-#ifdef NEW_ALLOC
   mem_mngr.Free_All();
-#else
-  for (int i=0;i<Size*periods;i++)
-    {
-      NonZeroElem *first=FNZE_R[i];
-      while (!first)
-        {
-          NonZeroElem *firsta=first->NZE_R_N;
-          mxFree(first);
-          first=firsta;
-        }
-    }
-#endif
   mxFree(FNZE_R);
   mxFree(FNZE_C);
   mxFree(NbNZRow);
@@ -937,175 +693,151 @@ void SparseMatrix::End(int Size)
 }
 
 bool
-SparseMatrix::compare( int *save_op, int *save_opa, int *save_opaa, int beg_t, int periods, long int nop4,  int Size
-#ifdef PROFILER
-, long int *ndiv, long int *nsub
-#endif
-)
+SparseMatrix::compare(int *save_op, int *save_opa, int *save_opaa, int beg_t, int periods, long int nop4,  int Size)
 {
-  long int i,j,nop=nop4/2, t, index_d, k;
-  double r=0.0;
-  bool OK=true;
+  long int i, j, nop = nop4/2, t, k;
+  double r = 0.0;
+  bool OK = true;
+  clock_t t001;
   t_save_op_s *save_op_s, *save_opa_s, *save_opaa_s;
   int *diff1, *diff2;
-  diff1=(int*)mxMalloc(nop*sizeof(int));
-  diff2=(int*)mxMalloc(nop*sizeof(int));
-  int max_save_ops_first=-1;
-  j=k=i=0;
-  while (i<nop4 && OK)
+  t001 = clock();
+  diff1 = (int *) mxMalloc(nop*sizeof(int));
+  diff2 = (int *) mxMalloc(nop*sizeof(int));
+  int max_save_ops_first = -1;
+  j = k = i = 0;
+  while (i < nop4 && OK)
     {
-      save_op_s=(t_save_op_s*)&(save_op[i]);
-      save_opa_s=(t_save_op_s*)&(save_opa[i]);
-      save_opaa_s=(t_save_op_s*)&(save_opaa[i]);
-      diff1[j]=save_op_s->first-save_opa_s->first;
-      if(max_save_ops_first<save_op_s->first+diff1[j]*(periods-beg_t))
+      save_op_s = (t_save_op_s *) &(save_op[i]);
+      save_opa_s = (t_save_op_s *) &(save_opa[i]);
+      save_opaa_s = (t_save_op_s *) &(save_opaa[i]);
+      diff1[j] = save_op_s->first-save_opa_s->first;
+      if (max_save_ops_first < save_op_s->first+diff1[j]*(periods-beg_t))
         {
-          max_save_ops_first=save_op_s->first+diff1[j]*(periods-beg_t);
+          max_save_ops_first = save_op_s->first+diff1[j]*(periods-beg_t);
         }
       switch (save_op_s->operat)
         {
-          case IFLD:
-          case IFDIV:
-            OK=(save_op_s->operat==save_opa_s->operat && save_opa_s->operat==save_opaa_s->operat
-                && diff1[j]==(save_opa_s->first-save_opaa_s->first));
-            i+=2;
-            break;
-          case IFLESS:
-          case IFSUB:
-            diff2[j]=save_op_s->second-save_opa_s->second;
-            OK=(save_op_s->operat==save_opa_s->operat && save_opa_s->operat==save_opaa_s->operat
-                && diff1[j]==(save_opa_s->first-save_opaa_s->first)
-                && diff2[j]==(save_opa_s->second-save_opaa_s->second));
-            i+=3;
-            break;
-          default:
-            mexPrintf("unknown operator = %d ",save_op_s->operat);
-            mexEvalString("st=fclose('all');clear all;");
-            filename+=" stopped";
-            mexErrMsgTxt(filename.c_str());
-            break;
+        case IFLD:
+        case IFDIV:
+          OK = (save_op_s->operat == save_opa_s->operat && save_opa_s->operat == save_opaa_s->operat
+                && diff1[j] == (save_opa_s->first-save_opaa_s->first));
+          i += 2;
+          break;
+        case IFLESS:
+        case IFSUB:
+          diff2[j] = save_op_s->second-save_opa_s->second;
+          OK = (save_op_s->operat == save_opa_s->operat && save_opa_s->operat == save_opaa_s->operat
+                && diff1[j] == (save_opa_s->first-save_opaa_s->first)
+                && diff2[j] == (save_opa_s->second-save_opaa_s->second));
+          i += 3;
+          break;
+        default:
+          mexPrintf("unknown operator = %d ", save_op_s->operat);
+          mexEvalString("st=fclose('all');clear all;");
+          filename += " stopped";
+          mexErrMsgTxt(filename.c_str());
+          break;
         }
       j++;
     }
+	//mexPrintf("beg_t=%d, periods=%d, j=%d OK=%d y_kmin=%d\n",beg_t, periods, j, OK, y_kmin);
   // the same pivot for all remaining periods
-  if (OK)
-    //#pragma omp parallel for  num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) ordered private(j) schedule(dynamic)
-    for (i=beg_t;i<periods;i++)
-      {
-        for (j=0;j<Size;j++)
-          {
-            ///#pragma omp ordered
-            pivot[i*Size+j]=pivot[(i-1)*Size+j]+Size;
-          }
-      }
   if (OK)
     {
-      if (max_save_ops_first>=u_count_alloc)
+      //#pragma omp parallel for  num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) ordered private(j) schedule(dynamic)
+      for (i = beg_t; i < periods; i++)
+        {
+          for (j = 0; j < Size; j++)
+            {
+              ///#pragma omp ordered
+              pivot[i*Size+j] = pivot[(i-1)*Size+j]+Size;
+            }
+        }
+      if (max_save_ops_first >= u_count_alloc)
         {
-          u_count_alloc+=5*u_count_alloc_save;
-          u=(double*)mxRealloc(u,u_count_alloc*sizeof(double));
+          u_count_alloc += max_save_ops_first;
+          u = (double *) mxRealloc(u, u_count_alloc*sizeof(double));
           if (!u)
             {
-              mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n",u_count_alloc*sizeof(double));
+              mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n", u_count_alloc*sizeof(double));
               mexEvalString("st=fclose('all');clear all;");
               mexErrMsgTxt("Exit from Dynare");
             }
-          }
-      for (t=1;t<periods-beg_t-y_kmax/*max(y_kmax,y_kmin)*/;t++)
+        }
+      double *up;
+      for (t = 1; t < periods-beg_t-y_kmax; t++)
         {
-          i=j=0;
-          while (i<nop4)
+          i = j = 0;
+          while (i < nop4)
             {
-              save_op_s=(t_save_op_s*)(&(save_op[i]));
-              index_d=save_op_s->first+t*diff1[j];
-              if (index_d>u_count_alloc)
-                {
-                  u_count_alloc+=2*u_count_alloc_save;
-                  u=(double*)mxRealloc(u,u_count_alloc*sizeof(double));
-                  if (!u)
-                    {
-                      mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n",u_count_alloc*sizeof(double));
-                      mexEvalString("st=fclose('all');clear all;");
-                      mexErrMsgTxt("Exit from Dynare");
-                    }
-                }
+              save_op_s = (t_save_op_s *) (&(save_op[i]));
+              up = &u[save_op_s->first+t*diff1[j]];
               switch (save_op_s->operat)
                 {
-                  case IFLD  :
-                    r=u[index_d];
-                    i+=2;
-                    break;
-                  case IFDIV :
-                    u[index_d]/=r;
-                    i+=2;
-                    break;
-                  case IFSUB :
-                    u[index_d]-=u[save_op_s->second+t*diff2[j]]*r;
-                    i+=3;
-                    break;
-                  case IFLESS:
-                    u[index_d]=-u[save_op_s->second+t*diff2[j]]*r;
-                    i+=3;
-                    break;
+                case IFLD:
+                  r = *up;
+                  i += 2;
+                  break;
+                case IFDIV:
+                  *up /= r;
+                  i += 2;
+                  break;
+                case IFSUB:
+                  *up -= u[save_op_s->second+t*diff2[j]]*r;;
+                  i += 3;
+                  break;
+                case IFLESS:
+                  *up = -u[save_op_s->second+t*diff2[j]]*r;
+                  i += 3;
+                  break;
                 }
               j++;
             }
         }
-      int t1=max(1,periods-beg_t-y_kmax);
-      //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) ordered private(t, i,j, save_op_s, index_d, r) schedule(dynamic)
-      for (t=t1;t<periods-beg_t;t++)
+      int t1 = max(1, periods-beg_t-y_kmax);
+      int periods_beg_t = periods-beg_t;
+      for (t = t1; t < periods_beg_t; t++)
         {
-          i=j=0;
-          //#pragma omp ordered
-          while (i<nop4)
+          i = j = 0;
+          while (i < nop4)
             {
-              save_op_s=(t_save_op_s*)(&(save_op[i]));
-              if (save_op_s->lag<((periods-beg_t)-t))
+              save_op_s = (t_save_op_s *) (&(save_op[i]));
+              if (save_op_s->lag < (periods_beg_t-t))
                 {
-                  index_d=save_op_s->first+t*diff1[j];
-                  if (index_d>u_count_alloc)
-                    {
-                      u_count_alloc+=2*u_count_alloc_save;
-                      u=(double*)mxRealloc(u,u_count_alloc*sizeof(double));
-                      if (!u)
-                        {
-                          mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n",u_count_alloc*sizeof(double));
-                          mexEvalString("st=fclose('all');clear all;");
-                          mexErrMsgTxt("Exit from Dynare");
-                        }
-                    }
+                  up = &u[save_op_s->first+t*diff1[j]];
                   switch (save_op_s->operat)
                     {
-                      case IFLD  :
-                        r=u[index_d];
-                        i+=2;
-                        break;
-                      case IFDIV :
-                        u[index_d]/=r;
-                        i+=2;
-                        break;
-                      case IFSUB :
-                        u[index_d]-=u[save_op_s->second+t*diff2[j]]*r;
-                        i+=3;
-                        break;
-                      case IFLESS:
-                        u[index_d]=-u[save_op_s->second+t*diff2[j]]*r;
-                        i+=3;
-                        break;
+                    case IFLD:
+                      r = *up;
+                      i += 2;
+                      break;
+                    case IFDIV:
+                      *up /= r;
+                      i += 2;
+                      break;
+                    case IFSUB:
+                      *up -= u[save_op_s->second+t*diff2[j]]*r;
+                      i += 3;
+                      break;
+                    case IFLESS:
+                      *up = -u[save_op_s->second+t*diff2[j]]*r;
+                      i += 3;
+                      break;
                     }
                 }
               else
                 {
                   switch (save_op_s->operat)
                     {
-                      case IFLD  :
-                      case IFDIV :
-                        i+=2;
-                        break;
-                      case IFSUB :
-                      case IFLESS :
-                        i+=3;
-                        break;
+                    case IFLD:
+                    case IFDIV:
+                      i += 2;
+                      break;
+                    case IFSUB:
+                    case IFLESS:
+                      i += 3;
+                      break;
                     }
                 }
               j++;
@@ -1117,152 +849,6 @@ SparseMatrix::compare( int *save_op, int *save_opa, int *save_opaa, int beg_t, i
   return OK;
 }
 
-void
-SparseMatrix::run_u_period1(int periods)
-{
-  double r=0;
-  int index_d, t;
-  for (t=0;t<periods;t++)
-    {
-      for (long int i=0;i<g_nop_all;)
-        {
-          index_d=g_save_op[i+1]+t*g_save_op[i+2];
-          if (index_d>=u_count_alloc)
-            {
-              u_count_alloc+=5*u_count_alloc_save;
-#ifdef MEM_ALLOC_CHK
-              mexPrintf("u=(double*)mxRealloc(u,u_count_alloc*sizeof(double))\n",u_count_alloc);
-#endif
-              u=(double*)mxRealloc(u,u_count_alloc*sizeof(double));
-#ifdef MEM_ALLOC_CHK
-              mexPrintf("ok\n");
-#endif
-              if (!u)
-                {
-                  mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n",u_count_alloc*sizeof(double));
-                  mexEvalString("st=fclose('all');clear all;");
-                  mexErrMsgTxt("Exit from Dynare");
-                }
-            }
-          switch (g_save_op[i])
-            {
-              case IFLD  :
-                r=u[index_d];
-#ifdef PRINT_u
-                mexPrintf("FLD u[%d] (%f)\n",index_d,u[index_d]);
-#endif
-                break;
-              case IFDIV :
-                u[index_d]/=r;
-#ifdef PRINT_u
-                mexPrintf("FDIV u[%d](%f)/=r(%f)=(%f)\n",index_d,u[index_d],r,u[index_d]);
-#endif
-                break;
-              case IFSUB :
-                u[index_d]-=u[g_save_op[i+3]+t*g_save_op[i+4]]*r;
-#ifdef PRINT_u
-                mexPrintf("FSUB u[%d]-=u[%d](%f)*r(%f)=(%f) index1=%d index2=%d\n",index_d,g_save_op[i+3]+t*g_save_op[i+4],u[g_save_op[i+3]+t*g_save_op[i+4]],r,u[index_d],g_save_op[i+1],g_save_op[i+2] );
-#endif
-                break;
-              case IFLESS:
-                u[index_d]=-u[g_save_op[i+3]+t*g_save_op[i+4]]*r;
-#ifdef PRINT_u
-                mexPrintf("FLESS u[%d]=-u[%d](%f)*r(%f)=(%f) index1=%d index2=%d\n",index_d,g_save_op[i+3]+t*g_save_op[i+4],u[g_save_op[i+3]+t*g_save_op[i+4]],r,u[index_d],g_save_op[i+1],g_save_op[i+2] );
-#endif
-                break;
-            }
-          i+=5;
-        }
-    }
-}
-
-
-
-
-void
-SparseMatrix::run_it(int nop_all,int *op_all)
-{
-  double r=0;
-  int index_d;
-  for (long int i=0;i<nop_all;)
-    {
-      index_d=op_all[i+1];
-      if (index_d>=u_count_alloc)
-        {
-          u_count_alloc+=5*u_count_alloc_save;
-#ifdef MEM_ALLOC_CHK
-          mexPrintf("u=(double*)mxRealloc(u,u_count_alloc*sizeof(double))\n",u_count_alloc);
-#endif
-          u=(double*)mxRealloc(u,u_count_alloc*sizeof(double));
-#ifdef MEM_ALLOC_CHK
-          mexPrintf("ok\n");
-#endif
-          if (!u)
-            {
-              mexPrintf("Error in Get_u: memory exhausted (realloc(%d))\n",u_count_alloc*sizeof(double));
-              mexEvalString("st=fclose('all');clear all;");
-              mexErrMsgTxt("Exit from Dynare");
-            }
-        }
-      switch (op_all[i])
-        {
-          case IFLD  :
-            r=u[index_d];
-#ifdef PRINT_u
-            mexPrintf("FLD u[%d] (%f)\n",index_d,u[index_d]);
-#endif
-            i+=2;
-            break;
-          case IFDIV :
-            u[index_d]/=r;
-#ifdef PRINT_u
-            mexPrintf("FDIV u[%d](%f)/=r(%f)=(%f)\n",index_d,u[index_d],r,u[index_d]);
-#endif
-            i+=2;
-            break;
-          case IFSUB :
-            u[index_d]-=u[op_all[i+2]]*r;
-#ifdef PRINT_u
-            mexPrintf("FSUB u[%d]-=u[%d](%f)*r(%f)=(%f)\n",index_d,op_all[i+2],u[op_all[i+2]],r,u[index_d]);
-#endif
-            i+=3;
-            break;
-          case IFLESS:
-            u[index_d]=-u[op_all[i+2]]*r;
-#ifdef PRINT_u
-            mexPrintf("FLESS u[%d]=-u[%d](%f)*r(%f)=(%f)\n",index_d,op_all[i+2],u[op_all[i+2]],r,u[index_d]);
-#endif
-            i+=3;
-            break;
-        }
-    }
-}
-
-
-void
-SparseMatrix::run_triangular(int nop_all,int *op_all)
-{
-  int j=0;
-  //mexPrintf("begining of run_triangular nop_all=%d\n",nop_all);
-  if (mem_mngr.swp_f)
-    {
-      bool OK=true;
-      int* save_op;
-      long int nop;
-      while (OK)
-        {
-          mexPrintf("reading blck%d\n",j++);
-          OK=mem_mngr.read_swp_f(&save_op,&nop);
-          if (OK)
-            {
-              run_it(nop,save_op);
-              mxFree(save_op);
-            }
-        }
-    }
-  run_it(nop_all,op_all);
-}
-
 int
 SparseMatrix::complete(int beg_t, int Size, int periods, int *b)
 {
@@ -1270,153 +856,133 @@ SparseMatrix::complete(int beg_t, int Size, int periods, int *b)
   NonZeroElem *first;
   int *save_code;
   int *diff;
-  double yy=0.0, err;
+  double yy = 0.0, err;
 
-  int size_of_save_code=(1+y_kmax)*Size*(Size+1+4)/2*4;
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("save_code=(int*)mxMalloc(%d*sizeof(int))\n",size_of_save_code);
-#endif
-  save_code=(int*)mxMalloc(size_of_save_code*sizeof(int));
-  int size_of_diff=(1+y_kmax)*Size*(Size+1+4);
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("diff=(int*)mxMalloc(%d*sizeof(int))\n",size_of_diff);
-#endif
-  diff=(int*)mxMalloc(size_of_diff*sizeof(int));
-#ifdef MEM_ALLOC_CHK
-  mexPrintf("ok\n");
-#endif
-  cal_y=y_size*y_kmin;
+  int size_of_save_code = (1+y_kmax)*Size*(Size+1+4)/2*4;
+  save_code = (int *) mxMalloc(size_of_save_code*sizeof(int));
+  int size_of_diff = (1+y_kmax)*Size*(Size+1+4);
+  diff = (int *) mxMalloc(size_of_diff*sizeof(int));
+  cal_y = y_size*y_kmin;
 
-  i=(beg_t+1)*Size-1;
-  nop=0;
-  for (j=i;j>i-Size;j--)
+  i = (beg_t+1)*Size-1;
+  nop = 0;
+  for (j = i; j > i-Size; j--)
     {
-      pos=pivot[j];
-      nb_var=At_Row(pos,&first);
-      first=first->NZE_R_N;
+      pos = pivot[j];
+      nb_var = At_Row(pos, &first);
+      first = first->NZE_R_N;
       nb_var--;
-      save_code[nop]=IFLDZ;
-      save_code[nop+1]=0;
-      save_code[nop+2]=0;
-      save_code[nop+3]=0;
-      if ((nop+3)>=size_of_save_code)
-        mexPrintf("out of save_code[%d] (bound=%d)\n",nop+2,size_of_save_code);
-      nop+=4;
-      for (k=0;k<nb_var;k++)
+      save_code[nop] = IFLDZ;
+      save_code[nop+1] = 0;
+      save_code[nop+2] = 0;
+      save_code[nop+3] = 0;
+      if ((nop+3) >= size_of_save_code)
+        mexPrintf("out of save_code[%d] (bound=%d)\n", nop+2, size_of_save_code);
+      nop += 4;
+      for (k = 0; k < nb_var; k++)
         {
-          save_code[nop]=IFMUL;
-          save_code[nop+1]=index_vara[first->c_index]+cal_y;
-          save_code[nop+2]=first->u_index;
-          save_code[nop+3]=first->lag_index;
-          if ((nop+3)>=size_of_save_code)
-            mexPrintf("out of save_code[%d] (bound=%d)\n",nop+2,size_of_save_code);
-          nop+=4;
-          first=first->NZE_R_N;
+          save_code[nop] = IFMUL;
+          save_code[nop+1] = index_vara[first->c_index]+cal_y;
+          save_code[nop+2] = first->u_index;
+          save_code[nop+3] = first->lag_index;
+          if ((nop+3) >= size_of_save_code)
+            mexPrintf("out of save_code[%d] (bound=%d)\n", nop+2, size_of_save_code);
+          nop += 4;
+          first = first->NZE_R_N;
         }
-      //yy=-(yy+u[b[pos]]);
-      //mexPrintf("|u[%d]|\n",b[pos]);
-      save_code[nop]=IFADD;
-      save_code[nop+1]=b[pos];
-      save_code[nop+2]=0;
-      save_code[nop+3]=0;
-      if ((nop+3)>=size_of_save_code)
-        mexPrintf("out of save_code[%d] (bound=%d)\n",nop+2,size_of_save_code);
-      nop+=4;
-      save_code[nop]=IFSTP;
-      save_code[nop+1]=index_vara[j]+y_size*y_kmin;
-      save_code[nop+2]=0;
-      save_code[nop+3]=0;
-      if ((nop+2)>=size_of_save_code)
-        mexPrintf("out of save_code[%d] (bound=%d)\n",nop+2,size_of_save_code);
-      nop+=4;
+      save_code[nop] = IFADD;
+      save_code[nop+1] = b[pos];
+      save_code[nop+2] = 0;
+      save_code[nop+3] = 0;
+      if ((nop+3) >= size_of_save_code)
+        mexPrintf("out of save_code[%d] (bound=%d)\n", nop+2, size_of_save_code);
+      nop += 4;
+      save_code[nop] = IFSTP;
+      save_code[nop+1] = index_vara[j]+y_size*y_kmin;
+      save_code[nop+2] = 0;
+      save_code[nop+3] = 0;
+      if ((nop+2) >= size_of_save_code)
+        mexPrintf("out of save_code[%d] (bound=%d)\n", nop+2, size_of_save_code);
+      nop += 4;
     }
-  i=beg_t*Size-1;
-  nop1=nopa=0;
-  for (j=i;j>i-Size;j--)
+  i = beg_t*Size-1;
+  nop1 = nopa = 0;
+  for (j = i; j > i-Size; j--)
     {
-      pos=pivot[j];
-      nb_var=At_Row(pos,&first);
-      first=first->NZE_R_N;
+      pos = pivot[j];
+      nb_var = At_Row(pos, &first);
+      first = first->NZE_R_N;
       nb_var--;
-      diff[nopa]=0;
-      diff[nopa+1]=0;
-      nopa+=2;
-      nop1+=4;
-      for (k=0;k<nb_var;k++)
+      diff[nopa] = 0;
+      diff[nopa+1] = 0;
+      nopa += 2;
+      nop1 += 4;
+      for (k = 0; k < nb_var; k++)
         {
-          diff[nopa]=save_code[nop1+1]-(index_vara[first->c_index]+cal_y);
-          diff[nopa+1]=save_code[nop1+2]-(first->u_index);
-          if ((nop1+2)>=size_of_save_code)
-            mexPrintf("out of save_code[%d] (bound=%d)\n",nop1+2,size_of_save_code);
-          if ((nopa+1)>=size_of_diff)
-            mexPrintf("out of diff[%d] (bound=%d)\n",nopa+2,size_of_diff);
-          nopa+=2;
-          nop1+=4;
-          first=first->NZE_R_N;
+          diff[nopa] = save_code[nop1+1]-(index_vara[first->c_index]+cal_y);
+          diff[nopa+1] = save_code[nop1+2]-(first->u_index);
+          if ((nop1+2) >= size_of_save_code)
+            mexPrintf("out of save_code[%d] (bound=%d)\n", nop1+2, size_of_save_code);
+          if ((nopa+1) >= size_of_diff)
+            mexPrintf("out of diff[%d] (bound=%d)\n", nopa+2, size_of_diff);
+          nopa += 2;
+          nop1 += 4;
+          first = first->NZE_R_N;
         }
-      diff[nopa]=save_code[nop1+1]-(b[pos]);
-      diff[nopa+1]=0;
-      if ((nop1+3)>=size_of_save_code)
-        mexPrintf("out of save_code[%d] (bound=%d)\n",nop1+2,size_of_save_code);
-      if ((nopa+1)>=size_of_diff)
-        mexPrintf("out of diff[%d] (bound=%d)\n",nopa+2,size_of_diff);
-      nopa+=2;
-      nop1+=4;
-      diff[nopa]=save_code[nop1+1]-(index_vara[j]+y_size*y_kmin);
-      diff[nopa+1]=0;
-      if ((nop1+4)>=size_of_save_code)
-        mexPrintf("out of save_code[%d] (bound=%d)\n",nop1+2,size_of_save_code);
-      if ((nopa+1)>=size_of_diff)
-        mexPrintf("out of diff[%d] (bound=%d)\n",nopa+2,size_of_diff);
-      nopa+=2;
-      nop1+=4;
+      diff[nopa] = save_code[nop1+1]-(b[pos]);
+      diff[nopa+1] = 0;
+      if ((nop1+3) >= size_of_save_code)
+        mexPrintf("out of save_code[%d] (bound=%d)\n", nop1+2, size_of_save_code);
+      if ((nopa+1) >= size_of_diff)
+        mexPrintf("out of diff[%d] (bound=%d)\n", nopa+2, size_of_diff);
+      nopa += 2;
+      nop1 += 4;
+      diff[nopa] = save_code[nop1+1]-(index_vara[j]+y_size*y_kmin);
+      diff[nopa+1] = 0;
+      if ((nop1+4) >= size_of_save_code)
+        mexPrintf("out of save_code[%d] (bound=%d)\n", nop1+2, size_of_save_code);
+      if ((nopa+1) >= size_of_diff)
+        mexPrintf("out of diff[%d] (bound=%d)\n", nopa+2, size_of_diff);
+      nopa += 2;
+      nop1 += 4;
     }
-  max_var=(periods+y_kmin)*y_size;
-  min_var=y_kmin*y_size;
-  int k1=0;
-  for (t=periods+y_kmin-1;t>=beg_t+y_kmin;t--)
+  max_var = (periods+y_kmin)*y_size;
+  min_var = y_kmin*y_size;
+  int k1 = 0;
+  for (t = periods+y_kmin-1; t >= beg_t+y_kmin; t--)
     {
-      j=0;
-      ti=t-y_kmin-beg_t;
-      for (i=0;i<nop;i+=4)
+      j = 0;
+      ti = t-y_kmin-beg_t;
+      for (i = 0; i < nop; i += 4)
         {
           switch (save_code[i])
             {
-              case IFLDZ :
-                yy=0;
-                break;
-              case IFMUL :
-                k=save_code[i+1]+ti*diff[j];
-                if (k<max_var && k>min_var)
-                  {
-                    yy+=y[k]*u[save_code[i+2]+ti*diff[j+1]];
-#ifdef PRINT_OUT_y1
-                    mexPrintf("y[%d](%f)*u[%d](%f)+",k, double(y[k]), save_code[i+2]+ti*diff[j+1], double(u[save_code[i+2]+ti*diff[j+1]]));
-#endif
-                  }
-                break;
-              case IFADD :
-                yy=-(yy+u[save_code[i+1]+ti*diff[j]]);
-#ifdef PRINT_OUT_y1
-                mexPrintf("|u[%d](%f)|",save_code[i+1]+ti*diff[j],double(u[save_code[i+1]+ti*diff[j]]));
-#endif
-                break;
-              case IFSTP :
-                k=save_code[i+1]+ti*diff[j];
-                k1=k;
-                err = yy - y[k];
-                y[k] += slowc*(err);
-#ifdef PRINT_OUT_y1
-                mexPrintf("=y[%d]=%f  diff[%d]=%d save_code[%d]=%d ti=%d\n",save_code[i+1]+ti*diff[j],y[k],j,diff[j],i+1,save_code[i+1],ti);
-#endif
-                break;
+            case IFLDZ:
+              yy = 0;
+              break;
+            case IFMUL:
+              k = save_code[i+1]+ti*diff[j];
+              if (k < max_var && k > min_var)
+                {
+                  yy += y[k]*u[save_code[i+2]+ti*diff[j+1]];
+                }
+              break;
+            case IFADD:
+              yy = -(yy+u[save_code[i+1]+ti*diff[j]]);
+              break;
+            case IFSTP:
+              k = save_code[i+1]+ti*diff[j];
+              k1 = k;
+              err = yy - y[k];
+              y[k] += slowc*(err);
+              break;
             }
-          j+=2;
+          j += 2;
         }
     }
   mxFree(save_code);
   mxFree(diff);
-  return(beg_t);
+  return (beg_t);
 }
 
 void
@@ -1425,1781 +991,1069 @@ SparseMatrix::close_swp_file()
   mem_mngr.close_swp_f();
 }
 
-
-
-
-
-
-
-
-
-
 double
-SparseMatrix::bksub( int tbreak, int last_period, int Size, double slowc_l
-#ifdef PROFILER
-, /*NonZeroElem *first,*/ long int *nmul
-#endif
-)
+SparseMatrix::bksub(int tbreak, int last_period, int Size, double slowc_l)
 {
   NonZeroElem *first;
   int i, j, k;
   double yy;
   res1 = res2 = max_res = 0;
-  for (i=0;i<y_size*(periods+y_kmin);i++)
-    y[i]=ya[i];
+  for (i = 0; i < y_size*(periods+y_kmin); i++)
+    y[i] = ya[i];
   if (symbolic && tbreak)
-    last_period=complete(tbreak, Size, periods, b);
+    last_period = complete(tbreak, Size, periods, b);
   else
-    last_period=periods;
-  for (int t=last_period+y_kmin-1;t>=y_kmin;t--)
+    last_period = periods;
+  for (int t = last_period+y_kmin-1; t >= y_kmin; t--)
     {
-      int ti=(t-y_kmin)*Size;
-#ifdef PRINT_OUT
-      mexPrintf("t=%d ti=%d\n",t,ti);
-#endif
-      int cal=y_kmin*Size;
-      int cal_y=y_size*y_kmin;
-      for (i=ti-1;i>=ti-Size;i--)
+      int ti = (t-y_kmin)*Size;
+      int cal = y_kmin*Size;
+      int cal_y = y_size*y_kmin;
+      for (i = ti-1; i >= ti-Size; i--)
         {
-          j=i+cal;
-#ifdef PRINT_OUT_y
-          mexPrintf("t=%d, ti=%d j=%d i+Size=%d\n",t,ti,j,i+Size);
-#endif
-          int pos=pivot[/*j*/i+Size];
-#ifdef PRINT_OUT_y
-          mexPrintf("i-ti+Size=%d pos=%d j=%d\n",i-ti+Size,pos,j);
-#endif
-          int nb_var=At_Row(pos,&first);
-          first=first->NZE_R_N;
+          j = i+cal;
+          int pos = pivot[i+Size];
+          int nb_var = At_Row(pos, &first);
+          first = first->NZE_R_N;
           nb_var--;
-          int eq=index_vara[j]+y_size;
-#ifdef PRINT_OUT_y1
-          mexPrintf("y[index_vara[%d]=%d]=",j,index_vara[j]+y_size);
-#endif
-          yy=0;
-          for (k=0;k<nb_var;k++)
+          int eq = index_vara[j]+y_size;
+          yy = 0;
+          ostringstream tmp_out;
+          tmp_out.clear();
+          for (k = 0; k < nb_var; k++)
             {
-              yy+=y[index_vara[first->c_index]+cal_y]*u[first->u_index];
-#ifdef PROFILER
-              (*nmul)++;
-#endif
-              first=first->NZE_R_N;
+              yy += y[index_vara[first->c_index]+cal_y]*u[first->u_index];
+              tmp_out << "y[" << index_vara[first->c_index]+cal_y << "]" << "(" << y[index_vara[first->c_index]+cal_y] << ")*u[" << first->u_index << "](" << u[first->u_index] << ")+";
+              first = first->NZE_R_N;
             }
-#ifdef PRINT_OUT_y1
-          mexPrintf("|u[%d](%f)|",b[pos],double(u[b[pos]]));
-#endif
-          yy=-(yy+y[eq]+u[b[pos]]);
-          direction[eq]=yy;
-          //mexPrintf("direction[%d] = %f\n",eq,yy);
+          yy = -(yy+y[eq]+u[b[pos]]);
+          direction[eq] = yy;
           y[eq] += slowc_l*yy;
-#ifdef PRINT_OUT_y1
-          mexPrintf("=%f (%f)\n",double(yy),double(y[eq]));
-#endif
         }
     }
   return res1;
 }
 
-
 double
 SparseMatrix::simple_bksub(int it_, int Size, double slowc_l)
 {
-  int i,k;
+  int i, k;
   double yy;
   NonZeroElem *first;
   res1 = res2 = max_res = 0;
-  //mexPrintf("simple_bksub\n");
-  for (i=0;i<y_size;i++)
-    y[i+it_*y_size]=ya[i+it_*y_size];
-  //mexPrintf("setp 1\n");
-  //mexPrintf("Size=%d\n",Size);
-  for(i=Size-1;i>=0;i--)
+  for (i = 0; i < y_size; i++)
+    y[i+it_*y_size] = ya[i+it_*y_size];
+  for (i = Size-1; i >= 0; i--)
     {
-      //mexPrintf("i=%d\n",i);
-      int pos=pivot[i];
-      //mexPrintf("pos=%d\n",pos);
-      int nb_var=At_Row(pos,&first);
-      //mexPrintf("nb_var=%d\n",nb_var);
-      first=first->NZE_R_N;
+      int pos = pivot[i];
+      int nb_var = At_Row(pos, &first);
+      first = first->NZE_R_N;
       nb_var--;
-      //mexPrintf("i=%d\n",i);
-      int eq=index_vara[i];
-      //mexPrintf("eq=%d\n",eq);
+      int eq = index_vara[i];
       yy = 0;
-      for (k=0;k<nb_var;k++)
+      ostringstream tmp_out;
+      tmp_out.clear();
+      tmp_out << "|";
+      for (k = 0; k < nb_var; k++)
         {
-          //mexPrintf("y[index_vara[%d]=%d]=%f\n",first->c_index, index_vara[first->c_index], y[index_vara[first->c_index]+it_*y_size]);
-          //mexPrintf("u[first->u_index=%d]=%f\n",first->u_index, u[first->u_index]);
-          yy+=y[index_vara[first->c_index]+it_*y_size]*u[first->u_index];
-          first=first->NZE_R_N;
+          yy += y[index_vara[first->c_index]+it_*y_size]*u[first->u_index];
+          tmp_out << "y[" << index_vara[first->c_index]+it_*y_size << "](" << y[index_vara[first->c_index]+it_*y_size] << ")*u[" << first->u_index << "](" << u[first->u_index] << ")+";
+          first = first->NZE_R_N;
         }
-      yy=-(yy+y[eq+it_*y_size]+u[b[pos]]);
-      //mexPrintf("yy=%f\n",yy);
-      direction[eq+it_*y_size]=yy;
+      yy = -(yy+y[eq+it_*y_size]+u[b[pos]]);
+      direction[eq+it_*y_size] = yy;
       y[eq+it_*y_size] += slowc_l*yy;
     }
   return res1;
 }
 
-
-int
-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
+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 i, j, k;
-  int pivj=0, pivk=0;
-  double piv_abs, first_elem;
-  NonZeroElem *first, *firsta, *first_sub, *first_piv, *first_suba;
-#ifdef MARKOVITZ
+  int pivj = 0, pivk = 0;
+  double piv_abs/*, first_elem*/;
+  NonZeroElem *first, *firsta, *first_suba;
   double piv_v[Size];
   int pivj_v[Size], pivk_v[Size], NR[Size], l, N_max;
   bool one;
-#endif
-#ifdef PROFILER
-  //long int ndiv=0, nsub=0, ncomp=0, nmul=0;
-  //double tinsert=0, tdelete=0, tpivot=0, tbigloop=0;
-  //clock_t td1;
-  int nbpivot=0, nbpivot_it=0;
-  //int nbdiv=0, nbless=0, nbRealloc=0, insert=0;
-#endif
-  /*mexPrintf("begining\n");
-  mexEvalString("drawnow;");*/
-  if (cvg)
-    return(0);
-  /*mexPrintf("begining after cvg Size=%d\n", Size);
-  mexEvalString("drawnow;");*/
-  Simple_Init(it_, y_kmin, y_kmax, Size, IM_i);
-  /*mexPrintf("begining after Simple_Init\n");
-  mexEvalString("drawnow;");*/
+  Clear_u();
+  error_not_printed = true;
+  u_count_alloc_save = u_count_alloc;
   if (isnan(res1) || isinf(res1))
     {
-      if (slowc_save<1e-8)
+      if (iter == 0)
         {
-          mexPrintf("slowc_save=%g\n", slowc_save);
-          mexPrintf("Dynare cannot improve the simulation in block %d at time %d\n", blck, it_);
+          for (j = 0; j < y_size; j++)
+            {
+            	bool select=false;
+              for(int i = 0; i<Size; i++)
+                if(j == index_vara[i])
+                  {
+                  	select=true;
+                  	break;
+                  }
+							if(select)
+                mexPrintf("-> variable %d at time %d = %f direction = %f\n", j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
+							else
+							  mexPrintf("   variable %d at time %d = %f direction = %f\n", j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
+            }
+					mexPrintf("res1=%5.25\n",res1);
+          mexPrintf("The initial values of endogenous variables are too far from the solution.\n");
+          mexPrintf("Change them!\n");
           mexEvalString("drawnow;");
-          mexEvalString("st=fclose('all');clear all;");
-          filename+=" stopped";
-          mexErrMsgTxt(filename.c_str());
+          if(steady_state)
+            return false;
+					else
+					  {
+              mexEvalString("st=fclose('all');clear all;");
+              filename += " stopped";
+              mexErrMsgTxt(filename.c_str());
+					  }
+        }
+      if (slowc_save < 1e-8)
+        {
+          for (j = 0; j < y_size; j++)
+            {
+              bool select=false;
+              for(int i = 0; i<Size; i++)
+                if(j == index_vara[i])
+                  {
+                  	select=true;
+                  	break;
+                  }
+							if(select)
+                mexPrintf("-> variable %d at time %d = %f direction = %f\n", j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
+							else
+							  mexPrintf("   variable %d at time %d = %f direction = %f\n", j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
+            }
+          mexPrintf("Dynare cannot improve the simulation in block %d at time %d (variable %d)\n", blck+1, it_+1, max_res_idx);
+          mexEvalString("drawnow;");
+          if(steady_state)
+            return false;
+					else
+					  {
+              mexEvalString("st=fclose('all');clear all;");
+              filename += " stopped";
+               mexErrMsgTxt(filename.c_str());
+					  }
         }
-      slowc_save/=2;
-      mexPrintf("Error: Simulation diverging, trying to correct it using slowc=%f\n",slowc_save);
-      for (i=0;i<y_size;i++)
-        y[i+it_*y_size]=ya[i+it_*y_size]+slowc_save*direction[i+it_*y_size];
+      slowc_save /= 2;
+      mexPrintf("Error: Simulation diverging, trying to correct it using slowc=%f\n", slowc_save);
+      for (i = 0; i < y_size; i++)
+        y[i+it_*y_size] = ya[i+it_*y_size] + slowc_save*direction[i+it_*y_size];
+      /*for (i = 0; i < y_size*(periods+y_kmin); i++)
+        y[i] = ya[i]+slowc_save*direction[i];*/
       iter--;
-      return(0);
+      return true;
     }
-  //mexPrintf("begining after nan\n");
-  //mexEvalString("drawnow;");
-  //mexPrintf("before the main loop y_size=%d\n",y_size);
-  for (i=0;i<Size;i++)
+  /*if (Size>1)
+    {
+      mexPrintf("-----------------------------------\n");
+      mexPrintf("      Simulate     iteration� %d     \n", iter+1);
+      mexPrintf("      max. error=%.10e       \n", double (max_res));
+      mexPrintf("      sqr. error=%.10e       \n", double (res2));
+      mexPrintf("      abs. error=%.10e       \n", double (res1));
+      mexPrintf("-----------------------------------\n");
+    }*/
+  if (cvg)
+    return (true);
+  Simple_Init(it_, y_kmin, y_kmax, Size, IM_i);
+  for (i = 0; i < Size; i++)
     {
-      //mexPrintf("i=%d\n",i);
-      //mexEvalString("drawnow;");
       /*finding the max-pivot*/
-      double piv=piv_abs=0;
-      //int nb_eq=At_Col(i, 0, &first);
-      int nb_eq=At_Col(i, &first);
-      //mexPrintf("nb_eq=%d\n",nb_eq);
-      //mexEvalString("drawnow;");
-#ifdef MARKOVITZ
-      l=0; N_max=0;
-      one=false;
-      piv_abs=0;
-#endif
-      for (j=0;j<nb_eq/*Size*/;j++)
+      double piv = piv_abs = 0;
+      int nb_eq = At_Col(i, &first);
+      l = 0; N_max = 0;
+      one = false;
+      piv_abs = 0;
+      for (j = 0; j < nb_eq; j++)
         {
-          //mexPrintf("j=%d \n",j);
-          //mexEvalString("drawnow;");
-          //mexPrintf("first->r_index=%d \n",first->r_index);
-          //mexPrintf("line_done[%d]=%d \n",first->r_index,line_done[first->r_index]);
-          //mexEvalString("drawnow;");
           if (!line_done[first->r_index])
             {
-              //mexPrintf("first->u_index=%d \n",first->u_index);
-              //mexEvalString("drawnow;");
-              k=first->u_index;
-              int jj=first->r_index;
-              int NRow_jj=NRow(jj);
-#ifdef PROFILER
-              nbpivot++;
-              nbpivot_it++;
-#endif
-
-#ifdef MARKOVITZ
-              piv_v[l]=u[k];
-              //mexPrintf("piv_v[%d]=%f\n",l, piv_v[l]);
-              //mexEvalString("drawnow;");
-              double piv_fabs=fabs(u[k]);
-              pivj_v[l]=jj;
-              pivk_v[l]=k;
-              NR[l]=NRow_jj;
-              if (NRow_jj==1 && !one)
+              k = first->u_index;
+              int jj = first->r_index;
+              int NRow_jj = NRow(jj);
+
+              piv_v[l] = u[k];
+              double piv_fabs = fabs(u[k]);
+              pivj_v[l] = jj;
+              pivk_v[l] = k;
+              NR[l] = NRow_jj;
+              if (NRow_jj == 1 && !one)
                 {
-                  one=true;
-                  piv_abs=piv_fabs;
-                  N_max=NRow_jj;
+                  one = true;
+                  piv_abs = piv_fabs;
+                  N_max = NRow_jj;
                 }
               if (!one)
                 {
-                  if (piv_fabs>piv_abs)
-                    piv_abs=piv_fabs;
-                  if (NRow_jj>N_max)
-                    N_max=NRow_jj;
+                  if (piv_fabs > piv_abs)
+                    piv_abs = piv_fabs;
+                  if (NRow_jj > N_max)
+                    N_max = NRow_jj;
                 }
               else
                 {
-                  if (NRow_jj==1)
+                  if (NRow_jj == 1)
                     {
-                      if (piv_fabs>piv_abs)
-                        piv_abs=piv_fabs;
-                      if (NRow_jj>N_max)
-                        N_max=NRow_jj;
+                      if (piv_fabs > piv_abs)
+                        piv_abs = piv_fabs;
+                      if (NRow_jj > N_max)
+                        N_max = NRow_jj;
                     }
                 }
               l++;
-#else
-              if (piv_abs<fabs(u[k])||NRow_jj==1)
-                {
-                  piv=u[k];
-                  piv_abs=fabs(piv);
-                  pivj=jj;   //Line number
-                  pivk=k;   //position in u
-                  if (NRow_jj==1)
-                  break;
-                }
-#endif
             }
-          first=first->NZE_C_N;
+          first = first->NZE_C_N;
         }
-      /*mexPrintf("pivot found piv_v[0]=%f pivk_v[0]=%d l=%d one=%d\n", piv_v[0], pivk_v[0], l, one);
-      mexEvalString("drawnow;");*/
-#ifdef MARKOVITZ
-      double markovitz=0, markovitz_max=-9e70;
+      double markovitz = 0, markovitz_max = -9e70;
       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 (markovitz>markovitz_max)
+              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;
+                  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++)
+          for (j = 0; j < l; j++)
             {
-              markovitz=exp(log(fabs(piv_v[j])/piv_abs)-markowitz_c*log(NR[j]/N_max));
-              //mexPrintf("j=%d markovitz=%f\n",j, markovitz);
-              if (markovitz>markovitz_max && NR[j]==1)
+              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;
-                  //mexPrintf("stored\n");
+                  piv = piv_v[j];
+                  pivj = pivj_v[j];   //Line number
+                  pivk = pivk_v[j];   //positi
+                  markovitz_max = markovitz;
                 }
             }
         }
-#endif
-      //mexPrintf("OK i=%d\n", i);
-      pivot[i]=pivj;
-      //mexPrintf("pivot[%d]=%d\n",i,pivot[i]);
-      pivotk[i]=pivk;
-      pivotv[i]=piv;
-      line_done[pivj]=true;
-      if (piv_abs<eps)
+      pivot[i] = pivj;
+      pivotk[i] = pivk;
+      pivotv[i] = piv;
+      line_done[pivj] = true;
+      if (piv_abs < eps)
         {
-          mexPrintf("Error: singular system in Simulate_NG\n");
+          mexPrintf("Error: singular system in Simulate_NG in block %d\n",blck+1);
           mexEvalString("drawnow;");
-          mexEvalString("st=fclose('all');clear all;");
-          filename+=" stopped";
-          mexErrMsgTxt(filename.c_str());
+          if(steady_state)
+            return false;
+					else
+					  {
+              mexEvalString("st=fclose('all');clear all;");
+              filename += " stopped";
+              mexErrMsgTxt(filename.c_str());
+					  }
         }
-      //mexPrintf("piv=%f\n",piv);
       /*divide all the non zeros elements of the line pivj by the max_pivot*/
-      int nb_var=At_Row(pivj,&first);
-      for (j=0;j<nb_var;j++)
+      int nb_var = At_Row(pivj, &first);
+      for (j = 0; j < nb_var; j++)
         {
-          u[first->u_index]/=piv;
-          first=first->NZE_R_N;
+          u[first->u_index] /= piv;
+          first = first->NZE_R_N;
         }
-      u[b[pivj]]/=piv;
+      u[b[pivj]] /= piv;
       /*substract the elements on the non treated lines*/
-      nb_eq=At_Col(i,&first);
+      nb_eq = At_Col(i, &first);
       NonZeroElem *first_piva;
-      int nb_var_piva=At_Row(pivj,&first_piva);
+      int nb_var_piva = At_Row(pivj, &first_piva);
+      NonZeroElem *bc[nb_eq];
+			int nb_eq_todo = 0;
+      for (j = 0; j < nb_eq && first; j++)
+				{
+          if (!line_done[first->r_index])
+            bc[nb_eq_todo++] = first;
+          first = first->NZE_C_N;
+				}
       //#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
-      for (j=0;j<Size /*and first*/;j++)
-        {
-        	if(first)
-        	{
-          int row=first->r_index;
-          //mexPrintf("j=%d row=%d line_done[row]=%d\n",j, row, line_done[row]);
-          if (!line_done[row])
+      for (j = 0; j < nb_eq_todo; j++)
+				{
+          //t_save_op_s *save_op_s_l;
+          //NonZeroElem *
+          first = bc[j];
+          int row = first->r_index;
+          double first_elem = u[first->u_index];
+
+          int nb_var_piv = nb_var_piva;
+          NonZeroElem *first_piv = first_piva;
+          NonZeroElem *first_sub;
+          int nb_var_sub = At_Row(row, &first_sub);
+          int l_sub = 0, l_piv = 0;
+          int sub_c_index = first_sub->c_index, piv_c_index = first_piv->c_index;
+          while (l_sub < nb_var_sub || l_piv < nb_var_piv)
             {
-              first_elem=u[first->u_index];
-              int nb_var_piv=nb_var_piva;
-              first_piv=first_piva;
-              int nb_var_sub=At_Row(row,&first_sub);
-              //mexPrintf("nb_var_sub=%d nb_var_piv=%d\n",nb_var_sub,nb_var_piv);
-              int l_sub=0, l_piv=0;
-              int sub_c_index=first_sub->c_index, piv_c_index=first_piv->c_index;
-              //int tmp_lag=first_sub->lag_index;
-              while (l_sub<nb_var_sub || l_piv<nb_var_piv)
+              if (l_sub < nb_var_sub && (sub_c_index < piv_c_index || l_piv >= nb_var_piv))
+                {
+                  first_sub = first_sub->NZE_R_N;
+                  if (first_sub)
+                    sub_c_index = first_sub->c_index;
+                  else
+                    sub_c_index = Size;
+                  l_sub++;
+                }
+              else if (sub_c_index > piv_c_index || l_sub >= nb_var_sub)
+                {
+                  int tmp_u_count = Get_u();
+                  Insert(row, first_piv->c_index, tmp_u_count, 0);
+                  u[tmp_u_count] = -u[first_piv->u_index]*first_elem;
+                  first_piv = first_piv->NZE_R_N;
+                  if (first_piv)
+                    piv_c_index = first_piv->c_index;
+                  else
+                    piv_c_index = Size;
+                  l_piv++;
+                }
+              else //first_sub->c_index==first_piv->c_index
                 {
-                  if (l_sub<nb_var_sub && (sub_c_index<piv_c_index || l_piv>=nb_var_piv))
+                  if (i == sub_c_index)
                     {
-                      first_sub=first_sub->NZE_R_N;
+                      firsta = first;
+                      first_suba = first_sub->NZE_R_N;
+                      Delete(first_sub->r_index, first_sub->c_index);
+                      first = firsta->NZE_C_N;
+                      first_sub = first_suba;
                       if (first_sub)
-                        sub_c_index=first_sub->c_index;
+                        sub_c_index = first_sub->c_index;
                       else
-                        sub_c_index=Size/* *periods*/;
+                        sub_c_index = Size;
                       l_sub++;
-                    }
-                  else if (sub_c_index>piv_c_index || l_sub>=nb_var_sub)
-                    {
-                      int tmp_u_count=Get_u();
-                      //int lag=first_piv->c_index/Size-row/Size;
-                      Insert(row,first_piv->c_index,tmp_u_count,/*lag*/0);
-                      u[tmp_u_count]=-u[first_piv->u_index]*first_elem;
-                      first_piv=first_piv->NZE_R_N;
+                      first_piv = first_piv->NZE_R_N;
                       if (first_piv)
-                        piv_c_index=first_piv->c_index;
+                        piv_c_index = first_piv->c_index;
                       else
-                        piv_c_index=Size/* *periods*/;
+                        piv_c_index = Size;
                       l_piv++;
                     }
-                  else /*first_sub->c_index==first_piv->c_index*/
+                  else
                     {
-                      if (i==sub_c_index)
-                        {
-                          firsta=first;
-                          first_suba=first_sub->NZE_R_N;
-                          Delete(first_sub->r_index,first_sub->c_index, Size);
-                          first=firsta->NZE_C_N;
-                          first_sub=first_suba;
-                          if (first_sub)
-                            sub_c_index=first_sub->c_index;
-                          else
-                            sub_c_index=Size/* *periods*/;
-                          l_sub++;
-                          first_piv=first_piv->NZE_R_N;
-                          if (first_piv)
-                            piv_c_index=first_piv->c_index;
-                          else
-                            piv_c_index=Size;
-                          l_piv++;
-                        }
+                      u[first_sub->u_index] -= u[first_piv->u_index]*first_elem;
+                      first_sub = first_sub->NZE_R_N;
+                      if (first_sub)
+                        sub_c_index = first_sub->c_index;
                       else
-                        {
-                          u[first_sub->u_index]-=u[first_piv->u_index]*first_elem;
-                          first_sub=first_sub->NZE_R_N;
-                          if (first_sub)
-                            sub_c_index=first_sub->c_index;
-                          else
-                            sub_c_index=Size /* *periods*/;
-                          l_sub++;
-                          first_piv=first_piv->NZE_R_N;
-                          if (first_piv)
-                            piv_c_index=first_piv->c_index;
-                          else
-                            piv_c_index=Size/* *periods*/;
-                          l_piv++;
-                        }
+                        sub_c_index = Size;
+                      l_sub++;
+                      first_piv = first_piv->NZE_R_N;
+                      if (first_piv)
+                        piv_c_index = first_piv->c_index;
+                      else
+                        piv_c_index = Size;
+                      l_piv++;
                     }
                 }
-              u[b[row]]-=u[b[pivj]]*first_elem;
             }
-          else
-            first=first->NZE_C_N;
-            /*first=first->NZE_R_N;*/
-        }
-        }
-    }
-  /*mexPrintf("before bcksub\n");
-  mexEvalString("drawnow;");*/
-  double slowc_lbx=slowc, res1bx;
-  //mexPrintf("before bksub it_=%d\n",it_);
-  for (i=0;i<y_size;i++)
-    ya[i+it_*y_size]=y[i+it_*y_size];
-  slowc_save=slowc;
-  //res1bx=bksub( NULL, 1, y_size, slowc_lbx);
-  res1bx=simple_bksub(it_,Size,slowc_lbx);
-  //mexPrintf("End of simulate_NG\n");
+          u[b[row]] -= u[b[pivj]]*first_elem;
+          first = first->NZE_C_N;
+				}
+		}
+  double slowc_lbx = slowc, res1bx;
+  for (i = 0; i < y_size; i++)
+    ya[i+it_*y_size] = y[i+it_*y_size];
+  slowc_save = slowc;
+  res1bx = simple_bksub(it_, Size, slowc_lbx);
   End(Size);
-  return(0);
+  return true;
 }
 
-
-
-
 void
 SparseMatrix::CheckIt(int y_size, int y_kmin, int y_kmax, int Size, int periods, int iter)
 {
-	const double epsilon=1e-7;
-	fstream SaveResult;
+  const double epsilon = 1e-7;
+  fstream SaveResult;
   ostringstream out;
   out << "Result" << iter;
-	SaveResult.open(out.str().c_str(), std::ios::in );
+  SaveResult.open(out.str().c_str(), ios::in);
   if (!SaveResult.is_open())
     {
       mexPrintf("Error : Can't open file \"%s\" for reading\n", "Result");
       mexEvalString("st=fclose('all');clear all;");
       mexErrMsgTxt("Exit from Dynare");
     }
-	mexPrintf("Reading Result...");
-	int row, col;
-	SaveResult >> row;
-	mexPrintf("row=%d\n",row);
-	SaveResult >> col;
-	mexPrintf("col=%d\n",col);
-	//double G1a[row][col];
-	double G1a;
-	mexPrintf("Allocated\n");
-	NonZeroElem *first;
-	for(int j=0; j< col; j++)
-	  {
-	  	mexPrintf("j=%d ",j);
-      int nb_equ=At_Col(j,&first);
-      mexPrintf("nb_equ=%d\n",nb_equ);
+  mexPrintf("Reading Result...");
+  int row, col;
+  SaveResult >> row;
+  mexPrintf("row=%d\n", row);
+  SaveResult >> col;
+  mexPrintf("col=%d\n", col);
+  double G1a;
+  mexPrintf("Allocated\n");
+  NonZeroElem *first;
+  for (int j = 0; j < col; j++)
+    {
+      mexPrintf("j=%d ", j);
+      int nb_equ = At_Col(j, &first);
+      mexPrintf("nb_equ=%d\n", nb_equ);
       int line;
-      if(first)
-      	line = first->r_index;
-			else
-			  line = -9999999;
-	    for(int i=0; i< row; i++)
-	      {
-	        SaveResult >> G1a;
-	        if(line == i)
+      if (first)
+        line = first->r_index;
+      else
+        line = -9999999;
+      for (int i = 0; i < row; i++)
+        {
+          SaveResult >> G1a;
+          if (line == i)
             {
-            	if(abs(u[first->u_index]/G1a-1)>epsilon)
-            	  mexPrintf("Problem at r=%d c=%d u[first->u_index]=%5.14f G1a[i][j]=%5.14f %f\n",i,j,u[first->u_index],G1a, u[first->u_index]/G1a-1);
-				  	  first=first->NZE_C_N;
-					  	if(first)
-						  	 line = first->r_index;
-							else
-  							 line = -9999999;
-						}
-		  		else
-			  		{
-				  	  if(G1a!=0.0)
-  				  	  mexPrintf("Problem at r=%d c=%d G1a[i][j]=%f\n",i,j,G1a);
+              if (abs(u[first->u_index]/G1a-1) > epsilon)
+                mexPrintf("Problem at r=%d c=%d u[first->u_index]=%5.14f G1a[i][j]=%5.14f %f\n", i, j, u[first->u_index], G1a, u[first->u_index]/G1a-1);
+              first = first->NZE_C_N;
+              if (first)
+                line = first->r_index;
+              else
+                line = -9999999;
+            }
+          else
+            {
+              if (G1a != 0.0)
+                mexPrintf("Problem at r=%d c=%d G1a[i][j]=%f\n", i, j, G1a);
             }
-	      }
-	  }
-	mexPrintf("G1a red done\n");
-	SaveResult >> row;
-	mexPrintf("row(2)=%d\n",row);
-	double B[row];
-	for(int i=0; i< row; i++)
-	  SaveResult >> B[i];
-	SaveResult.close();
+        }
+    }
+  mexPrintf("G1a red done\n");
+  SaveResult >> row;
+  mexPrintf("row(2)=%d\n", row);
+  double B[row];
+  for (int i = 0; i < row; i++)
+    SaveResult >> B[i];
+  SaveResult.close();
   mexPrintf("done\n");
   mexPrintf("Comparing...");
-  /*NonZeroElem *first;
-  for(int i=0;i<row;i++)
+  for (int i = 0; i < row; i++)
     {
-    	mexPrintf("i=%d ",i);
-      int nb_var=At_Row(i,&first);
-      mexPrintf("nb_var=%d\n",nb_var);
-      int column;
-      if(first)
-      	column = first->c_index;
-			else
-			  column = -9999999;
-      for(int j=0;j<col;j++)
-        {
-          if(column == j)
-            {
-            	if(abs(u[first->u_index]-G1a[i][j])>epsilon)
-            	  mexPrintf("Problem at r=%d c=%d u[first->u_index]=%f G1a[i][j]=%f\n",i,j,u[first->u_index],G1a[i][j]);
-				  	  first=first->NZE_R_N;
-					  	if(first)
-						  	 column = first->c_index;
-							else
-  							 column = -9999999;
-						}
-		  		else
-			  		{
-				  	  if(G1a[i][j]!=0)
-  				  	  mexPrintf("Problem at r=%d c=%d G1a[i][j]=%f\n",i,j,G1a[i][j]);
-            }
-        }
-    }*/
-	for(int i=0; i<row; i++)
-	  {
-	  	if(abs(u[b[i]]+B[i])>epsilon)
-	  	  mexPrintf("Problem at i=%d u[b[i]]=%f B[i]=%f\n",i,u[b[i]],B[i]);
-	  }
+      if (abs(u[b[i]]+B[i]) > epsilon)
+        mexPrintf("Problem at i=%d u[b[i]]=%f B[i]=%f\n", i, u[b[i]], B[i]);
+    }
 }
 
-
 void
-SparseMatrix::Check_the_Solution(int periods, int y_kmin, int y_kmax, int Size, double *u, int *pivot, int* b)
+SparseMatrix::Check_the_Solution(int periods, int y_kmin, int y_kmax, int Size, double *u, int *pivot, int *b)
 {
-	const double epsilon=1e-10;
-	//std::map<std::pair<std::pair<int, int> ,int>, int> IM_i;
-	Init(periods, y_kmin, y_kmax, Size, IM_i);
-	NonZeroElem *first;
-	int cal_y = y_kmin*Size;
-	mexPrintf("     ");
-	for(int i=0; i<Size; i++)
-	  mexPrintf(" %8d",i);
-	mexPrintf("\n");
-	for(int t=y_kmin; t<periods+y_kmin; t++)
-	  {
-	  	mexPrintf("t=%5d",t);
-      for(int i=0; i<Size; i++)
-	  	   mexPrintf(" %d %1.6f",t*y_size+index_vara[i], y[t*y_size+index_vara[i]]);
-			mexPrintf("\n");
-	  }
-	for(int i=0;i<Size*periods;i++)
-	  {
-	  	double res=0;
-	  	int pos = pivot[i];
-	  	mexPrintf("pos[%d]=%d",i,pos);
-	  	int nb_var = At_Row(pos, &first);
-	  	mexPrintf(" nb_var=%d\n",nb_var);
-	  	for(int j=0;j<nb_var; j++)
-	  	  {
-	  	  	mexPrintf("(y[%d]=%f)*(u[%d]=%f)(r=%d, c=%d)\n",index_vara[first->c_index]+cal_y, y[index_vara[first->c_index]+cal_y], first->u_index, u[first->u_index], first->r_index, first->c_index);
-	  	  	res += y[index_vara[first->c_index]+cal_y]*u[first->u_index];
-	  	  	first=first->NZE_R_N;
-	  	  }
-			double tmp_=res;
-			res += u[b[pos]];
-			if(abs(res)>epsilon)
-			  mexPrintf("Error for equation %d => res=%f y[%d]=%f u[b[%d]]=%f somme(y*u)=%f\n",pos,res,pos,y[index_vara[pos]], pos, u[b[pos]], tmp_);
-	  }
-	filename+=" stopped";
-	mexErrMsgTxt(filename.c_str());
+  const double epsilon = 1e-10;
+  Init(periods, y_kmin, y_kmax, Size, IM_i);
+  NonZeroElem *first;
+  int cal_y = y_kmin*Size;
+  mexPrintf("     ");
+  for (int i = 0; i < Size; i++)
+    mexPrintf(" %8d", i);
+  mexPrintf("\n");
+  for (int t = y_kmin; t < periods+y_kmin; t++)
+    {
+      mexPrintf("t=%5d", t);
+      for (int i = 0; i < Size; i++)
+        mexPrintf(" %d %1.6f", t*y_size+index_vara[i], y[t*y_size+index_vara[i]]);
+      mexPrintf("\n");
+    }
+  for (int i = 0; i < Size*periods; i++)
+    {
+      double res = 0;
+      int pos = pivot[i];
+      mexPrintf("pos[%d]=%d", i, pos);
+      int nb_var = At_Row(pos, &first);
+      mexPrintf(" nb_var=%d\n", nb_var);
+      for (int j = 0; j < nb_var; j++)
+        {
+          mexPrintf("(y[%d]=%f)*(u[%d]=%f)(r=%d, c=%d)\n", index_vara[first->c_index]+cal_y, y[index_vara[first->c_index]+cal_y], first->u_index, u[first->u_index], first->r_index, first->c_index);
+          res += y[index_vara[first->c_index]+cal_y]*u[first->u_index];
+          first = first->NZE_R_N;
+        }
+      double tmp_ = res;
+      res += u[b[pos]];
+      if (abs(res) > epsilon)
+        mexPrintf("Error for equation %d => res=%f y[%d]=%f u[b[%d]]=%f somme(y*u)=%f\n", pos, res, pos, y[index_vara[pos]], pos, u[b[pos]], tmp_);
+    }
+  filename += " stopped";
+  mexErrMsgTxt(filename.c_str());
 }
 
-
-
-
-
 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)
 {
   /*Triangularisation at each period of a block using a simple gaussian Elimination*/
   t_save_op_s *save_op_s;
-  bool record=false;
-  int *save_op=NULL, *save_opa=NULL, *save_opaa=NULL;
-  long int nop=0, nopa=0;
-  int tbreak=0, last_period=periods;
-  int i,j,k;
-  int pivj=0, pivk=0;
-  int row, nb_var_piv, nb_var_sub, l_sub, sub_c_index, tmp_lag, l_piv, piv_c_index, tmp_u_count, lag;
-  NonZeroElem *first, *firsta, *first_sub, *first_piv, *first_suba;
-  double piv_abs, first_elem;
-  if(start_compare==0)
-    start_compare=y_kmin;;
-#ifdef RECORD_ALL
-  int save_u_count=u_count;
-#endif
-  u_count_alloc_save=u_count_alloc;
-#ifdef PROFILER
-  long int ndiv=0, nsub=0, ncomp=0, nmul=0;
-  double tinsert=0, tdelete=0, tpivot=0, tbigloop=0;
-  clock_t td1;
-  int nbpivot=0, nbdiv=0, nbless=0, nbpivot_it=0, nbRealloc=0, ninsert=0;
-#endif
-  //pctimer_t t01;
+  bool record = false;
+  int *save_op = NULL, *save_opa = NULL, *save_opaa = NULL;
+  long int nop = 0, nopa = 0;
+  int tbreak = 0, last_period = periods;
+  int i, j, k;
+  int pivj = 0, pivk = 0;
+  int tmp_u_count, lag;
+  NonZeroElem *first;
+  double piv_abs;
+  if (start_compare == 0)
+    start_compare = y_kmin;
+  u_count_alloc_save = u_count_alloc;
   clock_t t01;
-  //pctimer_t t1 = pctimer();
   clock_t t1 = clock();
-#ifdef PROFILER
-  tdelete1=0; tdelete2=0; tdelete21=0; tdelete22=0; tdelete221=0; tdelete222=0;
-#endif
   nop1 = 0;
-  if (iter>0)
+  error_not_printed = true;
+  if (iter > 0)
     {
-      mexPrintf("Sim : %f ms\n",(1000.0*(double(clock())-double(time00)))/double(CLOCKS_PER_SEC));
+      mexPrintf("Sim : %f ms\n", (1000.0*(double (clock())-double (time00)))/double (CLOCKS_PER_SEC));
       mexEvalString("drawnow;");
+      time00 = clock();
     }
-#ifdef MEMORY_LEAKS
-  mexEvalString("feature('memstats');");
-#endif
   if (isnan(res1) || isinf(res1))
     {
-    	if(iter==0)
-    	  {
-    	  	for(j=0;j<y_size; j++)
-            mexPrintf("variable %d at time %d = %f, %f\n",j+1, it_, y[j+it_*y_size], y[j+(it_+1)*y_size]);
-    	  	mexPrintf("The initial values of endogenous variables are too far from the solution.\n");
-    	  	mexPrintf("Change them!\n");
-    	  	mexEvalString("drawnow;");
+      if (iter == 0)
+        {
+          for (j = 0; j < y_size; j++)
+            mexPrintf("variable %d at time %d = %f\n", j+1, it_, y[j+it_*y_size]);
+					for(j = 0; j < Size; j++)
+					  mexPrintf("residual(%d)=%5.25f\n",j, u[j]);
+					mexPrintf("res1=%5.25f\n",res1);
+          mexPrintf("The initial values of endogenous variables are too far from the solution.\n");
+          mexPrintf("Change them!\n");
+          mexEvalString("drawnow;");
           mexEvalString("st=fclose('all');clear all;");
-          filename+=" stopped";
+          filename += " stopped";
           mexErrMsgTxt(filename.c_str());
-    	  }
-      if (slowc_save<1e-8)
+        }
+      if (slowc_save < 1e-8)
         {
           mexPrintf("slowc_save=%g\n", slowc_save);
-          for(j=0;j<y_size; j++)
-            mexPrintf("variable %d at time %d = %f, %f\n",j+1, it_, y[j+it_*y_size], y[j+(it_+1)*y_size]);
+          for (j = 0; j < y_size; j++)
+            mexPrintf("variable %d at time %d = %f\n", j+1, it_, y[j+it_*y_size]);
           mexPrintf("Dynare cannot improve the simulation in block %d at time %d (variable %d)\n", blck+1, it_+1, max_res_idx);
           mexEvalString("drawnow;");
           mexEvalString("st=fclose('all');clear all;");
-          filename+=" stopped";
+          filename += " stopped";
           mexErrMsgTxt(filename.c_str());
-#ifdef DEBUG_EX
-          exit(-1);
-#endif
         }
-      slowc_save/=2;
-      mexPrintf("Error: Simulation diverging, trying to correct it using slowc=%f\n",slowc_save);
-      for (i=0;i<y_size*(periods+y_kmin);i++)
-        y[i]=ya[i]+slowc_save*direction[i];
+      slowc_save /= 2;
+      mexPrintf("Error: Simulation diverging, trying to correct it using slowc=%f\n", slowc_save);
+      for (i = 0; i < y_size*(periods+y_kmin); i++)
+        y[i] = ya[i]+slowc_save*direction[i];
       iter--;
-      return(0);
+      return (0);
     }
-  u_count+=u_count_init;
-  if (alt_symbolic && alt_symbolic_count<alt_symbolic_count_max)
+  u_count += u_count_init;
+  if (alt_symbolic && alt_symbolic_count < alt_symbolic_count_max)
     {
       mexPrintf("Pivoting method will be applied only to the first periods.\n");
-      alt_symbolic=false;
-      symbolic=true;
-      markowitz_c=markowitz_c_s;
+      alt_symbolic = false;
+      symbolic = true;
+      markowitz_c = markowitz_c_s;
       alt_symbolic_count++;
     }
-  if (((res1/res1a-1)>-0.3) && symbolic && iter>0)
+  if (((res1/res1a-1) > -0.3) && symbolic && iter > 0)
     {
-    	if(restart>2)
-          {
-            mexPrintf("Divergence or slowdown occured during simulation.\nIn the next iteration, pivoting method will be applied to all periods.\n");
-            symbolic=false;
-            alt_symbolic=true;
-            markowitz_c_s=markowitz_c;
-            markowitz_c=0;
-          }
+      if (restart > 2)
+        {
+          mexPrintf("Divergence or slowdown occured during simulation.\nIn the next iteration, pivoting method will be applied to all periods.\n");
+          symbolic = false;
+          alt_symbolic = true;
+          markowitz_c_s = markowitz_c;
+          markowitz_c = 0;
+        }
       else
         {
           mexPrintf("Divergence or slowdown occured during simulation.\nIn the next iteration, pivoting method will be applied for a longer period.\n");
-          start_compare=min(tbreak_g,periods);
+          start_compare = min(tbreak_g, periods);
           restart++;
         }
     }
-	else
-	  {
-	    start_compare=y_kmin;
-	    restart = 0;
-	  }
-  res1a=res1;
-
-
+  else
+    {
+      start_compare = y_kmin;
+      restart = 0;
+    }
+  res1a = res1;
 
-  if(print_it)
+  if (print_it)
     {
       mexPrintf("-----------------------------------\n");
-      mexPrintf("      Simulate     iteration� %d     \n",iter+1);
-      mexPrintf("      max. error=%.10e       \n",double(max_res));
-      mexPrintf("      sqr. error=%.10e       \n",double(res2));
-      mexPrintf("      abs. error=%.10e       \n",double(res1));
+      mexPrintf("      Simulate     iteration� %d     \n", iter+1);
+      mexPrintf("      max. error=%.10e       \n", double (max_res));
+      mexPrintf("      sqr. error=%.10e       \n", double (res2));
+      mexPrintf("      abs. error=%.10e       \n", double (res1));
       mexPrintf("-----------------------------------\n");
     }
-	//Print(Size, b);
   if (cvg)
     {
-      /*mexPrintf("End of simulate_NG1\n");
-      mexEvalString("drawnow;");*/
-      return(0);
-    }
-#ifdef PRINT_OUT
-  mexPrintf("Size=%d y_size=%d y_kmin=%d y_kmax=%d u_count=%d u_count_alloc=%d periods=%d\n",Size,y_size,y_kmin,y_kmax,u_count,u_count_alloc,periods);
-  mexEvalString("drawnow;");
-#endif
-#ifdef PROFILER
-  clock_t t00 = clock();
-#endif
-#ifdef WRITE_u
-  fstream toto;
-  int i_toto=0;
-  if (!symbolic)
-    {
-      toto.open("compare_good.txt", std::ios::out);
-    }
-#endif
-#ifdef PROFILER
-  t01=clock();
-#endif
-#ifdef PROFILER
-  mexPrintf("initialization time=%f ms\n",1000.0*(double(t01)-double(t00))/double(CLOCKS_PER_SEC));
-  mexEvalString("drawnow;");
-#endif
-
-#ifdef PRINT_OUT
-  mexPrintf("sizeof(NonZeroElem)=%d\n",sizeof(NonZeroElem));
-  /*for (i=0;i<Size*periods;i++)
-    mexPrintf("b[%d]=%f\n",i,double(b[i]));*/
-#endif
-#ifdef RECORD_ALL
-  if (record_all && !save_op_all)
-    {
-      nopa_all=(Size*periods)*Size*periods*4;  /*Initial guess on the total number of operations*/
-#ifdef MEM_ALLOC_CHK
-      mexPrintf("record_all save_op_all=(int*)mxMalloc(%d*sizeof(int))\n",nopa_all);
-#endif
-      save_op_all=(int*)mxMalloc(nopa_all*sizeof(int));
-#ifdef MEM_ALLOC_CHK
-      mexPrintf("ok\n");
-#endif
-      nop_all=0;
-    }
-#endif
-  /*Add the first and the last values of endogenous to the exogenous */
-#ifdef PROFILER
-  t00 = clock();
-#endif
-#ifdef RECORD_ALL
-  if (record_all && nop_all)
-    {
-//#ifdef PRINT_OUT
-      mexPrintf("ShortInit\n");
-      mexEvalString("drawnow;");
-//#endif
-      ShortInit(periods, y_kmin, y_kmax, Size, IM_i);
-//#ifdef PRINT_OUT
-      mexPrintf("run_triangular\n");
-      mexEvalString("drawnow;");
-//#endif
-      run_triangular(nop_all,save_op_all);
-//#ifdef PRINT_OUT
-      mexPrintf("OK\n");
-      mexEvalString("drawnow;");
-//#endif
+      return (0);
     }
   else
-#endif
-    if (g_nop_all>0)
-      {
-#ifdef PRINT_OUT
-        mexPrintf("run_triangular\n");
-        mexEvalString("drawnow;");
-#endif
-        run_u_period1(periods);
-#ifdef PRINT_OUT
-        mexPrintf("done\n");
-        mexEvalString("drawnow;");
-#endif
-      }
-    else
-      {
-#ifdef PRINT_OUT
-        mexPrintf("Init\n");
-        mexEvalString("drawnow;");
-#endif
-        Init(periods, y_kmin, y_kmax, Size, IM_i);
-	      /*ua = (double*)mxMalloc(u_count_init * periods*sizeof(double));
-	      for(i=0; i< u_count_init * periods;i++)
-	        ua[i] = u[i];*/
-#ifdef PRINT_OUT
-        mexPrintf("done\n");
-        mexEvalString("drawnow;");
-#endif
-        //Print(Size, b);
-
-        //CheckIt(y_size, y_kmin, y_kmax, Size, periods, iter);
-
-        //mexErrMsgTxt("Exit from Dynare");
-        /*for(int i=0; i<row; i++)
-	        {
-	        	u[b[i]] = - u[b[i]];
-	        }*/
-
-        for (int t=0;t<periods;t++)
-          {
-          	//mexPrintf("t=%d periods=%d\n",t,periods);
-#ifdef WRITE_u
-            if (!symbolic && ((periods-t)<=y_kmax))
+    {
+      Init(periods, y_kmin, y_kmax, Size, IM_i);
+      for (int t = 0; t < periods; t++)
+        {
+          if (record && symbolic)
+            {
+              if (save_op) ;
               {
-                toto << "t=" << t << endl;
+                mxFree(save_op);
+                save_op = NULL;
               }
-#endif
-            if (record && symbolic)
-              {
-                //nop*=8;
-                if (save_op);
+              save_op = (int *) mxMalloc(nop*sizeof(int));
+              nopa = nop;
+            }
+          nop = 0;
+          Clear_u();
+          int ti = t*Size;
+          for (i = ti; i < Size+ti; i++)
+            {
+              /*finding the max-pivot*/
+              double piv = piv_abs = 0;
+              int nb_eq = At_Col(i, 0, &first);
+              if ((symbolic && t <= start_compare) || !symbolic)
                 {
-                  mxFree(save_op);
-                  save_op=NULL;
+                  double piv_v[Size];
+                  int pivj_v[Size], pivk_v[Size], NR[Size], l = 0, N_max = 0;
+                  bool one = false;
+                  piv_abs = 0;
+                  for (j = 0; j < nb_eq; j++)
+                    {
+                      if (!line_done[first->r_index])
+                        {
+                          k = first->u_index;
+                          int jj = first->r_index;
+                          int NRow_jj = NRow(jj);
+                          piv_v[l] = u[k];
+                          double piv_fabs = fabs(u[k]);
+                          pivj_v[l] = jj;
+                          pivk_v[l] = k;
+                          NR[l] = NRow_jj;
+                          if (NRow_jj == 1 && !one)
+                            {
+                              one = true;
+                              piv_abs = piv_fabs;
+                              N_max = NRow_jj;
+                            }
+                          if (!one)
+                            {
+                              if (piv_fabs > piv_abs)
+                                piv_abs = piv_fabs;
+                              if (NRow_jj > N_max)
+                                N_max = NRow_jj;
+                            }
+                          else
+                            {
+                              if (NRow_jj == 1)
+                                {
+                                  if (piv_fabs > piv_abs)
+                                    piv_abs = piv_fabs;
+                                  if (NRow_jj > N_max)
+                                    N_max = NRow_jj;
+                                }
+                            }
+                          l++;
+                        }
+                      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(NR[j]/N_max));
+                          if (markovitz > markovitz_max && NR[j] == 1)
+                            {
+                              piv = piv_v[j];
+                              pivj = pivj_v[j];   //Line number
+                              pivk = pivk_v[j];   //position
+                              markovitz_max = markovitz;
+                            }
+                        }
+                    }
+                  pivot[i] = pivj;
+                  pivot_save[i] = pivj;
+                  pivotk[i] = pivk;
+                  pivotv[i] = piv;
+                }
+              else
+                {
+                  pivj = pivot[i-Size]+Size;
+                  pivot[i] = pivj;
+                  At_Pos(pivj, i, &first);
+                  pivk = first->u_index;
+                  piv = u[pivk];
+                  piv_abs = fabs(piv);
+                }
+              line_done[pivj] = true;
+              if (symbolic)
+                {
+                  if (record)
+                    {
+                      if (nop+1 >= nopa)
+                        {
+                          nopa = int (1.5*nopa);
+                          save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
+                        }
+                      save_op_s = (t_save_op_s *) (&(save_op[nop]));
+                      save_op_s->operat = IFLD;
+                      save_op_s->first = pivk;
+                      save_op_s->lag = 0;
+                    }
+                  nop += 2;
+                }
+              if (piv_abs < eps)
+                {
+                  mexPrintf("Error: singular system in Simulate_NG1\n");
+                  mexEvalString("drawnow;");
+                  mexEvalString("st=fclose('all');clear all;");
+                  filename += " stopped";
+                  mexErrMsgTxt(filename.c_str());
+                }
+              /*divide all the non zeros elements of the line pivj by the max_pivot*/
+              int nb_var = At_Row(pivj, &first);
+              NonZeroElem *bb[nb_var];
+              for (j = 0; j < nb_var; j++)
+                {
+                  bb[j] = first;
+                  first = first->NZE_R_N;
                 }
-#ifdef MEM_ALLOC_CHK
-                mexPrintf("save_op=(int*)mxMalloc(%d*sizeof(int))\n",nop);
-#endif
-#ifdef N_MX_ALLOC
-                save_op=malloc_std(nop);
-#else
-                save_op=(int*)mxMalloc(nop*sizeof(int));
-#endif
-                nopa=nop;
-#ifdef MEM_ALLOC_CHK
-                mexPrintf("ok\n");
-#endif
-              }
-            nop=0;
-#ifdef PRINT_OUT
-            mexPrintf("---------------------------------------------------------\n");
-            mexPrintf("t=%d\n",t);
-            mexPrintf("---------------------------------------------------------\n");
-#endif
-            Clear_u();
-            int ti=t*Size;
-#ifdef PROFILER
-            if (t<=start_compare)
-              nbpivot_it=0;
-#endif
-            for (i=ti;i<Size+ti;i++)
-              {
-                /*finding the max-pivot*/
-#ifdef PRINT_OUT
-                Print(Size,b);
-                mexPrintf("*************************************\n");
-                mexPrintf("Finding the Pivot at column i=%d\n",i);
-#endif
-#ifdef PROFILER
-                clock_t td0=clock();
-#endif
-                double piv=piv_abs=0;
-                int nb_eq=At_Col(i, 0, &first);
-#ifdef PRINT_OUT
-                mexPrintf("nb_eq=%d\n",nb_eq);
-#endif
-                //mexPrintf("symbolic=%d t=%d start_compare=%d\n",symbolic, t, start_compare);
-                if ((symbolic && t<=start_compare) || !symbolic)
-                  {
-#ifdef MARKOVITZ
-                    double piv_v[Size];
-                    int pivj_v[Size], pivk_v[Size], NR[Size], l=0, N_max=0;
-                    bool one=false;
-                    piv_abs=0;
-#endif
-                    for (j=0;j<nb_eq;j++)
-                      {
-                        //mexPrintf("j=%d\n",j);
-#ifdef PRINT_OUT
-                        mexPrintf("first=%x\n",first);
-                        mexPrintf("examine col %d row %d with lag 0 line_done=%d \n",i,first->r_index,line_done[first->r_index]);
-#endif
-                        if (!line_done[first->r_index])
-                          {
-                            k=first->u_index;
-#ifdef PRINT_OUT
-                            mexPrintf("u[%d]=%f fabs(u[%d])=%f\n",k,double(u[k]),k,double(fabs(u[k])));
-#endif
-                            int jj=first->r_index;
-                            int NRow_jj=NRow(jj);
-#ifdef PROFILER
-                            nbpivot++;
-                            nbpivot_it++;
-#endif
 
-#ifdef MARKOVITZ
-                            piv_v[l]=u[k];
-                            double piv_fabs=fabs(u[k]);
-                            pivj_v[l]=jj;
-                            pivk_v[l]=k;
-                            NR[l]=NRow_jj;
-                            if (NRow_jj==1 && !one)
-                              {
-                                one=true;
-                                piv_abs=piv_fabs;
-                                N_max=NRow_jj;
-                              }
-                            if (!one)
-                              {
-                                if (piv_fabs>piv_abs)
-                                  piv_abs=piv_fabs;
-                                if (NRow_jj>N_max)
-                                  N_max=NRow_jj;
-                              }
-                            else
-                              {
-                                if (NRow_jj==1)
-                                  {
-                                    if (piv_fabs>piv_abs)
-                                      piv_abs=piv_fabs;
-                                    if (NRow_jj>N_max)
-                                      N_max=NRow_jj;
-                                  }
-                              }
-                            l++;
-#else
-                            if (piv_abs<fabs(u[k])||NRow_jj==1)
-                              {
-                                piv=u[k];
-                                piv_abs=fabs(piv);
-                                pivj=jj;   //Line number
-                                pivk=k;   //position in u
-                                if (NRow_jj==1)
-                                  break;
-                              }
-#endif
-                          }
-                        first=first->NZE_C_N;
-                      }
-#ifdef MARKOVITZ
-                    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(NR[j]/N_max));
-                            if (markovitz>markovitz_max && NR[j]==1)
+              for (j = 0; j < nb_var; j++)
+                {
+                  first = bb[j];
+                  u[first->u_index] /= piv;
+                  if (symbolic)
+                    {
+                      if (record)
+                        {
+                          if (nop+j*2+1 >= nopa)
+                            {
+                              nopa = int (1.5*nopa);
+                              save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
+                            }
+                          save_op_s = (t_save_op_s *) (&(save_op[nop+j*2]));
+                          save_op_s->operat = IFDIV;
+                          save_op_s->first = first->u_index;
+                          save_op_s->lag = first->lag_index;
+                        }
+                    }
+                }
+              nop += nb_var*2;
+              u[b[pivj]] /= piv;
+              if (symbolic)
+                {
+                  if (record)
+                    {
+                      if (nop+1 >= nopa)
+                        {
+                          nopa = int (1.5*nopa);
+                          save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
+                        }
+                      save_op_s = (t_save_op_s *) (&(save_op[nop]));
+                      save_op_s->operat = IFDIV;
+                      save_op_s->first = b[pivj];
+                      save_op_s->lag = 0;
+                    }
+                  nop += 2;
+                }
+              /*substract the elements on the non treated lines*/
+              nb_eq = At_Col(i, &first);
+              NonZeroElem *first_piva;
+              int nb_var_piva = At_Row(pivj, &first_piva);
+
+              NonZeroElem *bc[nb_eq];
+              int nb_eq_todo = 0;
+              for (j = 0; j < nb_eq && first; j++)
+                {
+                  if (!line_done[first->r_index])
+                    bc[nb_eq_todo++] = first;
+                  first = first->NZE_C_N;
+                }
+              //#pragma omp parallel for num_threads(2) shared(nb_var_piva, first_piva, nopa, nop, save_op, record)
+              for (j = 0; j < nb_eq_todo; j++)
+                {
+                  t_save_op_s *save_op_s_l;
+                  //NonZeroElem *
+                  first = bc[j];
+                  int row = first->r_index;
+                  double first_elem = u[first->u_index];
+                  if (symbolic)
+                    {
+                      if (record)
+                        {
+                          if (nop+2 >= nopa)
+                            {
+                              //#pragma omp critical
                               {
-                                piv=piv_v[j];
-                                pivj=pivj_v[j];   //Line number
-                                pivk=pivk_v[j];   //positi
-                                markovitz_max=markovitz;
+                                nopa = int (1.5*nopa);
+                                save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
                               }
-                          }
-                      }
-#endif
-#ifdef PROFILER
-                    tpivot+=clock()-td0;
-#endif
-
-#ifdef PRINT_OUT
-                    mexPrintf("Thats the pivot: %d with value %f in u[%d] \n",pivj,double(piv),pivk);
-                    mexPrintf("______________________________________________\n");
-                    mexPrintf("pivot[%d]=%d\n",i,pivj);
-                    mexEvalString("drawnow;");
-#endif
-										if(iter>0 && t>start_compare)
-										  {
-										  	if(pivot_save[i-Size]+Size!=pivj)
-										  	  mexPrintf("At t=%d at line i=%d pivj=%d and pivot_save[i-Size]+Size=%d\n",t,i,pivj, pivot_save[i-Size]+Size);
-										  }
-                    pivot[i]=pivj;
-                    pivot_save[i]=pivj;
-                    pivotk[i]=pivk;
-                    pivotv[i]=piv;
-                  }
-                else
-                  {
-                    pivj=pivot[i-Size]+Size;
-                    pivot[i]=pivj;
-                    At_Pos(pivj, i, &first);
-                    pivk=first->u_index;
-                    piv=u[pivk];
-                    piv_abs=fabs(piv);
-                  }
-                line_done[pivj]=true;
-#ifdef PRINT_u
-                mexPrintf("FLD u[%d] (%f=%f)   |",pivk,u[pivk],piv);
-                Print_u();mexPrintf("\n");
-                mexEvalString("drawnow;");
-#endif
-                if (symbolic)
-                  {
-                    if (record)
-                      {
-                        if (nop+1>=nopa)
-                          {
-                            nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                            mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                            nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                            save_op=realloc_std(save_op, nopa);
-#else
-                            save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                            mexPrintf("ok\n");
-#endif
-                          }
-                        save_op_s=(t_save_op_s*)(&(save_op[nop]));
-                        save_op_s->operat=IFLD;
-                        save_op_s->first=pivk;
-                        save_op_s->lag=0;
-                      }
-                    nop+=2;
-                  }
-#ifdef RECORD_ALL
-                else if (record_all)
-                  {
-                    if (nop_all+1>=nopa_all)
-                      chk_avail_mem(&save_op_all,&nop_all,&nopa_all,1,t);
-                    save_op_all[nop_all]=IFLD;
-                    save_op_all[nop_all+1]=pivk;
-                    nop_all+=2;
-                  }
-#endif
-								/*mexPrintf("piv_abs=%f\n",piv_abs);
-								mexEvalString("drawnow;");*/
-                if (piv_abs<eps)
-                  {
-                    mexPrintf("Error: singular system in Simulate_NG1\n");
-                    mexEvalString("drawnow;");
-                    mexEvalString("st=fclose('all');clear all;");
-                    filename+=" stopped";
-                    mexErrMsgTxt(filename.c_str());
-                  }
-                /*divide all the non zeros elements of the line pivj by the max_pivot*/
-                int nb_var=At_Row(pivj,&first);
-                NonZeroElem* bb[nb_var];
-                /*mexPrintf("nb_var=%d\n",nb_var);
-                mexEvalString("drawnow;");*/
-                for(j=0;j<nb_var;j++)
-                  {
-                    bb[j]=first;
-                    /*mexPrintf("j=%d",j);
-                    mexPrintf(" first->NZE_R_N=%x\n",first->NZE_R_N);*/
-                    first=first->NZE_R_N;
-                  }
+                            }
+                          save_op_s_l = (t_save_op_s *) (&(save_op[nop]));
+                          save_op_s_l->operat = IFLD;
+                          save_op_s_l->first = first->u_index;
+                          save_op_s_l->lag = abs(first->lag_index);
+                        }
+                      nop += 2;
+                    }
 
-#ifdef PRINT_OUT
-                mexPrintf("nb_var=%d\n",nb_var);
-#endif
-                for (j=0;j<nb_var;j++)
-                  {
-                    first=bb[j];
-#ifdef PRINT_OUT
-                    mexPrintf("j=%d ",j);
-                    mexPrintf("first=%x ",first);
-                    mexPrintf("dividing at lag %d [%d, %d] u[%d]\n",first->lag_index, first->r_index, first->c_index, first->u_index);
-#endif
-                    u[first->u_index]/=piv;
-#ifdef PROFILER
-                    nbdiv++;
-#endif
-#ifdef WRITE_u
-                    if ((periods-t)<=y_kmax)
-                      {
-                        toto << i_toto << " u[" /*<< first->u_index*/ << "]/=" << piv << "=" << u[first->u_index] << endl;
-                        i_toto++;
-                      }
-#endif
-#ifdef PRINT_u
-                    mexPrintf("FDIV u[%d](%f)/=piv(%f)=(%f)   |",first->u_index,u[first->u_index],piv,u[first->u_index]);
-                    Print_u();mexPrintf("\n");
-#endif
-                    if (symbolic)
-                      {
-                        if (record)
-                          {
-                            if (nop+j*2+1>=nopa)
-                              {
-                                nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                                mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                                nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                                save_op=realloc_std(save_op, nopa);
-#else
-                                save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                                mexPrintf("ok\n");
-#endif
-                              }
-                            save_op_s=(t_save_op_s*)(&(save_op[nop+j*2]));
-                            //mexPrintf("save_op[%d] : operat=%d, first=%d, lag=%d omp_get_thread_num()=%d\n",nop+j*2, IFDIV, first->u_index, first->lag_index, omp_get_thread_num());
-                            save_op_s->operat=IFDIV;
-                            save_op_s->first=first->u_index;
-                            save_op_s->lag=first->lag_index;
-                          }
-                        //nop+=2; ///!!
-                      }
-#ifdef RECORD_ALL
-                    else if (record_all)
-                      {
-                        if (nop_all+1>=nopa_all)
-                          chk_avail_mem(&save_op_all,&nop_all,&nopa_all,1,t);
-                        save_op_all[nop_all]=IFDIV;
-                        save_op_all[nop_all+1]=first->u_index;
-                        nop_all+=2;
-                      }
-#endif
-                    //first=first->NZE_R_N;
-                  }
-                nop += nb_var*2;
-#ifdef PRINT_OUT
-                mexPrintf("dividing at u[%d]\n",b[pivj]);
-#endif
-                u[b[pivj]]/=piv;
-#ifdef WRITE_u
-                if ((periods-t)<=y_kmax)
-                  {
-                    toto << i_toto << " u[" /*<< b[pivj]*/ << "]/=" << piv << "=" << u[b[pivj]] << endl;
-                    i_toto++;
-                  }
-#endif
-#ifdef PRINT_u
-                mexPrintf("FDIV u[%d](%f)/=piv(%f)=(%f)   |",b[pivj],u[b[pivj]],piv,u[b[pivj]]);
-                Print_u();mexPrintf("\n");
-#endif
-                if (symbolic)
-                  {
-                    if (record)
-                      {
-                        if (nop+1>=nopa)
+                  int nb_var_piv = nb_var_piva;
+                  NonZeroElem *first_piv = first_piva;
+                  NonZeroElem *first_sub;
+                  int nb_var_sub = At_Row(row, &first_sub);
+                  int l_sub = 0;
+                  int l_piv = 0;
+                  int sub_c_index = first_sub->c_index;
+                  int piv_c_index = first_piv->c_index;
+                  int tmp_lag = first_sub->lag_index;
+                  while (l_sub < nb_var_sub || l_piv < nb_var_piv)
+                    {
+                      if (l_sub < nb_var_sub && (sub_c_index < piv_c_index || l_piv >= nb_var_piv))
+                        {
+                          //There is no nonzero element at row pivot for this column=> Nothing to do for the current element got to next column
+                          first_sub = first_sub->NZE_R_N;
+                          if (first_sub)
+                            sub_c_index = first_sub->c_index;
+                          else
+                            sub_c_index = Size*periods;
+                          l_sub++;
+                        }
+                      else if (sub_c_index > piv_c_index || l_sub >= nb_var_sub)
+                        {
+                          // There is an nonzero element at row pivot but not at the current row=> insert a negative element in the current row
+                          tmp_u_count = Get_u();
+                          lag = first_piv->c_index/Size-row/Size;
+                          //#pragma omp critical
                           {
-                            nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                            mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                            nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                            save_op=realloc_std(save_op, nopa);
-#else
-                            save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                            mexPrintf("ok\n");
-#endif
+                            Insert(row, first_piv->c_index, tmp_u_count, lag);
                           }
-                        save_op_s=(t_save_op_s*)(&(save_op[nop]));
-                        save_op_s->operat=IFDIV;
-                        save_op_s->first=b[pivj];
-                        save_op_s->lag=0;
-                      }
-                    nop+=2;
-                  }
-#ifdef RECORD_ALL
-                else if (record_all)
-                  {
-                    if (nop_all+1>=nopa_all)
-                      chk_avail_mem(&save_op_all,&nop_all,&nopa_all,1,t);
-                    save_op_all[nop_all]=IFDIV;
-                    save_op_all[nop_all+1]=b[pivj];
-                    nop_all+=2;
-                  }
-#endif
-                /*substract the elements on the non treated lines*/
-                nb_eq=At_Col(i,&first);
-                NonZeroElem *first_piva;
-                int nb_var_piva=At_Row(pivj,&first_piva);
-                //mexPrintf("pivj=%d\n",pivj);
-#ifdef PRINT_OUT
-                if(iter>0)
-                  {
-                mexPrintf("ok4 nb_eq=%d iter=%d\n",nb_eq,iter);
-                mexEvalString("drawnow;");
-                  }
-#endif
+                          u[tmp_u_count] = -u[first_piv->u_index]*first_elem;
+                          if (symbolic)
+                            {
+                              if (record)
+                                {
+                                  if (nop+2 >= nopa)
+                                    {
+                                      //#pragma omp critical
+                                      {
+                                        nopa = int (1.5*nopa);
+                                        save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
+                                      }
+                                    }
+                                  save_op_s_l = (t_save_op_s *) (&(save_op[nop]));
+                                  save_op_s_l->operat = IFLESS;
+                                  save_op_s_l->first = tmp_u_count;
+                                  save_op_s_l->second = first_piv->u_index;
+                                  save_op_s_l->lag = max(first_piv->lag_index, abs(tmp_lag));
+                                }
+                              nop += 3;
+                            }
+                          first_piv = first_piv->NZE_R_N;
+                          if (first_piv)
+                            piv_c_index = first_piv->c_index;
+                          else
+                            piv_c_index = Size*periods;
+                          l_piv++;
+                        }
+                      else /*first_sub->c_index==first_piv->c_index*/
+                        {
+                          if (i == sub_c_index)
+                            {
 
-                NonZeroElem* bc[nb_eq];
-                for(j=0;j<nb_eq;j++)
-                  {
-                    bc[j]=first;
-                    first=first->NZE_C_N;
-                  }
-								//#pragma omp parallel for num_threads(atoi(getenv("DYNARE_NUM_THREADS"))) private(first, row, first_elem, nopa, save_op_s, nb_var_piv, nb_var_piva, first_piv, first_piva, first_sub, nb_var_sub, l_sub, l_piv, sub_c_index, piv_c_index, tmp_lag)
-                for (j=0;j<nb_eq;j++)
-                  {
-                    first=bc[j];
-                    row=first->r_index;
-                    /*mexPrintf("-------------------\n");
-                  	mexPrintf("j=%d line_done[row=%d]=%d\n",j,row, line_done[row]);*/
-#ifdef PRINT_OUT
-                    mexPrintf("t=%d, j=%d, line_done[%d]=%hd process=%d\n", t, j, row, line_done[row],omp_get_thread_num());
-#endif
-                    if (!line_done[row])
-                      {
-#ifdef PRINT_OUT
-                        mexPrintf("Substracting from line %d lag %d\n",row,first->lag_index);
-#endif
-                        first_elem=u[first->u_index];
-#ifdef PRINT_u
-                        mexPrintf("FLD u[%d] (%f)  |",first->u_index,u[first->u_index]);
-                        Print_u();mexPrintf("\n");
-#endif
-                        if (symbolic)
-                          {
-                            if (record)
+                              //#pragma omp barrier
+                              //#pragma omp single
+                              //#pragma omp critical
                               {
-                                if (nop+1>=nopa)
-                                  {
-                                    nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                                    mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                                    nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                                    save_op=realloc_std(save_op, nopa);
-#else
-                                    save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                                    mexPrintf("ok\n");
-#endif
-                                  }
-                                save_op_s=(t_save_op_s*)(&(save_op[nop]));
-                                save_op_s->operat=IFLD;
-                                save_op_s->first=first->u_index;
-                                save_op_s->lag=abs(first->lag_index);
+                                NonZeroElem *firsta = first;
+                                NonZeroElem *first_suba = first_sub->NZE_R_N;
+                                Delete(first_sub->r_index, first_sub->c_index);
+                                first = firsta->NZE_C_N;
+                                first_sub = first_suba;
                               }
-                            nop+=2;
-                          }
-#ifdef RECORD_ALL
-                        else if (record_all)
-                          {
-                            if (nop_all+1>=nopa_all)
-                              chk_avail_mem(&save_op_all,&nop_all,&nopa_all,1,t);
-                            save_op_all[nop_all]=IFLD;
-                            save_op_all[nop_all+1]=first->u_index;
-                            nop_all+=2;
-                          }
-#endif
-                        /*mexPrintf("For equ=9\n");
-                        int nb_var__=At_Row(9,&first_piv);
-                        for(int uu=0; uu<nb_var__; uu++)
-											    {
-											    	mexPrintf("->   first_piv->c_index=%d\n",first_piv->c_index);
-											    	first_piv=first_piv->NZE_R_N;
-											    }
-
-												first_piv = first_piva;
-												mexPrintf("OK\n");
-												for(int uu=0; uu<nb_var_piva; uu++)
-											    {
-											    	mexPrintf("->   first_piv->c_index=%d\n",first_piv->c_index);
-											    	first_piv=first_piv->NZE_R_N;
-											    }*/
 
-                        nb_var_piv=nb_var_piva;
-                        first_piv=first_piva;
-                        nb_var_sub=At_Row(row,&first_sub);
-                        l_sub=0;
-                        l_piv=0;
-                        sub_c_index=first_sub->c_index;
-                        piv_c_index=first_piv->c_index;
-                        tmp_lag=first_sub->lag_index;
-#ifdef PROFILER
-                        td1 = clock();
-#endif
-                        while (l_sub<nb_var_sub || l_piv<nb_var_piv)
-                          {
-#ifdef PRINT_OUT
-                            if (l_piv<nb_var_piv)
-                              mexPrintf(" piv eq=%d lag=%d var=%d l1=%d",first_piv->r_index, first_piv->lag_index, first_piv->c_index,l_piv);
-                            mexPrintf("l_sub(%d)<nb_var_sub(%d)\n",l_sub,nb_var_sub);
-                            if (l_sub<nb_var_sub)
-                              mexPrintf(" sub eq=%d lag=%d var=%d l0=%d",first_sub->r_index, first_sub->lag_index, first_sub->c_index,l_sub);
-#endif
-                            //mexPrintf("sub_c_index=%d piv_c_index=%d, l_sub=%d nb_var_sub=%d, l_piv=%d nb_var_piv=%d\n",sub_c_index, piv_c_index, l_sub, nb_var_sub, l_piv, nb_var_piv);
-                            if (l_sub<nb_var_sub && (sub_c_index<piv_c_index || l_piv>=nb_var_piv))
-                              {
-                              	//There is no nonzero element at line pivot for this column=> Nothing to do for the current element got to next column
-                              	//mexPrintf("Nothing\n");
-                                first_sub=first_sub->NZE_R_N;
-                                if (first_sub)
-                                  sub_c_index=first_sub->c_index;
-                                else
-                                  sub_c_index=Size*periods;
-                                l_sub++;
-                              }
-                            else if (sub_c_index>piv_c_index || l_sub>=nb_var_sub)
-                              {
-                              	// There is an nonzero element at row pivot but not at the current row=> insert a negative element in the current row
-                              	//mexPrintf("Insert\n");
-                                tmp_u_count=Get_u();
-#ifdef PROFILER
-                                clock_t td0=clock();
-#endif
-                                lag=first_piv->c_index/Size-row/Size;
-                                Insert(row,first_piv->c_index,tmp_u_count,lag);
-#ifdef PROFILER
-                                tinsert+=clock()-td0;
-#endif
-                                u[tmp_u_count]=-u[first_piv->u_index]*first_elem;
-#ifdef PROFILER
-                                nbless++;
-                                ninsert++;
-#endif
-                                if (symbolic)
-                                  {
-                                    if (record)
-                                      {
-                                        if (nop+2>=nopa)
-                                          {
-                                            nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                                            mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                                            nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                                            save_op=realloc_std(save_op, nopa);
-#else
-                                            save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                                            mexPrintf("ok\n");
-#endif
-                                          }
-                                        save_op_s=(t_save_op_s*)(&(save_op[nop]));
-                                        save_op_s->operat=IFLESS;
-                                        save_op_s->first=tmp_u_count;
-                                        save_op_s->second=first_piv->u_index;
-                                        save_op_s->lag=max(first_piv->lag_index,abs(tmp_lag));
-                                      }
-                                    nop+=3;
-                                  }
-#ifdef RECORD_ALL
-                                else if (record_all)
-                                  {
-                                    if (nop_all+2>=nopa_all)
-                                      chk_avail_mem(&save_op_all,&nop_all,&nopa_all,2,t);
-                                    save_op_all[nop_all]=IFLESS;
-                                    save_op_all[nop_all+1]=tmp_u_count;
-                                    save_op_all[nop_all+2]=first_piv->u_index;
-                                    nop_all+=3;
-                                  }
-#endif
-                                first_piv=first_piv->NZE_R_N;
-                                if (first_piv)
-                                  piv_c_index=first_piv->c_index;
-                                else
-                                  piv_c_index=Size*periods;
-                                l_piv++;
-                              }
-                            else /*first_sub->c_index==first_piv->c_index*/
-                              {
-                                if (i==sub_c_index)
-                                  {
-                                  	 //mexPrintf("Delete\n");
-#ifdef PRINT_OUT
-                                    /*if(iter>0)
-                                      {
-                                    mexPrintf("   delete element [%d, %d] lag %d u[%d]\n",first_sub->r_index,first_sub->c_index,first_sub->lag_index,first_sub->u_index);
-                                        mexEvalString("drawnow;");
-                                      }*/
-#endif
-                                    firsta=first;
-                                    first_suba=first_sub->NZE_R_N;
-#ifdef PROFILER
-                                    clock_t td0=clock();
-#endif
-                                    Delete(first_sub->r_index,first_sub->c_index, Size);
-#ifdef PROFILER
-                                    tdelete+=clock()-td0;
-#endif
-                                    first=firsta->NZE_C_N;
-                                    first_sub=first_suba;
-                                    if (first_sub)
-                                      sub_c_index=first_sub->c_index;
-                                    else
-                                      sub_c_index=Size*periods;
-                                    l_sub++;
-                                    first_piv=first_piv->NZE_R_N;
-                                    if (first_piv)
-                                      piv_c_index=first_piv->c_index;
-                                    else
-                                      piv_c_index=Size*periods;
-                                    l_piv++;
-#ifdef PRINT_OUT
-                                    Print(Size,b);
-#endif
-                                  }
-                                else
-                                  {
-                                  	//mexPrintf("Substract\n");
-#ifdef PRINT_OUT
-                                    mexPrintf("  u[%d]-=u[%d]*%f\n",first_sub->u_index,first_piv->u_index,double(first_elem));
-#endif
-                                    u[first_sub->u_index]-=u[first_piv->u_index]*first_elem;
-#ifdef PROFILER
-                                    nbless++;
-#endif
-#ifdef WRITE_u
-                                    if ((periods-t)<=y_kmax)
-                                      {
-                                        toto << i_toto << " u[" /*<< first_sub->u_index*/ << "]-=u[" /*<< first_piv->u_index*/ << "]*" << first_elem << "=" << u[first_sub->u_index] << endl;
-                                        i_toto++;
-                                      }
-#endif
-#ifdef PRINT_u
-                                    if(iter>0)
-                                      {
-                                    mexPrintf("FSUB u[%d]-=u[%d](%f)*r(%f)=(%f)  |",first_sub->u_index,first_piv->u_index,u[first_piv->u_index],first_elem,u[first_sub->u_index]);
-                                    /*Print_u();*/mexPrintf("\n");
-                                        mexEvalString("drawnow;");
-                                      }
-#endif
-                                    if (symbolic)
-                                      {
-                                        if (record)
+                              if (first_sub)
+                                sub_c_index = first_sub->c_index;
+                              else
+                                sub_c_index = Size*periods;
+                              l_sub++;
+                              first_piv = first_piv->NZE_R_N;
+                              if (first_piv)
+                                piv_c_index = first_piv->c_index;
+                              else
+                                piv_c_index = Size*periods;
+                              l_piv++;
+                            }
+                          else
+                            {
+                              u[first_sub->u_index] -= u[first_piv->u_index]*first_elem;
+                              if (symbolic)
+                                {
+                                  if (record)
+                                    {
+                                      if (nop+3 >= nopa)
+                                        {
+                                          //#pragma omp critical
                                           {
-                                            if (nop+2>=nopa)
-                                              {
-                                                nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                                                mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                                                nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                                                save_op=realloc_std(save_op, nopa);
-#else
-                                                save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                                                mexPrintf("ok\n");
-#endif
-                                              }
-                                            save_op_s=(t_save_op_s*)(&(save_op[nop]));
-                                            save_op_s->operat=IFSUB;
-                                            save_op_s->first=first_sub->u_index;
-                                            save_op_s->second=first_piv->u_index;
-                                            save_op_s->lag=max(abs(tmp_lag),first_piv->lag_index);
+                                            nopa = int (1.5*nopa);
+                                            save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
                                           }
-                                        nop+=3;
-                                      }
-#ifdef RECORD_ALL
-                                    else if (record_all)
-                                      {
-                                        if (nop_all+2>=nopa_all)
-                                          chk_avail_mem(&save_op_all,&nop_all,&nopa_all,2,t);
-                                        save_op_all[nop_all]=IFSUB;
-                                        save_op_all[nop_all+1]=first_sub->u_index;
-                                        save_op_all[nop_all+2]=first_piv->u_index;
-                                        nop_all+=3;
-                                      }
-#endif
-                                    first_sub=first_sub->NZE_R_N;
-                                    if (first_sub)
-                                      sub_c_index=first_sub->c_index;
-                                    else
-                                      sub_c_index=Size*periods;
-                                    l_sub++;
-                                    first_piv=first_piv->NZE_R_N;
-                                    if (first_piv)
-                                      piv_c_index=first_piv->c_index;
-                                    else
-                                      piv_c_index=Size*periods;
-                                    l_piv++;
-                                  }
-                              }
-                          }
-#ifdef PRINT_OUT
-                        mexPrintf("row=%d pivj=%d\n",row,pivj);
-                        mexPrintf("  u[%d](%f)-=u[%d](%f)*%f\n",b[row],double(u[b[row]]), b[pivj],double(u[b[pivj]]),double(first_elem));
-#endif
-
-                        u[b[row]]-=u[b[pivj]]*first_elem;
-#ifdef PROFILER
-                        nbless++;
-                        tbigloop += clock() - td1;
-#endif
-#ifdef WRITE_u
-                        if ((periods-t)<=y_kmax)
-                          {
-                            toto << i_toto << " u[" /*<< b[row]*/ << "]-=u[" /*<< b[pivj]*/ << "]*" << first_elem << "=" << u[b[row]] << endl;
-                            i_toto++;
-                          }
-#endif
-#ifdef PRINT_u
-                        mexPrintf("FSUB u[%d]-=u[%d](%f)*r(%f)=(%f)   |",b[row],b[pivj],u[b[pivj]],first_elem,u[b[row]]);
-                        Print_u();mexPrintf("\n");
-#endif
+                                        }
+                                      save_op_s_l = (t_save_op_s *) (&(save_op[nop]));
+                                      save_op_s_l->operat = IFSUB;
+                                      save_op_s_l->first = first_sub->u_index;
+                                      save_op_s_l->second = first_piv->u_index;
+                                      save_op_s_l->lag = max(abs(tmp_lag), first_piv->lag_index);
+                                    }
+                                  nop += 3;
+                                }
+                              first_sub = first_sub->NZE_R_N;
+                              if (first_sub)
+                                sub_c_index = first_sub->c_index;
+                              else
+                                sub_c_index = Size*periods;
+                              l_sub++;
+                              first_piv = first_piv->NZE_R_N;
+                              if (first_piv)
+                                piv_c_index = first_piv->c_index;
+                              else
+                                piv_c_index = Size*periods;
+                              l_piv++;
+                            }
+                        }
+                    }
+                  u[b[row]] -= u[b[pivj]]*first_elem;
 
-                        if (symbolic)
-                          {
-                            if (record)
+                  if (symbolic)
+                    {
+                      if (record)
+                        {
+                          if (nop+3 >= nopa)
+                            {
+                              //#pragma omp critical
                               {
-                                if (nop+2>=nopa)
-                                  {
-                                    nopa=int(1.5*nopa);
-#ifdef MEM_ALLOC_CHK
-                                    mexPrintf("save_op=(int*)mxRealloc(save_op,%d*sizeof(int))\n",nopa);
-#endif
-#ifdef PROFILER
-                                    nbRealloc++;
-#endif
-#ifdef N_MX_ALLOC
-                                    save_op=realloc_std(save_op, nopa);
-#else
-                                    save_op=(int*)mxRealloc(save_op,nopa*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                                    mexPrintf("ok\n");
-#endif
-                                  }
-                                save_op_s=(t_save_op_s*)(&(save_op[nop]));
-                                save_op_s->operat=IFSUB;
-                                save_op_s->first=b[row];
-                                save_op_s->second=b[pivj];
-                                save_op_s->lag=abs(tmp_lag);
+                                nopa = int (1.5*nopa);
+                                save_op = (int *) mxRealloc(save_op, nopa*sizeof(int));
                               }
-                            nop+=3;
-                          }
-#ifdef RECORD_ALL
-                        else if (record_all)
-                          {
-                            if (nop_all+2>=nopa_all)
-                              chk_avail_mem(&save_op_all,&nop_all,&nopa_all,2,t);
-                            save_op_all[nop_all]=IFSUB;
-                            save_op_all[nop_all+1]=b[row];
-                            save_op_all[nop_all+2]=b[pivj];
-                            nop_all+=3;
-                          }
-                        if(iter>0)
-                          {
-                            mexPrintf("ok4g j=%d\n",j);
-                            mexEvalString("drawnow;");
-                          }
-
-#endif
-                      }
-                    /*else
-                      first=first->NZE_C_N;*/
-
-#ifdef PRINT_OUT
-                    mexPrintf(" bef first=%x\n",first);
-#endif
-                  }
-              }
-            if (symbolic)
-              {
-#ifdef PROFILER
-                td1=clock();
-                mexPrintf("at %d nop=%d ?= nop1=%d record=%d save_opa=%x save_opaa=%x \n", t, nop, nop1, record, save_opa, save_opaa);
-                mexEvalString("drawnow;");
-#endif
-                if (record && (nop==nop1))
-                  {
-#ifdef PRINT_OUT
-                    mexPrintf("nop=%d, nop1=%d, record=%d save_opa=%x save_opaa=%x\n",nop, nop1, record, save_opa, save_opaa);
-#endif
-                    if (save_opa && save_opaa)
-                      {
-#ifdef PROFILER
-                        clock_t ta=clock();
-#endif
-                        if (compare( save_op, save_opa, save_opaa, t, periods, nop, Size
-#ifdef PROFILER
-                        , &ndiv, &nsub
-#endif
-                        ))
-                          {
-#ifdef PROFILER
-                            mexPrintf("done OK\n");
-                            mexPrintf("t=%d over periods=%d t0=%f t1=%f y_kmin=%d y_kmax=%d\n",t,periods,1000*(ta-t00), 1000.0*(double(clock())-double(ta))/double(CLOCKS_PER_SEC),y_kmin, y_kmax);
-                            mexPrintf("compare time %f ms\n",1000.0*(double(clock())-double(ta))/double(CLOCKS_PER_SEC));
-                            mexEvalString("drawnow;");
-#endif
-                            tbreak=t;
-                            tbreak_g=tbreak;
-                            break;
-                          }
-                      }
-                    if (save_opa)
-                      {
-                        if (save_opaa)
-                          {
-#ifdef N_MX_ALLOC
-                            free(save_opaa);
-#else
-                            mxFree(save_opaa);
-#endif
-                            save_opaa=NULL;
-                          }
-#ifdef MEM_ALLOC_CHK
-                        mexPrintf("save_opaa=(int*)mxMalloc(%d*sizeof(int))\n",nop1);
-#endif
-#ifdef N_MX_ALLOC
-                        save_opaa=malloc_std(nop1);
-#else
-                        save_opaa=(int*)mxMalloc(nop1*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                        mexPrintf("ok\n");
-#endif
-                        memcpy(save_opaa, save_opa, nop1*sizeof(int));
-                      }
-                    if (save_opa)
-                      {
-#ifdef N_MX_ALLOC
-                        free(save_opa);
-#else
-                        mxFree(save_opa);
-#endif
-                        save_opa=NULL;
-                      }
-#ifdef MEM_ALLOC_CHK
-                    mexPrintf("save_opa=(int*)mxMalloc(%d*sizeof(int))\n",nop);
-#endif
-#ifdef N_MX_ALLOC
-                    save_opa=malloc_std(nop);
-#else
-                    save_opa=(int*)mxMalloc(nop*sizeof(int));
-#endif
-#ifdef MEM_ALLOC_CHK
-                    mexPrintf("ok\n");
-#endif
-                    memcpy(save_opa, save_op, nop*sizeof(int));
-                  }
-                else
-                  {
-                    if (nop==nop1)
-                      record=true;
-                    else
-                      {
-                        record=false;
-                        if (save_opa)
-                          {
-#ifdef N_MX_ALLOC
-                            free(save_opa);
-#else
-                            mxFree(save_opa);
-#endif
-                            save_opa=NULL;
-                          }
-                        if (save_opaa)
-                          {
-#ifdef N_MX_ALLOC
-                            free(save_opaa);
-#else
-                            mxFree(save_opaa);
-#endif
-                            save_opaa=NULL;
-                          }
-                      }
-                  }
-                nop2=nop1;
-                nop1=nop;
-#ifdef PROFILER
-                tcompare+=clock()-td1;
-#endif
-              }
-            record=true;
-          }
-      }
-  nop_all+=nop;
-#ifdef PROFILER
-  t01=clock();
-  mexPrintf("resolution time=%f ms ndiv=%d nsub=%d ncomp=%d \n",1000.0*(double(t01)-double(t00))/double(CLOCKS_PER_SEC),ndiv,nsub,ncomp);
-  mexPrintf(" tinsert=%f tdelete=%f tpivot=%f tbigloop=%f tdelete1=%f tdelete2=%f \n",double(1000*tinsert), double(1000*tdelete), double(1000*tpivot), double(1000*tbigloop), double(1000*tdelete1), double(1000*tdelete2));
-  mexPrintf(" tdelete21=%f tdelete22=%f \n",double(1000*tdelete21),double(1000*tdelete22));
-  mexPrintf(" tdelete221=%f tdelete222=%f \n",double(1000*tdelete221),double(1000*tdelete222));
-  mexPrintf(" tcompare=%f \n",double(1000*tcompare));
-  mexPrintf(" ninsert=%d\n",ninsert);
-  mexPrintf("nbpivot=%d, nbdiv=%d, nbless=%d, nop=%d nbpivot_it=%d nbRealloc=%d\n", nbpivot, nbdiv, nbless, nbpivot + nbdiv + nbless, nbpivot_it, nbRealloc);
-  mexEvalString("drawnow;");
-#endif
+                            }
+                          save_op_s_l = (t_save_op_s *) (&(save_op[nop]));
+                          save_op_s_l->operat = IFSUB;
+                          save_op_s_l->first = b[row];
+                          save_op_s_l->second = b[pivj];
+                          save_op_s_l->lag = abs(tmp_lag);
+                        }
+                      nop += 3;
+                    }
+                }
+            }
+          if (symbolic)
+            {
+              if (record && (nop == nop1))
+                {
+                  if (save_opa && save_opaa)
+                    {
+                      if (compare(save_op, save_opa, save_opaa, t, periods, nop, Size))
+                        {
+                          tbreak = t;
+                          tbreak_g = tbreak;
+                          break;
+                        }
+                    }
+                  if (save_opa)
+                    {
+                      if (save_opaa)
+                        {
+                          mxFree(save_opaa);
+                          save_opaa = NULL;
+                        }
+                      save_opaa = (int *) mxMalloc(nop1*sizeof(int));
+                      memcpy(save_opaa, save_opa, nop1*sizeof(int));
+                    }
+                  if (save_opa)
+                    {
+                      mxFree(save_opa);
+                      save_opa = NULL;
+                    }
+                  save_opa = (int *) mxMalloc(nop*sizeof(int));
+                  memcpy(save_opa, save_op, nop*sizeof(int));
+                }
+              else
+                {
+                  if (nop == nop1)
+                    record = true;
+                  else
+                    {
+                      record = false;
+                      if (save_opa)
+                        {
+                          mxFree(save_opa);
+                          save_opa = NULL;
+                        }
+                      if (save_opaa)
+                        {
+                          mxFree(save_opaa);
+                          save_opaa = NULL;
+                        }
+                    }
+                }
+              nop2 = nop1;
+              nop1 = nop;
+            }
+          //record = true;
+        }
+    }
+  nop_all += nop;
   if (symbolic)
     {
-#ifdef N_MX_ALLOC
-      if (save_op)
-        free(save_op);
-      if (save_opa)
-        free(save_opa);
-      if (save_opaa)
-        free(save_opaa);
-#else
       if (save_op)
         mxFree(save_op);
       if (save_opa)
         mxFree(save_opa);
       if (save_opaa)
         mxFree(save_opaa);
-#endif
     }
   close_swp_file();
 
   /*The backward substitution*/
-#ifdef PRINT_OUT
-  Print(Size,b);
-#endif
-  double slowc_lbx=slowc, res1bx;
-#ifdef PROFILER
-  t00 = clock();
-#endif
-  for (i=0;i<y_size*(periods+y_kmin);i++)
-    ya[i]=y[i];
-  slowc_save=slowc;
-  res1bx=bksub( tbreak, last_period, Size, slowc_lbx
-#ifdef PROFILER
-  , &nmul
-#endif
-  );
-  //t01=pctimer();
-  t01=clock();
-#ifdef PROFILER
-  mexPrintf("backward substitution time=%f ms nmul=%d\n",1000.0*(double(t01)-double(t00))/double(CLOCKS_PER_SEC),nmul);
-  mexEvalString("drawnow;");
-#endif
-#ifdef RECORD_ALL
-  if (!((record_all && nop_all)||g_nop_all>0))
-    {
-      u_count=save_u_count;
-
-    }
-#endif
+  double slowc_lbx = slowc, res1bx;
+  for (i = 0; i < y_size*(periods+y_kmin); i++)
+    ya[i] = y[i];
+  slowc_save = slowc;
+  res1bx = bksub(tbreak, last_period, Size, slowc_lbx);
+  t01 = clock();
   End(Size);
   if (print_it)
     {
-      //pctimer_t t2 = pctimer();
       clock_t t2 = clock();
-      mexPrintf("(** %f milliseconds **)\n", 1000.0*(double(t2) - double(t1))/double(CLOCKS_PER_SEC));
+      mexPrintf("(** %f milliseconds **)\n", 1000.0*(double (t2) - double (t1))/double (CLOCKS_PER_SEC));
       mexEvalString("drawnow;");
     }
 
-#ifdef WRITE_u
-  if (!symbolic)
-    {
-      toto.close();
-      mexEvalString("st=fclose('all');clear all;");
-      filename+=" stopped";
-      mexErrMsgTxt(filename.c_str());
-    }
-#endif
   close_swp_file();
-  time00=clock();
-  if(tbreak_g==0)
-    tbreak_g=periods;
+  time00 = clock();
+  if (tbreak_g == 0)
+    tbreak_g = periods;
+
+  /*Check the solution*/
 
-	/*Check the solution*/
-	/*Check_the_Solution(periods, y_kmin, y_kmax, Size, ua, pivot, b);
-	mxFree(ua);*/
+  /*Check_the_Solution(periods, y_kmin, y_kmax, Size, ua, pivot, b);
+     mxFree(ua);*/
 
-  return(0);
+  return (0);
 }
 
 void
 SparseMatrix::fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1)
 {
-  //mexPrintf("u_count_int=%d\n",u_count_int);
-  u_count=u_count_int * periods;
+  u_count = u_count_int * periods;
   u_count_alloc = 2*u_count;
-  //mexPrintf("mxMalloc(%d*sizeof(double)=%d)\n",u_count_alloc,u_count_alloc*sizeof(double));
-  (*u)=(double*)mxMalloc(u_count_alloc*sizeof(double));
+  (*u) = (double *) mxMalloc(u_count_alloc*sizeof(double));
   memset((*u), 0, u_count_alloc*sizeof(double));
-  u_count_init=max_lag_plus_max_lead_plus_1;
+  u_count_init = max_lag_plus_max_lead_plus_1;
 }
 
diff --git a/mex/sources/simulate/SparseMatrix.hh b/mex/sources/simulate/SparseMatrix.hh
index e5b57a76ab7c3249a1ec70fdace027e8cd0ca6dd..3954fae7a9eabaa63a12a8a26edaa42278f56313 100644
--- a/mex/sources/simulate/SparseMatrix.hh
+++ b/mex/sources/simulate/SparseMatrix.hh
@@ -33,15 +33,13 @@
 #endif
 #define NEW_ALLOC
 #define MARKOVITZ
-//#define PROFILER
-//#define MEMORY_LEAKS
 
 using namespace std;
 
 struct t_save_op_s
 {
   short int lag, operat;
-  long int first, second;
+  int first, second;
 };
 
 const int IFLD  =0;
@@ -62,11 +60,10 @@ class SparseMatrix
   public:
     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 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 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);
     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 initialize(int periods_arg, int nb_endo_arg, int y_kmin_arg, int y_kmax_arg, int y_size_arg, int u_count_arg, int u_count_init_arg, double *u_arg, double *y_arg, double *ya_arg, double slowc_arg, int y_decal_arg, double markowitz_c_arg, double res1_arg, double res2_arg, double max_res_arg);
-    void Read_SparseMatrix(string file_name, int Size, int periods, int y_kmin, int y_kmax);
+    void Read_SparseMatrix(string file_name, int Size, int periods, int y_kmin, int y_kmax, bool steady_state);
     void Read_file(string file_name, int periods, int u_size1, int y_size, int y_kmin, int y_kmax, int &nb_endo, int &u_count, int &u_count_init, double* u);
 
  private:
@@ -80,7 +77,7 @@ class SparseMatrix
 #endif
                 );
     void Insert(const int r, const int c, const int u_index, const int lag_index);
-    void Delete(const int r,const int c, const int Size);
+    void Delete(const int r,const int c);
     int At_Row(int r, NonZeroElem **first);
     int At_Pos(int r, int c, NonZeroElem **first);
     int At_Col(int c, NonZeroElem **first);
@@ -102,9 +99,6 @@ class SparseMatrix
 #endif
     );
     double simple_bksub(int it_, int Size, double slowc_l);
-    void run_triangular(int nop_all,int *op_all);
-    void run_it(int nop_all,int *op_all);
-    void run_u_period1(int periods);
     void close_swp_file();
     stack<double> Stack;
     int nb_prologue_table_u, nb_first_table_u, nb_middle_table_u, nb_last_table_u;
@@ -118,6 +112,7 @@ class SparseMatrix
 
     Mem_Mngr mem_mngr;
     vector<int> u_liste;
+    map<pair<int, int>,NonZeroElem*> Mapped_Array;
     int *NbNZRow, *NbNZCol;
     NonZeroElem **FNZE_R, **FNZE_C;
     int nb_endo, u_count_init;
@@ -148,6 +143,7 @@ protected:
     double *direction;
     int start_compare;
     int restart;
+    bool error_not_printed;
   };
 
 
diff --git a/mex/sources/simulate/simulate.cc b/mex/sources/simulate/simulate.cc
index 737afb8b51bfd93f0413e9685ace288f95b0f4fd..f311df18ab815e295e9e82aa2d8f3747ef3139a0 100644
--- a/mex/sources/simulate/simulate.cc
+++ b/mex/sources/simulate/simulate.cc
@@ -43,7 +43,6 @@ max(int a, int b)
 
 
 #ifdef DEBUG_EX
-/*The Matlab c++ interface*/
 
 using namespace std;
 #include <sstream>
@@ -53,7 +52,14 @@ int
 main( int argc, const char* argv[] )
 {
   FILE *fid;
+  bool steady_state = false;
   printf("argc=%d\n",argc);
+  if(argc<2)
+    {
+    	mexPrintf("model filename expected\n");
+    	mexEvalString("st=fclose('all');clear all;");
+      mexErrMsgTxt("Exit from Dynare");
+    }
   float f_tmp;
   ostringstream tmp_out("");
   tmp_out << argv[1] << "_options.txt";
@@ -64,51 +70,48 @@ main( int argc, const char* argv[] )
   double *direction;
 
   string file_name(argv[1]);
-  //mexPrintf("file_name=%s\n",file_name.c_str());
 
+  if(argc>2)
+    {
+      string f(argv[1]);
+      if(f == "steady_state")
+        steady_state = true;
+    }
   fid = fopen(tmp_out.str().c_str(),"r");
+  int periods;
   fscanf(fid,"%d",&periods);
+  int maxit_;
   fscanf(fid,"%d",&maxit_);
   fscanf(fid,"%f",&f_tmp);
-  slowc = f_tmp;
-  //mexPrintf("slowc_save=%f\n",slowc_save);
+  double slowc = f_tmp;
   fscanf(fid,"%f",&f_tmp);
-  markowitz_c = f_tmp;
+  double markowitz_c = f_tmp;
   fscanf(fid,"%f",&f_tmp);
-  solve_tolf = f_tmp;
+  double solve_tolf = f_tmp;
   fclose(fid);
 
   tmp_out.str("");
   tmp_out << argv[1] << "_M.txt";
-  //printf("%s\n",tmp_out.str().c_str());
   fid = fopen(tmp_out.str().c_str(),"r");
+  int y_kmin;
   fscanf(fid,"%d",&y_kmin);
-  //printf("y_kmin=%d\n",y_kmin);
+  int y_kmax;
   fscanf(fid,"%d",&y_kmax);
-  //printf("y_kmax=%d\n",y_kmax);
+  int y_decal;
   fscanf(fid,"%d",&y_decal);
-  //printf("y_decal=%d\n",y_decal);
   fscanf(fid,"%d",&nb_params);
-  //printf("nb_params=%d\n",nb_params);
   fscanf(fid,"%d",&row_x);
-  //printf("row_x=%d\n",row_x);
   fscanf(fid,"%d",&col_x);
-  //printf("col_x=%d\n",col_x);
   fscanf(fid,"%d",&row_y);
-  //printf("row_y=%d\n",row_y);
   fscanf(fid,"%d",&col_y);
-  //printf("col_y=%d\n",col_y);
+  int nb_row_xd;
   fscanf(fid,"%d",&nb_row_xd);
-  //printf("nb_row_xd=%d\n",nb_row_xd);
-  params = (double*)malloc(nb_params*sizeof(params[0]));
-  //printf("OK1\n");
+  double * params = (double*)malloc(nb_params*sizeof(params[0]));
   for(i=0; i < nb_params; i++)
     {
       fscanf(fid,"%f",&f_tmp);
       params[i] = f_tmp;
-      //printf("param[%d]=%f\n",i,params[i]);
     }
-  //printf("OK2\n");
   fclose(fid);
   yd = (double*)malloc(row_y*col_y*sizeof(yd[0]));
   xd = (double*)malloc(row_x*col_x*sizeof(xd[0]));
@@ -127,12 +130,12 @@ main( int argc, const char* argv[] )
     }
   fclose(fid);
 
-  size_of_direction=col_y*row_y*sizeof(double);
-  y=(double*)mxMalloc(size_of_direction);
-  ya=(double*)mxMalloc(size_of_direction);
+  int size_of_direction=col_y*row_y*sizeof(double);
+  double * y=(double*)mxMalloc(size_of_direction);
+  double * ya=(double*)mxMalloc(size_of_direction);
   direction=(double*)mxMalloc(size_of_direction);
   memset(direction,0,size_of_direction);
-  x=(double*)mxMalloc(col_x*row_x*sizeof(double));
+  double * x=(double*)mxMalloc(col_x*row_x*sizeof(double));
   for (i=0;i<row_x*col_x;i++)
      x[i]=double(xd[i]);
   for (i=0;i<row_y*col_y;i++)
@@ -140,36 +143,14 @@ main( int argc, const char* argv[] )
   free(yd);
   free(xd);
 
-  y_size=row_y;
-  x_size=col_x/*row_x*/;
-  nb_row_x=row_x;
-  /*for(int i=0; i<y_size; i++)
-    {
-      for(int it_=0; it_<8;it_++)
-        mexPrintf("y[t=%d, var=%d]=%f  ",it_+1, i+1, y[(it_)*y_size+i]);
-      mexPrintf("\n");
-    }
-
-  for(int i=0; i<col_x; i++)
-    {
-      for(int it_=0; it_<8;it_++)
-        mexPrintf("x[t=%d, var=%d]=%f  ",it_, i+1, x[it_+i*nb_row_x]);
-      mexPrintf("\n");
-    }*/
-
-  t0= clock();
+  int y_size=row_y;
+  int nb_row_x=row_x;
+  clock_t t0= clock();
   Interpreter interprete(params, y, ya, x, direction, y_size, nb_row_x, nb_row_xd, periods, y_kmin, y_kmax, maxit_, solve_tolf, size_of_direction, slowc, y_decal, markowitz_c, file_name);
   string f(file_name);
-  interprete.compute_blocks(f+"_dynamic", f);
-  t1= clock();
+  interprete.compute_blocks(f, f, steady_state);
+  clock_t t1= clock();
   mexPrintf("Simulation Time=%f milliseconds\n",1000.0*(double(t1)-double(t0))/double(CLOCKS_PER_SEC));
-  /*if (nlhs>0)
-    {
-      plhs[0] = mxCreateDoubleMatrix(row_y, col_y, mxREAL);
-      pind = mxGetPr(plhs[0]);
-      for (i=0;i<row_y*col_y;i++)
-        pind[i]=y[i];
-    }*/
   if(x)
     mxFree(x);
   if(y)
@@ -187,9 +168,24 @@ void
 mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
 {
   mxArray *M_, *oo_, *options_;
-  int i, row_y, col_y, row_x, col_x;
+  int i, row_y, col_y, row_x, col_x, nb_row_xd;
+  int y_kmin=0, y_kmax=0, y_decal=0, periods=1;
   double * pind ;
   double *direction;
+  bool steady_state = false;
+  if(nrhs>0)
+    {
+    	const mxArray *mxa = prhs[0];
+      int buflen=mxGetM(mxa) * mxGetN(mxa) + 1;
+      char *first_argument;
+      first_argument=(char*)mxCalloc(buflen, sizeof(char));
+      int status = mxGetString(mxa, first_argument, buflen);
+      if (status != 0)
+        mexWarnMsgTxt("Not enough space. The first argument is truncated.");
+      string f(first_argument);
+      if(f == "steady_state")
+        steady_state = true;
+    }
   M_ = mexGetVariable("global","M_");
   if (M_ == NULL )
     {
@@ -213,22 +209,41 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
       mexErrMsgTxt("options_ \n");
     }
   //mexPrintf("ok0\n");
-  params = mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"params")));
+  double * params = mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"params")));
   double *yd, *xd;
-  yd= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"endo_simul")));
-  row_y=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"endo_simul")));
-  xd= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_simul")));
-  row_x=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_simul")));
-  col_x=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_simul")));
-  y_kmin=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"maximum_lag"))))));
-  y_kmax=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"maximum_lead"))))));
-  y_decal=max(0,y_kmin-int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"maximum_endo_lag")))))));
-  periods=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"periods"))))));
-  maxit_=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"maxit_"))))));
-  slowc=double(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"slowc")))));
-  //slowc_save=slowc;
-  markowitz_c=double(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"markowitz")))));
-  nb_row_xd=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"exo_det_nbr"))))));
+  if(!steady_state)
+    {
+      yd= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"endo_simul")));
+      row_y=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"endo_simul")));
+      col_y=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"endo_simul")));;
+      xd= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_simul")));
+      row_x=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_simul")));
+      col_x=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_simul")));
+      nb_row_xd=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"exo_det_nbr"))))));
+
+      y_kmin=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"maximum_lag"))))));
+      y_kmax=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"maximum_lead"))))));
+      y_decal=max(0,y_kmin-int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"maximum_endo_lag")))))));
+      periods=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"periods"))))));
+    }
+	else
+	  {
+	  	yd= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"steady_state")));
+      row_y=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"steady_state")));
+      col_y=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"steady_state")));;
+      xd= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_steady_state")));
+      row_x=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_steady_state")));
+      col_x=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"exo_steady_state")));
+      nb_row_xd=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"exo_det_nbr"))))));
+	  }
+	int maxit_=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"maxit_"))))));
+  double slowc=double(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"slowc")))));
+  double markowitz_c=double(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"markowitz")))));
+  double solve_tolf;
+  if(steady_state)
+    solve_tolf=*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"solve_tolf"))));
+	else
+    solve_tolf=*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"dynatol"))));
   mxArray *mxa=mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,"fname"));
   int buflen=mxGetM(mxa) * mxGetN(mxa) + 1;
   char *fname;
@@ -237,48 +252,47 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
   int status = mxGetString(mxa, fname, buflen);
   if (status != 0)
     mexWarnMsgTxt("Not enough space. Filename is truncated.");
-  col_y=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,"endo_simul")));;
-  solve_tolf=*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,"dynatol"))));
-  size_of_direction=col_y*row_y*sizeof(double);
-  y=(double*)mxMalloc(size_of_direction);
-  ya=(double*)mxMalloc(size_of_direction);
+
+
+  int size_of_direction=col_y*row_y*sizeof(double);
+  double * y=(double*)mxMalloc(size_of_direction);
+  double * ya=(double*)mxMalloc(size_of_direction);
   direction=(double*)mxMalloc(size_of_direction);
   memset(direction,0,size_of_direction);
-  x=(double*)mxMalloc(col_x*row_x*sizeof(double));
+  double * x=(double*)mxMalloc(col_x*row_x*sizeof(double));
   for (i=0;i<row_x*col_x;i++)
      x[i]=double(xd[i]);
   for (i=0;i<row_y*col_y;i++)
     y[i]=double(yd[i]);
-  y_size=row_y;
-  x_size=col_x/*row_x*/;
-  nb_row_x=row_x;
-
-  /*for(int i=0; i<y_size; i++)
-    {
-      for(int it_=0; it_<8;it_++)
-        mexPrintf("y[t=%d, var=%d]=%f  ",it_+1, i+1, y[(it_)*y_size+i]);
-      mexPrintf("\n");
-    }
+  int y_size=row_y;
+  int nb_row_x=row_x;
 
-  for(int i=0; i<col_x; i++)
-    {
-      for(int it_=0; it_<8;it_++)
-        mexPrintf("x[t=%d, var=%d]=%f  ",it_, i+1, x[it_+i*nb_row_x]);
-      mexPrintf("\n");
-    }*/
+  /*int it_ = y_kmin;
+  for (int j = 0; j < y_size; j++)
+		mexPrintf("   variable %d at time %d and %d = %f\n", j+1, it_, it_+1, y[j+it_*y_size]);*/
 
-  t0= clock();
+  clock_t t0= clock();
   Interpreter interprete(params, y, ya, x, direction, y_size, nb_row_x, nb_row_xd, periods, y_kmin, y_kmax, maxit_, solve_tolf, size_of_direction, slowc, y_decal, markowitz_c, file_name);
   string f(fname);
-  interprete.compute_blocks(f+"_dynamic", f);
-  t1= clock();
-  mexPrintf("Simulation Time=%f milliseconds\n",1000.0*(double(t1)-double(t0))/double(CLOCKS_PER_SEC));
+  bool result = interprete.compute_blocks(f, f, steady_state);
+  clock_t t1= clock();
+  if(!steady_state)
+    mexPrintf("Simulation Time=%f milliseconds\n",1000.0*(double(t1)-double(t0))/double(CLOCKS_PER_SEC));
   if (nlhs>0)
     {
       plhs[0] = mxCreateDoubleMatrix(row_y, col_y, mxREAL);
       pind = mxGetPr(plhs[0]);
       for (i=0;i<row_y*col_y;i++)
         pind[i]=y[i];
+			if(nlhs>1)
+			  {
+			    plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL);
+			    pind = mxGetPr(plhs[1]);
+			    if(result)
+			      pind[0] = 0;
+					else
+					  pind[0] = 1;
+			  }
     }
   if(x)
     mxFree(x);
diff --git a/mex/sources/simulate/simulate.hh b/mex/sources/simulate/simulate.hh
index 8e17565624dcfbabaa24984046015e8b0f35dae9..516dd459ef85a3de7a5ce851ffca0882efa3b983 100644
--- a/mex/sources/simulate/simulate.hh
+++ b/mex/sources/simulate/simulate.hh
@@ -31,32 +31,6 @@
 using namespace std;
 
 
-
-
-int nb_row_x, nb_row_xd, u_size, y_size, x_size, y_kmin, y_kmax, y_decal;
-int periods, maxit_;
-double *params, markowitz_c, slowc, slowc_save;
-double  *u, *y, *x, *r, *g1, *g2, *ya;
-double solve_tolf;
-//pctimer_t t0, t1;
-clock_t t0, t1;
-int size_of_direction;
-int i, j, k;
-
-
-/*double err;
-
-
-
-
-
-
-double res1, res2;
-
-double max_res;
-bool cvg;
-
-*/
-
+//double  *u, *y, *x, *r, *g1, *g2, *ya;
 
 #endif // SIMULATE_HH_INCLUDED
diff --git a/mex/sources/simulate/testing/mex_interface.cc b/mex/sources/simulate/testing/mex_interface.cc
index 8f9ff5d20c34c88e7f968eafed48b908bf650e81..40b76f0f037b895265daefb2bac6b41cfd4049f8 100644
--- a/mex/sources/simulate/testing/mex_interface.cc
+++ b/mex/sources/simulate/testing/mex_interface.cc
@@ -5,66 +5,23 @@
 using namespace std;
 
 int
-mexPrintf(/*string */const char *str, ...)
+mexPrintf(const char *str, ...)
 {
-  /*va_list vl;
-  size_t found, found_p=0;
-  found=str.find_first_of("%");
-  va_start(vl,str);
-  while (found!=string::npos)
-  {
-    ostringstream tmp_out("");
-    //tmp_out.clear();
-    tmp_out << "%";
-    char c = str[found+1];
-    while((c>='0' and c<='9') or c=='.')
-      {
-        tmp_out << c;
-        found++;
-        c = str[found+1];
-      }
-    tmp_out << c;
-    switch(c)
-      {
-        case 'd':
-          printf(str.substr(found_p, found-found_p).c_str());
-          printf(tmp_out.str().c_str(),va_arg(vl,int));
-          break;
-        case 'e':
-        case 'f':
-        case 'g':
-          printf(str.substr(found_p, found-found_p).c_str());
-          printf(tmp_out.str().c_str(),va_arg(vl,double));
-          break;
-        case 's':
-          printf(str.substr(found_p, found-found_p).c_str());
-          printf(tmp_out.str().c_str(),va_arg(vl,char*));
-          break;
-        case 'x':
-          printf(str.substr(found_p, found-found_p).c_str());
-          printf(tmp_out.str().c_str(),va_arg(vl,int));
-          break;
-      }
-    found_p = found+2;
-    found=str.find_first_of("%",found_p);
-   }
-  printf(str.substr(found_p, str.size()-found_p+1).c_str());
-  return 0;*/
   va_list args;
-        int retval;
+  int retval;
 
-        va_start (args, str);
-        retval = vprintf (str, args);
-        va_end (args);
-
-        return retval;
+  va_start (args, str);
+  retval = vprintf (str, args);
+  va_end (args);
 
+  return retval;
 }
 
 void
 mexErrMsgTxt(const string str)
 {
   perror(str.c_str());
+  exit(EXIT_FAILURE);
 }
 
 void
diff --git a/mex/sources/simulate/testing/simulate_debug.m b/mex/sources/simulate/testing/simulate_debug.m
index ce21bfa34c00be3eaa9944c3997da0d31a60255b..b75aadc5150f1c489e64751d4b1b8c3c99ac9e85 100644
--- a/mex/sources/simulate/testing/simulate_debug.m
+++ b/mex/sources/simulate/testing/simulate_debug.m
@@ -3,9 +3,9 @@ global M_ oo_ options_;
      fid = fopen([M_.fname '_options.txt'],'wt');
      fprintf(fid,'%d\n',options_.periods);
      fprintf(fid,'%d\n',options_.maxit_);
-     fprintf(fid,'%f\n',options_.slowc);
-     fprintf(fid,'%f\n',options_.markowitz);
-     fprintf(fid,'%f\n',options_.dynatol);
+     fprintf(fid,'%6.20f\n',options_.slowc);
+     fprintf(fid,'%6.20f\n',options_.markowitz);
+     fprintf(fid,'%6.20f\n',options_.dynatol);
      fclose(fid);
      
      fid = fopen([M_.fname '_M.txt'],'wt');
@@ -18,11 +18,11 @@ global M_ oo_ options_;
      fprintf(fid,'%d\n',M_.endo_nbr);
      fprintf(fid,'%d\n',size(oo_.endo_simul, 2));
      fprintf(fid,'%d\n',M_.exo_det_nbr);
-     fprintf(fid,'%f\n',M_.params);
+     fprintf(fid,'%6.20f\n',M_.params);
 
      fclose(fid);
      fid = fopen([M_.fname '_oo.txt'],'wt');
-     fprintf(fid,'%f\n',oo_.endo_simul);
-     fprintf(fid,'%f\n',oo_.exo_simul);
+     fprintf(fid,'%6.20f\n',oo_.endo_simul);
+     fprintf(fid,'%6.20f\n',oo_.exo_simul);
      fclose(fid);
      
\ No newline at end of file
diff --git a/preprocessor/BlockTriangular.cc b/preprocessor/BlockTriangular.cc
index 3260e546959ed08a60f0f440d1efbe68d1c18d0a..14c8063e275682d2a7cac176ade4a6aae20421b0 100644
--- a/preprocessor/BlockTriangular.cc
+++ b/preprocessor/BlockTriangular.cc
@@ -20,7 +20,6 @@
 #include <iostream>
 #include <sstream>
 #include <fstream>
-#include <ctime>
 #include <cstdlib>
 #include <cstring>
 #include <cmath>
@@ -46,6 +45,7 @@ BlockTriangular::BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstan
   bt_verbose = 0;
   ModelBlock = NULL;
   periods = 0;
+  prologue = epilogue = 0;
   Normalized_Equation = new DataTree(symbol_table, num_const);
 }
 
@@ -114,7 +114,7 @@ BlockTriangular::Prologue_Epilogue(bool *IM, int &prologue, int &epilogue, int n
 //------------------------------------------------------------------------------
 // Find a matching between equations and endogenous variables
 bool
-BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Equ_IM) const
+BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, int verbose, bool *IM0, vector<int> &Index_Equ_IM) const
 {
   int n = equation_number - prologue - epilogue;
 
@@ -143,9 +143,17 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
       mate_map_t::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits<BipartiteGraph>::null_vertex());
       if (it != mate_map.begin() + n)
         {
-          if (verbose)
+          if (verbose == 1)
             {
-              cerr << "ERROR: Could not normalize dynamic model. Variable "
+              cerr << "WARNING: Could not normalize dynamic model. Variable "
+                   << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin()))
+                   << " is not in the maximum cardinality matching. Trying to find a singular normalization." << endl;
+              //exit(EXIT_FAILURE);
+              return false;
+            }
+          else if (verbose == 2)
+            {
+              cerr << "ERROR: Could not normalize dynamic model (even with a singularity). Variable "
                    << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin()))
                    << " is not in the maximum cardinality matching." << endl;
               exit(EXIT_FAILURE);
@@ -183,7 +191,7 @@ BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int
           variable_blck[Index_Var_IM[i]] = i;
           equation_blck[Index_Equ_IM[i]] = i;
         }
-      else if (i < components_set.size() + prologue)
+      else if (i < (int)components_set.size() + prologue)
         {
           variable_blck[Index_Var_IM[i]] = components_set[i-prologue] + prologue;
           equation_blck[Index_Equ_IM[i]] = components_set[i-prologue] + prologue;
@@ -226,7 +234,7 @@ BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int
 }
 
 void
-BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const
+BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs) const
 {
   t_vtype V_Variable_Type;
   int n = nb_var - prologue - epilogue;
@@ -272,11 +280,16 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
   memcpy(SIM, IM, nb_var*nb_var*sizeof(bool));
 
   //Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set
-  for (int i = 0; i < n; i++)
-    if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or V_Variable_Type[Index_Var_IM[i+prologue]].second > 0 or V_Variable_Type[Index_Var_IM[i+prologue]].first > 0
-                                                               or equation_lead_lag[Index_Equ_IM[i+prologue]].second > 0 or equation_lead_lag[Index_Equ_IM[i+prologue]].first > 0)
-      add_edge(i, i, G2);
-
+  if(select_feedback_variable)
+    for (int i = 0; i < n; i++)
+      if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or V_Variable_Type[Index_Var_IM[i+prologue]].second > 0 or V_Variable_Type[Index_Var_IM[i+prologue]].first > 0
+                                                               or equation_lead_lag[Index_Equ_IM[i+prologue]].second > 0 or equation_lead_lag[Index_Equ_IM[i+prologue]].first > 0
+                                                               or mfs == 0)
+        add_edge(i, i, G2);
+  else
+    for (int i = 0; i < n; i++)
+      if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or mfs == 0)
+        add_edge(i, i, G2);
   //For each block, the minimum set of feedback variable is computed
   // and the non-feedback variables are reordered to get
   // a sub-recursive block without feedback variables
@@ -686,7 +699,7 @@ BlockTriangular::Free_Block(Model_Block *ModelBlock) const
 }
 
 t_etype
-BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM)
+BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs)
 {
   NodeID lhs, rhs;
   ostringstream tmp_output;
@@ -709,44 +722,40 @@ BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations,
       lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
       tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")";
       map<pair<int, pair<int, int> >, NodeID>::iterator derivative = first_order_endo_derivatives.find(make_pair(eq, make_pair(var, 0)));
-      /*cout << "eq=" << eq << " var=" << var << "=";
-         first_cur_endo_derivatives[make_pair(eq, var)]->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
-         cout << "\n";
-         cout << "equation : ";
-         eq_node->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
-         cout << "\n";*/
       set<pair<int, int> > result;
       pair<bool, NodeID> res;
       derivative->second->collectEndogenous(result);
-      /*for(set<pair<int, int> >::const_iterator iitt = result.begin(); iitt!=result.end(); iitt++)
-         cout << "result = " << iitt->first << ", " << iitt->second << "\n";*/
       set<pair<int, int> >::const_iterator d_endo_variable = result.find(make_pair(var, 0));
       //Determine whether the equation could be evaluated rather than to be solved
-      if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end())
+      ostringstream tt("");
+      derivative->second->writeOutput(tt, oMatlabDynamicModelSparse, temporary_terms);
+      //cout << tt.str().c_str() << " tmp_output.str()=" << tmp_output.str() << " tmp_s.str()=" << tmp_s.str();
+      if (tmp_output.str() == tmp_s.str() and tt.str()=="1")
         {
           Equation_Simulation_Type = E_EVALUATE;
+          //cout << " E_EVALUATE ";
         }
       else
         {
-        	//vector<pair<int, NodeID> > List_of_Op_RHS;
-          //the equation could be normalized by a permutation of the rhs and the lhs
-          if (d_endo_variable == result.end())  //the equation is linear in the endogenous and could be normalized using the derivative
+        	vector<pair<int, pair<NodeID, NodeID> > > List_of_Op_RHS;
+          res =  equations[eq]->normalizeEquation(var, List_of_Op_RHS);
+          if(mfs==2)
             {
-              Equation_Simulation_Type = E_EVALUATE_S;
-              //cout << " gone normalized : ";
-              res =  equations[eq]->normalizeLinearInEndoEquation(var, derivative->second/*, List_of_Op_RHS*/);
-              /*res.second->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
-                 cout << " done\n";*/
+              if(d_endo_variable == result.end() && res.second)
+                Equation_Simulation_Type = E_EVALUATE_S;
+            }
+          else if(mfs==3)
+            {
+              if(res.second) // The equation could be solved analytically
+                Equation_Simulation_Type = E_EVALUATE_S;
             }
         }
+      //cout << " " << c_Equation_Type(Equation_Simulation_Type) << endl;
       V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast<BinaryOpNode *>(res.second));
     }
   return (V_Equation_Simulation_Type);
 }
 
-/*void
-BlockTriangular::Recompute_Deriavtives_Respect_to_Feedback_Variables(
-*/
 t_type
 BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM)
 {
@@ -859,15 +868,15 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
 map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>
 BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck)
 {
-	map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives;
-	Derivatives.clear();
-	int nb_endo = symbol_table.endo_nbr();
-	/*ModelBlock.Block_List[Blck].first_order_determinstic_simulation_derivatives = new*/
+  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives;
+  Derivatives.clear();
+  int nb_endo = symbol_table.endo_nbr();
+  /*ModelBlock.Block_List[Blck].first_order_determinstic_simulation_derivatives = new*/
   for(int lag = -ModelBlock->Block_List[blck].Max_Lag; lag <= ModelBlock->Block_List[blck].Max_Lead; lag++)
     {
-    	bool *IM=incidencematrix.Get_IM(lag, eEndogenous);
-    	if(IM)
-    	  {
+      bool *IM=incidencematrix.Get_IM(lag, eEndogenous);
+      if(IM)
+        {
           for(int eq = 0; eq < ModelBlock->Block_List[blck].Size; eq++)
             {
               int eqr = ModelBlock->Block_List[blck].Equation[eq];
@@ -886,26 +895,26 @@ BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck)
                         	  OK=false;
                         }
 
-											if(OK)
-											  {
-											    if (ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives)
-											    //It's a normalized equation, we have to recompute the derivative using chain rule derivative function*/
+                      if(OK)
+                        {
+                          if (ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives)
+                            //It's a normalized equation, we have to recompute the derivative using chain rule derivative function*/
                             Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1;
-	  								      else
-												  //It's a feedback equation we can use the derivatives
-		  							        Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0;
-											  }
-									    if(var<ModelBlock->Block_List[blck].Nb_Recursives)
-									      {
-									  	    int eqs = ModelBlock->Block_List[blck].Equation[var];
-									  	    for(int vars=ModelBlock->Block_List[blck].Nb_Recursives; vars<ModelBlock->Block_List[blck].Size; vars++)
-									  	      {
-									  	  	    int varrs = ModelBlock->Block_List[blck].Variable[vars];
-									  	  	    //A new derivative need to be computed using the chain rule derivative function (a feedback variable appear in a recursive equation)
-									  	        if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end())
-									  	          Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2;
-									  	      }
-									      }
+                          else
+                            //It's a feedback equation we can use the derivatives
+                            Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0;
+                        }
+                      if(var<ModelBlock->Block_List[blck].Nb_Recursives)
+                        {
+                          int eqs = ModelBlock->Block_List[blck].Equation[var];
+                          for(int vars=ModelBlock->Block_List[blck].Nb_Recursives; vars<ModelBlock->Block_List[blck].Size; vars++)
+                            {
+                              int varrs = ModelBlock->Block_List[blck].Variable[vars];
+                              //A new derivative need to be computed using the chain rule derivative function (a feedback variable appear in a recursive equation)
+                              if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end())
+                                Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2;
+                            }
+                        }
                     }
                 }
             }
@@ -915,18 +924,18 @@ BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck)
 }
 
 void
-BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives)
+BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, bool dynamic, int mfs, double cutoff)
 {
   int i, j, Nb_TotalBlocks, Nb_RecursBlocks, Nb_SimulBlocks;
   BlockType Btype;
   int count_Block, count_Equ;
   bool *SIM0, *SIM00;
 
-
-  SIM0 = (bool *) malloc(n * n * sizeof(bool));
+	SIM0 = (bool *) malloc(n * n * sizeof(bool));
   memcpy(SIM0, IM_0, n*n*sizeof(bool));
   Prologue_Epilogue(IM, prologue, epilogue, n, Index_Var_IM, Index_Equ_IM, SIM0);
   free(SIM0);
+
   int counted = 0;
   if (prologue+epilogue < n)
     {
@@ -956,7 +965,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock,
           memset(SIM00, 0, n*n*sizeof(bool));
           for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
             {
-              if (fabs(iter->second) > bi)
+              if (fabs(iter->second) > max(bi, cutoff))
                 {
                   SIM0[iter->first.first*n+iter->first.second] = 1;
                   if (!IM_0[iter->first.first*n+iter->first.second])
@@ -974,7 +983,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock,
               }
           free(SIM0);
           if (suppress != suppressed)
-            OK = Compute_Normalization(IM, n, prologue, epilogue, false, SIM00, Index_Equ_IM);
+            OK = Compute_Normalization(IM, n, prologue, epilogue, 0, SIM00, Index_Equ_IM);
           suppressed = suppress;
           if (!OK)
             //bi/=1.07;
@@ -984,15 +993,23 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock,
             free(SIM00);
         }
       if (!OK)
-        Compute_Normalization(IM, n, prologue, epilogue, true, SIM00, Index_Equ_IM);
+        {
+          Compute_Normalization(IM, n, prologue, epilogue, 1, SIM00, Index_Equ_IM);
+          Compute_Normalization(IM, n, prologue, epilogue, 2, IM_0, Index_Equ_IM);
+        }
     }
 
-  V_Equation_Type = Equation_Type_determination(equations, first_order_endo_derivatives, Index_Var_IM, Index_Equ_IM);
+  V_Equation_Type = Equation_Type_determination(equations, first_order_endo_derivatives, Index_Var_IM, Index_Equ_IM, mfs);
 
   cout << "Finding the optimal block decomposition of the model ...\n";
   vector<pair<int, int> > blocks;
   if (prologue+epilogue < n)
-    Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false);
+    {
+      if(dynamic)
+        Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false, true, mfs);
+      else
+        Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false, false, mfs);
+    }
 
   t_type  Type = Reduce_Blocks_and_type_determination(prologue, epilogue, blocks, equations, V_Equation_Type, Index_Var_IM, Index_Equ_IM);
 
@@ -1049,7 +1066,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock,
 // normalize each equation of the dynamic model
 // and find the optimal block triangular decomposition of the static model
 void
-BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives)
+BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, int mfs, double cutoff)
 {
   bool *SIM, *SIM_0;
   bool *Cur_IM;
@@ -1091,7 +1108,7 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vec
   SIM_0 = (bool *) malloc(symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM_0));
   for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++)
     SIM_0[i] = Cur_IM[i];
-  Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), prologue, epilogue, Index_Var_IM, Index_Equ_IM, SIM_0, j_m, equations, equation_simulation_type, first_order_endo_derivatives);
+  Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), prologue, epilogue, Index_Var_IM, Index_Equ_IM, SIM_0, j_m, equations, equation_simulation_type, first_order_endo_derivatives, true, mfs, cutoff);
   free(SIM_0);
   free(SIM);
 }
diff --git a/preprocessor/BlockTriangular.hh b/preprocessor/BlockTriangular.hh
index 3d6e6dabf1b2165de81c577d46b20d1e7384d8af..c0ebfb4bb2cb96126c81ba6e7b9513a5ea633e31 100644
--- a/preprocessor/BlockTriangular.hh
+++ b/preprocessor/BlockTriangular.hh
@@ -97,11 +97,11 @@ private:
   //! Allocates and fills the Model structure describing the content of each block
   void Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block *ModelBlock, t_etype &Equation_Type, int recurs_Size, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
   //! Finds a matching between equations and endogenous variables
-  bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Var_IM) const;
+  bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, int verbose, bool *IM0, vector<int> &Index_Var_IM) const;
   //! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables
-  void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const;
+  void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs) const;
   //! determines the type of each equation of the model (could be evaluated or need to be solved)
-  t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
+  t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs);
   //! Tries to merge the consecutive blocks in a single block and determine the type of each block: recursive, simultaneous, ...
   t_type Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
   //! Compute for each variable its maximum lead and lag in its block
@@ -121,8 +121,8 @@ public:
   map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(Model_Block *ModelBlock, int Blck);
 
 
-  void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives);
-  void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives);
+  void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, int mfs, double cutoff);
+  void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, bool dynamic, int mfs, double cutoff);
   vector<int> Index_Equ_IM;
   vector<int> Index_Var_IM;
   int prologue, epilogue;
@@ -187,11 +187,10 @@ public:
   };
   inline static std::string c_Equation_Type(int type)
   {
-    char c_Equation_Type[5][13]=
+    char c_Equation_Type[4][13]=
     {
     "E_UNKNOWN   ",
     "E_EVALUATE  ",
-    //"E_EVALUATE_R",
     "E_EVALUATE_S",
     "E_SOLVE     "
     };
diff --git a/preprocessor/CodeInterpreter.hh b/preprocessor/CodeInterpreter.hh
index cb495131eff5d239aac0103b20fae99a57160a42..a33301f5486287d8dfa2ec864eb72ea8e710db28 100644
--- a/preprocessor/CodeInterpreter.hh
+++ b/preprocessor/CodeInterpreter.hh
@@ -40,6 +40,15 @@ const char FDIMT=16;
 const char FEND=17;
 const char FOK=18;
 const char FENDEQU=19;
+const char FLDSV=20;
+const char FSTPSV=21;
+const char FLDSU=22;
+const char FSTPSU=23;
+const char FLDST=24;
+const char FSTPST=25;
+const char FDIMST=26;
+
+
 
 enum BlockType
   {
@@ -53,7 +62,6 @@ enum EquationType
   {
     E_UNKNOWN,              //!< Unknown equation type
     E_EVALUATE,             //!< Simple evaluation, normalized variable on left-hand side
-    //E_EVALUATE_R,           //!< Simple evaluation, normalized variable on right-hand side
     E_EVALUATE_S,           //!< Simple evaluation, normalize using the first order derivative
     E_SOLVE                 //!< No simple evaluation of the equation, it has to be solved
   };
diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc
index 533f280676028c354a3e8c0e199275841b0e14fe..22ba5950ad6be4c2fac22614154cfce0d3639139 100644
--- a/preprocessor/ComputingTasks.cc
+++ b/preprocessor/ComputingTasks.cc
@@ -27,8 +27,8 @@ using namespace std;
 #include "ComputingTasks.hh"
 #include "Statement.hh"
 
-SteadyStatement::SteadyStatement(const OptionsList &options_list_arg) :
-  options_list(options_list_arg)
+SteadyStatement::SteadyStatement(const OptionsList &options_list_arg, StaticDllModel::mode_t mode_arg) :
+  options_list(options_list_arg), mode(mode_arg)
 {
 }
 
@@ -37,12 +37,17 @@ SteadyStatement::checkPass(ModFileStructure &mod_file_struct)
 {
   if (options_list.num_options.find("block_mfs") != options_list.num_options.end())
     mod_file_struct.steady_block_mfs_option = true;
+  else if (options_list.num_options.find("block_mfs_dll") != options_list.num_options.end())
+    mod_file_struct.steady_block_mfs_dll_option = true;
 }
 
 void
 SteadyStatement::writeOutput(ostream &output, const string &basename) const
 {
   options_list.writeOutput(output);
+  /*if (mode == StaticDllModel::eSparseDLLMode)
+    output << "oo_.steady_state=simulate('steady');" << endl;
+  else*/
   output << "steady;\n";
 }
 
diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh
index fad2123a949c63be3816d08596a4d63a9da4270d..37f7ebc329ddd71e2ffa33b28f506e6412120ce9 100644
--- a/preprocessor/ComputingTasks.hh
+++ b/preprocessor/ComputingTasks.hh
@@ -32,8 +32,9 @@ class SteadyStatement : public Statement
 {
 private:
   const OptionsList options_list;
+  const StaticDllModel::mode_t mode;
 public:
-  SteadyStatement(const OptionsList &options_list_arg);
+  SteadyStatement(const OptionsList &options_list_arg, StaticDllModel::mode_t mode_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct);
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc
index 27471170ff861368ee237aac7f38dd9da4d49bca..89afb45582f2c5f5c38a5972766ad2309a95bf75 100644
--- a/preprocessor/DynamicModel.cc
+++ b/preprocessor/DynamicModel.cc
@@ -23,7 +23,6 @@
 #include <cassert>
 #include <cstdio>
 #include <cerrno>
-
 #include "DynamicModel.hh"
 
 // For mkdir() and chdir()
@@ -46,6 +45,7 @@ DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
     mode(eStandardMode),
     cutoff(1e-15),
     markowitz(0.7),
+    mfs(0),
     block_triangular(symbol_table_arg, num_constants_arg)
 {
 }
@@ -62,7 +62,7 @@ DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int la
     //first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symb_id, lag)));
     first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), lag)));
     if (it != first_derivatives.end())
-      (it->second)->compile(code_file, false, temporary_terms, map_idx);
+      (it->second)->compile(code_file, false, temporary_terms, map_idx, true);
     else
       code_file.write(&FLDZ, sizeof(FLDZ));
   }
@@ -73,7 +73,7 @@ DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr,
 {
   map<pair<int, pair<int, int> >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag)));
   if (it != first_chain_rule_derivatives.end())
-    (it->second)->compile(code_file, false, temporary_terms, map_idx);
+    (it->second)->compile(code_file, false, temporary_terms, map_idx, true);
   else
     code_file.write(&FLDZ, sizeof(FLDZ));
 }
@@ -112,7 +112,7 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
 {
   map<NodeID, pair<int, int> > first_occurence;
   map<NodeID, int> reference_count;
-  int i, j, m, eq, var, lag;
+  int i, j, m, eq, var, eqr, varr, lag;
   temporary_terms_type vect;
   ostringstream tmp_output;
   BinaryOpNode *eq_node;
@@ -127,12 +127,24 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
       // Compute the temporary terms reordered
       for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
         {
-          eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-          eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
-          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-            if(ModelBlock->Block_List[j].Equation_Normalized[i])
+          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i])
               ModelBlock->Block_List[j].Equation_Normalized[i]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
+          else
+            {
+              eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+              eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
+            }
         }
+      for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+        {
+          pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
+          lag=it.first.first;
+          int eqr=it.second.first;
+          int varr=it.second.second;
+          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
+          it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
+        }
+
       for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
         {
           lag=m-ModelBlock->Block_List[j].Max_Lag;
@@ -141,21 +153,18 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
               eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
               var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
               it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag)));
-              //printf("it=%d eq=%d var=%s (%d)\n",it!=first_derivatives.end(), eq, symbol_table.getName(symbol_table.getID(eEndogenous, var)).c_str(), var);
-              //if(it!=first_derivatives.end())
               it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
             }
         }
-			for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+      /*for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
         {
           pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
           lag=it.first.first;
-          eq=it.first.second.first;
-          var=it.first.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eq, make_pair( var, lag)));
-          //it_chr->second->writeChainRuleDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+          eqr=it.second.first;
+          varr=it.second.second;
+          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
           it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
-        }
+        }*/
       /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
         {
           lag=m-ModelBlock->Block_List[j].Max_Lag;
@@ -178,8 +187,6 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
                   eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i];
                   var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
                   it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag)));
-                  //it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
-                  //if(it!=first_derivatives.end())
                   it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
                 }
             }
@@ -190,13 +197,21 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
       // Collecte the temporary terms reordered
       for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
         {
-          eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i])
+              ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j);
+          else
+            {
+              eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+              eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j);
+            }
+
+          /*eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
           eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j);
           if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
             if(ModelBlock->Block_List[j].Equation_Normalized[i])
               ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j);
           for(temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin(); it!= ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
-            (*it)->collectTemporary_terms(temporary_terms, ModelBlock, j);
+            (*it)->collectTemporary_terms(temporary_terms, ModelBlock, j);*/
         }
       for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
         {
@@ -211,14 +226,13 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
               it->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
             }
         }
-			for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+      for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
         {
           pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
           lag=it.first.first;
-          eq=it.first.second.first;
-          var=it.first.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eq, make_pair( var, lag)));
-          //it_chr->second->writeChainRuleDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+          eqr=it.second.first;
+          varr=it.second.second;
+          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
           it_chr->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
         }
       /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
@@ -268,7 +282,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
     BinaryOpNode *eq_node;
     ostringstream Uf[symbol_table.endo_nbr()];
     map<NodeID, int> reference_count;
-    int prev_Simulation_Type=-1, count_derivates=0;
+    //int prev_Simulation_Type=-1, count_derivates=0;
     int jacobian_max_endo_col;
     ofstream  output;
     //temporary_terms_type::const_iterator it_temp=temporary_terms.begin();
@@ -324,10 +338,9 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
         << BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) << "  //" << endl
         << "  % ////////////////////////////////////////////////////////////////////////" << endl;
         //The Temporary terms
+        //output << "  relax = 1;\n";
         if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
-            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
-            /*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
-            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R*/)
+            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)
           {
             output << "  if(jacobian_eval)\n";
             output << "    g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives
@@ -437,15 +450,18 @@ evaluation:     if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDAR
                   {
                     output << tmp_output.str();
                     output << " = ";
+                    /*if(!(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD))
+                      {
+                        lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        output << "-relax*(";
+                        lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        output << "-(";
+                        rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        output << "))";
+                      }
+                    else*/
                     rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
                   }
-                /*else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_R)
-                  {
-                    rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                    output << " = ";
-                    output << tmp_output.str();
-                    output << "; %reversed " << ModelBlock->Block_List[j].Equation_Type[i] << " \n";
-                  }*/
                 else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
                   {
                     output << "%" << tmp_output.str();
@@ -454,19 +470,23 @@ evaluation:     if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDAR
                       {
                         rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
                         output << "\n    ";
-                        /*temporary_terms_type tt2;
-                        tt2.clear();*/
                         tmp_output.str("");
                         eq_node = (BinaryOpNode *)ModelBlock->Block_List[j].Equation_Normalized[i];
                         lhs = eq_node->get_arg1();
                         rhs = eq_node->get_arg2();
-                        if(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)
-                         lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
-                        else
-                         lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
-                        output << tmp_output.str();
+                        lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
                         output << " = ";
-                        rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        /*if(!(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD))
+                          {
+                            lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                            output << "-relax*(";
+                            lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                            output << "-(";
+                            rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                            output << "))";
+                          }
+                        else*/
+                          rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
                       }
                   }
                 else
@@ -535,9 +555,6 @@ end:
           {
           case EVALUATE_BACKWARD:
           case EVALUATE_FORWARD:
-          /*case EVALUATE_BACKWARD_R:
-          case EVALUATE_FORWARD_R:*/
-            count_derivates++;
             for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++)
               {
                 k=m-ModelBlock->Block_List[j].Max_Lag;
@@ -604,7 +621,6 @@ end:
           case SOLVE_FORWARD_SIMPLE:
           case SOLVE_BACKWARD_COMPLETE:
           case SOLVE_FORWARD_COMPLETE:
-            count_derivates++;
             for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++)
               {
                 k=m-ModelBlock->Block_List[j].Max_Lag;
@@ -649,7 +665,7 @@ end:
                         int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
                         int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_other_endo[i];
                         int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var_other_endo[i];
-                        output << "    g1_o(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", "
+                        output << "    g1_o(" << eqr+1/*-ModelBlock->Block_List[j].Nb_Recursives*/ << ", "
                         << varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
                         writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
                         output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
@@ -662,130 +678,76 @@ end:
             output << "    varargout{2}=g1_o;\n";
             output << "  else" << endl;
 
-            m=ModelBlock->Block_List[j].Max_Lag;
-            //cout << "\nDerivatives in Block " << j << "\n";
-            for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-              {
-                    //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
-                    pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                    k=it.first.first;
-                    int eq=it.first.second.first;
-                    int var=it.first.second.second;
-                    int eqr=it.second.first;
-                    int varr=it.second.second;
-
-            /*for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
+            for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
               {
-                int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i];
-                ostringstream tmp_output;
-                if (eqr<ModelBlock->Block_List[j].Nb_Recursives)
-                  {
-                    if (varr>=ModelBlock->Block_List[j].Nb_Recursives)
-                      {*/
-                        output << "    g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << ", "
-                        << var+1-ModelBlock->Block_List[j].Nb_Recursives  << ") = ";
-                        writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms);
-                        output << ";";
-                        output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
-                        << "(" << k
-                        << ") " << varr+1
-                        << ", equation=" << eqr+1 << endl;
-                      }
-                      /*}
-                  }
-              }*/
+                pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
+                k=it.first.first;
+                int eq=it.first.second.first;
+                int var=it.first.second.second;
+                int eqr=it.second.first;
+                int varr=it.second.second;
+                output << "    g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << ", "
+                       << var+1-ModelBlock->Block_List[j].Nb_Recursives  << ") = ";
+                writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms);
+                output << "; %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
+                       << "(" << k << ") " << varr+1 << ", equation=" << eqr+1 << endl;
+              }
             output << "  end;\n";
             break;
           case SOLVE_TWO_BOUNDARIES_SIMPLE:
           case SOLVE_TWO_BOUNDARIES_COMPLETE:
             output << "    if ~jacobian_eval" << endl;
-            /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+            for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
+                pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
+                k=it.first.first;
+                int eq=it.first.second.first;
+                int var=it.first.second.second;
+                int eqr=it.second.first;
+                int varr=it.second.second;
+                ostringstream tmp_output;
+                if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives)
                   {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i];*/
-            for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-              {
-                    //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
-                    pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                    k=it.first.first;
-                    int eq=it.first.second.first;
-                    int var=it.first.second.second;
-                    int eqr=it.second.first;
-                    int varr=it.second.second;
-
-                    //bool derivative_exist;
-                    ostringstream tmp_output;
-                    /*if (eqr>=ModelBlock->Block_List[j].Nb_Recursives)
-                      {
-                        if (varr>=ModelBlock->Block_List[j].Nb_Recursives)
-                          {*/
-                    /*for(int equation = ModelBlock->Block_List[j].Nb_Recursives; equation<ModelBlock->Block_List[j].Size; equation++)
-                      {
-                        int eq = ModelBlock->Block_List[j].Equation[equation];
-                        int eqr = equation - ModelBlock->Block_List[j].Nb_Recursives;
-                        for(int variable = ModelBlock->Block_List[j].Nb_Recursives; variable<ModelBlock->Block_List[j].Size; variable++)
-                          {
-                            int var = ModelBlock->Block_List[j].Variable[variable];
-                            int varr = variable - ModelBlock->Block_List[j].Nb_Recursives;*/
-                            //cout << "eqr=" << eqr << " varr=" << varr;
-                        //cout << "k=" << k << " eq=" << eq << " var=" << var << " eqr=" << eqr << " varr=" << varr << " ModelBlock->Block_List[j].Equation[eq]=" << ModelBlock->Block_List[j].Equation[eq] << "\n";
-												if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives)
-												  {
-
-                            if (k==0)
-                              Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+Per_K_)*y(it_, " << varr+1 << ")";
-                            else if (k==1)
-                              Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+Per_y_)*y(it_+1, " << varr+1 << ")";
-                            else if (k>0)
-                              Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << varr+1 << ")";
-                            else if (k<0)
-                              Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
-                              << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << varr+1 << ")";
-                            if (k==0)
-                              tmp_output << "      g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                              << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_K_) = ";
-                            else if (k==1)
-                              tmp_output << "      g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                              << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_y_) = ";
-                            else if (k>0)
-                              tmp_output << "      g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                              << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_+" << k-1 << ")) = ";
-                            else if (k<0)
-                              tmp_output << "      g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                              << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_" << k-1 << ")) = ";
-
-
-                            output << " " << tmp_output.str();
-
-                            writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms);
-
-                            output << ";";
-                            output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
-                                   << "(" << k << ") " << varr+1
-                                   << ", equation=" << eqr+1 << " (" << eq+1 << ")" << endl;
-												  }
-                            //cout << " done\n";
-                         /* }
-                      }*/
-
+                    if (k==0)
+                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+Per_K_)*y(it_, " << varr+1 << ")";
+                    else if (k==1)
+                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+Per_y_)*y(it_+1, " << varr+1 << ")";
+                    else if (k>0)
+                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << varr+1 << ")";
+                    else if (k<0)
+                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
+                        << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << varr+1 << ")";
+                    if (k==0)
+                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
+                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_K_) = ";
+                    else if (k==1)
+                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
+                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_y_) = ";
+                    else if (k>0)
+                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
+                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_+" << k-1 << ")) = ";
+                    else if (k<0)
+                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
+                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_" << k-1 << ")) = ";
+                    output << " " << tmp_output.str();
+
+                    writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms);
+
+                    output << ";";
+                    output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
+                      << "(" << k << ") " << varr+1
+                      << ", equation=" << eqr+1 << " (" << eq+1 << ")" << endl;
+                  }
 #ifdef CONDITION
-                    output << "  if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n";
-                    output << "    condition(" << eqr << ")=u(" << u << "+Per_u_);\n";
+                output << "  if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n";
+                output << "    condition(" << eqr << ")=u(" << u << "+Per_u_);\n";
 #endif
                   //}
               }
@@ -879,7 +841,6 @@ end:
           default:
             break;
           }
-        prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type;
         output.close();
       }
   }
@@ -896,16 +857,14 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
     struct Uff
       {
         Uff_l *Ufl, *Ufl_First;
-        int eqr;
       };
 
-    int i,j,k,m, v;
+    int i,j,k,v;
     string tmp_s;
     ostringstream tmp_output;
     ofstream code_file;
     NodeID lhs=NULL, rhs=NULL;
     BinaryOpNode *eq_node;
-    bool lhs_rhs_done;
     Uff Uf[symbol_table.endo_nbr()];
     map<NodeID, int> reference_count;
     vector<int> feedback_variables;
@@ -948,7 +907,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
             //cout << "ModelBlock->Block_List[j].Nb_Recursives = " << ModelBlock->Block_List[j].Nb_Recursives << "\n";
             Write_Inf_To_Bin_File(file_name, bin_basename, j, u_count_int,file_open,
                                   ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE);
-						//cout << "u_count_int=" << u_count_int << "\n";
+            //cout << "u_count_int=" << u_count_int << "\n";
             code_file.write(reinterpret_cast<char *>(&ModelBlock->Block_List[j].is_linear),sizeof(ModelBlock->Block_List[j].is_linear));
             //v=block_triangular.ModelBlock->Block_List[j].IM_lead_lag[block_triangular.ModelBlock->Block_List[j].Max_Lag + block_triangular.ModelBlock->Block_List[j].Max_Lead].u_finish + 1;
             v = u_count_int ;
@@ -964,30 +923,19 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
             code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
             file_open=true;
           }
-            /*if (ModelBlock->Block_List[j].Size==1)
-              {
-                lhs_rhs_done=true;
-                eq_node = equations[ModelBlock->Block_List[j].Equation[0]];
-                lhs = eq_node->get_arg1();
-                rhs = eq_node->get_arg2();
-              }
-            else
-              lhs_rhs_done=false;*/
             // The equations
             for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
               {
                 //The Temporary terms
                 temporary_terms_type tt2;
                 tt2.clear();
-                /*if (ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->size())
-                  output << "  " << sps << "% //Temporary variables" << endl;*/
 #ifdef DEBUGC
                 k=0;
 #endif
                 for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin();
                      it != ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
                   {
-                    (*it)->compile(code_file, false, tt2, map_idx);
+                    (*it)->compile(code_file, false, tt2, map_idx, true);
                     code_file.write(&FSTPT, sizeof(FSTPT));
                     map_idx_type::const_iterator ii=map_idx.find((*it)->idx);
                     v=(int)ii->second;
@@ -1010,12 +958,6 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
                     cout << "map_idx[" << (*it)->idx <<"]=" << ii->second << "\n";
                   }
 #endif
-                /*if (!lhs_rhs_done)
-                  {*/
-                    eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-                    lhs = eq_node->get_arg1();
-                    rhs = eq_node->get_arg2();
-                  /*}*/
                 switch (ModelBlock->Block_List[j].Simulation_Type)
                   {
 evaluation:
@@ -1023,17 +965,19 @@ evaluation:
                   case EVALUATE_FORWARD:
                     if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE)
                       {
-                        rhs->compile(code_file, false, temporary_terms, map_idx);
-                        lhs->compile(code_file, true, temporary_terms, map_idx);
+                        eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+                        lhs = eq_node->get_arg1();
+                        rhs = eq_node->get_arg2();
+                        rhs->compile(code_file, false, temporary_terms, map_idx, true);
+                        lhs->compile(code_file, true, temporary_terms, map_idx, true);
                       }
                     else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
                       {
                         eq_node = (BinaryOpNode*)ModelBlock->Block_List[j].Equation_Normalized[i];
-                        //cout << "EVALUATE_S var " << ModelBlock->Block_List[j].Variable[i] << "\n";
                         lhs = eq_node->get_arg1();
                         rhs = eq_node->get_arg2();
-                        rhs->compile(code_file, false, temporary_terms, map_idx);
-                        lhs->compile(code_file, true, temporary_terms, map_idx);
+                        rhs->compile(code_file, false, temporary_terms, map_idx, true);
+                        lhs->compile(code_file, true, temporary_terms, map_idx, true);
                       }
                     break;
                   case SOLVE_BACKWARD_COMPLETE:
@@ -1044,29 +988,27 @@ evaluation:
                       goto evaluation;
                     feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
                     v=ModelBlock->Block_List[j].Equation[i];
-                    Uf[v].eqr=i;
                     Uf[v].Ufl=NULL;
                     goto end;
                   default:
 end:
-                    lhs->compile(code_file, false, temporary_terms, map_idx);
-                    rhs->compile(code_file, false, temporary_terms, map_idx);
+                    eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+                    lhs = eq_node->get_arg1();
+                    rhs = eq_node->get_arg2();
+                    lhs->compile(code_file, false, temporary_terms, map_idx, true);
+                    rhs->compile(code_file, false, temporary_terms, map_idx, true);
                     code_file.write(&FBINARY, sizeof(FBINARY));
                     int v=oMinus;
                     code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
                     code_file.write(&FSTPR, sizeof(FSTPR));
                     v = i - ModelBlock->Block_List[j].Nb_Recursives;
-                    //cout << "residual[" << v << "]\n";
                     code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
                   }
               }
             code_file.write(&FENDEQU, sizeof(FENDEQU));
             // The Jacobian if we have to solve the block
-            bool feedback_variable =  (feedback_variables.size()>0);
             if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD
-                && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD
-                /*&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD_R
-                && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD_R*/)
+                && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
               {
                 switch (ModelBlock->Block_List[j].Simulation_Type)
                   {
@@ -1077,87 +1019,15 @@ end:
                     v=0;
                     code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
                     break;
+
                   case SOLVE_BACKWARD_COMPLETE:
                   case SOLVE_FORWARD_COMPLETE:
-                    count_u = feedback_variables.size();
-                    //cout << "todo SOLVE_COMPLETE\n";
-                    for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-                      {
-                        //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
-                        pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                        k=it.first.first;
-                        int eq=it.first.second.first;;
-                        int var=it.first.second.second;
-                        int eqr=it.second.first;
-                        int varr=it.second.second;
-                        int v=ModelBlock->Block_List[j].Equation[eq];
-                        if (!Uf[v].Ufl)
-                          {
-                            Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
-                            Uf[v].Ufl_First=Uf[v].Ufl;
-                          }
-                        else
-                          {
-                            Uf[v].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l));
-                            Uf[v].Ufl=Uf[v].Ufl->pNext;
-                          }
-                        Uf[v].Ufl->pNext=NULL;
-                        Uf[v].Ufl->u=count_u;
-                        Uf[v].Ufl->var=varr;
-                        compileChainRuleDerivative(code_file, eqr, varr, 0, map_idx);
-                        code_file.write(&FSTPU, sizeof(FSTPU));
-                        code_file.write(reinterpret_cast<char *>(&count_u), sizeof(count_u));
-                        count_u++;
-                      }
-										//cout << "done SOLVE_COMPLETE\n";
-                    for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-                      {
-                      	if(i>=ModelBlock->Block_List[j].Nb_Recursives)
-                      	  {
-                            code_file.write(&FLDR, sizeof(FLDR));
-                            v = i-ModelBlock->Block_List[j].Nb_Recursives;
-                            code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
-                            code_file.write(&FLDZ, sizeof(FLDZ));
-                            int v=ModelBlock->Block_List[j].Equation[i];
-                            for (Uf[v].Ufl=Uf[v].Ufl_First;Uf[v].Ufl;Uf[v].Ufl=Uf[v].Ufl->pNext)
-                              {
-                                code_file.write(&FLDU, sizeof(FLDU));
-                                code_file.write(reinterpret_cast<char *>(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u));
-                                code_file.write(&FLDV, sizeof(FLDV));
-                                char vc=eEndogenous;
-                                code_file.write(reinterpret_cast<char *>(&vc), sizeof(vc));
-                                code_file.write(reinterpret_cast<char *>(&Uf[v].Ufl->var), sizeof(Uf[v].Ufl->var));
-                                int v1=0;
-                                code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1));
-                                code_file.write(&FBINARY, sizeof(FBINARY));
-                                v1=oTimes;
-                                code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1));
-                                code_file.write(&FCUML, sizeof(FCUML));
-                              }
-                            Uf[v].Ufl=Uf[v].Ufl_First;
-                            while (Uf[v].Ufl)
-                              {
-                                Uf[v].Ufl_First=Uf[v].Ufl->pNext;
-                                free(Uf[v].Ufl);
-                                Uf[v].Ufl=Uf[v].Ufl_First;
-                              }
-                            code_file.write(&FBINARY, sizeof(FBINARY));
-                            v=oMinus;
-                            code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
-                            code_file.write(&FSTPU, sizeof(FSTPU));
-                            v = i - ModelBlock->Block_List[j].Nb_Recursives;
-                            code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
-                      	  }
-                      }
-                    break;
                   case SOLVE_TWO_BOUNDARIES_COMPLETE:
                   case SOLVE_TWO_BOUNDARIES_SIMPLE:
-										count_u=ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives;
-										//cout << "todo SOLVE_TWO_BOUNDARIES\n";
-										//cout << "ModelBlock->Block_List[j].Nb_Recursives=" << ModelBlock->Block_List[j].Nb_Recursives << "\n";
-                    for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-											{
-                        //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
+                    //count_u=ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives;
+                    count_u = feedback_variables.size();
+                    for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+                      {
                         pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
                         k=it.first.first;
                         int eq=it.first.second.first;
@@ -1166,11 +1036,11 @@ end:
                         int varr=it.second.second;
                         //cout << "k=" << k << " eq=" << eq << " (" << eq-ModelBlock->Block_List[j].Nb_Recursives << ") var=" << var << " (" << var-ModelBlock->Block_List[j].Nb_Recursives << ") eqr=" << eqr << " varr=" << varr << " count_u=" << count_u << "\n";
                         int v=ModelBlock->Block_List[j].Equation[eq];
-												/*m = ModelBlock->Block_List[j].Max_Lag + k;
+                        /*m = ModelBlock->Block_List[j].Max_Lag + k;
                         int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i];*/
                         if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives)
-												  {
-												  	if (!Uf[v].Ufl)
+                          {
+                            if (!Uf[v].Ufl)
                               {
                                 Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
                                 Uf[v].Ufl_First=Uf[v].Ufl;
@@ -1184,53 +1054,21 @@ end:
                             Uf[v].Ufl->u=count_u;
                             Uf[v].Ufl->var=varr;
                             Uf[v].Ufl->lag=k;
-                            //writeChainRuleDerivative(cout, eqr, varr, k, oMatlabDynamicModelSparse, /*map_idx*/temporary_terms);
-                            //cout <<"\n";
                             compileChainRuleDerivative(code_file, eqr, varr, k, map_idx);
                             code_file.write(&FSTPU, sizeof(FSTPU));
                             code_file.write(reinterpret_cast<char *>(&count_u), sizeof(count_u));
                             count_u++;
 												  }
 											}
-										//cout << "done it SOLVE_TWO_BOUNDARIES\n";
-                    /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-                      {
-                        k=m-ModelBlock->Block_List[j].Max_Lag;
-                        for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                          {
-                            int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                            int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                            int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i];
-                            int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                            int v=ModelBlock->Block_List[j].Equation[eqr];
-                            if (!Uf[v].Ufl)
-                              {
-                                Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
-                                Uf[v].Ufl_First=Uf[v].Ufl;
-                              }
-                            else
-                              {
-                                Uf[v].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l));
-                                Uf[v].Ufl=Uf[v].Ufl->pNext;
-                              }
-                            Uf[v].Ufl->pNext=NULL;
-                            Uf[v].Ufl->u=u;
-                            Uf[v].Ufl->var=var;
-                            Uf[v].Ufl->lag=k;
-                            compileDerivative(code_file, eq, var, k, map_idx);
-                            code_file.write(&FSTPU, sizeof(FSTPU));
-                            code_file.write(reinterpret_cast<char *>(&u), sizeof(u));
-                          }
-                      }*/
                     for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
                       {
-                      	if(i>=ModelBlock->Block_List[j].Nb_Recursives)
-                      	  {
+                        if(i>=ModelBlock->Block_List[j].Nb_Recursives)
+                          {
                             code_file.write(&FLDR, sizeof(FLDR));
                             v = i-ModelBlock->Block_List[j].Nb_Recursives;
                             code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
                             code_file.write(&FLDZ, sizeof(FLDZ));
-                            int v=ModelBlock->Block_List[j].Equation[i];
+                            v=ModelBlock->Block_List[j].Equation[i];
                             for (Uf[v].Ufl=Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl=Uf[v].Ufl->pNext)
                               {
                                 code_file.write(&FLDU, sizeof(FLDU));
@@ -1260,24 +1098,8 @@ end:
                             code_file.write(&FSTPU, sizeof(FSTPU));
                             v = i - ModelBlock->Block_List[j].Nb_Recursives;
                             code_file.write(reinterpret_cast<char *>(&v), sizeof(v));
-                      	  }
-                      }
-#ifdef CONDITION
-                    for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-                      {
-                        k=m-ModelBlock->Block_List[j].Max_Lag;
-                        for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                          {
-                            int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                            int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                            int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i];
-                            int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                            output << "  u[" << u << "+Per_u_] /= condition[" << eqr << "];\n";
                           }
                       }
-                    for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-                      output << "  u[" << i << "+Per_u_] /= condition[" << i << "];\n";
-#endif
                     break;
                   default:
                     break;
@@ -1421,17 +1243,17 @@ DynamicModel::Write_Inf_To_Bin_File(const string &dynamic_basename, const string
     int j;
     std::ofstream SaveCode;
     if (file_open)
-      SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate );
+      SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate );
     else
-      SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::binary);
+      SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::binary);
     if (!SaveCode.is_open())
       {
-        cout << "Error : Can't open file \"" << bin_basename << ".bin\" for writing\n";
+        cout << "Error : Can't open file \"" << bin_basename << "_dynamic.bin\" for writing\n";
         exit(EXIT_FAILURE);
       }
     u_count_int=0;
     int Size = block_triangular.ModelBlock->Block_List[num].Size - block_triangular.ModelBlock->Block_List[num].Nb_Recursives;
-    for(int i=0; i<block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->size();i++)
+    for(int i=0; i<(int)block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->size();i++)
 			{
         //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
         pair< pair<int, pair<int, int> >, pair<int, int> > it = block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->at(i);
@@ -1578,70 +1400,50 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
     tmp_eq.str("");
     for (int count_call=1, i = 0;i < block_triangular.ModelBlock->Size;i++, count_call++)
       {
+        mDynamicModelFile << "    %block_triangular.ModelBlock->Block_List[i].Nb_Recursives=" << block_triangular.ModelBlock->Block_List[i].Nb_Recursives << " block_triangular.ModelBlock->Block_List[i].Size=" <<  block_triangular.ModelBlock->Block_List[i].Size << "\n";
         k=block_triangular.ModelBlock->Block_List[i].Simulation_Type;
-        if ((BlockTriangular::BlockSim(prev_Simulation_Type)!=BlockTriangular::BlockSim(k))  &&
-            ((prev_Simulation_Type==EVALUATE_FORWARD || prev_Simulation_Type==EVALUATE_BACKWARD /*|| prev_Simulation_Type==EVALUATE_FORWARD_R || prev_Simulation_Type==EVALUATE_BACKWARD_R*/)
-             || (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/)))
-          {
-            mDynamicModelFile << "    y_index_eq=[" << tmp_eq.str() << "];\n";
-            tmp_eq.str("");
-            mDynamicModelFile << "    y_index=[" << tmp.str() << "];\n";
-            tmp.str("");
-            mDynamicModelFile << tmp1.str();
-            tmp1.str("");
-          }
-        for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+        if(k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD)
           {
-            tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
-            tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1;
+            for (int ik=0 ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+              {
+                tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
+                tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1;
+              }
           }
-        if (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/)
+        else
           {
-            if (i==block_triangular.ModelBlock->Size-1)
+            for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
               {
-                mDynamicModelFile << "    y_index_eq=[" << tmp_eq.str() << "];\n";
-                tmp_eq.str("");
-                mDynamicModelFile << "    y_index=[" << tmp.str() << "];\n";
-                tmp.str("");
-                mDynamicModelFile << tmp1.str();
-                tmp1.str("");
+                tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
+                tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1;
               }
           }
-        if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(k) &&
-            (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/))
-          skip_head=true;
-        else
-          skip_head=false;
+        mDynamicModelFile << "    y_index_eq=[" << tmp_eq.str() << "];\n";
+        mDynamicModelFile << "    y_index=[" << tmp.str() << "];\n";
+
         switch (k)
           {
           case EVALUATE_FORWARD:
           case EVALUATE_BACKWARD:
-          /*case EVALUATE_FORWARD_R:
-          case EVALUATE_BACKWARD_R:*/
-            if (!skip_head)
-              {
-                tmp1 << "    [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 1, it_-1, 1);\n";
-                tmp1 << "    residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n";
-              }
-            break;
+            mDynamicModelFile << "    [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 1, it_-1, 1);\n";
+            mDynamicModelFile << "    residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n";
+           break;
           case SOLVE_FORWARD_SIMPLE:
           case SOLVE_BACKWARD_SIMPLE:
-            mDynamicModelFile << "    y_index_eq = " << block_triangular.ModelBlock->Block_List[i].Equation[0]+1 << ";\n";
+            //mDynamicModelFile << "    y_index_eq = " << block_triangular.ModelBlock->Block_List[i].Equation[0]+1 << ";\n";
             mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_, 1);\n";
             mDynamicModelFile << "    residual(y_index_eq)=r;\n";
-            tmp_eq.str("");
-            tmp.str("");
             break;
           case SOLVE_FORWARD_COMPLETE:
           case SOLVE_BACKWARD_COMPLETE:
-            mDynamicModelFile << "    y_index_eq = [" << tmp_eq.str() << "];\n";
+            //mDynamicModelFile << "    y_index_eq = [" << tmp_eq.str() << "];\n";
             mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_, 1);\n";
             mDynamicModelFile << "    residual(y_index_eq)=r;\n";
             break;
           case SOLVE_TWO_BOUNDARIES_COMPLETE:
           case SOLVE_TWO_BOUNDARIES_SIMPLE:
             int j;
-            mDynamicModelFile << "    y_index_eq = [" << tmp_eq.str() << "];\n";
+            /*mDynamicModelFile << "    y_index_eq = [" << tmp_eq.str() << "];\n";
             tmp_i=block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1;
             mDynamicModelFile << "    y_index = [";
             for (j=0;j<tmp_i;j++)
@@ -1653,9 +1455,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
             for (j=0;j<tmp_ix;j++)
               for (int ik=0;ik<block_triangular.ModelBlock->Block_List[i].nb_exo;ik++)
                 mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Exogenous[ik]+1+j*symbol_table.exo_nbr()+symbol_table.endo_nbr()*tmp_i;
-            mDynamicModelFile << " ];\n";
-            tmp.str("");
-            tmp_eq.str("");
+            mDynamicModelFile << " ];\n";*/
             //mDynamicModelFile << "    ga = [];\n";
             j = block_triangular.ModelBlock->Block_List[i].Size*(block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1)
                 + block_triangular.ModelBlock->Block_List[i].nb_exo*(block_triangular.ModelBlock->Block_List[i].Max_Lag_Exo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Exo+1);
@@ -1670,7 +1470,8 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
             mDynamicModelFile << "    residual(y_index_eq)=r(:,M_.maximum_lag+1);\n";
             break;
           }
-        prev_Simulation_Type=k;
+        tmp_eq.str("");
+        tmp.str("");
       }
     if (tmp1.str().length())
       {
@@ -2343,7 +2144,7 @@ DynamicModel::writeOutputPostComputing(ostream &output, const string &basename)
 }
 
 void
-DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m)
+DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic)
 {
   int i=0;
   int j=0;
@@ -2376,10 +2177,10 @@ DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map
               IM=block_triangular.incidencematrix.Get_IM(k1, eEndogenous);
               a_variable_lag=k1;
             }
-          if (k1==0)
+          if (k1==0 or !dynamic)
             {
               j++;
-              (*j_m)[make_pair(eq,var)]=val;
+              (*j_m)[make_pair(eq,var)]+=val;
             }
           if (IM[eq*symbol_table.endo_nbr()+var] && (fabs(val) < cutoff))
             {
@@ -2547,8 +2348,7 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
       BuildIncidenceMatrix();
 
       jacob_map j_m;
-
-      evaluateJacobian(eval_context, &j_m);
+      evaluateJacobian(eval_context, &j_m, true);
 
 
       if (block_triangular.bt_verbose)
@@ -2559,12 +2359,15 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
       t_etype equation_simulation_type;
       map<pair<int, pair<int, int> >, NodeID> first_order_endo_derivatives = collect_first_order_derivatives_endogenous();
 
-      block_triangular.Normalize_and_BlockDecompose_Static_0_Model(j_m, equations, equation_simulation_type, first_order_endo_derivatives);
+      block_triangular.Normalize_and_BlockDecompose_Static_0_Model(j_m, equations, equation_simulation_type, first_order_endo_derivatives, mfs, cutoff);
+
       BlockLinear(block_triangular.ModelBlock);
+
+      computeChainRuleJacobian(block_triangular.ModelBlock);
+
       if (!no_tmp_terms)
         computeTemporaryTermsOrdered(block_triangular.ModelBlock);
 
-			computeChainRuleJacobian(block_triangular.ModelBlock);
     }
   else
     if (!no_tmp_terms)
@@ -2633,6 +2436,20 @@ DynamicModel::toStatic(StaticModel &static_model) const
       static_model.addEquation((*it)->toStatic(static_model));
   }
 
+void
+DynamicModel::toStaticDll(StaticDllModel &static_model) const
+  {
+    // Convert model local variables (need to be done first)
+    for (map<int, NodeID>::const_iterator it = local_variables_table.begin();
+         it != local_variables_table.end(); it++)
+      static_model.AddLocalVariable(symbol_table.getName(it->first), it->second->toStatic(static_model));
+
+    // Convert equations
+    for (vector<BinaryOpNode *>::const_iterator it = equations.begin();
+         it != equations.end(); it++)
+      static_model.addEquation((*it)->toStatic(static_model));
+  }
+
 int
 DynamicModel::computeDerivID(int symb_id, int lag)
 {
@@ -2789,17 +2606,13 @@ DynamicModel::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDExcepti
 void
 DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock)
 {
-  //cout << "computeChainRuleJacobian\n";
-  //clock_t t1 = clock();
   map<int, NodeID> recursive_variables;
   first_chain_rule_derivatives.clear();
   for(int blck = 0; blck<ModelBlock->Size; blck++)
     {
-      //cout << "blck=" << blck << "\n";
       recursive_variables.clear();
       if (ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
         {
-          //cout << "SOLVE_TWO_BOUNDARIES_COMPLETE \n";
           ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear();
           for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++)
             {
@@ -2808,56 +2621,41 @@ DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock)
               else
                 recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = equations[ModelBlock->Block_List[blck].Equation[i]];
             }
-          //cout << "After recursive_alloc\n";
           map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives = block_triangular.get_Derivatives(ModelBlock, blck);
-          for(map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin(); it != Derivatives.end(); it++)
-            {
-            	int lag = it->first.first.first;
-            	int eq = it->first.first.second.first;
-            	int var = it->first.first.second.second;
-            	int eqr = it->first.second.first;
-            	int varr = it->first.second.second;
-            	int Deriv_type = it->second;
-            	if(Deriv_type == 0)
-            	  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))];
-							else if (Deriv_type == 1)
-							  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-							else if (Deriv_type == 2)
-							  {
-							  	if(ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives)
-   						      first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-									else
-									  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-							  }
-							ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
-            }
 
-
-
-          /*for(int lag = -ModelBlock->Block_List[blck].Max_Lag; lag <= ModelBlock->Block_List[blck].Max_Lead; lag++)
+          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin();
+          //#pragma omp parallel for shared(it, blck)
+          for(int i=0; i<(int)Derivatives.size(); i++)
             {
-
-              for(int eq = 0; eq < ModelBlock->Block_List[blck].Size; eq++)
+              int Deriv_type = it->second;
+              pair<pair<int, pair<int, int> >, pair<int, int> > it_l(it->first);
+              it++;
+              int lag = it_l.first.first;
+              int eq = it_l.first.second.first;
+              int var = it_l.first.second.second;
+              int eqr = it_l.second.first;
+              int varr = it_l.second.second;
+              if(Deriv_type == 0)
                 {
-                  int eqr = ModelBlock->Block_List[blck].Equation[eq];
-                  for(int var = ModelBlock->Block_List[blck].Nb_Recursives; var < ModelBlock->Block_List[blck].Size; var++)
-                    {
-                      int varr = ModelBlock->Block_List[blck].Variable[var];
-                      NodeID d1 = equations[eqr]->getChainRuleDerivative(recursive_variables, varr, lag);
-                      if (d1 == Zero)
-                        continue;
-                      first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = d1;
-                      ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(eqr, eq), make_pair(varr, make_pair(var, lag))));
-                    }
+                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))];
                 }
-            }*/
-
-
+              else if (Deriv_type == 1)
+                {
+                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+                }
+              else if (Deriv_type == 2)
+                {
+                  if(ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S && eq<ModelBlock->Block_List[blck].Nb_Recursives)
+                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+                  else
+                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+                }
+              ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
+            }
         }
       else if(   ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_SIMPLE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_SIMPLE
               or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_COMPLETE)
         {
-          //cout << "SOLVE_FORWARD_SIMPLE \n";
           ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear();
           for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++)
             {
@@ -2881,7 +2679,6 @@ DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock)
             }
         }
     }
-  //cout << "elapsed time in milliseconds = " << 1000.0*(double(clock()) - double(t1))/double(CLOCKS_PER_SEC)  << "\n";
 }
 
 
diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh
index 54263fbecc22841922dcecb1305ea7b45e705429..ee05ea9546316b56694b12dce96eaaf59aea6bd6 100644
--- a/preprocessor/DynamicModel.hh
+++ b/preprocessor/DynamicModel.hh
@@ -25,6 +25,7 @@ using namespace std;
 #include <fstream>
 
 #include "StaticModel.hh"
+#include "StaticDllModel.hh"
 #include "BlockTriangular.hh"
 
 //! Stores a dynamic model
@@ -100,7 +101,7 @@ private:
     - computes the jacobian for the model w.r. to contemporaneous variables
     - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
   */
-  void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m);
+  void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic);
   void BlockLinear(Model_Block *ModelBlock);
   string reform(string name) const;
   map_idx_type map_idx;
@@ -152,8 +153,15 @@ public:
   virtual NodeID AddVariable(const string &name, int lag = 0);
   //! Absolute value under which a number is considered to be zero
   double cutoff;
-  //! The weight of the Markowitz criteria to determine the pivot in the linear solver (simul_NG1 from simulate.cc)
+  //! The weight of the Markowitz criteria to determine the pivot in the linear solver (simul_NG1 and simul_NG from simulate.cc)
   double markowitz;
+  //! Compute the minimum feedback set in the dynamic model:
+  /*!   0 : all endogenous variables are considered as feedback variables
+        1 : the variables belonging to non normalized equation are considered as feedback variables
+        2 : the variables belonging to a non linear equation are considered as feedback variables
+        3 : the variables belonging to a non normalizable non linear equation are considered as feedback variables
+        default value = 0 */
+  int mfs;
   //! the file containing the model and the derivatives code
   ofstream code_file;
   //! Execute computations (variable sorting + derivation)
@@ -184,6 +192,8 @@ public:
   /*! It assumes that the static model given in argument has just been allocated */
   void toStatic(StaticModel &static_model) const;
 
+  void toStaticDll(StaticDllModel &static_model) const;
+
   //! Writes LaTeX file with the equations of the dynamic model
   void writeLatexFile(const string &basename) const;
 
diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy
index d7423e8288c4702c5395dc4b49cda9f81dcfe255..439c7532e706b37f9bbd450469803a6bf1b21c2e 100644
--- a/preprocessor/DynareBison.yy
+++ b/preprocessor/DynareBison.yy
@@ -87,7 +87,7 @@ class ParsingDriver;
 %}
 
 %token AR AUTOCORR
-%token BAYESIAN_IRF BETA_PDF BICGSTAB BLOCK_MFS
+%token BAYESIAN_IRF BETA_PDF BICGSTAB BLOCK_MFS BLOCK_MFS_DLL
 %token BVAR_DENSITY BVAR_FORECAST
 %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA
 %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN
@@ -106,7 +106,7 @@ class ParsingDriver;
 %token KALMAN_ALGO KALMAN_TOL
 %token LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LU
 %token MARKOWITZ MARGINAL_DENSITY MAX
-%token METHOD MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN
+%token METHOD MFS MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN
 %token MODE_CHECK MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS
 %token MODIFIEDHARMONICMEAN MOMENTS_VARENDO DIFFUSE_FILTER
 %token <string_val> NAME
@@ -449,6 +449,7 @@ model_sparse_options_list : model_sparse_options_list COMMA model_sparse_options
 
 model_sparse_options : o_cutoff
                      | o_markowitz
+                     | o_mfs
                      ;
 
 model : MODEL ';' { driver.begin_model(); }
@@ -641,6 +642,10 @@ steady_options : o_solve_algo
                | o_homotopy_mode
                | o_homotopy_steps
                | o_block_mfs
+               | o_block_mfs_dll
+               | o_cutoff
+               | o_markowitz
+               | o_mfs
                ;
 
 check : CHECK ';'
@@ -1496,6 +1501,7 @@ o_method : METHOD EQUAL INT_NUMBER { driver.option_num("simulation_method",$3);}
            | METHOD EQUAL GMRES { driver.option_num("simulation_method", "2"); }
            | METHOD EQUAL BICGSTAB { driver.option_num("simulation_method", "3"); };
 o_markowitz : MARKOWITZ EQUAL number { driver.option_num("markowitz", $3); };
+o_mfs : MFS EQUAL number { driver.option_num("mfs", $3); };
 o_simul : SIMUL { driver.option_num("simul", "1"); };
 o_simul_seed : SIMUL_SEED EQUAL INT_NUMBER { driver.option_num("simul_seed", $3); } ;
 o_qz_criterium : QZ_CRITERIUM EQUAL number { driver.option_num("qz_criterium", $3); };
@@ -1602,6 +1608,8 @@ o_gsa_trans_ident : TRANS_IDENT EQUAL INT_NUMBER { driver.option_num("trans_iden
 o_homotopy_mode : HOMOTOPY_MODE EQUAL INT_NUMBER {driver.option_num("homotopy_mode",$3); };
 o_homotopy_steps : HOMOTOPY_STEPS EQUAL INT_NUMBER {driver.option_num("homotopy_steps",$3); };
 o_block_mfs : BLOCK_MFS { driver.option_num("block_mfs", "1"); }
+o_block_mfs_dll : BLOCK_MFS_DLL { driver.option_num("block_mfs_dll", "1"); }
+
 o_parameters : PARAMETERS EQUAL symbol {driver.option_str("parameters",$3);};
 o_shocks : SHOCKS EQUAL '(' list_of_symbol_lists ')' { driver.option_symbol_list("shocks"); };
 o_labels : LABELS EQUAL '(' symbol_list ')' { driver.option_symbol_list("labels"); };
diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll
index 0180d384f1f22e518794d729197f42d054782c53..395050c03e5871efbde0ccb3103ae381c34d5026 100644
--- a/preprocessor/DynareFlex.ll
+++ b/preprocessor/DynareFlex.ll
@@ -210,6 +210,7 @@ int sigma_e = 0;
 <DYNARE_STATEMENT>periods	{return token::PERIODS;}
 <DYNARE_STATEMENT>cutoff	{return token::CUTOFF;}
 <DYNARE_STATEMENT>markowitz	{return token::MARKOWITZ;}
+<DYNARE_STATEMENT>mfs	{return token::MFS;}
 <DYNARE_STATEMENT>marginal_density {return token::MARGINAL_DENSITY;}
 <DYNARE_STATEMENT>laplace       {return token::LAPLACE;}
 <DYNARE_STATEMENT>modifiedharmonicmean {return token::MODIFIEDHARMONICMEAN;}
@@ -220,6 +221,8 @@ int sigma_e = 0;
 <DYNARE_STATEMENT>diffuse_filter {return token::DIFFUSE_FILTER;}
 <DYNARE_STATEMENT>plot_priors   {return token::PLOT_PRIORS;}
 <DYNARE_STATEMENT>block_mfs {return token::BLOCK_MFS;}
+<DYNARE_STATEMENT>block_mfs_dll {return token::BLOCK_MFS_DLL;}
+
 <DYNARE_STATEMENT>freq {return token::FREQ;}
 <DYNARE_STATEMENT>initial_year {return token::INITIAL_YEAR;}
 <DYNARE_STATEMENT>initial_subperiod {return token::INITIAL_SUBPERIOD;}
@@ -302,6 +305,7 @@ int sigma_e = 0;
 <DYNARE_BLOCK>periods {return token::PERIODS;}
 <DYNARE_BLOCK>cutoff {return token::CUTOFF;}
 <DYNARE_BLOCK>markowitz {return token::MARKOWITZ;}
+<DYNARE_BLOCK>mfs	{return token::MFS;}
 <DYNARE_BLOCK>gamma_pdf {return token::GAMMA_PDF;}
 <DYNARE_BLOCK>beta_pdf {return token::BETA_PDF;}
 <DYNARE_BLOCK>normal_pdf {return token::NORMAL_PDF;}
diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc
index 5c799fcc0ac50475a2f68988e2f85e3a7fe065dd..6acccd01ba96c261ff6cc3f9ed4ef9e3158d87ca 100644
--- a/preprocessor/ExprNode.cc
+++ b/preprocessor/ExprNode.cc
@@ -131,6 +131,13 @@ ExprNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
   }
 
 
+pair<int, NodeID >
+ExprNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const
+  {
+    return(make_pair(0, (NodeID)NULL));
+  }
+
+
 void
 ExprNode::writeOutput(ostream &output)
 {
@@ -184,13 +191,10 @@ NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalExcep
 }
 
 void
-NumConstNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const
+NumConstNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const
   {
     CompileCode.write(&FLDC, sizeof(FLDC));
     double vard = datatree.num_constants.getDouble(id);
-#ifdef DEBUGC
-    cout << "FLDC " << vard << "\n";
-#endif
     CompileCode.write(reinterpret_cast<char *>(&vard),sizeof(vard));
   }
 
@@ -199,10 +203,10 @@ NumConstNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result
 {
 }
 
-pair<bool, NodeID>
-NumConstNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
+pair<int, NodeID >
+NumConstNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const
   {
-    return(make_pair(false, datatree.AddNumConstant(datatree.num_constants.get(id))));
+    return(make_pair(0, datatree.AddNumConstant(datatree.num_constants.get(id))));
   }
 
 NodeID
@@ -295,9 +299,6 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
                           const temporary_terms_type &temporary_terms) const
   {
     // If node is a temporary term
-#ifdef DEBUGC
-    cout << "write_ouput Variable output_type=" << output_type << "\n";
-#endif
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this));
     if (it != temporary_terms.end())
       {
@@ -464,19 +465,22 @@ VariableNode::eval(const eval_context_type &eval_context) const throw (EvalExcep
 }
 
 void
-VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const
+VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const
   {
     int i, lagl;
-#ifdef DEBUGC
-    cout << "output_type=" << output_type << "\n";
-#endif
     if (!lhs_rhs)
       {
-        CompileCode.write(&FLDV, sizeof(FLDV));
+        if(dynamic)
+          CompileCode.write(&FLDV, sizeof(FLDV));
+        else
+          CompileCode.write(&FLDSV, sizeof(FLDSV));
       }
     else
       {
-        CompileCode.write(&FSTPV, sizeof(FSTPV));
+        if(dynamic)
+          CompileCode.write(&FSTPV, sizeof(FSTPV));
+        else
+          CompileCode.write(&FSTPSV, sizeof(FSTPSV));
       }
     char typel=(char)type;
     CompileCode.write(&typel, sizeof(typel));
@@ -487,35 +491,41 @@ VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_
         //cout << "Parameter=" << tsid << "\n";
         i = tsid;
         CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
-#ifdef DEBUGC
-        cout << "FLD Param[ " << i << ", symb_id=" << symb_id << "]\n";
-#endif
         break;
       case eEndogenous :
         //cout << "Endogenous=" << symb_id << "\n";
         i = tsid;//symb_id;
         CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
-        lagl=lag;
-        CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
+        if(dynamic)
+          {
+            lagl=lag;
+            CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
+          }
         break;
       case eExogenous :
         //cout << "Exogenous=" << tsid << "\n";
         i = tsid;
         CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
-        lagl=lag;
-        CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
+        if(dynamic)
+          {
+            lagl=lag;
+            CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
+          }
         break;
       case eExogenousDet:
         i = tsid + datatree.symbol_table.exo_nbr();
         //cout << "ExogenousDet=" << i << "\n";
         CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
-        lagl=lag;
-        CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
+        if(dynamic)
+          {
+            lagl=lag;
+            CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
+          }
         break;
       case eModelLocalVariable:
       case eModFileLocalVariable:
         //cout << "eModelLocalVariable=" << symb_id << "\n";
-        datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
+        datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
         break;
       case eUnknownFunction:
         cerr << "Impossible case: eUnknownFuncion" << endl;
@@ -545,22 +555,22 @@ VariableNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result
     datatree.local_variables_table[symb_id]->collectVariables(type_arg, result);
 }
 
-pair<bool, NodeID>
-VariableNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
+pair<int, NodeID>
+VariableNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const
   {
     if (type ==eEndogenous)
       {
         if (datatree.symbol_table.getTypeSpecificID(symb_id)==var_endo && lag==0)
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         else
-          return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag)));
+          return(make_pair(0, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag) ));
       }
     else
       {
         if (type == eParameter)
-          return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), 0)));
+          return(make_pair(0, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), 0) ));
         else
-          return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag)));
+          return(make_pair(0, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag) ));
       }
   }
 
@@ -581,9 +591,19 @@ VariableNode::getChainRuleDerivative(int deriv_id_arg, const map<int, NodeID> &r
           map<int, NodeID>::const_iterator it = recursive_variables.find(deriv_id);
           if (it != recursive_variables.end())
             {
-              map<int, NodeID> recursive_vars2(recursive_variables);
-              recursive_vars2.erase(it->first);
-              return datatree.AddUMinus(it->second->getChainRuleDerivative(deriv_id_arg, recursive_vars2));
+              map<int, NodeID>::const_iterator it2 = derivatives.find(deriv_id_arg);
+              if (it2 != derivatives.end())
+                return it2->second;
+              else
+                {
+                  map<int, NodeID> recursive_vars2(recursive_variables);
+                  recursive_vars2.erase(it->first);
+                  //NodeID c = datatree.AddNumConstant("1");
+                  NodeID d = datatree.AddUMinus(it->second->getChainRuleDerivative(deriv_id_arg, recursive_vars2));
+                  //d = datatree.AddTimes(c, d);
+                  derivatives[deriv_id_arg] = d;
+                  return d;
+                }
             }
           else
             return datatree.Zero;
@@ -997,17 +1017,20 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept
 }
 
 void
-UnaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const
+UnaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
     if (it != temporary_terms.end())
       {
-        CompileCode.write(&FLDT, sizeof(FLDT));
+        if(dynamic)
+          CompileCode.write(&FLDT, sizeof(FLDT));
+        else
+          CompileCode.write(&FLDST, sizeof(FLDST));
         int var=map_idx[idx];
         CompileCode.write(reinterpret_cast<char *>(&var), sizeof(var));
         return;
       }
-    arg->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
+    arg->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
     CompileCode.write(&FUNARY, sizeof(FUNARY));
     UnaryOpcode op_codel=op_code;
     CompileCode.write(reinterpret_cast<char *>(&op_codel), sizeof(op_codel));
@@ -1019,53 +1042,101 @@ UnaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result)
   arg->collectVariables(type_arg, result);
 }
 
-pair<bool, NodeID>
-UnaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
+pair<int, NodeID>
+UnaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const
   {
-    pair<bool, NodeID> res = arg->normalizeLinearInEndoEquation(var_endo, Derivative);
-    bool is_endogenous_present = res.first;
+    pair<bool, NodeID > res = arg->normalizeEquation(var_endo, List_of_Op_RHS);
+    int is_endogenous_present = res.first;
     NodeID New_NodeID = res.second;
-    if (!is_endogenous_present)
+    /*if(res.second.second)*/
+    if(is_endogenous_present==2)
+      return(make_pair(2, (NodeID)NULL));
+    else if (is_endogenous_present)
+      {
+        switch (op_code)
+          {
+          case oUminus:
+            List_of_Op_RHS.push_back(make_pair(oUminus, make_pair((NodeID)NULL, (NodeID)NULL)));
+            return(make_pair(1, (NodeID)NULL));
+          case oExp:
+            List_of_Op_RHS.push_back(make_pair(oLog, make_pair((NodeID)NULL, (NodeID)NULL)));
+            return(make_pair(1, (NodeID)NULL));
+          case oLog:
+            List_of_Op_RHS.push_back(make_pair(oExp, make_pair((NodeID)NULL, (NodeID)NULL)));
+            return(make_pair(1, (NodeID)NULL));
+          case oLog10:
+            List_of_Op_RHS.push_back(make_pair(oPower, make_pair((NodeID)NULL, datatree.AddNumConstant("10"))));
+            return(make_pair(1, (NodeID)NULL));
+          case oCos:
+            return(make_pair(1, (NodeID)NULL));
+          case oSin:
+            return(make_pair(1, (NodeID)NULL));
+          case oTan:
+            return(make_pair(1, (NodeID)NULL));
+          case oAcos:
+            return(make_pair(1, (NodeID)NULL));
+          case oAsin:
+            return(make_pair(1, (NodeID)NULL));
+          case oAtan:
+            return(make_pair(1, (NodeID)NULL));
+          case oCosh:
+            return(make_pair(1, (NodeID)NULL));
+          case oSinh:
+            return(make_pair(1, (NodeID)NULL));
+          case oTanh:
+            return(make_pair(1, (NodeID)NULL));
+          case oAcosh:
+            return(make_pair(1, (NodeID)NULL));
+          case oAsinh:
+            return(make_pair(1, (NodeID)NULL));
+          case oAtanh:
+            return(make_pair(1, (NodeID)NULL));
+          case oSqrt:
+            List_of_Op_RHS.push_back(make_pair(oPower, make_pair((NodeID)NULL, datatree.AddNumConstant("2"))));
+            return(make_pair(1, (NodeID)NULL));
+          }
+      }
+    else
       {
         switch (op_code)
           {
           case oUminus:
-            return(make_pair(false, /*tmp_*/datatree.AddUMinus(New_NodeID)));
+            return(make_pair(0, datatree.AddUMinus(New_NodeID)));
           case oExp:
-            return(make_pair(false, /*tmp_*/datatree.AddExp(New_NodeID)));
+            return(make_pair(0, datatree.AddExp(New_NodeID)));
           case oLog:
-            return(make_pair(false, /*tmp_*/datatree.AddLog(New_NodeID)));
+            return(make_pair(0, datatree.AddLog(New_NodeID)));
           case oLog10:
-            return(make_pair(false, /*tmp_*/datatree.AddLog10(New_NodeID)));
+            return(make_pair(0, datatree.AddLog10(New_NodeID)));
           case oCos:
-            return(make_pair(false, /*tmp_*/datatree.AddCos(New_NodeID)));
+            return(make_pair(0, datatree.AddCos(New_NodeID)));
           case oSin:
-            return(make_pair(false, /*tmp_*/datatree.AddSin(New_NodeID)));
+            return(make_pair(0, datatree.AddSin(New_NodeID)));
           case oTan:
-            return(make_pair(false, /*tmp_*/datatree.AddTan(New_NodeID)));
+            return(make_pair(0, datatree.AddTan(New_NodeID)));
           case oAcos:
-            return(make_pair(false, /*tmp_*/datatree.AddAcos(New_NodeID)));
+            return(make_pair(0, datatree.AddAcos(New_NodeID)));
           case oAsin:
-            return(make_pair(false, /*tmp_*/datatree.AddAsin(New_NodeID)));
+            return(make_pair(0, datatree.AddAsin(New_NodeID)));
           case oAtan:
-            return(make_pair(false, /*tmp_*/datatree.AddAtan(New_NodeID)));
+            return(make_pair(0, datatree.AddAtan(New_NodeID)));
           case oCosh:
-            return(make_pair(false, /*tmp_*/datatree.AddCosh(New_NodeID)));
+            return(make_pair(0, datatree.AddCosh(New_NodeID)));
           case oSinh:
-            return(make_pair(false, /*tmp_*/datatree.AddSinh(New_NodeID)));
+            return(make_pair(0, datatree.AddSinh(New_NodeID)));
           case oTanh:
-            return(make_pair(false, /*tmp_*/datatree.AddTanh(New_NodeID)));
+            return(make_pair(0, datatree.AddTanh(New_NodeID)));
           case oAcosh:
-            return(make_pair(false, /*tmp_*/datatree.AddAcosh(New_NodeID)));
+            return(make_pair(0, datatree.AddAcosh(New_NodeID)));
           case oAsinh:
-            return(make_pair(false, /*tmp_*/datatree.AddAsinh(New_NodeID)));
+            return(make_pair(0, datatree.AddAsinh(New_NodeID)));
           case oAtanh:
-            return(make_pair(false, /*tmp_*/datatree.AddAtanh(New_NodeID)));
+            return(make_pair(0, datatree.AddAtanh(New_NodeID)));
           case oSqrt:
-            return(make_pair(false, /*tmp_*/datatree.AddSqrt(New_NodeID)));
+            return(make_pair(0, datatree.AddSqrt(New_NodeID)));
           }
       }
-    return(make_pair(true, (NodeID)NULL));
+    return(make_pair(1, (NodeID)NULL));
   }
 
 
@@ -1435,19 +1506,22 @@ BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcep
 }
 
 void
-BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const
+BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const
   {
     // If current node is a temporary term
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
     if (it != temporary_terms.end())
       {
-        CompileCode.write(&FLDT, sizeof(FLDT));
+        if(dynamic)
+          CompileCode.write(&FLDT, sizeof(FLDT));
+        else
+          CompileCode.write(&FLDST, sizeof(FLDST));
         int var=map_idx[idx];
         CompileCode.write(reinterpret_cast<char *>(&var), sizeof(var));
         return;
       }
-    arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
-    arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
+    arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
+    arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
     CompileCode.write(&FBINARY, sizeof(FBINARY));
     BinaryOpcode op_codel=op_code;
     CompileCode.write(reinterpret_cast<char *>(&op_codel),sizeof(op_codel));
@@ -1636,129 +1710,272 @@ BinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result
   arg2->collectVariables(type_arg, result);
 }
 
-pair<bool, NodeID>
-BinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
+NodeID
+BinaryOpNode::Compute_RHS(NodeID arg1, NodeID arg2, int op, int op_type) const
+{
+  temporary_terms_type temp;
+  switch(op_type)
+    {
+    case 0: /*Unary Operator*/
+      switch(op)
+        {
+        case oUminus:
+          return(datatree.AddUMinus(arg1));
+          break;
+        case oExp:
+          return(datatree.AddExp(arg1));
+          break;
+        case oLog:
+          return(datatree.AddLog(arg1));
+          break;
+        case oLog10:
+          return(datatree.AddLog10(arg1));
+          break;
+        }
+      break;
+    case 1: /*Binary Operator*/
+      switch(op)
+        {
+        case oPlus:
+          return(datatree.AddPlus(arg1, arg2));
+          break;
+        case oMinus:
+          return(datatree.AddMinus(arg1, arg2));
+          break;
+        case oTimes:
+          return(datatree.AddTimes(arg1, arg2));
+          break;
+        case oDivide:
+          return(datatree.AddDivide(arg1, arg2));
+          break;
+        case oPower:
+          return(datatree.AddPower(arg1, arg2));
+          break;
+        }
+      break;
+    }
+  return((NodeID)NULL);
+}
+
+pair<int, NodeID>
+BinaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const
   {
-    pair<bool, NodeID> res = arg1->normalizeLinearInEndoEquation(var_endo, Derivative);
-    bool is_endogenous_present_1 = res.first;
-    NodeID NodeID_1 = res.second;
-    res = arg2->normalizeLinearInEndoEquation(var_endo, Derivative);
-    bool is_endogenous_present_2 = res.first;
-    NodeID NodeID_2 = res.second;
+    vector<pair<int, pair<NodeID, NodeID> > > List_of_Op_RHS1, List_of_Op_RHS2;
+    int is_endogenous_present_1, is_endogenous_present_2;
+    pair<int, NodeID> res;
+    NodeID NodeID_1, NodeID_2;
+    res = arg1->normalizeEquation(var_endo, List_of_Op_RHS1);
+    is_endogenous_present_1 = res.first;
+    NodeID_1 = res.second;
+
+    res = arg2->normalizeEquation(var_endo, List_of_Op_RHS2);
+    is_endogenous_present_2 = res.first;
+    NodeID_2 = res.second;
+    if(is_endogenous_present_1==2 || is_endogenous_present_2==2)
+      return(make_pair(2,(NodeID)NULL));
+    else if(is_endogenous_present_1 && is_endogenous_present_2)
+      return(make_pair(2,(NodeID)NULL));
+    else if(is_endogenous_present_1)
+      {
+        if(op_code==oEqual)
+          {
+            pair<int, pair<NodeID, NodeID> > it;
+            int oo=List_of_Op_RHS1.size();
+            for(int i=0;i<oo;i++)
+              {
+                it = List_of_Op_RHS1.back();
+                List_of_Op_RHS1.pop_back();
+                if(it.second.first && !it.second.second) /*Binary operator*/
+                  NodeID_2 = Compute_RHS(NodeID_2, (BinaryOpNode*)it.second.first, it.first, 1);
+                else if(it.second.second && !it.second.first) /*Binary operator*/
+                  NodeID_2 = Compute_RHS(it.second.second, NodeID_2, it.first, 1);
+                else if(it.second.second && it.second.first) /*Binary operator*/
+                  NodeID_2 = Compute_RHS(it.second.first, it.second.second, it.first, 1);
+                else  /*Unary operator*/
+                  NodeID_2 = Compute_RHS((UnaryOpNode*)NodeID_2, (UnaryOpNode*)it.second.first, it.first, 0);
+              }
+          }
+        else
+          List_of_Op_RHS = List_of_Op_RHS1;
+      }
+    else if(is_endogenous_present_2)
+      {
+        if(op_code==oEqual)
+          {
+            int oo=List_of_Op_RHS2.size();
+            for(int i=0;i<oo;i++)
+              {
+                pair<int, pair<NodeID, NodeID> > it;
+                it = List_of_Op_RHS2.back();
+                List_of_Op_RHS2.pop_back();
+                if(it.second.first && !it.second.second) /*Binary operator*/
+                  NodeID_1 = Compute_RHS((BinaryOpNode*)NodeID_1, (BinaryOpNode*)it.second.first, it.first, 1);
+                else if(it.second.second && !it.second.first) /*Binary operator*/
+                  NodeID_1 = Compute_RHS((BinaryOpNode*)it.second.second, (BinaryOpNode*)NodeID_1, it.first, 1);
+                else if(it.second.second && it.second.first) /*Binary operator*/
+                  NodeID_1 = Compute_RHS(it.second.first, it.second.second, it.first, 1);
+                else
+                  NodeID_1 = Compute_RHS((UnaryOpNode*)NodeID_1, (UnaryOpNode*)it.second.first, it.first, 0);
+              }
+          }
+        else
+          List_of_Op_RHS =List_of_Op_RHS2;
+      }
     switch (op_code)
       {
       case oPlus:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddPlus(NodeID_1, NodeID_2)));
+          {
+            List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(datatree.AddPlus(NodeID_1, NodeID_2), (NodeID)NULL)));
+            return(make_pair(0, datatree.AddPlus(NodeID_1, NodeID_2)));
+          }
         else if (is_endogenous_present_1 && is_endogenous_present_2)
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL));
         else if (!is_endogenous_present_1 && is_endogenous_present_2)
-          return(make_pair(false, NodeID_1));
+          {
+            List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(NodeID_1, (NodeID)NULL)));
+            return(make_pair(1, NodeID_1));
+          }
         else if (is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, NodeID_2));
+          {
+            List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(NodeID_2, (NodeID)NULL) ));
+            return(make_pair(1, NodeID_2));
+          }
         break;
       case oMinus:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddMinus(NodeID_1, NodeID_2)));
+          {
+            List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(datatree.AddMinus(NodeID_1, NodeID_2), (NodeID)NULL) ));
+            return(make_pair(0, datatree.AddMinus(NodeID_1, NodeID_2)));
+          }
         else if (is_endogenous_present_1 && is_endogenous_present_2)
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL));
         else if (!is_endogenous_present_1 && is_endogenous_present_2)
-          return(make_pair(false, NodeID_1));
+          {
+            List_of_Op_RHS.push_back(make_pair(oUminus, make_pair((NodeID)NULL, (NodeID)NULL)));
+            List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(NodeID_1, (NodeID)NULL) ));
+            return(make_pair(1, NodeID_1));
+          }
         else if (is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddUMinus(NodeID_2)));
+          {
+            List_of_Op_RHS.push_back(make_pair(oPlus, make_pair(NodeID_2, (NodeID) NULL) ));
+            return(make_pair(1, datatree.AddUMinus(NodeID_2)));
+          }
         break;
       case oTimes:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddTimes(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddTimes(NodeID_1, NodeID_2)));
+        else if(!is_endogenous_present_1 && is_endogenous_present_2)
+          {
+            List_of_Op_RHS.push_back(make_pair(oDivide, make_pair(NodeID_1, (NodeID)NULL) ));
+            return(make_pair(1, NodeID_1));
+          }
+        else if(is_endogenous_present_1 && !is_endogenous_present_2)
+          {
+            List_of_Op_RHS.push_back(make_pair(oDivide, make_pair(NodeID_2, (NodeID)NULL) ));
+            return(make_pair(1, NodeID_2));
+          }
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL));
         break;
       case oDivide:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, datatree.AddDivide(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddDivide(NodeID_1, NodeID_2)));
+        else if(!is_endogenous_present_1 && is_endogenous_present_2)
+          {
+            List_of_Op_RHS.push_back(make_pair(oDivide, make_pair((NodeID)NULL, NodeID_1) ));
+            return(make_pair(1, NodeID_1));
+          }
+        else if(is_endogenous_present_1 && !is_endogenous_present_2)
+          {
+            List_of_Op_RHS.push_back(make_pair(oTimes, make_pair(NodeID_2, (NodeID)NULL) ));
+            return(make_pair(1, NodeID_2));
+          }
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL));
         break;
       case oPower:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, datatree.AddPower(NodeID_1, NodeID_2)));
-        else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(0, datatree.AddPower(NodeID_1, NodeID_2)));
+        else if(is_endogenous_present_1 && !is_endogenous_present_2)
+          {
+            List_of_Op_RHS.push_back(make_pair(oPower, make_pair(datatree.AddDivide( datatree.AddNumConstant("1"), NodeID_2), (NodeID)NULL) ));
+            return(make_pair(1, (NodeID)NULL));
+          }
         break;
       case oEqual:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
           {
-            if (Derivative!=datatree.One)
-              return( make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddDivide(datatree.AddMinus(NodeID_2, NodeID_1), Derivative))) );
-            else
-              return( make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddMinus(NodeID_2, NodeID_1))) );
+              return( make_pair(0,
+              datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddMinus(NodeID_2, NodeID_1))
+              ));
           }
         else if (is_endogenous_present_1 && is_endogenous_present_2)
           {
-            return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.Zero)));
+            return(make_pair(0,
+            datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.Zero)
+            ));
           }
         else if (!is_endogenous_present_1 && is_endogenous_present_2)
           {
-            if (Derivative!=datatree.One)
-              return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddDivide(datatree.AddUMinus(NodeID_1), Derivative))));
-            else
-              return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddUMinus(NodeID_1))));
+              return(make_pair(0,
+              datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), /*datatree.AddUMinus(NodeID_1)*/NodeID_1)
+              ));
           }
         else if (is_endogenous_present_1 && !is_endogenous_present_2)
           {
-            if (Derivative!=datatree.One)
-              return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddDivide(NodeID_2, Derivative))));
-            else
-              return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), NodeID_2)));
+              return(make_pair(0,
+              datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), NodeID_2)
+              ));
           }
         break;
       case oMax:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, datatree.AddMax(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddMax(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oMin:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, datatree.AddMin(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddMin(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oLess:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddLess(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddLess(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oGreater:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddGreater(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddGreater(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oLessEqual:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddLessEqual(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddLessEqual(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oGreaterEqual:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddGreaterEqual(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddGreaterEqual(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oEqualEqual:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddEqualEqual(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddEqualEqual(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       case oDifferent:
         if (!is_endogenous_present_1 && !is_endogenous_present_2)
-          return(make_pair(false, /*tmp_*/datatree.AddDifferent(NodeID_1, NodeID_2)));
+          return(make_pair(0, datatree.AddDifferent(NodeID_1, NodeID_2) ));
         else
-          return(make_pair(true, (NodeID)NULL));
+          return(make_pair(1, (NodeID)NULL ));
         break;
       }
     // Suppress GCC warning
@@ -2023,20 +2240,23 @@ TrinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExce
 }
 
 void
-TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const
+TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const
   {
     // If current node is a temporary term
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this));
     if (it != temporary_terms.end())
       {
-        CompileCode.write(&FLDT, sizeof(FLDT));
+        if(dynamic)
+          CompileCode.write(&FLDT, sizeof(FLDT));
+        else
+          CompileCode.write(&FLDST, sizeof(FLDST));
         int var=map_idx[idx];
         CompileCode.write(reinterpret_cast<char *>(&var), sizeof(var));
         return;
       }
-    arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
-    arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
-    arg3->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
+    arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
+    arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
+    arg3->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic);
     CompileCode.write(&FBINARY, sizeof(FBINARY));
     TrinaryOpcode op_codel=op_code;
     CompileCode.write(reinterpret_cast<char *>(&op_codel),sizeof(op_codel));
@@ -2094,22 +2314,22 @@ TrinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &resul
   arg3->collectVariables(type_arg, result);
 }
 
-pair<bool, NodeID>
-TrinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
+pair<int, NodeID>
+TrinaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const
   {
-    pair<bool, NodeID> res = arg1->normalizeLinearInEndoEquation(var_endo, Derivative);
+    pair<int, NodeID> res = arg1->normalizeEquation(var_endo, List_of_Op_RHS);
     bool is_endogenous_present_1 = res.first;
     NodeID NodeID_1 = res.second;
-    res = arg2->normalizeLinearInEndoEquation(var_endo, Derivative);
+    res = arg2->normalizeEquation(var_endo, List_of_Op_RHS);
     bool is_endogenous_present_2 = res.first;
     NodeID NodeID_2 = res.second;
-    res = arg3->normalizeLinearInEndoEquation(var_endo, Derivative);
+    res = arg3->normalizeEquation(var_endo, List_of_Op_RHS);
     bool is_endogenous_present_3 = res.first;
     NodeID NodeID_3 = res.second;
     if (!is_endogenous_present_1 && !is_endogenous_present_2 && !is_endogenous_present_3)
-      return(make_pair(false, /*tmp_*/datatree.AddNormcdf(NodeID_1, NodeID_2, NodeID_3)));
+      return(make_pair(0, datatree.AddNormcdf(NodeID_1, NodeID_2, NodeID_3) ));
     else
-      return(make_pair(true, (NodeID)NULL));
+      return(make_pair(1, (NodeID)NULL ));
   }
 
 NodeID
@@ -2226,14 +2446,14 @@ UnknownFunctionNode::eval(const eval_context_type &eval_context) const throw (Ev
 }
 
 void
-UnknownFunctionNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const
+UnknownFunctionNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const
   {
     cerr << "UnknownFunctionNode::compile: operation impossible!" << endl;
     exit(EXIT_FAILURE);
   }
 
-pair<bool, NodeID>
-UnknownFunctionNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
+pair<int, NodeID>
+UnknownFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const
   {
     vector<pair<bool, NodeID> > V_arguments;
     vector<NodeID> V_NodeID;
@@ -2241,14 +2461,14 @@ UnknownFunctionNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivati
     for (vector<NodeID>::const_iterator it = arguments.begin();
          it != arguments.end(); it++)
       {
-        V_arguments.push_back((*it)->normalizeLinearInEndoEquation(var_endo, Derivative));
+        V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS));
         present = present || V_arguments[V_arguments.size()-1].first;
         V_NodeID.push_back(V_arguments[V_arguments.size()-1].second);
       }
     if (!present)
-      return(make_pair(false, datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), V_NodeID)));
+      return(make_pair(0, datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), V_NodeID)));
     else
-      return(make_pair(true, (NodeID)NULL));
+      return(make_pair(1, (NodeID)NULL ));
   }
 
 NodeID
diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh
index cb2c751a386cef3de76c14ca8f21cbfb6dae39a3..b4d0b0505785c2c384b435146705e1fd06c7194a 100644
--- a/preprocessor/ExprNode.hh
+++ b/preprocessor/ExprNode.hh
@@ -94,6 +94,7 @@ class ExprNode
 {
   friend class DataTree;
   friend class DynamicModel;
+  friend class StaticDllModel;
   friend class ExprNodeLess;
   friend class NumConstNode;
   friend class VariableNode;
@@ -200,7 +201,7 @@ public:
   };
 
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException) = 0;
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const = 0;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const = 0;
   //! Creates a static version of this node
   /*!
     This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
@@ -208,7 +209,7 @@ public:
   */
   virtual NodeID toStatic(DataTree &static_datatree) const = 0;
   //! Try to normalize an equation linear in its endogenous variable
-  virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const = 0;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const = 0;
 };
 
 //! Object used to compare two nodes (using their indexes)
@@ -234,9 +235,9 @@ public:
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
   virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
-  virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const;
   virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
 };
 
@@ -264,10 +265,10 @@ public:
                                      map_idx_type &map_idx) const;
   virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
   int get_symb_id() const { return symb_id; };
-  virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const;
   virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
 };
 
@@ -296,13 +297,13 @@ public:
   virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
   static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const;
   //! Returns operand
   NodeID get_arg() const { return(arg); };
   //! Returns op code
   UnaryOpcode get_op_code() const { return(op_code); };
   virtual NodeID toStatic(DataTree &static_datatree) const;
-  virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const;
   virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
 };
 
@@ -333,7 +334,8 @@ public:
   virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
   static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const;
+  virtual NodeID Compute_RHS(NodeID arg1, NodeID arg2, int op, int op_type) const;
   //! Returns first operand
   NodeID get_arg1() const { return(arg1); };
   //! Returns second operand
@@ -341,7 +343,7 @@ public:
   //! Returns op code
   BinaryOpcode get_op_code() const { return(op_code); };
   virtual NodeID toStatic(DataTree &static_datatree) const;
-  pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const;
   virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
 };
 
@@ -373,9 +375,9 @@ public:
   virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
   static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
-  virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const;
   virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
 };
 
@@ -401,9 +403,9 @@ public:
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
   virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
-  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
+  virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
-  virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
+  virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > >  &List_of_Op_RHS) const;
   virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
 };
 
diff --git a/preprocessor/Makefile.in b/preprocessor/Makefile.in
index a8d2af7c9cbef075de40ad50f6dea22c21d39810..6dc04bddf198c19e034955fd8002ccade599ca0c 100644
--- a/preprocessor/Makefile.in
+++ b/preprocessor/Makefile.in
@@ -14,6 +14,7 @@ MAIN_OBJS = \
 	ComputingTasks.o \
 	ModelTree.o \
 	StaticModel.o \
+	StaticDllModel.o \
 	DynamicModel.o \
 	NumericalConstants.o \
 	NumericalInitialization.o \
diff --git a/preprocessor/MinimumFeedbackSet.cc b/preprocessor/MinimumFeedbackSet.cc
index 0be2e17a9bcf0fab4994203aef3e1cc92d41a1d8..d9d50ee20542afd05306198f7588c0b929667d0e 100644
--- a/preprocessor/MinimumFeedbackSet.cc
+++ b/preprocessor/MinimumFeedbackSet.cc
@@ -382,6 +382,7 @@ namespace MFS
     {
       bool something_has_been_done = true;
       int cut_ = 0;
+      feed_back_vertices.clear();
       AdjacencyList_type G(G1);
       while (num_vertices(G) > 0)
         {
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 138f3b1b665946b37c19046fd0eb5d4879a01e54..c5bb7914828ae47430f6ce92bfa9c5e385ed460f 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -25,6 +25,7 @@
 
 ModFile::ModFile() : expressions_tree(symbol_table, num_constants),
                      static_model(symbol_table, num_constants),
+                     static_dll_model(symbol_table, num_constants),
                      dynamic_model(symbol_table, num_constants),
                      linear(false)
 {
@@ -143,9 +144,16 @@ ModFile::computingPass(bool no_tmp_terms)
   if (dynamic_model.equation_number() > 0)
     {
       // Compute static model and its derivatives
-      dynamic_model.toStatic(static_model);
-      static_model.computingPass(mod_file_struct.steady_block_mfs_option, false, no_tmp_terms);
-
+      if(mod_file_struct.steady_block_mfs_dll_option)
+        {
+          dynamic_model.toStaticDll(static_dll_model);
+          static_dll_model.computingPass(global_eval_context, no_tmp_terms);
+        }
+      else
+        {
+          dynamic_model.toStatic(static_model);
+          static_model.computingPass(mod_file_struct.steady_block_mfs_option, false, no_tmp_terms);
+        }
       // Set things to compute for dynamic model
 
       if (mod_file_struct.simul_present)
@@ -228,7 +236,10 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all) const
   if (dynamic_model.equation_number() > 0)
     {
       dynamic_model.writeOutput(mOutputFile, basename);
-      static_model.writeOutput(mOutputFile);
+      if(mod_file_struct.steady_block_mfs_dll_option)
+        static_dll_model.writeOutput(mOutputFile, basename);
+      else
+        static_model.writeOutput(mOutputFile);
     }
 
   // Print statements
@@ -248,7 +259,10 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all) const
   // Create static and dynamic files
   if (dynamic_model.equation_number() > 0)
     {
-      static_model.writeStaticFile(basename);
+      if(mod_file_struct.steady_block_mfs_dll_option)
+        static_dll_model.writeStaticFile(basename);
+      else
+        static_model.writeStaticFile(basename);
       dynamic_model.writeDynamicFile(basename);
       dynamic_model.writeParamsDerivativesFile(basename);
     }
diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh
index b43f408fbb36fe5064c30fc7eca30300d6282ed1..c7f4647eca871e2bcd0da161710b82176e4db2f4 100644
--- a/preprocessor/ModFile.hh
+++ b/preprocessor/ModFile.hh
@@ -29,6 +29,7 @@ using namespace std;
 #include "NumericalConstants.hh"
 #include "NumericalInitialization.hh"
 #include "StaticModel.hh"
+#include "StaticDllModel.hh"
 #include "DynamicModel.hh"
 #include "Statement.hh"
 
@@ -46,6 +47,8 @@ public:
   DataTree expressions_tree;
   //! Static model
   StaticModel static_model;
+  //! Static Dll model
+  StaticDllModel static_dll_model;
   //! Dynamic model
   DynamicModel dynamic_model;
   //! Option linear
diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc
index c3641a3308b166c5ef2135d70573b2af900c735b..fd8a2258351b24afd2fca0a51dd7e992777e3842 100644
--- a/preprocessor/ParsingDriver.cc
+++ b/preprocessor/ParsingDriver.cc
@@ -586,7 +586,7 @@ ParsingDriver::add_to_row(NodeID v)
 void
 ParsingDriver::steady()
 {
-  mod_file->addStatement(new SteadyStatement(options_list));
+  mod_file->addStatement(new SteadyStatement(options_list, mod_file->static_dll_model.mode));
   options_list.clear();
 }
 
@@ -620,7 +620,17 @@ ParsingDriver::option_num(const string &name_option, const string &opt)
   if ((name_option == "periods") && (mod_file->dynamic_model.mode == DynamicModel::eSparseDLLMode || mod_file->dynamic_model.mode == DynamicModel::eSparseMode))
     mod_file->dynamic_model.block_triangular.periods = atoi(opt.c_str());
   else if (name_option == "cutoff")
-    mod_file->dynamic_model.cutoff = atof(opt.c_str());
+    {
+      mod_file->dynamic_model.cutoff = atof(opt.c_str());
+      mod_file->static_dll_model.cutoff = atof(opt.c_str());
+    }
+	else if (name_option == "mfs")
+	  {
+		  mod_file->dynamic_model.mfs = atoi(opt.c_str());
+		  mod_file->static_dll_model.mfs = atoi(opt.c_str());
+	  }
+	else if (name_option == "block_mfs_dll")
+	  mod_file->static_dll_model.mode = (StaticDllModel::mode_t)DynamicModel::eSparseDLLMode;
 
   options_list.num_options[name_option] = opt;
 }
diff --git a/preprocessor/Statement.cc b/preprocessor/Statement.cc
index 4350af575e931385a51ece1f1d12cb4cd6add0f3..527b9af3f502009f4779d3743653155973949ed0 100644
--- a/preprocessor/Statement.cc
+++ b/preprocessor/Statement.cc
@@ -31,7 +31,8 @@ ModFileStructure::ModFileStructure() :
   bvar_density_present(false),
   bvar_forecast_present(false),
   identification_present(false),
-  steady_block_mfs_option(false)
+  steady_block_mfs_option(false),
+  steady_block_mfs_dll_option(false)
 {
 }
 
diff --git a/preprocessor/Statement.hh b/preprocessor/Statement.hh
index 85f7686e9b8ad6e9859b32d27c175e382b8759ea..fd519c52cf125e5d343fb4a6c8cf9ca8e97b538f 100644
--- a/preprocessor/Statement.hh
+++ b/preprocessor/Statement.hh
@@ -62,6 +62,8 @@ public:
   bool identification_present;
   //! Whether the option "block_mfs" is used on steady statement
   bool steady_block_mfs_option;
+  //! Whether the option "block_mfs_dll" is used on steady statement
+  bool steady_block_mfs_dll_option;
 };
 
 class Statement
diff --git a/tests/ferhat/fs2000.mod b/tests/ferhat/fs2000.mod
index 73ab64bbb0c94fce2009da49d44f59a08d348d7c..e85eaf6556d03f90f5884b7f0a5c8b0cb7ffd039 100644
--- a/tests/ferhat/fs2000.mod
+++ b/tests/ferhat/fs2000.mod
@@ -93,7 +93,7 @@ end;
 
 //options_.solve_tolf=1e-10;
 options_.maxit_=10;
-steady(block_mfs);
+steady;//(block_mfs);
 model_info;
 //check;
 shocks;
diff --git a/tests/ferhat/multimod.mod b/tests/ferhat/multimod.mod
index b4dbc0fe54990523dc3cbb74d91ddcae87f355dc..ce3858bdfc3475c3472917263fcb01d73696ff07 100644
--- a/tests/ferhat/multimod.mod
+++ b/tests/ferhat/multimod.mod
@@ -852,7 +852,7 @@ W0906=0.0800069594276;
 W0907=0.147854375051;
 W0908=0.206834342322;
 W0909=-1;
-model(SPARSE_DLL,markowitz=2/*0.5*//*2.0*/);
+model(SPARSE_DLL,markowitz=3, mfs = 3);
 //model(SPARSE,markowitz=2.0);
 //model;
  ( log(US_CPI)-(log(US_CPI(-1)))) = US_CPI1*( log(US_PIM)-(log(US_PIM(-1))))+US_CPI2*( log(US_PGNP)-(log(US_PGNP(-1))))+(1-US_CPI1-US_CPI2)*log(US_CPI(-1)/US_CPI(-2))+RES_US_CPI ;