From 97134cc3624aa7f29b7092adad1e0cf26c213b0c Mon Sep 17 00:00:00 2001
From: Willi Mutschler <willi@mutschler.eu>
Date: Thu, 18 Jun 2020 11:28:22 +0200
Subject: [PATCH] :bug: Fix issue with endogenous params in steady state

Identification should switch to analytic_derivation_mode=-2 if steady state block/file changes parameter values. Dynare/dynare!1732 already adresses this when there is a prior specified. This fix also addresses this when there are no priors.

kim2.mod is now not only an integration test but also a unit test for this.
---
 matlab/dynare_estimation_init.m   | 10 +++++++---
 matlab/dynare_identification.m    |  1 +
 tests/identification/kim/kim2.mod |  6 ++++++
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/matlab/dynare_estimation_init.m b/matlab/dynare_estimation_init.m
index 3495a7d04a..c893be9c63 100644
--- a/matlab/dynare_estimation_init.m
+++ b/matlab/dynare_estimation_init.m
@@ -501,11 +501,15 @@ if options_.analytic_derivation
         error('analytic derivation is incompatible with diffuse filter')
     end
     options_.analytic_derivation = 1;
-    if estim_params_.np
+    if estim_params_.np || isfield(options_,'identification_check_endogenous_params_with_no_prior')
         % check if steady state changes param values
         M=M_;
-        M.params(estim_params_.param_vals(:,1)) = xparam1(estim_params_.nvx+estim_params_.ncx+estim_params_.nvn+estim_params_.ncn+1:end); %set parameters
-        M.params(estim_params_.param_vals(:,1)) = M.params(estim_params_.param_vals(:,1))*1.01; %vary parameters
+        if isfield(options_,'identification_check_endogenous_params_with_no_prior')
+            M.params = M.params*1.01; %vary parameters
+        else
+            M.params(estim_params_.param_vals(:,1)) = xparam1(estim_params_.nvx+estim_params_.ncx+estim_params_.nvn+estim_params_.ncn+1:end); %set parameters
+            M.params(estim_params_.param_vals(:,1)) = M.params(estim_params_.param_vals(:,1))*1.01; %vary parameters
+        end
         if options_.diffuse_filter || options_.steadystate.nocheck
             steadystate_check_flag = 0;
         else
diff --git a/matlab/dynare_identification.m b/matlab/dynare_identification.m
index 70788e0577..063f4e451c 100644
--- a/matlab/dynare_identification.m
+++ b/matlab/dynare_identification.m
@@ -270,6 +270,7 @@ if isempty(estim_params_)
     %reset some options
     options_ident.prior_mc = 1;
     options_ident.prior_range = 0;
+    options_.identification_check_endogenous_params_with_no_prior = true; %needed to trigger endogenous steady state parameter check in dynare_estimation_init
 else
     prior_exist = 1;
     parameters = options_ident.parameter_set;
diff --git a/tests/identification/kim/kim2.mod b/tests/identification/kim/kim2.mod
index 6322b8da44..9ab32dfc34 100644
--- a/tests/identification/kim/kim2.mod
+++ b/tests/identification/kim/kim2.mod
@@ -86,6 +86,12 @@ identification(advanced=1,max_dim_cova_group=3);
 //identification(ar=1,advanced=1,max_dim_cova_group=3,prior_mc=250);
 //identification(prior_mc=100);
 
+% Unit test for analytic_derivation_mode
+load('kim2/identification/kim2_prior_mean_identif.mat','store_options_ident')
+if store_options_ident.analytic_derivation~=1 && store_options_ident.analytic_derivation_mode~=-2
+    error('the steady state file changed parameters and we should switch to numerical derivatives for the steady state, i.e. analytic_derivation_mode=-2')
+end
 
+% Integration test if identification works without priors
 estim_params_=[]; 
 identification(advanced=1,max_dim_cova_group=3);
-- 
GitLab