From cd2ed823b66f2bc78cb83eb4ef8fc074e369b01e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ry=C3=BBk=29?=
 <stepan@adjemian.eu>
Date: Wed, 21 Jul 2021 17:58:29 +0200
Subject: [PATCH] Fix constant in VAR and PAC expectations...

When the VAR auxiliary model has a constant.
---
 matlab/+pac/+update/parameters.m              | 23 +++++++++++++++++--
 matlab/+var_expectation/update_parameters.m   | 13 +++++++++--
 matlab/get_companion_matrix.m                 |  1 +
 matlab/print_expectations.m                   | 13 ++++++++++-
 matlab/write_expectations.m                   | 13 ++++++++++-
 tests/var-expectations/1/example1.mod         |  6 ++---
 .../2-with-time-shift/example1.mod            |  2 ++
 tests/var-expectations/2/example1.mod         |  4 ++--
 .../3-with-time-shift/example1.mod            |  2 +-
 tests/var-expectations/3/example1.mod         |  2 +-
 .../4-with-time-shift/example1.mod            |  2 +-
 tests/var-expectations/4/example1.mod         |  4 ++--
 .../5-with-time-shift/example1.mod            |  2 +-
 tests/var-expectations/5/example1.mod         |  4 ++--
 14 files changed, 72 insertions(+), 19 deletions(-)

diff --git a/matlab/+pac/+update/parameters.m b/matlab/+pac/+update/parameters.m
index ff24e8b9a0..8404d42e68 100644
--- a/matlab/+pac/+update/parameters.m
+++ b/matlab/+pac/+update/parameters.m
@@ -13,7 +13,7 @@ function DynareModel = parameters(pacname, DynareModel, DynareOutput, verbose)
 % SPECIAL REQUIREMENTS
 %    none
 
-% Copyright (C) 2018-2019 Dynare Team
+% Copyright © 2018-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -135,6 +135,16 @@ for e=1:number_of_pac_eq
     end
     % Update the parameters related to the stationary components.
     if ~isempty(h0)
+        if isequal(pacmodel.auxiliary_model_type, 'var')
+            if DynareModel.var.(pacmodel.auxiliary_model_name).isconstant
+                DynareModel.params(equations.(eqtag).h0_param_indices) = h0;
+            else
+                DynareModel.params(equations.(eqtag).h0_param_indices(1)) = .0;
+                DynareModel.params(equations.(eqtag).h0_param_indices(2:end)) = h0;
+            end
+        else
+            DynareModel.params(equations.(eqtag).h0_param_indices) = h0;
+        end
         DynareModel.params(pacmodel.equations.(eqtag).h0_param_indices) = h0;
     else
         if ~isempty(equations.(eqtag).h0_param_indices)
@@ -143,7 +153,16 @@ for e=1:number_of_pac_eq
     end
     % Update the parameters related to the nonstationary components.
     if ~isempty(h1)
-        DynareModel.params(equations.(eqtag).h1_param_indices) = h1;
+        if isequal(pacmodel.auxiliary_model_type, 'var')
+            if DynareModel.var.(pacmodel.auxiliary_model_name).isconstant
+                DynareModel.params(equations.(eqtag).h1_param_indices) = h1;
+            else
+                DynareModel.params(equations.(eqtag).h1_param_indices(1)) = .0;
+                DynareModel.params(equations.(eqtag).h1_param_indices(2:end)) = h1;
+            end
+        else
+            DynareModel.params(equations.(eqtag).h1_param_indices) = h1;
+        end
     else
         if ~isempty(equations.(eqtag).h1_param_indices)
             DynareModel.params(equations.(eqtag).h1_param_indices) = .0;
