diff --git a/matlab/utilities/estimation/check_varobs_are_endo_and_declared_once.m b/matlab/utilities/estimation/check_varobs_are_endo_and_declared_once.m index 1cb92635d..874f75b90 100644 --- a/matlab/utilities/estimation/check_varobs_are_endo_and_declared_once.m +++ b/matlab/utilities/estimation/check_varobs_are_endo_and_declared_once.m @@ -1,22 +1,15 @@ -function check_varobs_are_endo_and_declared_once(varobs,endo_names) -% function check_varobs_are_endo_and_declared_once(varobs,endo_names) -% ------------------------------------------------------------------------- -% Check that each declared observed variable: -% - is also an endogenous variable -% - is declared only once -% ------------------------------------------------------------------------- -% INPUTS -% o varobs: [cell] list of observed variables -% o endo_names: [cell] list of endogenous variables -% ------------------------------------------------------------------------- -% OUTPUTS -% none, display an error message something is wrong with VAROBS -% ------------------------------------------------------------------------- -% This function is called by -% o dynare_estimation_init.m -% ------------------------------------------------------------------------- +function check_varobs_are_endo_and_declared_once(varobs, endo_names) -% Copyright © 2023 Dynare Team +% Check that each declared observed variable is an endogenous variable and is declared only once +% +% INPUTS +% - varobs [cell] list of observed variables +% - endo_names [cell] list of endogenous variables +% +% OUTPUTS +% None, display an error message something is wrong with VAROBS + +% Copyright © 2023-2024 Dynare Team % % This file is part of Dynare. % @@ -33,18 +26,88 @@ function check_varobs_are_endo_and_declared_once(varobs,endo_names) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -number_of_observed_variables = length(varobs); -for i = 1:number_of_observed_variables - if ~any(strcmp(varobs{i},endo_names)) - error(['VAROBS: unknown variable (' varobs{i} ')!']) - end +cut = @(x) x(1:end-2); % Remove the last two elements of an array. + +% Throw an error if an observed variable is not declared as an endogenous variable. +unknown_varobs = setdiff(varobs, endo_names); +if ~isempty(unknown_varobs) + error('Estimation:varobs:unknown', 'VAROBS: Unknown endogenous variables (%s)\n', cut(sprintf('%s, ', unknown_varobs{:}))) end % Check that a variable is not declared as observed more than once. -if length(unique(varobs)) 1 - error(['VAROBS: a variable cannot be declared as observed more than once (' varobs{i} ')!']) +[varobs_, vi, vj] = unique(varobs); +if ~isequal(vi, vj) + duplicates = {}; j=0; + for i=2:length(vi) + if vi(i)>vi(i-1)+1 + j = j+1; + duplicates{j} = varobs{vi(i-1)}; end end -end \ No newline at end of file + if sum(length(vi)==vj) + duplicates{j+1} = varobs{vi(end)}; + end + error('Estimation:varobs:duplicate', 'VAROBS: A variable cannot be declared as observed more than once (%s)\n', cut(sprintf('%s, ', duplicates{:}))) +end + +return % --*-- Unit tests --*-- + +%@test:1 +endovar={'A1','A2','A3','A4','A5'}; +obsvar={'A1','A1','A3','A4','A4','A4','A5'}; + + +% Call the tested routine. +try + check_varobs_are_endo_and_declared_once(obsvar, endovar) + t(1) = false; +catch ME + t(1) = true; +end + +if t(1) + t(2) = strcmp(ME.identifier, 'Estimation:varobs:duplicate'); +end + +T = all(t); +%@eof:1 + +%@test:2 +endovar={'A1','A2','A3','A4','A5'}; +obsvar={'A1','A3','A4','A5','A5'}; + + +% Call the tested routine. +try + check_varobs_are_endo_and_declared_once(obsvar, endovar) + t(1) = false; +catch ME + t(1) = true; +end + +if t(1) + t(2) = strcmp(ME.identifier, 'Estimation:varobs:duplicate'); +end + +T = all(t); +%@eof:2 + +%@test:3 +endovar={'A1','A2','A3','A4','A5'}; +obsvar={'A1','A3','A4','B1','A5'}; + + +% Call the tested routine. +try + check_varobs_are_endo_and_declared_once(obsvar, endovar) + t(1) = false; +catch ME + t(1) = true; +end + +if t(1) + t(2) = strcmp(ME.identifier, 'Estimation:varobs:unknown'); +end + +T = all(t); +%@eof:3