diff --git a/matlab/+occbin/DSGE_smoother.m b/matlab/+occbin/DSGE_smoother.m
index 265f631cb94878447a8309a742e76b5bdf9c88ca..2a5d919d53a64070ed381babd76c51f5ec127b3f 100644
--- a/matlab/+occbin/DSGE_smoother.m
+++ b/matlab/+occbin/DSGE_smoother.m
@@ -185,7 +185,9 @@ while is_changed && maxiter>iter && ~is_periodic
     [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,occbin_options,TT,RR,CC);%     T1=TT;
     sto_etahat(iter)={etahat};
     regime_history0(iter,:) = regime_history;
-    save('info1','regime_history0');
+    if occbin_smoother_debug
+        save('info1','regime_history0');
+    end
     
     sto_CC = CC;
     sto_RR = RR;
diff --git a/matlab/DsgeSmoother.m b/matlab/DsgeSmoother.m
index 8922a2b5a37b01aad94bd924a3ae5893ab9fbdfc..18d0f286c08fba86940de23fdf9c5aa18e8be786 100644
--- a/matlab/DsgeSmoother.m
+++ b/matlab/DsgeSmoother.m
@@ -319,7 +319,7 @@ if kalman_algo == 2 || kalman_algo == 4
     a_initial     = zeros(np,1);
     a_initial=set_Kalman_smoother_starting_values(a_initial,M_,oo_,options_);
     a_initial=ST*a_initial; %set state prediction for first Kalman step;
