diff --git a/matlab/moment_function.m b/matlab/moment_function.m
new file mode 100644
index 000000000..57a87a26b
--- /dev/null
+++ b/matlab/moment_function.m
@@ -0,0 +1,141 @@
+function [g,flag] = moment_function(xparams,sample_moments,weighting_matrix,options,parallel)
+% Evaluates the moment function of the Simulated Moments Method (discrepancy between sample and
+% ).
+%
+% INPUTS:
+% xparams [double] p*1 vector of estimated parameters.
+% sample_moments [double] n*1 vector of sample moments (n>=p).
+% weighting_matrix [double] n*n symetric, positive definite matrix.
+% options [ ] Structure defining options for SMM.
+% parallel [ ] Structure defining the parallel mode settings (optional).
+%
+% OUTPUTS:
+% g [double] n*1 vector, the gap between simulated and sample moments.
+% flag [intger] empty matrix.
+%
+% SPECIAL REQUIREMENTS
+% The user has to provide a file where the moment conditions are defined.
+
+% Copyright (C) 2010 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare. If not, see .
+
+global M_ options_
+persistent mainStream mainState
+persistent priorObjectiveValue
+
+flag = 1;
+
+if nargin<5
+ if isempty(mainStream)
+ mainStream = RandStream.getDefaultStream;
+ mainState = mainStream.State;
+ else
+ mainStream.State = mainState;
+ end
+end
+
+penalty = 0;
+for i=1:options.estimated_parameters.nb
+ if ~isnan(options.estimated_parameters.upper_bound(i)) && xparams(i)>options.estimated_parameters.upper_bound(i)
+ penalty = penalty + (xparams(i)-options.estimated_parameters.upper_bound(i))^2;
+ end
+ if ~isnan(options.estimated_parameters.lower_bound(i)) && xparams(i)0
+ flag = 0;
+ return;
+end
+
+save('estimated_parameters.mat','xparams');
+
+% Check for local determinacy of the deterministic steady state.
+noprint = options_.noprint; options_.noprint = 1;
+[local_determinacy_and_stability,info] = check; options_.noprint = noprint;
+if ~local_determinacy_and_stability
+ flag = 0;
+ return
+end
+
+simulated_moments = zeros(size(sample_moments));
+
+% Just to be sure that things don't mess up with persistent variables...
+clear perfect_foresight_simulation;
+
+if nargin<5
+ for s = 1:options.number_of_simulated_sample
+ time_series = extended_path([],options.simulated_sample_size,1);
+ data = time_series(options.observed_variables_idx,options.burn_in_periods+1:options.simulated_sample_size);
+ eval(['tmp = ' options.moments_file_name '(data);'])
+ simulated_moments = simulated_moments + tmp;
+ simulated_moments = simulated_moments / options.number_of_simulated_sample;
+ end
+else% parallel mode.
+ if ~isunix
+ error('The parallel version of SMM estimation is not implemented for non unix platforms!')
+ end
+ job_number = 1;% Remark. First job is for the master.
+ [Junk,hostname] = unix('hostname --fqdn');
+ hostname = deblank(hostname);
+ for i=1:length(parallel)
+ machine = deblank(parallel(i).machine);
+ if ~strcmpi(hostname,machine)
+ % For the slaves on a remote computer.
+ unix(['scp estimated_parameters.mat ' , parallel(i).login , '@' , machine , ':' parallel(i).folder ' > /dev/null']);
+ else
+ if ~strcmpi(pwd,parallel(i).folder)
+ % For the slaves on this computer but not in the same directory as the master.
+ unix(['cp estimated_parameters.mat ' , parallel(i).folder]);
+ end
+ end
+ for j=1:parallel(i).number_of_jobs
+ if (strcmpi(hostname,machine) && j>1) || ~strcmpi(hostname,machine)
+ job_number = job_number + 1;
+ unix(['ssh -A ' parallel(i).login '@' machine ' ./call_matlab_session.sh job' int2str(job_number) '.m &']);
+ end
+ end
+ end
+ % Finally the Master do its job
+ tStartMasterJob = clock;
+ eval('job1;')
+ tElapsedMasterJob = etime(clock, tStartMasterJob);
+ TimeLimit = tElapsedMasterJob*1.2;
+ % Master waits for the slaves' output...
+ tStart = clock;
+ tElapsed = 0;
+ while tElapsed