From bfd93f4ac0ff1eeece0883faba993052b9d2ea57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemia=20=28Scylla=29?= <stepan@dynare.org>
Date: Thu, 25 Oct 2018 10:08:21 +0200
Subject: [PATCH] Fixed estimated_params_init behaviour...

... when an initial value is given to a parameter that is not
estimated.

The generated driver file was crashing with cryptic error message
because we were searching in the first (and second) column of a
potentially empty array with 0 columns. The fix is to initialize the
fields of estimated_params_ with empty arrays with 10 columns (ie
zeros(0, 10)). Also print a message in the matlab command window if
parameter declared in estimated_params_init is not estimated.
---
 src/ComputingTasks.cc | 51 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index 2f256a86..9c87b5eb 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -1391,11 +1391,11 @@ EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo
 void
 EstimatedParamsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
-  output << "estim_params_.var_exo = [];" << endl
-         << "estim_params_.var_endo = [];" << endl
-         << "estim_params_.corrx = [];" << endl
-         << "estim_params_.corrn = [];" << endl
-         << "estim_params_.param_vals = [];" << endl;
+  output << "estim_params_.var_exo = zeros(0, 10);" << endl
+         << "estim_params_.var_endo = zeros(0, 10);" << endl
+         << "estim_params_.corrx = zeros(0, 10);" << endl
+         << "estim_params_.corrn = zeros(0, 10);" << endl
+         << "estim_params_.param_vals = zeros(0, 10);" << endl;
 
   for (const auto & it : estim_params_list)
     {
@@ -1514,6 +1514,8 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam
   if (use_calibration)
     output << "options_.use_calibration_initialization = 1;" << endl;
 
+  bool skipline = false;
+
   for (const auto & it : estim_params_list)
     {
       int symb_id = symbol_table.getTypeSpecificID(it.name) + 1;
@@ -1524,23 +1526,38 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam
           if (symb_type == SymbolType::exogenous)
             {
               output << "tmp1 = find(estim_params_.var_exo(:,1)==" << symb_id << ");" << endl;
-              output << "estim_params_.var_exo(tmp1,2) = ";
+              output << "if isempty(tmp1)" << endl;
+              output << "    disp(sprintf('The standard deviation of %s is not estimated (the value provided in estimated_params_init is not used).', M_.exo_names{" << symb_id << "}))" << endl;
+              skipline = true;
+              output << "else" << endl;
+              output << "    estim_params_.var_exo(tmp1,2) = ";
               it.init_val->writeOutput(output);
               output << ";" << endl;
+              output << "end" << endl;
             }
           else if (symb_type == SymbolType::endogenous)
             {
               output << "tmp1 = find(estim_params_.var_endo(:,1)==" << symb_id << ");" << endl;
-              output << "estim_params_.var_endo(tmp1,2) = ";
+              output << "if isempty(tmp1)" << endl;
+              output << "    disp(sprintf('The standard deviation of the measurement error on %s is not estimated (the value provided in estimated_params_init is not used).', M_.endo_names{" << symb_id << "}))" << endl;
+              skipline = true;
+              output << "else" << endl;
+              output << "    estim_params_.var_endo(tmp1,2) = ";
               it.init_val->writeOutput(output);
               output << ";" << endl;
+              output << "end" << endl;
             }
           else if (symb_type == SymbolType::parameter)
             {
               output << "tmp1 = find(estim_params_.param_vals(:,1)==" << symb_id << ");" << endl;
-              output << "estim_params_.param_vals(tmp1,2) = ";
+              output << "if isempty(tmp1)" << endl;
+              output << "    disp(sprintf('Parameter %s is not estimated (the value provided in estimated_params_init is not used).', M_.param_names{" << symb_id << "}))" << endl;
+              skipline = true;
+              output << "else" << endl;
+              output << "    estim_params_.param_vals(tmp1,2) = ";
               it.init_val->writeOutput(output);
               output << ";" << endl;
+              output << "end" << endl;
             }
         }
       else
@@ -1549,20 +1566,34 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam
             {
               output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << " & estim_params_.corrx(:,2)==" << symbol_table.getTypeSpecificID(it.name2)+1 << ") | "
                      <<             "(estim_params_.corrx(:,2)==" << symb_id << " & estim_params_.corrx(:,1)==" << symbol_table.getTypeSpecificID(it.name2)+1 << "));" << endl;
-              output << "estim_params_.corrx(tmp1,3) = ";
+              output << "if isempty(tmp1)" << endl;
+              output << "    disp(sprintf('The correlation between %s and %s is not estimated (the value provided in estimated_params_init is not used).', M_.exo_names{"
+                     << symb_id << "}, M_.exo_names{" << symbol_table.getTypeSpecificID(it.name2)+1 << "}))" << endl;
+              skipline = true;
+              output << "else" << endl;
+              output << "    estim_params_.corrx(tmp1,3) = ";
               it.init_val->writeOutput(output);
               output << ";" << endl;
+              output << "end" << endl;
             }
           else if (symb_type == SymbolType::endogenous)
             {
               output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << " & estim_params_.corrn(:,2)==" << symbol_table.getTypeSpecificID(it.name2)+1 << ") | "
                      <<             "(estim_params_.corrn(:,2)==" << symb_id << " & estim_params_.corrn(:,1)==" << symbol_table.getTypeSpecificID(it.name2)+1 << "));" << endl;
-              output << "estim_params_.corrn(tmp1,3) = ";
+              output << "if isempty(tmp1)" << endl;
+              output << "    disp(sprintf('The correlation between measurement errors on %s and %s is not estimated (the value provided in estimated_params_init is not used).', M_.endo_names{"
+                     << symb_id << "}, M_.endo_names{" << symbol_table.getTypeSpecificID(it.name2)+1 << "}))" << endl;
+              skipline = true;
+              output << "else" << endl;
+              output << "    estim_params_.corrn(tmp1,3) = ";
               it.init_val->writeOutput(output);
               output << ";" << endl;
+              output << "end" << endl;
             }
         }
     }
+  if (skipline == true)
+    output << "skipline()" << endl;
 }
 
 void
-- 
GitLab