diff --git a/matlab/+var_expectation/update_parameters.m b/matlab/+var_expectation/update_parameters.m
index c57d5eed38..7b5b08fef9 100644
--- a/matlab/+var_expectation/update_parameters.m
+++ b/matlab/+var_expectation/update_parameters.m
@@ -13,7 +13,7 @@ function DynareModel = update_parameters(varexpectationmodelname, DynareModel, D
 % SPECIAL REQUIREMENTS
 %    none
 
-% Copyright (C) 2018-2021 Dynare Team
+% Copyright © 2018-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -205,4 +205,13 @@ else
 end
 
 % Update reduced form parameters in M_.params.
-DynareModel.params(varexpectationmodel.param_indices) = parameters;
+if isequal(varexpectationmodel.auxiliary_model_type, 'var')
+    if DynareModel.var.(varexpectationmodel.auxiliary_model_name).isconstant
+        DynareModel.params(varexpectationmodel.param_indices) = parameters;
+    else
+        DynareModel.params(varexpectationmodel.param_indices(1)) = .0;
+        DynareModel.params(varexpectationmodel.param_indices(2:end)) = parameters;
+    end
+else
+    DynareModel.params(varexpectationmodel.param_indices) = parameters;
+end
diff --git a/matlab/get_companion_matrix.m b/matlab/get_companion_matrix.m
index d2ea827a63..b0757b5620 100644
--- a/matlab/get_companion_matrix.m
+++ b/matlab/get_companion_matrix.m
@@ -44,6 +44,7 @@ end
 if strcmp(auxiliary_model_type, 'var')
     [AR, ~, Constant] = feval(sprintf('%s.varmatrices', M_.fname), auxiliary_model_name, M_.params, M_.var.(auxiliary_model_name).structural);
     isconstant = any(abs(Constant)>0);
+    M_.var.(auxiliary_model_name).isconstant = isconstant; % FIXME Could be done by preprocessor instead…
 elseif strcmp(auxiliary_model_type, 'trend_component')
     [AR, A0, A0star] = feval(sprintf('%s.trend_component_ar_a0', M_.fname), auxiliary_model_name, M_.params);
 else
diff --git a/matlab/print_expectations.m b/matlab/print_expectations.m
index a4697dddd2..da23994e5e 100644
--- a/matlab/print_expectations.m
+++ b/matlab/print_expectations.m
@@ -22,7 +22,7 @@ function print_expectations(eqname, expectationmodelname, expectationmodelkind,
 %
 % The variable expectationmodelkind can take two values 'var' or 'pac'.
 
-% Copyright (C) 2018-2019 Dynare Team
+% Copyright © 2018-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -251,6 +251,17 @@ if isequal(expectationmodel.auxiliary_model_type, 'trend_component')
     maxlag = maxlag+1;
 end
 
+if isequal(expectationmodelkind, 'var') && isequal(expectationmodel.auxiliary_model_type, 'var')
+    id = id+1;
+    expression = sprintf('%1.16f', M_.params(expectationmodel.param_indices(id)));
+end
+
+if isequal(expectationmodelkind, 'pac') && isequal(expectationmodel.auxiliary_model_type, 'var')
+    id = id+1;
+    expression = sprintf('%1.16f', M_.params(expectationmodel.equations.(eqtag).h0_param_indices(id))+ ...
+                         M_.params(expectationmodel.equations.(eqtag).h1_param_indices(id)));
+end
+
 for i=1:maxlag
     for j=1:length(auxmodel.list_of_variables_in_companion_var)
         id = id+1;
diff --git a/matlab/write_expectations.m b/matlab/write_expectations.m
index 831bea27db..3850989318 100644
--- a/matlab/write_expectations.m
+++ b/matlab/write_expectations.m
@@ -12,7 +12,7 @@ function [expression, growthneutralitycorrection] = write_expectations(eqname, e
 % - expression                  [string]    Unrolled expectation expression.
 % - growthneutralitycorrection  [string]
 
-% Copyright (C) 2019 Dynare Team
+% Copyright © 2019-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -78,6 +78,17 @@ if isequal(expectationmodelkind, 'var')
     timeindices = (0:(maxlag-1))+abs(expectationmodel.time_shift);
 end
 
+if isequal(expectationmodelkind, 'var') && isequal(expectationmodel.auxiliary_model_type, 'var')
+    id = id+1;
+    expression = sprintf('%s', M_.param_names{expectationmodel.param_indices(id)});
+end
+
+if isequal(expectationmodelkind, 'pac') && isequal(expectationmodel.auxiliary_model_type, 'var')
+    id = id+1;
+    expression = sprintf('%s+%s', M_.param_names{expectationmodel.equations.(eqtag).h0_param_indices(id)}, ...
+                         M_.param_names{expectationmodel.equations.(eqtag).h1_param_indices(id)});
+end
+
 for i=1:maxlag
     for j=1:length(auxmodel.list_of_variables_in_companion_var)
         id = id+1;
diff --git a/tests/var-expectations/1/example1.mod b/tests/var-expectations/1/example1.mod
index 0a607e56ad..33d7c20df7 100644
--- a/tests/var-expectations/1/example1.mod
+++ b/tests/var-expectations/1/example1.mod
@@ -50,8 +50,8 @@ y = d*y(-2) + e*z(-1) + e_y;
 foo = .5*foo(-1) + var_expectation(varexp);
 end;
 
-
 // Initialize the VAR expectation model, will build the companion matrix of the VAR.
+
 var_expectation.initialize('varexp')
 
 // Update VAR_EXPECTATION reduced form parameters
@@ -66,6 +66,6 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
-end
\ No newline at end of file
+end
diff --git a/tests/var-expectations/2-with-time-shift/example1.mod b/tests/var-expectations/2-with-time-shift/example1.mod
index c2c91d02c1..730ffb94e7 100644
--- a/tests/var-expectations/2-with-time-shift/example1.mod
+++ b/tests/var-expectations/2-with-time-shift/example1.mod
@@ -74,6 +74,7 @@ if ~isfield(M_.var_expectation.varexp, 'time_shift') || ~isequal(M_.var_expectat
 end
 
 str = strrep(str, 'foo = .5*foo(-1)', '');
+str = strrep(str, '+ var_expectation_model_varexp_constant', '');
 str = strrep(str, '+ var_expectation_model_varexp_x_0*x(-2)', '');
 str = strrep(str, '+ var_expectation_model_varexp_y_0*y(-2)', '');
 str = strrep(str, '+ var_expectation_model_varexp_z_0*z(-2)', '');
@@ -81,6 +82,7 @@ str = strrep(str, '+ var_expectation_model_varexp_x_1*x(-3)', '');
 str = strrep(str, '+ var_expectation_model_varexp_y_1*y(-3)', '');
 str = strrep(str, '+ var_expectation_model_varexp_z_1*z(-3)', '');
 str = strrep(str, ';', '');
+
 if ~isempty(strtrim(str))
     error('Printed equation is wrong.')
 end
diff --git a/tests/var-expectations/2/example1.mod b/tests/var-expectations/2/example1.mod
index 59d59f9060..f4b0543870 100644
--- a/tests/var-expectations/2/example1.mod
+++ b/tests/var-expectations/2/example1.mod
@@ -75,6 +75,6 @@ fprintf('\n')
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
-end
\ No newline at end of file
+end
diff --git a/tests/var-expectations/3-with-time-shift/example1.mod b/tests/var-expectations/3-with-time-shift/example1.mod
index 952599ec1b..973a2ba85e 100644
--- a/tests/var-expectations/3-with-time-shift/example1.mod
+++ b/tests/var-expectations/3-with-time-shift/example1.mod
@@ -65,7 +65,7 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
 end
 
diff --git a/tests/var-expectations/3/example1.mod b/tests/var-expectations/3/example1.mod
index e85c31f23a..06e89bb368 100644
--- a/tests/var-expectations/3/example1.mod
+++ b/tests/var-expectations/3/example1.mod
@@ -64,7 +64,7 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
 end
 
diff --git a/tests/var-expectations/4-with-time-shift/example1.mod b/tests/var-expectations/4-with-time-shift/example1.mod
index b78c8a22f5..7cc7570d34 100644
--- a/tests/var-expectations/4-with-time-shift/example1.mod
+++ b/tests/var-expectations/4-with-time-shift/example1.mod
@@ -65,7 +65,7 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
 end
 
diff --git a/tests/var-expectations/4/example1.mod b/tests/var-expectations/4/example1.mod
index 2ec4fe30a6..109c762f9c 100644
--- a/tests/var-expectations/4/example1.mod
+++ b/tests/var-expectations/4/example1.mod
@@ -64,7 +64,7 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
 end
 
@@ -74,4 +74,4 @@ if max(abs(weights-WEIGHTS.weights))>1e-12
    error('Inconsistent results in var-expectations/3 and var-expectations/4.')
 end
 
-delete('../3/weights.mat')
\ No newline at end of file
+delete('../3/weights.mat')
diff --git a/tests/var-expectations/5-with-time-shift/example1.mod b/tests/var-expectations/5-with-time-shift/example1.mod
index c527e9da6e..56fa0cda39 100644
--- a/tests/var-expectations/5-with-time-shift/example1.mod
+++ b/tests/var-expectations/5-with-time-shift/example1.mod
@@ -64,6 +64,6 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
 end
diff --git a/tests/var-expectations/5/example1.mod b/tests/var-expectations/5/example1.mod
index 8f088186b2..03d442321a 100644
--- a/tests/var-expectations/5/example1.mod
+++ b/tests/var-expectations/5/example1.mod
@@ -63,6 +63,6 @@ var_expectation.update('varexp');
 
 weights = M_.params(M_.var_expectation.varexp.param_indices);
 
-if weights(2) || ~weights(3) || weights(5) || ~weights(1) || ~weights(4) || ~weights(6)
+if weights(3) || ~weights(4) || weights(6) || ~weights(2) || ~weights(5) || ~weights(7) || weights(1)
    error('Wrong reduced form parameter for VAR_EXPECTATION_MODEL')
-end
\ No newline at end of file
+end
-- 
GitLab