diff --git a/matlab/csolve.m b/matlab/csolve.m
new file mode 100644
index 0000000000000000000000000000000000000000..a99f893ae1efb4a06c069cb65757a1d6bf6efed2
--- /dev/null
+++ b/matlab/csolve.m
@@ -0,0 +1,142 @@
+function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)
+%function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)
+% FUN should be written so that any parametric arguments are packed in to xp,
+% and so that if presented with a matrix x, it produces a return value of
+% same dimension of x.  The number of rows in x and FUN(x) are always the
+% same.  The number of columns is the number of different input arguments
+% at which FUN is to be evaluated.
+%
+% gradfun:  string naming the function called to evaluate the gradient matrix.  If this
+%           is null (i.e. just "[]"), a numerical gradient is used instead.
+% crit:     if the sum of absolute values that FUN returns is less than this,
+%           the equation is solved.
+% itmax:    the solver stops when this number of iterations is reached, with rc=4
+% varargin: in this position the user can place any number of additional arguments, all
+%           of which are passed on to FUN and gradfun (when it is non-empty) as a list of 
+%           arguments following x.
+% rc:       0 means normal solution, 1 and 3 mean no solution despite extremely fine adjustments
+%           in step length (very likely a numerical problem, or a discontinuity). 4 means itmax
+%           termination.
+%---------- delta --------------------
+% differencing interval for numerical gradient
+delta = 1e-6;
+%-------------------------------------
+%------------ alpha ------------------
+% tolerance on rate of descent
+alpha=1e-3;
+%---------------------------------------
+%------------ verbose ----------------
+verbose=0;% if this is set to zero, all screen output is suppressed
+%-------------------------------------
+%------------ analyticg --------------
+analyticg=1-isempty(gradfun); %if the grad argument is [], numerical derivatives are used.
+%-------------------------------------
+nv=length(x);
+tvec=delta*eye(nv);
+done=0;
+if isempty(varargin)
+   f0=feval(FUN,x);
+else
+   f0=feval(FUN,x,varargin{:});
+end   
+af0=sum(abs(f0));
+af00=af0;
+itct=0;
+while ~done
+   disp([af00-af0 crit*max(1,af0)])
+   if itct>3 & af00-af0<crit*max(1,af0) & rem(itct,2)==1
+      randomize=1;
+   else
+      if ~analyticg
+         if isempty(varargin)
+            grad = (feval(FUN,x*ones(1,nv)+tvec)-f0*ones(1,nv))/delta;
+         else
+            grad = (feval(FUN,x*ones(1,nv)+tvec,varargin{:})-f0*ones(1,nv))/delta;
+         end
+      else % use analytic gradient
+         grad=feval(gradfun,x,varargin{:});
+      end
+      if isreal(grad)
+         if rcond(grad)<1e-12
+            grad=grad+tvec;
+         end
+         dx0=-grad\f0;
+         randomize=0;
+      else
+         if(verbose),disp('gradient imaginary'),end
+         randomize=1;
+      end
+   end
+   if randomize
+      if(verbose),fprintf(1,'\n Random Search'),end
+      dx0=norm(x)./randn(size(x));
+   end
+   lambda=1;
+   lambdamin=1;
+   fmin=f0;
+   xmin=x;
+   afmin=af0;
+   dxSize=norm(dx0);
+   factor=.6;
+   shrink=1;
+   subDone=0;
+   while ~subDone
+      dx=lambda*dx0;
+      f=feval(FUN,x+dx,varargin{:});
+      af=sum(abs(f));
+      if af<afmin
+         afmin=af;
+         fmin=f;
+         lambdamin=lambda;
+         xmin=x+dx;
+      end
+      if ((lambda >0) & (af0-af < alpha*lambda*af0)) | ((lambda<0) & (af0-af < 0) )
+         if ~shrink
+            factor=factor^.6;
+            shrink=1;
+         end
+         if abs(lambda*(1-factor))*dxSize > .1*delta;
+            lambda = factor*lambda;
+         elseif (lambda > 0) & (factor==.6) %i.e., we've only been shrinking
+            lambda=-.3;
+         else %
+            subDone=1;
+            if lambda > 0
+               if factor==.6
+                  rc = 2;
+               else
+                  rc = 1;
+               end
+            else
+               rc=3;
+            end
+         end
+      elseif (lambda >0) & (af-af0 > (1-alpha)*lambda*af0)
+         if shrink
+            factor=factor^.6;
+            shrink=0;
+         end
+         lambda=lambda/factor;
+      else % good value found
+         subDone=1;
+         rc=0;
+      end
+   end % while ~subDone
+   itct=itct+1;
+   if(verbose)
+      fprintf(1,'\nitct %d, af %g, lambda %g, rc %g',itct,afmin,lambdamin,rc)
+      fprintf(1,'\n   x  %10g %10g %10g %10g',xmin);
+      fprintf(1,'\n   f  %10g %10g %10g %10g',fmin);
+   end
+   x=xmin;
+   f0=fmin;
+   af00=af0;
+   af0=afmin;
+   if itct >= itmax
+      done=1;
+      rc=4;
+   elseif af0<crit;
+      done=1;
+      rc=0;
+   end
+end
diff --git a/matlab/dynare_solve.m b/matlab/dynare_solve.m
index c2fa873429e2a44cffda3093267a520a9c15f87b..f394d1674ae6c1770c076061a585c024537b366f 100644
--- a/matlab/dynare_solve.m
+++ b/matlab/dynare_solve.m
@@ -77,6 +77,8 @@ function [x,info] = dynare_solve(func,x,jacobian_flag,varargin)
     end
     [x,info]=solve1(func,x,1:nn,1:nn,jacobian_flag,varargin{:});
       
+  elseif options_.solve_algo == 3
+      [x,info] = csolve(func,x,'grad_ss',1e-6,500,varargin{:});
   end
 %    fvec1 = feval(func,x,varargin{:})