From efcf6bd9c09fa43bcf78fdb88b7b2d3a4dae5e05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?=
 <stephane.adjemian@univ-lemans.fr>
Date: Mon, 16 Jun 2014 17:41:59 +0200
Subject: [PATCH] Use dseries object in the estimation routines.

---
 matlab/dsge_likelihood.m                      |  34 +--
 matlab/dynare_estimation_1.m                  |  72 ++++---
 matlab/dynare_estimation_init.m               | 105 +--------
 matlab/initial_estimation_checks.m            |  13 +-
 matlab/metropolis_hastings_initialization.m   |   8 +-
 matlab/random_walk_metropolis_hastings.m      |   5 +-
 matlab/random_walk_metropolis_hastings_core.m |   3 +-
 matlab/utilities/dataset/makedataset.m        | 203 ++++++++++++++++++
 tests/fs2000/fs2000_dseries.mod               |   2 +-
 9 files changed, 279 insertions(+), 166 deletions(-)
 create mode 100644 matlab/utilities/dataset/makedataset.m

diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m
index e3ffc7ceac..1ef6952621 100644
--- a/matlab/dsge_likelihood.m
+++ b/matlab/dsge_likelihood.m
@@ -1,4 +1,4 @@
-function [fval,DLIK,Hess,exit_flag,ys,trend_coeff,info,Model,DynareOptions,BayesInfo,DynareResults] = dsge_likelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults,derivatives_info)
+function [fval,DLIK,Hess,exit_flag,ys,trend_coeff,info,Model,DynareOptions,BayesInfo,DynareResults] = dsge_likelihood(xparam1,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults,derivatives_info)
 % Evaluates the posterior kernel of a dsge model using the specified
 % kalman_algo; the resulting posterior includes the 2*pi constant of the
 % likelihood function
@@ -295,7 +295,7 @@ BayesInfo.mf = BayesInfo.mf1;
 
 % Define the constant vector of the measurement equation.
 if DynareOptions.noconstant
-    constant = zeros(DynareDataset.info.nvobs,1);
+    constant = zeros(DynareDataset.vobs,1);
 else
     if DynareOptions.loglinear
         constant = log(SteadyState(BayesInfo.mfys));
@@ -306,28 +306,28 @@ end
 
 % Define the deterministic linear trend of the measurement equation.
 if BayesInfo.with_trend
-    trend_coeff = zeros(DynareDataset.info.nvobs,1);
+    trend_coeff = zeros(DynareDataset.vobs,1);
     t = DynareOptions.trend_coeffs;
     for i=1:length(t)
         if ~isempty(t{i})
             trend_coeff(i) = evalin('base',t{i});
         end
     end
-    trend = repmat(constant,1,DynareDataset.info.ntobs)+trend_coeff*[1:DynareDataset.info.ntobs];
+    trend = repmat(constant,1,DynareDataset.nobs)+trend_coeff*[1:DynareDataset.nobs];
 else
-    trend = repmat(constant,1,DynareDataset.info.ntobs);
+    trend = repmat(constant,1,DynareDataset.nobs);
 end
 
 % Get needed informations for kalman filter routines.
 start = DynareOptions.presample+1;
-Z = BayesInfo.mf; % old mf
-no_missing_data_flag = ~DynareDataset.missing.state;
-mm = length(T); % old np
-pp = DynareDataset.info.nvobs;
+Z = BayesInfo.mf;
+no_missing_data_flag = ~DatasetInfo.missing.state;
+mm = length(T);
+pp = DynareDataset.vobs;
 rr = length(Q);
 kalman_tol = DynareOptions.kalman_tol;
 riccati_tol = DynareOptions.riccati_tol;
-Y   = DynareDataset.data-trend;
+Y = transpose(DynareDataset.data)-trend;
 
 %------------------------------------------------------------------------------
 % 3. Initial condition of the Kalman filter
@@ -406,7 +406,7 @@ switch DynareOptions.lik_init
                                                        kalman_tol, riccati_tol, DynareOptions.presample, ...
                                                        T,R,Q,H,Z,mm,pp,rr);
         else