-    [alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty, aahat, eehat, d, regimes_,TT,RR,CC] = missing_DiffuseKalmanSmootherH3_Z(a_initial,ST, ...
+    [alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty, aahat, eehat, d, regimes_,TT,RR,CC,TTx,RRx,CCx] = missing_DiffuseKalmanSmootherH3_Z(a_initial,ST, ...
         Z,R1,Q,diag(H), ...
         Pinf,Pstar,data1,vobs,np,smpl,data_index, ...
         options_.nk,kalman_tol,diffuse_kalman_tol, ...
@@ -386,9 +386,11 @@ else
         else
             opts_simul = options_.occbin.simul;
         end
+        % reconstruct smoothed variables
         aaa=zeros(M_.endo_nbr,gend);
         aaa(oo_.dr.restrict_var_list,:)=alphahat;
-        for k=2:gend
+        iTx = zeros(size(TTx));
+        for k=1:gend
             if isoccbin
                 A = TT(:,:,k);
                 B = RR(:,:,k);
@@ -396,20 +398,53 @@ else
             else
                 C=0;
             end
-            aaa(:,k) = C+A*aaa(:,k-1)+B*etahat(:,k);
+            iT = pinv(TTx(:,:,k));
+            % store pinv
+            iTx(:,:,k) = iT;
+            Tstar = A(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),oo_.dr.restrict_var_list);
+            Rstar = B(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),:);
+            Cstar = C(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list));
+            AS = Tstar*iT;
+            BS = Rstar-AS*RRx(:,:,k);
+            CS = Cstar-AS*CCx(:,k);
+            static_var_list = ~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list);
+            ilagged = any(abs(AS*TTx(:,:,k)-Tstar)'>1.e-12);
+            static_var_list0 = static_var_list;
+            static_var_list0(static_var_list) = ilagged;
+            static_var_list(static_var_list) = ~ilagged;
+            aaa(static_var_list,k) = AS(~ilagged,:)*alphahat(:,k)+BS(~ilagged,:)*etahat(:,k)+CS(~ilagged);
+            if any(ilagged) && k>1
+                aaa(static_var_list0,k) = Tstar(ilagged,:)*alphahat(:,k-1)+Rstar(ilagged,:)*etahat(:,k)+Cstar(ilagged);
+            end
+            
         end
         alphahat=aaa;
-        aaa=zeros(M_.endo_nbr,gend);
+
+        % reconstruct updated variables
         bbb=zeros(M_.endo_nbr,gend);
-        bbb(oo_.dr.restrict_var_list,:)=ahat;
-        aaa(oo_.dr.restrict_var_list,:)=aahat;
-        for k=d+2:gend
+        bbb(oo_.dr.restrict_var_list,:)=ahat; % this is t|t
+        for k=1:gend
             if isoccbin
                 A = TT(:,:,k);
                 B = RR(:,:,k);
                 C = CC(:,k);
-                bbb(:,k) = C+A*aaa(:,k-1)+B*eehat(:,k);
-            else
+                iT = iTx(:,:,k);
+                Tstar = A(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),oo_.dr.restrict_var_list);
+                Rstar = B(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),:);
+                Cstar = C(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list));
+                AS = Tstar*iT;
+                BS = Rstar-AS*RRx(:,:,k);
+                CS = Cstar-AS*CCx(:,k);
+                static_var_list = ~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list);
+                ilagged = any(abs(AS*TTx(:,:,k)-Tstar)'>1.e-12);
+                static_var_list0 = static_var_list;
+                static_var_list0(static_var_list) = ilagged;
+                static_var_list(static_var_list) = ~ilagged;
+                bbb(static_var_list,k) = AS(~ilagged,:)*ahat(:,k)+BS(~ilagged,:)*eehat(:,k)+CS(~ilagged);
+                if any(ilagged) && k>d+1
+                    bbb(static_var_list0,k) = Tstar(ilagged,:)*aahat(:,k-1)+Rstar(ilagged,:)*eehat(:,k)+Cstar(ilagged);
+                end
+            elseif k>d+1
                 opts_simul.curb_retrench = options_.occbin.smoother.curb_retrench;
                 opts_simul.waitbar = options_.occbin.smoother.waitbar;
                 opts_simul.maxit = options_.occbin.smoother.maxit;
@@ -430,11 +465,9 @@ else
                 % period ahead (so if regimestart was [1 5] it should be [1 4]
                 % in out
                 %         end
-                bbb(oo_.dr.inv_order_var,k) = out.piecewise(1,:);
+                bbb(oo_.dr.inv_order_var,k) = out.piecewise(1,:) - out.ys';
             end
         end
-        % do not overwrite accurate computations using reduced st. space
-        bbb(oo_.dr.restrict_var_list,:)=ahat;
         ahat0=ahat;
         ahat=bbb;
         if ~isempty(P)
@@ -475,7 +508,7 @@ else
             % in out
             %         end
             for jnk=1:options_.nk
-                aaa(jnk,oo_.dr.inv_order_var,k+jnk-1) = out.piecewise(jnk,:);
+                aaa(jnk,oo_.dr.inv_order_var,k+jnk-1) = out.piecewise(jnk,:) - out.ys';
             end
         end
         aK=aaa;
diff --git a/matlab/compute_Pinf_Pstar.m b/matlab/compute_Pinf_Pstar.m
index 9158f27b5bf5f4c7bc2d886e7e9814e6356b77f6..9a05188a5e6b385377bae8812d787d676eb570df 100644
--- a/matlab/compute_Pinf_Pstar.m
+++ b/matlab/compute_Pinf_Pstar.m
@@ -48,6 +48,16 @@ function [Pstar,Pinf] = compute_Pinf_Pstar(mf,T,R,Q,qz_criterium, restrict_colum
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
 np = size(T,1);
+if iszero(Q)
+    % this may happen if users set Q=0 and use heteroskedastic shocks to set
+    % variances period by period
+    % this in practice triggers a form of conditional filter where states
+    % are initialized at st. state with zero variances
+    Pstar=T*0;
+    Pinf=T*0;
+    return
+end
+
 if nargin == 6
     indx = restrict_columns;
     indx0=find(~ismember([1:np],indx));
diff --git a/matlab/expand_group.m b/matlab/expand_group.m
index 9c2e087944dabea2eef6e8ba58a3480d6973f90c..8e54f995a35a8a5c9851b959e1b3ee68684402ca 100644
--- a/matlab/expand_group.m
+++ b/matlab/expand_group.m
@@ -46,6 +46,9 @@ options.nobs=mydata.nobs;
 label = mydata.shock_group.label;
 label = strrep(label,' ','_');
 label = strrep(label,'-','_');
+label = strrep(label,'(','');
+label = strrep(label,')','');
+label = strrep(label,'.','');
 shocks = mydata.shock_group.shocks;
 options.plot_shock_decomp.fig_name = [mydata.fig_name '. Expand'];
 options.plot_shock_decomp.use_shock_groups = label; %[use_shock_groups_old int2str(ic)];
diff --git a/matlab/marginal_density.m b/matlab/marginal_density.m
index 489fb8cf61e5b05770886326bfc38b67a3bc2ccb..8bca13e6681c7204709d7dcc4d12e4983356b9f8 100644
--- a/matlab/marginal_density.m
+++ b/matlab/marginal_density.m
@@ -69,7 +69,14 @@ parameter_names = bayestopt_.name;
 save([M_.dname filesep 'Output' filesep M_.fname '_mean.mat'],'xparam1','hh','parameter_names','SIGMA');
 
 fprintf('Estimation::marginal density: I''m computing the posterior log marginal density (modified harmonic mean)... ');
-logdetSIGMA = log(det(SIGMA));
+try 
+    % use this robust option to avoid inf/nan
+    logdetSIGMA = 2*sum(log(diag(chol(SIGMA)))); 
+catch
+    % in case SIGMA is not positive definite
+    logdetSIGMA = nan;
+    fprintf('Estimation::marginal density: the covariance of MCMC draws is not positive definite. You may have too few MCMC draws.');
+end
 invSIGMA = hh;
 marginal = zeros(9,2);
 linee = 0;
diff --git a/matlab/missing_DiffuseKalmanSmootherH3_Z.m b/matlab/missing_DiffuseKalmanSmootherH3_Z.m
index aa06d67dc76187cbad7826bb38cb45e026506a0e..6ba116349471c14480f39fe4375d9a36e07bfd53 100644
--- a/matlab/missing_DiffuseKalmanSmootherH3_Z.m
+++ b/matlab/missing_DiffuseKalmanSmootherH3_Z.m
@@ -433,7 +433,7 @@ while notsteady && t<smpl
             Pf          = P(:,:,t+1);
         end
         aK(1,:,t+1) = a1(:,t+1);
-        if ~isempty(nk) && nk>1 && isoccbin 
+        if ~isempty(nk) && nk>1 && isoccbin && (t>=first_period_occbin_update || isinf(first_period_occbin_update))
             opts_simul = occbin_options.opts_regime;
             opts_simul.SHOCKS = zeros(nk,M_.exo_nbr);
             if smoother_redux
@@ -455,11 +455,11 @@ while notsteady && t<smpl
                 end
                 PK(jnk,:,:,t+jnk) = Pf;
             end
-            if isoccbin 
+            if isoccbin && (t>=first_period_occbin_update || isinf(first_period_occbin_update))
                 if smoother_redux
-                    aK(jnk,:,t+jnk) = out.piecewise(jnk,oo_.dr.order_var(oo_.dr.restrict_var_list));
+                    aK(jnk,:,t+jnk) = out.piecewise(jnk,oo_.dr.order_var(oo_.dr.restrict_var_list)) - out.ys(oo_.dr.order_var(oo_.dr.restrict_var_list))';
                 else
-                    aK(jnk,oo_.dr.inv_order_var,t+jnk) = out.piecewise(jnk,:);
+                    aK(jnk,oo_.dr.inv_order_var,t+jnk) = out.piecewise(jnk,:) - out.ys';
                 end
             elseif jnk>1
                 aK(jnk,:,t+jnk) = T*dynare_squeeze(aK(jnk-1,:,t+jnk-1));
@@ -486,6 +486,9 @@ varargout{1} = regimes_;
 varargout{2} = TTT;
 varargout{3} = RRR;
 varargout{4} = CCC;
+varargout{5} = TT;
+varargout{6} = RR;
+varargout{7} = CC;
 % $$$ P_s=tril(P(:,:,t))+tril(P(:,:,t),-1)';
 % $$$ P1_s=tril(P1(:,:,t))+tril(P1(:,:,t),-1)';
 % $$$ Fi_s = Fi(:,t);