From 0f3678ec4a22d06cc3c8cb7164eda2b0e619ee2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemian=28Charybdis=29?=
 <stephane.adjemian@univ-lemans.fr>
Date: Thu, 6 Sep 2018 22:07:31 +0200
Subject: [PATCH] Fixed ordering of variables in error correction term of PAC
 equation

PAC equation has to be written as

diff(x) = a0*(xstar(-1)-x(-1)) + a1*diff(x(-1)) + ... + ap*diff(x(-p)) + PAC_EXPECTATION(pacmodelname) + ...;

In the error correction term, a0*(xstar(-1)-x(-1)), we must have the difference
between the target (the trend xstar(-1)) and the level of the endogenous
variable (x(-1)). To ensure stability around the trend, the parameter a0 needs
to be positive.

REMARKS

 [1] In the TREND_COMPONENT_MODEL the error correction terms are written in
 reverse order, ie as the difference betwwen the level of the endogenous
 variable and the trend variable.

 [2] In the estimation routine we do not constrain a0 to be positive, but is
 would surely help to satisfy this condition in the initial condition.
---
 matlab/+pac/+estimate/iterative_ols.m | 11 ++++++++++-
 matlab/+pac/+estimate/nls.m           |  7 +++++++
 matlab/+pac/+update/parameters.m      |  9 +++------
 preprocessor                          |  2 +-
 4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/matlab/+pac/+estimate/iterative_ols.m b/matlab/+pac/+estimate/iterative_ols.m
index 0269a91e52..9836f4aa7a 100644
--- a/matlab/+pac/+estimate/iterative_ols.m
+++ b/matlab/+pac/+estimate/iterative_ols.m
@@ -83,9 +83,18 @@ if ~isempty(M_.pac.(pacmodl).h1_param_indices)
     end
 end
 
+% Reorder ec.vars locally if necessary. Second variable must be the
+% endogenous variable, while the first must be the associated trend.
+if M_.pac.(pacmodl).ec.isendo(2)
+    ecvars = M_.pac.(pacmodl).ec.vars;
+else
+    ecvars = flip(M_.pac.(pacmodl).ec.vars);
+end
+
 % Build matrix for EC and AR terms.
 DataForOLS = dseries();
-DataForOLS{'ec-term'} = data{M_.endo_names{M_.pac.(pacmodl).ec.vars(2)}}.lag(1)-data{M_.endo_names{M_.pac.(pacmodl).ec.vars(1)}}.lag(1);
+% Error correction term is trend minus the level of the endogenous variable.
+DataForOLS{'ec-term'} = data{M_.endo_names{ecvars(1)}}.lag(1)-data{M_.endo_names{ecvars(2)}}.lag(1);
 listofvariables3 = {'ec-term'};
 xparm = { M_.param_names(M_.pac.(pacmodl).ec.params(1))};
 for i = 1:length(M_.pac.(pacmodl).ar.params)
diff --git a/matlab/+pac/+estimate/nls.m b/matlab/+pac/+estimate/nls.m
index bf5dc8bd22..e11c83c3ee 100644
--- a/matlab/+pac/+estimate/nls.m
+++ b/matlab/+pac/+estimate/nls.m
@@ -44,6 +44,13 @@ global M_ oo_
 [pacmodl, lhs, rhs, pnames, enames, xnames, pid, eid, xid, ~, ipnames_, params, data, islaggedvariables] = ...
     pac.estimate.init(M_, oo_, eqname, params, data, range);
 
+% Check that the error correction term is correct.
+if M_.pac.(pacmodl).ec.isendo(1)
+    error(['\nThe error correction term in PAC equation (%s) is not correct.\nThe ' ...
+           'error correction term should be the difference between a trend\n' ...
+           'and the level of the endogenous variable.'], pacmodl);
+end
+
 % List of objects to be replaced
 objNames = [pnames; enames; xnames];
 objIndex = [pid; eid; xid];
diff --git a/matlab/+pac/+update/parameters.m b/matlab/+pac/+update/parameters.m
index d0b4faf169..dfefb8c81f 100644
--- a/matlab/+pac/+update/parameters.m
+++ b/matlab/+pac/+update/parameters.m
@@ -65,7 +65,7 @@ end
 pacvalues = DynareModel.params([pacmodel.ec.params; pacmodel.ar.params(1:pacmodel.max_lag)']);
 
 % Get the indices for the stationary/nonstationary variables in the VAR system.
-id = find(strcmp(DynareModel.endo_names{pacmodel.ec.vars(2)}, varmodel.list_of_variables_in_companion_var));
+id = find(strcmp(DynareModel.endo_names{pacmodel.ec.vars(find(~pacmodel.ec.isendo))}, varmodel.list_of_variables_in_companion_var));
 
 if isempty(id)
     % Find the auxiliary variables if any
@@ -75,14 +75,11 @@ if isempty(id)
     else
         for i=1:length(ad)
             auxinfo = DynareModel.aux_vars(get_aux_variable_id(varmodel.list_of_variables_in_companion_var{ad(i)}));
-            if isequal(auxinfo.endo_index, pacmodel.ec.vars(2))
-                % /!\ First element of ec.vars is the level of the endogenous
-                % variable in the PAC equation, the second element
-                % is the target variable.
+            if isequal(auxinfo.endo_index, pacmodel.ec.vars(find(~pacmodel.ec.isendo)))
                 id = ad(i);
                 break
             end
-            if isequal(auxinfo.type, 8) && isequal(auxinfo.orig_index, pacmodel.ec.vars(2))
+            if isequal(auxinfo.type, 8) && isequal(auxinfo.orig_index, pacmodel.ec.vars(find(~pacmodel.ec.isendo)))
                 id = ad(i);
                 break
             end
diff --git a/preprocessor b/preprocessor
index 27c9a9a5e0..e19a14869e 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit 27c9a9a5e03e05396b3df1a69351e44b11e5993b
+Subproject commit e19a14869eae4f2ed1571446c543ee39726421d8
-- 
GitLab