-            [dLIK,dlik,a,Pstar] = missing_observations_kalman_filter_d(DynareDataset.missing.aindex,DynareDataset.missing.number_of_observations,DynareDataset.missing.no_more_missing_observations, ...
+            [dLIK,dlik,a,Pstar] = missing_observations_kalman_filter_d(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations, ...
                                                               Y, 1, size(Y,2), ...
                                                               zeros(mm,1), Pinf, Pstar, ...
                                                               kalman_tol, riccati_tol, DynareOptions.presample, ...
@@ -441,9 +441,9 @@ switch DynareOptions.lik_init
         % no need to test again for correlation elements
         correlated_errors_have_been_checked = 1;
 
-        [dLIK,dlik,a,Pstar] = univariate_kalman_filter_d(DynareDataset.missing.aindex,...
-                                                        DynareDataset.missing.number_of_observations,...
-                                                        DynareDataset.missing.no_more_missing_observations, ...
+        [dLIK,dlik,a,Pstar] = univariate_kalman_filter_d(DatasetInfo.missing.aindex,...
+                                                        DatasetInfo.missing.number_of_observations,...
+                                                        DatasetInfo.missing.no_more_missing_observations, ...
                                                         Y, 1, size(Y,2), ...
                                                         zeros(mmm,1), Pinf, Pstar, ...
                                                         kalman_tol, riccati_tol, DynareOptions.presample, ...
@@ -655,10 +655,10 @@ if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter
         end
     else
         if 0 %DynareOptions.block
-            [err, LIK,lik] = block_kalman_filter(DynareDataset.missing.aindex,DynareDataset.missing.number_of_observations,DynareDataset.missing.no_more_missing_observations,...
+            [err, LIK,lik] = block_kalman_filter(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations,...
                                                                  T,R,Q,H,Pstar,Y,start,Z,kalman_tol,riccati_tol, Model.nz_state_var, Model.n_diag, Model.nobs_non_statevar);
         else
-            [LIK,lik] = missing_observations_kalman_filter(DynareDataset.missing.aindex,DynareDataset.missing.number_of_observations,DynareDataset.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ...
+            [LIK,lik] = missing_observations_kalman_filter(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ...
                                                a, Pstar, ...
                                                kalman_tol, DynareOptions.riccati_tol, ...
                                                DynareOptions.presample, ...
@@ -733,7 +733,7 @@ if (kalman_algo==2) || (kalman_algo==4)
         end
     end
 
-    [LIK, lik] = univariate_kalman_filter(DynareDataset.missing.aindex,DynareDataset.missing.number_of_observations,DynareDataset.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ...
+    [LIK, lik] = univariate_kalman_filter(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ...
                                        a,Pstar, ...
                                        DynareOptions.kalman_tol, ...
                                        DynareOptions.riccati_tol, ...
diff --git a/matlab/dynare_estimation_1.m b/matlab/dynare_estimation_1.m
index d617bfbf56..861af4d58d 100644
--- a/matlab/dynare_estimation_1.m
+++ b/matlab/dynare_estimation_1.m
@@ -29,7 +29,7 @@ function dynare_estimation_1(var_list_,dname)
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 
-global M_ options_ oo_ estim_params_ bayestopt_ dataset_
+global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info
 
 % Set particle filter flag.
 if options_.order > 1
@@ -78,7 +78,8 @@ else
     objective_function = str2func('dsge_var_likelihood');
 end
 
-[dataset_,xparam1, hh, M_, options_, oo_, estim_params_,bayestopt_] = dynare_estimation_init(var_list_, dname, [], M_, options_, oo_, estim_params_, bayestopt_);
+[dataset_,dataset_info, xparam1, hh, M_, options_, oo_, estim_params_, bayestopt_] = ...
+    dynare_estimation_init(var_list_, dname, [], M_, options_, oo_, estim_params_, bayestopt_);
 
 if options_.dsge_var
     check_dsge_var_model(M_, estim_params_, bayestopt_);
@@ -114,12 +115,12 @@ if estim_params_.ncx || any(nnz(tril(M_.Correlation_matrix,-1))) || isfield(esti
 end
 
 data = dataset_.data;
-rawdata = dataset_.rawdata;
-data_index = dataset_.missing.aindex;
-missing_value = dataset_.missing.state;
+rawdata = dataset_.data;
+data_index = dataset_info.missing.aindex;
+missing_value = dataset_info.missing.state;
 
 % Set number of observations
-gend = options_.nobs;
+gend = dataset_.nobs;
 % Set the number of observed variables.
 n_varobs = length(options_.varobs);
 % Get the number of parameters to be estimated.
@@ -156,7 +157,7 @@ end
 
 % compute sample moments if needed (bvar-dsge)
 if options_.dsge_var
-    if dataset_.missing.state
+    if dataset_info.missing.state
         error('I cannot estimate a DSGE-VAR model with missing observations!')
     end
     if options_.noconstant
@@ -176,7 +177,7 @@ end
 
 %% perform initial estimation checks;
 try
-    oo_ = initial_estimation_checks(objective_function,xparam1,dataset_,M_,estim_params_,options_,bayestopt_,oo_);
+    oo_ = initial_estimation_checks(objective_function,xparam1,dataset_,dataset_info,M_,estim_params_,options_,bayestopt_,oo_);
 catch % if check fails, provide info on using calibration if present
     e = lasterror();
     if full_calibration_detected %calibrated model present and no explicit starting values
@@ -246,7 +247,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
             optim_options = optimset(optim_options,'GradObj','on','TolX',1e-7);
         end
         [xparam1,fval,exitflag,output,lamdba,grad,hessian_fmincon] = ...
-            fmincon(objective_function,xparam1,[],[],[],[],lb,ub,[],optim_options,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+            fmincon(objective_function,xparam1,[],[],[],[],lb,ub,[],optim_options,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
       case 2
         error('ESTIMATION: mode_compute=2 option (Lester Ingber''s Adaptive Simulated Annealing) is no longer available')
       case 3
@@ -264,10 +265,10 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
             optim_options = optimset(optim_options,'GradObj','on');
         end
         if ~isoctave
-            [xparam1,fval,exitflag] = fminunc(objective_function,xparam1,optim_options,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+            [xparam1,fval,exitflag] = fminunc(objective_function,xparam1,optim_options,dataset_,dataset_info_,options_,M_,estim_params_,bayestopt_,oo_);
         else
             % Under Octave, use a wrapper, since fminunc() does not have a 4th arg
-            func = @(x) objective_function(x, dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+            func = @(x) objective_function(x, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
             [xparam1,fval,exitflag] = fminunc(func,xparam1,optim_options);
         end
       case 4
@@ -306,7 +307,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
         end
         % Call csminwell.
         [fval,xparam1,grad,hessian_csminwel,itct,fcount,retcodehat] = ...
-            csminwel1(objective_function, xparam1, H0, analytic_grad, crit, nit, numgrad, epsilon, dataset_, options_, M_, estim_params_, bayestopt_, oo_);
+            csminwel1(objective_function, xparam1, H0, analytic_grad, crit, nit, numgrad, epsilon, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_);
         % Disp value at the mode.
         disp(sprintf('Objective function at mode: %f',fval))
       case 5
@@ -334,7 +335,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
         else
             nit=1000;
         end
-        [xparam1,hh,gg,fval,invhess] = newrat(objective_function,xparam1,analytic_grad,crit,nit,flag,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        [xparam1,hh,gg,fval,invhess] = newrat(objective_function,xparam1,analytic_grad,crit,nit,flag,dataset_, dataset_info, options_,M_,estim_params_,bayestopt_,oo_);
         if options_.analytic_derivation,
             options_.analytic_derivation = ana_deriv;
         end
@@ -384,7 +385,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
             end
         end
         % Evaluate the objective function.
-        fval = feval(objective_function,xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        fval = feval(objective_function,xparam1,dataset_, dataset_info, options_,M_,estim_params_,bayestopt_,oo_);
         OldMode = fval;
         if ~exist('MeanPar','var')
             MeanPar = xparam1;
@@ -416,8 +417,8 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
                     flag = 'LastCall';
                 end
                 [xparam1,PostVar,Scale,PostMean] = ...
-                    gmhmaxlik(objective_function,xparam1,[lb ub],gmhmaxlikOptions,Scale,flag,MeanPar,CovJump,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
-                fval = feval(objective_function,xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                    gmhmaxlik(objective_function,xparam1,[lb ub],gmhmaxlikOptions,Scale,flag,MeanPar,CovJump,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
+                fval = feval(objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
                 options_.mh_jscale = Scale;
                 mouvement = max(max(abs(PostVar-OldPostVar)));
                 skipline()
@@ -436,11 +437,11 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
                 end
                 [xparam1,PostVar,Scale,PostMean] = ...
                     gmhmaxlik(objective_function,xparam1,[lb ub],...
-                              gmhmaxlikOptions,Scale,flag,PostMean,PostVar,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
-                fval = feval(objective_function,xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                              gmhmaxlikOptions,Scale,flag,PostMean,PostVar,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
+                fval = feval(objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
                 options_.mh_jscale = Scale;
                 mouvement = max(max(abs(PostVar-OldPostVar)));
-                fval = feval(objective_function,xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                fval = feval(objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
                 skipline()
                 disp('========================================================== ')
                 disp(['   Change in the covariance matrix = ' num2str(mouvement) '.'])
@@ -473,7 +474,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
         if isfield(options_,'optim_opt')
             eval(['optim_options = optimset(optim_options,' options_.optim_opt ');']);
         end
-        [xparam1,fval,exitflag] = fminsearch(objective_function,xparam1,optim_options,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        [xparam1,fval,exitflag] = fminsearch(objective_function,xparam1,optim_options,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
       case 8
         % Dynare implementation of the simplex algorithm.
         simplexOptions = options_.simplex;
@@ -498,7 +499,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
                 end
             end
         end
-        [xparam1,fval,exitflag] = simplex_optimization_routine(objective_function,xparam1,simplexOptions,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        [xparam1,fval,exitflag] = simplex_optimization_routine(objective_function,xparam1,simplexOptions,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
       case 9
         % Set defaults
         H0 = 1e-4*ones(nx,1);
@@ -523,7 +524,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
         end
         warning('off','CMAES:NonfinitenessRange');
         warning('off','CMAES:InitialSigma');
-        [x, fval, COUNTEVAL, STOPFLAG, OUT, BESTEVER] = cmaes(func2str(objective_function),xparam1,H0,cmaesOptions,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        [x, fval, COUNTEVAL, STOPFLAG, OUT, BESTEVER] = cmaes(func2str(objective_function),xparam1,H0,cmaesOptions,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
         xparam1=BESTEVER.x;
         disp(sprintf('\n Objective function at mode: %f',fval))
       case 10
@@ -554,16 +555,16 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
         end
         simpsaOptionsList = options2cell(simpsaOptions);
         simpsaOptions = simpsaset(simpsaOptionsList{:});
-        [xparam1, fval, exitflag] = simpsa(func2str(objective_function),xparam1,lb,ub,simpsaOptions,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        [xparam1, fval, exitflag] = simpsa(func2str(objective_function),xparam1,lb,ub,simpsaOptions,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
       case 11
          options_.cova_compute = 0 ;
-         [xparam1,stdh,lb_95,ub_95,med_param] = online_auxiliary_filter(xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_) ;
+         [xparam1,stdh,lb_95,ub_95,med_param] = online_auxiliary_filter(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) ;
       case 101
         myoptions=soptions;
         myoptions(2)=1e-6; %accuracy of argument
         myoptions(3)=1e-6; %accuracy of function (see Solvopt p.29)
         myoptions(5)= 1.0;
-        [xparam1,fval]=solvopt(xparam1,objective_function,[],myoptions,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        [xparam1,fval]=solvopt(xparam1,objective_function,[],myoptions,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
       case 102
         %simulating annealing
         %        LB=zeros(size(xparam1))-20;
@@ -600,10 +601,10 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
         disp(['c vector   ' num2str(c')]);
 
         [xparam1, fval, nacc, nfcnev, nobds, ier, t, vm] = sa(objective_function,xparam1,maxy,rt_,epsilon,ns,nt ...
-                                                              ,neps,maxevl,LB,UB,c,idisp ,t,vm,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                                                              ,neps,maxevl,LB,UB,c,idisp ,t,vm,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
       otherwise
         if ischar(options_.mode_compute)
-            [xparam1, fval, retcode ] = feval(options_.mode_compute,objective_function,xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+            [xparam1, fval, retcode ] = feval(options_.mode_compute,objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
         else
             error(['dynare_estimation:: mode_compute = ' int2str(options_.mode_compute) ' option is unknown!'])
         end
@@ -614,11 +615,11 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
                 ana_deriv = options_.analytic_derivation;
                 options_.analytic_derivation = 2;
                 [junk1, junk2, hh] = feval(objective_function,xparam1, ...
-                    dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                    dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
                 options_.analytic_derivation = ana_deriv;
             else
                 hh = reshape(hessian(objective_function,xparam1, ...
-                    options_.gstep,dataset_,options_,M_,estim_params_,bayestopt_,oo_),nx,nx);
+                    options_.gstep,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_),nx,nx);
             end
         end
     end
@@ -698,7 +699,7 @@ end
 if options_.mode_check.status == 1 && ~options_.mh_posterior_mode_estimation
     ana_deriv = options_.analytic_derivation;
     options_.analytic_derivation = 0;
-    mode_check(objective_function,xparam1,hh,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+    mode_check(objective_function,xparam1,hh,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
     options_.analytic_derivation = ana_deriv;
 end
 
@@ -732,7 +733,7 @@ if any(bayestopt_.pshape > 0) && ~options_.mh_posterior_mode_estimation
         estim_params_nbr = size(xparam1,1);
         scale_factor = -sum(log10(diag(invhess)));
         log_det_invhess = -estim_params_nbr*log(scale_factor)+log(det(scale_factor*invhess));
-        likelihood = feval(objective_function,xparam1,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+        likelihood = feval(objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
         oo_.MarginalDensity.LaplaceApproximation = .5*estim_params_nbr*log(2*pi) + .5*log_det_invhess - likelihood;
         skipline()
         disp(sprintf('Log data density [Laplace approximation] is %f.',oo_.MarginalDensity.LaplaceApproximation))
@@ -779,7 +780,7 @@ if (any(bayestopt_.pshape  >0 ) && options_.mh_replic) || ...
         ana_deriv = options_.analytic_derivation;
         options_.analytic_derivation = 0;
         if options_.cova_compute
-            feval(options_.posterior_sampling_method,objective_function,options_.proposal_distribution,xparam1,invhess,bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+            feval(options_.posterior_sampling_method,objective_function,options_.proposal_distribution,xparam1,invhess,bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
         else
             error('I Cannot start the MCMC because the Hessian of the posterior kernel at the mode was not computed.')
         end
@@ -842,7 +843,7 @@ if (~((any(bayestopt_.pshape > 0) && options_.mh_replic) || (any(bayestopt_.psha
                                                       > 0) && options_.load_mh_file)) ...
     || ~options_.smoother ) && options_.partial_information == 0  % to be fixed
     %% ML estimation, or posterior mode without metropolis-hastings or metropolis without bayesian smooth variable
-    [atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp] = DsgeSmoother(xparam1,dataset_.info.ntobs,dataset_.data,dataset_.missing.aindex,dataset_.missing.state);
+    [atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp] = DsgeSmoother(xparam1,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state);
     oo_.Smoother.SteadyState = ys;
     oo_.Smoother.TrendCoeffs = trend_coeff;
     oo_.Smoother.Variance = P;
@@ -949,8 +950,11 @@ if (~((any(bayestopt_.pshape > 0) && options_.mh_replic) || (any(bayestopt_.psha
     %%  Smooth observational errors...
     %%
     if options_.prefilter == 1
-        yf = atT(bayestopt_.mf,:)+repmat(dataset_.descriptive.mean',1,gend);
+        yf = atT(bayestopt_.mf,:)+repmat(dataset_info.descriptive.mean',1,gend);
     elseif options_.loglinear == 1
+        gend
+        bayestopt_.mfys
+        ys
         yf = atT(bayestopt_.mf,:)+repmat(log(ys(bayestopt_.mfys)),1,gend)+...
              trend_coeff*[1:gend];
     else
diff --git a/matlab/dynare_estimation_init.m b/matlab/dynare_estimation_init.m
index a9e9e18589..90189e7c85 100644
--- a/matlab/dynare_estimation_init.m
+++ b/matlab/dynare_estimation_init.m
@@ -1,4 +1,4 @@
-function [dataset_, xparam1, hh, M_, options_, oo_, estim_params_,bayestopt_, fake] = dynare_estimation_init(var_list_, dname, gsa_flag, M_, options_, oo_, estim_params_, bayestopt_)
+function [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_,bayestopt_, fake] = dynare_estimation_init(var_list_, dname, gsa_flag, M_, options_, oo_, estim_params_, bayestopt_)
 
 % function dynare_estimation_init(var_list_, gsa_flag)
 % preforms initialization tasks before estimation or
@@ -447,106 +447,8 @@ end
 k = find(isnan(bayestopt_.jscale));
 bayestopt_.jscale(k) = options_.mh_jscale;
 
-% Test if the dataset is declared.
-if isempty(options_.datafile) && isempty(options_.dataset) 
-    if gsa_flag
-        dataset_ = [];
-        return
-    else
-        error('datafile option is missing')
-    end
-end
-
-if ~isfield(options_,'nobs')
-    options_.nobs = [];
-end
-
-if isempty(options_.datafile) && ~isempty(options_.dataset.file)
-    datafile = options_.dataset.file;
-elseif ~isempty(options_.datafile) && isempty(options_.dataset.file)
-    datafile = options_.datafile;
-elseif isempty(options_.datafile) && ~isempty(options_.dataset.file)
-    error('You cannot use simultaneously the data command and the datafile option (in the estimation command)!')
-else
-    error('You have to specify the datafile!')
-end
-
-
-% Check extension.
-allowed_extensions = {'m','mat','csv','xls','xlsx'};
-datafile_extension = get_file_extension(datafile);
-if isempty(datafile_extension)
-    available_extensions = {}; j = 1;
-    for i=1:length(allowed_extensions)
-        if exist([datafile '.' allowed_extensions{i}])
-            available_extensions(j) = {allowed_extensions{i}};
-            j = j+1;
-        end
-    end
-    if isempty(available_extensions)
-        error(['I can''t find a datafile (with allowed extension)!'])
-    end
-    if length(available_extensions)>1
-        error(sprintf(['You did not specify an extension for the datafile, but more than one candidate ' ...
-                       'are available in the designed folder!\nPlease, add an extension to the datafile ' ...
-                       '(m, mat, csv, xls or xlsx are legal extensions).']));
-    end
-    datafile = [datafile '.' available_extensions{1}];
-end
-
-% Load the data in a dseries object.
-dataset = dseries(datafile);
-
-% Select a subset of the variables.
-dataset = dataset{options_.varobs{:}};
-
-% Apply log function if needed.
-if options_.loglinear && ~options_.logdata
-    dataset = dataset.log();
-end
-
-% Test if an initial period (different from its default value) is explicitely defined in the datafile.
-if isequal(dataset.init, dates(1))
-    dataset_default_initial_period = 1;
-else
-    dataset_default_initial_period = 0;
-end
-
-%  Test if an initial period (different from its default value) is explicitely defined in the mod file with the set_time command.
-if isequal(options_.initial_period, dates(1))
-    set_time_default_initial_period = 1;
-else
-    set_time_default_initial_period = 0;
-end
-
-if ~set_time_default_initial_period && dataset_default_initial_period
-    % Overwrite the initial period in dataset (it was set to default).
-    % Note that the update of freq and time members is auto-magically 
-    % done by dseries::subsasgn overload method.
-    dataset.init = options_.initial_period;
-end
-
-if set_time_default_initial_period && ~dataset_default_initial_period
-    % Overwrite the global initial period defined by set_time (it was set to default).
-    options_.initial_period = dataset.init;
-end
-
-if ~set_time_default_initial_period && ~dataset_default_initial_period
-    % Check if dataset.init and options_.initial_period are identical.
-    if  ~isequal(options_.initial_period, dataset.init)
-        error('dynare_estimation_init:: The date as defined by the set_time command is not consistent with the initial period in the database!')
-    end
-end
-
-
-if options_.initial_period>options_.dataset.first_obs
-    skipline()
-    error(['First observation (' format(options_.dataset.first_obs) ') must be greater than the initial period (' format(options_.initial_period)  ') as set by the set_time command']);
-end
-    
-dataset_ = initialize_dataset(options_.datafile,options_.varobs,options_.first_obs,options_.nobs,logged_data_flag,options_.prefilter,xls);
-
-options_.nobs = dataset_.info.ntobs;
+% Build the dataset
+[dataset_, dataset_info] = makedataset(options_);
 
 % setting steadystate_check_flag option
 if options_.diffuse_filter
@@ -554,6 +456,7 @@ if options_.diffuse_filter
 else
     steadystate_check_flag = 1;
 end
+
 % If the steady state of the observed variables is non zero, set noconstant equal 0 ()
 M = M_;
 nvx = estim_params_.nvx;
diff --git a/matlab/initial_estimation_checks.m b/matlab/initial_estimation_checks.m
index 9dee5461e9..c4cbf5ab96 100644
--- a/matlab/initial_estimation_checks.m
+++ b/matlab/initial_estimation_checks.m
@@ -1,11 +1,12 @@
-function DynareResults = initial_estimation_checks(objective_function,xparam1,DynareDataset,Model,EstimatedParameters,DynareOptions,BayesInfo,DynareResults)
+function DynareResults = initial_estimation_checks(objective_function,xparam1,DynareDataset,DatasetInfo,Model,EstimatedParameters,DynareOptions,BayesInfo,DynareResults)
 % function initial_estimation_checks(xparam1,gend,data,data_index,number_of_observations,no_more_missing_observations)
 % Checks data (complex values, ML evaluation, initial values, BK conditions,..)
 %
 % INPUTS
 %   objective_function  [function handle] of the objective function
 %   xparam1:            [vector] of parameters to be estimated
-%   DynareDataset:      [structure] storing the dataset information
+%   DynareDataset:      [dseries] object storing the dataset
+%   DataSetInfo:        [structure] storing informations about the sample.
 %   Model:              [structure] decribing the model
 %   EstimatedParameters [structure] characterizing parameters to be estimated
 %   DynareOptions       [structure] describing the options
@@ -35,11 +36,11 @@ function DynareResults = initial_estimation_checks(objective_function,xparam1,Dy
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 
-if DynareDataset.info.nvobs>Model.exo_nbr+EstimatedParameters.nvn
+if DynareDataset.vobs>Model.exo_nbr+EstimatedParameters.nvn
     error(['initial_estimation_checks:: Estimation can''t take place because there are less declared shocks than observed variables!'])
 end
- 
-if DynareDataset.info.nvobs>length(find(diag(Model.Sigma_e)))+EstimatedParameters.nvn
+
+if DynareDataset.vobs>length(find(diag(Model.Sigma_e)))+EstimatedParameters.nvn
     error(['initial_estimation_checks:: Estimation can''t take place because too many shocks have been calibrated with a zero variance!'])
 end
 
@@ -72,7 +73,7 @@ end
 % Evaluate the likelihood.
 ana_deriv = DynareOptions.analytic_derivation;
 DynareOptions.analytic_derivation=0;
-[fval,junk1,junk2,a,b,c,d] = feval(objective_function,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults);
+[fval,junk1,junk2,a,b,c,d] = feval(objective_function,xparam1,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults);
 DynareOptions.analytic_derivation=ana_deriv;
 
 if DynareOptions.dsge_var || strcmp(func2str(objective_function),'non_linear_dsge_likelihood')
diff --git a/matlab/metropolis_hastings_initialization.m b/matlab/metropolis_hastings_initialization.m
index 8c6ed5a9f6..b475bfcc5e 100644
--- a/matlab/metropolis_hastings_initialization.m
+++ b/matlab/metropolis_hastings_initialization.m
@@ -1,7 +1,7 @@
 function [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, nruns, NewFile, MAX_nruns, d ] = ...
-    metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_)
+    metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_)
 %function [ ix2, ilogpo2, ModelName, MhDirectoryName, fblck, fline, npar, nblck, nruns, NewFile, MAX_nruns, d ] = 
-%    metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds, dataset_,options_,M_,estim_params_,bayestopt_,oo_)
+%    metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds, dataset_,dataset_info,,options_,M_,estim_params_,bayestopt_,oo_)
 % Metropolis-Hastings initialization.
 % 
 % INPUTS 
@@ -110,7 +110,7 @@ if ~options_.load_mh_file && ~options_.mh_recover
                 candidate = rand_multivariate_normal( transpose(xparam1), d * options_.mh_init_scale, npar);
                 if all(candidate(:) > mh_bounds(:,1)) && all(candidate(:) < mh_bounds(:,2)) 
                     ix2(j,:) = candidate;
-                    ilogpo2(j) = - feval(TargetFun,ix2(j,:)',dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                    ilogpo2(j) = - feval(TargetFun,ix2(j,:)',dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
                     if ~isfinite(ilogpo2(j)) % if returned log-density is
                                              % Inf or Nan (penalized value)
                         validate = 0;
@@ -152,7 +152,7 @@ if ~options_.load_mh_file && ~options_.mh_recover
         candidate = transpose(xparam1(:));%
         if all(candidate(:) > mh_bounds(:,1)) && all(candidate(:) < mh_bounds(:,2)) 
             ix2 = candidate;
-            ilogpo2 = - feval(TargetFun,ix2',dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+            ilogpo2 = - feval(TargetFun,ix2',dataset_,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
             disp('Estimation::mcmc: Initialization at the posterior mode.')
             skipline()
             fprintf(fidlog,['    Blck ' int2str(1) 'params:\n']);
diff --git a/matlab/random_walk_metropolis_hastings.m b/matlab/random_walk_metropolis_hastings.m
index f524b44c13..c2a49e7a29 100644
--- a/matlab/random_walk_metropolis_hastings.m
+++ b/matlab/random_walk_metropolis_hastings.m
@@ -1,4 +1,4 @@
-function random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_)
+function random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_)
 %function record=random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_)
 % Random walk Metropolis-Hastings algorithm. 
 % 
@@ -60,7 +60,7 @@ objective_function_penalty_base = Inf;
 
 % Initialization of the random walk metropolis-hastings chains.
 [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, nruns, NewFile, MAX_nruns, d ] = ...
-    metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+    metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
 
 InitSizeArray = min([repmat(MAX_nruns,nblck,1) fline+nruns-1],[],2);
 
@@ -101,6 +101,7 @@ localVars =   struct('TargetFun', TargetFun, ...
                      'InitSizeArray',InitSizeArray, ...
                      'record', record, ...
                      'dataset_', dataset_, ...
+                     'dataset_info', dataset_info, ...
                      'options_', options_, ...
                      'M_',M_, ...
                      'bayestopt_', bayestopt_, ...
diff --git a/matlab/random_walk_metropolis_hastings_core.m b/matlab/random_walk_metropolis_hastings_core.m
index 481e92b77a..62e1728eb9 100644
--- a/matlab/random_walk_metropolis_hastings_core.m
+++ b/matlab/random_walk_metropolis_hastings_core.m
@@ -88,6 +88,7 @@ d=myinputs.d;
 InitSizeArray=myinputs.InitSizeArray;
 record=myinputs.record;
 dataset_ = myinputs.dataset_;
+dataset_info = myinputs.dataset_info;
 bayestopt_ = myinputs.bayestopt_;
 estim_params_ = myinputs.estim_params_;
 options_ = myinputs.options_;
@@ -164,7 +165,7 @@ for b = fblck:nblck,
         par = feval(ProposalFun, ix2(b,:), proposal_covariance_Cholesky_decomposition, n);
         if all( par(:) > mh_bounds(:,1) ) && all( par(:) < mh_bounds(:,2) )
             try
-                logpost = - feval(TargetFun, par(:),dataset_,options_,M_,estim_params_,bayestopt_,oo_);
+                logpost = - feval(TargetFun, par(:),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_);
             catch
                 logpost = -inf;
             end
diff --git a/matlab/utilities/dataset/makedataset.m b/matlab/utilities/dataset/makedataset.m
new file mode 100644
index 0000000000..52064d441b
--- /dev/null
+++ b/matlab/utilities/dataset/makedataset.m
@@ -0,0 +1,203 @@
+function [DynareDataset, DatasetInfo] = makedataset(DynareOptions)
+
+% Initialize a dataset as a dseries object.
+%
+%
+% INPUTS
+% ======
+%
+%     DynareOptions [struct] Structure of options built by Dynare's preprocessor.
+%
+%
+% OUTPUTS
+% =======
+%
+%     DynareDataset [dseries]  The dataset.
+%     DatasetInfo   [struct]   Various informations about the dataset (descriptive statistics and missing observations).
+%
+% EXAMPLE
+% =======
+%
+%     [dataset_, dataset_info] = makedataset(options_) ;
+%
+%
+% See also dynare_estimation_init
+
+if isempty(DynareOptions.datafile) && isempty(DynareOptions.dataset.file)
+    if gsa_flag
+        DynareDataset = dseries();
+        return
+    else
+        error('datafile option is missing')
+    end
+end
+
+if isempty(DynareOptions.datafile) && ~isempty(DynareOptions.dataset.file)
+    datafile = DynareOptions.dataset.file;
+    newdatainterface = 1;
+elseif ~isempty(DynareOptions.datafile) && isempty(DynareOptions.dataset.file)
+    datafile = DynareOptions.datafile;
+    newdatainterface = 0;
+elseif isempty(DynareOptions.datafile) && ~isempty(DynareOptions.dataset.file)
+    error('You cannot use simultaneously the data command and the datafile option (in the estimation command)!')
+else
+    error('You have to specify the datafile!')
+end
+
+% Check extension.
+allowed_extensions = {'m','mat','csv','xls','xlsx'};
+datafile_extension = get_file_extension(datafile);
+if isempty(datafile_extension)
+    available_extensions = {}; j = 1;
+    for i=1:length(allowed_extensions)
+        if exist([datafile '.' allowed_extensions{i}])
+            available_extensions(j) = {allowed_extensions{i}};
+            j = j+1;
+        end
+    end
+    if isempty(available_extensions)
+        error(['I can''t find a datafile (with allowed extension)!'])
+    end
+    if length(available_extensions)>1
+        error(sprintf(['You did not specify an extension for the datafile, but more than one candidate ' ...
+                       'are available in the designed folder!\nPlease, add an extension to the datafile ' ...
+                       '(m, mat, csv, xls or xlsx are legal extensions).']));
+    end
+    datafile = [datafile '.' available_extensions{1}];
+end
+
+% Load the data in a dseries object.
+DynareDataset = dseries(datafile);
+
+% Select a subset of the variables.
+DynareDataset = DynareDataset{DynareOptions.varobs{:}};
+
+% Apply log function if needed.
+if DynareOptions.loglinear && ~DynareOptions.logdata
+    DynareDataset = DynareDataset.log();
+end
+
+% Test if an initial period (different from its default value) is explicitely defined in the datafile.
+if isequal(DynareDataset.init, dates(1,1))
+    dataset_default_initial_period = 1;
+else
+    dataset_default_initial_period = 0;
+end
+
+%  Test if an initial period (different from its default value) is explicitely defined in the mod file with the set_time command.
+if isequal(DynareOptions.initial_period, dates(1,1))
+    set_time_default_initial_period = 1;
+else
+    set_time_default_initial_period = 0;
+end
+
+if ~set_time_default_initial_period && dataset_default_initial_period
+    % Overwrite the initial period in dataset (it was set to default).
+    % Note that the updates of freq and time members are auto-magically
+    % done by dseries::subsasgn overloaded method.
+    DynareDataset.init = DynareOptions.initial_period;
+end
+
+if set_time_default_initial_period && ~dataset_default_initial_period
+    % Overwrite the global initial period defined by set_time (it was set to default).
+    DynareOptions.initial_period = DynareDataset.init;
+end
+
+if ~set_time_default_initial_period && ~dataset_default_initial_period
+    % Check if dataset.init and options_.initial_period are identical.
+    if  ~isequal(DynareOptions.initial_period, DynareDataset.init)
+        error('The date as defined by the set_time command is not consistent with the initial period in the database!')
+    end
+end
+
+% Set firstobs, lastobs and nobs
+if newdatainterface
+    if isempty(DynareOptions.dataset.firstobs)
+        % first_obs option was not used in the data command.
+        firstobs = DynareDataset.init;
+    else
+        firstobs = DynareOptions.dataset.firstobs;
+    end
+    if isnan(DynareOptions.dataset.nobs)
+        % nobs option was not used in the data command.
+        if isempty(DynareOptions.dataset.lastobs)
+            % last_obs option was not used in the data command.
+            nobs = DynareDataset.nobs;
+            lastobs = DynareDataset.dates(end);
+        else
+            lastobs = DynareOptions.dataset.lastobs;
+            nobs = lastobs-firstobs+1;
+        end
+    else
+        nobs = DynareOptions.dataset.nobs;
+        if isempty(DynareOptions.dataset.lastobs)
+            % last_obs option was not used in the data command.
+            lastobs = firstobs+(nobs-1);
+        else
+            % last_obs and nobs were used in the data command. Check that they are consistent (with firstobs).
+            if ~isequal(lastobs,firstobs+(nobs-1))
+                error(sprintf('Options last_obs (%s), first_obs (%s) and nobs (%s) are not consistent!',char(lastobs),char(firstobs),num2str(nobs)));
+            end
+        end
+    end
+else
+    if isnan(DynareOptions.first_obs)
+        firstobs = DynareDataset.init;
+    else
+        firstobs = DynareDataset.dates(DynareOptions.first_obs);
+    end
+    if isnan(DynareOptions.nobs)
+        lastobs = DynareDataset.dates(end);
+        nobs = lastobs-firstobs+1;
+    else
+        nobs = DynareOptions.nobs;
+        lastobs = firstobs+(nobs-1);
+    end
+end
+
+% Check that firstobs belongs to DynareDataset.dates
+if firstobs<DynareDataset.init
+    error(sprintf('first_obs (%s) cannot be less than the first date in the dataset (%s)!',char(firstobs),char(DynareDataset.init)))
+end
+
+% Check that lastobs belongs to DynareDataset.dates...
+if newdatainterface
+    if lastobs>DynareDataset.dates(end)
+        error(sprintf('last_obs (%s) cannot be greater than the last date in the dataset (%s)!',char(lastobs),char(DynareDataset.dates(end))))
+    end
+else
+    % ...  or check that nobs is smaller than the number of observations in DynareDataset.
+    if nobs>DynareDataset.nobs
+        error(sprintf('nobs (%s) cannot be greater than the last date in the dataset (%s)!', num2str(nobs), num2str(nobs)))
+    end
+end
+
+% Select a subsample.
+DynareDataset = DynareDataset(firstobs:lastobs);
+
+% Initialize DatasetInfo structure.
+DatasetInfo = struct('missing', struct('state', NaN, 'aindex', [], 'vindex', [], 'number_of_observations', NaN, 'no_more_missing_observations', NaN), ...
+                     'descriptive', struct('mean', [], 'covariance', [], 'correlation', [], 'autocovariance', []));
+
+% Fill DatasetInfo.missing if some observations are missing
+DatasetInfo.missing.state = isanynan(DynareDataset.data);
+if DatasetInfo.missing.state
+    [DatasetInfo.missing.aindex, DatasetInfo.missing.number_of_observations, DatasetInfo.missing.no_more_missing_observations, DatasetInfo.missing.vindex] = ...
+        describe_missing_data(DynareDataset.data);
+else
+    DatasetInfo.missing.aindex = num2cell(transpose(repmat(1:DynareDataset.vobs,DynareDataset.nobs,1)),1);
+    DatasetInfo.missing.no_more_missing_observations = 1;
+end
+
+% Compute the empirical mean of the observed variables.
+DatasetInfo.descriptive.mean = nanmean(DynareDataset.data);
+
+% Compute the empirical covariance matrix of the observed variables.
+DatasetInfo.descriptive.covariance = nancovariance(DynareDataset.data);
+
+% Compute the empirical correlation matrix of the observed variables.
+normalization_matrix = diag(1./sqrt(diag(DatasetInfo.descriptive.covariance)));
+DatasetInfo.descriptive.correlation = normalization_matrix*DatasetInfo.descriptive.covariance*normalization_matrix;
+
+% Compute autocorrelation function.
+DatasetInfo.descriptive.autocovariance = nanautocovariance(DynareDataset.data, DynareOptions.ar);
\ No newline at end of file
diff --git a/tests/fs2000/fs2000_dseries.mod b/tests/fs2000/fs2000_dseries.mod
index c0d851721f..1210e7425c 100644
--- a/tests/fs2000/fs2000_dseries.mod
+++ b/tests/fs2000/fs2000_dseries.mod
@@ -72,6 +72,6 @@ varobs gp_obs gy_obs;
 
 options_.solve_tolf = 1e-12;
 
-data(file=fsdat_simul,first_obs=1950Q3, nobs=192);
+data(file=fsdat_simul_dseries,first_obs=1950Q3, nobs=192);
 
 estimation(order=1,loglinear,mh_replic=2000,mh_nblocks=2,mh_jscale=0.8);
-- 
GitLab