diff --git a/matlab/compute_moments_varendo.m b/matlab/compute_moments_varendo.m index e50f1adae8845c2e2dccdd31e15757ea5a6e9227..5d38ce71f979e4d8dc4d6c4842cf4f546324c688 100644 --- a/matlab/compute_moments_varendo.m +++ b/matlab/compute_moments_varendo.m @@ -171,7 +171,11 @@ if options_.order==1 skipline(); end if ~all(diag(M_.H)==0) - [observable_name_requested_vars, varlist_pos] = intersect(var_list_, options_.varobs, 'stable'); + if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + [observable_name_requested_vars, varlist_pos] = intersect_stable(var_list_, options_.varobs); + else + [observable_name_requested_vars, varlist_pos] = intersect(var_list_, options_.varobs, 'stable'); + end if ~isempty(observable_name_requested_vars) NumberOfObservedEndogenousVariables = length(observable_name_requested_vars); temp = NaN(NumberOfObservedEndogenousVariables, NumberOfExogenousVariables+1); diff --git a/matlab/conditional_variance_decomposition.m b/matlab/conditional_variance_decomposition.m index c9d92e406a4562e8c1fbd937f795fef6aab5b593..3ece5204218e6c153784fdc4eacc1230f5fe27d3 100644 --- a/matlab/conditional_variance_decomposition.m +++ b/matlab/conditional_variance_decomposition.m @@ -1,4 +1,5 @@ function [ConditionalVarianceDecomposition, ConditionalVarianceDecomposition_ME]= conditional_variance_decomposition(M_,options_,dr, Steps, SubsetOfVariables) +% [ConditionalVarianceDecomposition, ConditionalVarianceDecomposition_ME]= conditional_variance_decomposition(M_,options_,dr, Steps, SubsetOfVariables) % This function computes the conditional variance decomposition of a given state space model % for a subset of endogenous variables. % @@ -88,7 +89,11 @@ end % Measurement error if ~all(diag(M_.H)==0) - [observable_pos,index_subset,index_observables]=intersect(SubsetOfVariables,options_.varobs_id,'stable'); + if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + [observable_pos,index_subset,index_observables]=intersect_stable(SubsetOfVariables,options_.varobs_id); + else + [observable_pos,index_subset,index_observables]=intersect(SubsetOfVariables,options_.varobs_id,'stable'); + end ME_Variance=diag(M_.H); ConditionalVarianceDecomposition_ME = zeros(length(observable_pos),length(Steps),number_of_state_innovations+1); diff --git a/matlab/conditional_variance_decomposition_ME_mc_analysis.m b/matlab/conditional_variance_decomposition_ME_mc_analysis.m index 52e3ff344e1c0bafe24dd790cc7d6e30a2acc207..c4d4e349694592eaded997db30f36fa436a72ca1 100644 --- a/matlab/conditional_variance_decomposition_ME_mc_analysis.m +++ b/matlab/conditional_variance_decomposition_ME_mc_analysis.m @@ -1,5 +1,6 @@ function oo_ = ... conditional_variance_decomposition_ME_mc_analysis(NumberOfSimulations, type, dname, fname, Steps, exonames, exo, var_list, endo, mh_conf_sig, oo_,options_) +%oo_ = conditional_variance_decomposition_ME_mc_analysis(NumberOfSimulations, type, dname, fname, Steps, exonames, exo, var_list, endo, mh_conf_sig, oo_,options_) % This function analyses the (posterior or prior) distribution of the % endogenous variables' conditional variance decomposition with measurement error. % @@ -22,7 +23,7 @@ function oo_ = ... % OUTPUTS % oo_ [structure] Dynare structure where the results are saved. -% Copyright © 2017-2020 Dynare Team +% Copyright © 2017-2023 Dynare Team % % This file is part of Dynare. % @@ -63,7 +64,12 @@ if isempty(exogenous_variable_index) end end -[observable_pos_requested_vars,index_subset,index_observables]=intersect(var_list,options_.varobs,'stable'); +if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + [~,index_subset]=intersect_stable(var_list,options_.varobs); +else + [~,index_subset]=intersect(var_list,options_.varobs,'stable'); +end + matrix_pos=strmatch(endo, var_list(index_subset),'exact'); name_1 = endo; name_2 = exo; diff --git a/matlab/disp_moments.m b/matlab/disp_moments.m index 0dd5953269a402d4650b0c851188c4e1c4c18579..b9759cd51dc43ca9e4975de0295b644d02474af9 100644 --- a/matlab/disp_moments.m +++ b/matlab/disp_moments.m @@ -11,7 +11,7 @@ function oo_=disp_moments(y,var_list,M_,options_,oo_) % OUTPUTS % oo_ [structure] Dynare's results structure, -% Copyright © 2001-2021 Dynare Team +% Copyright © 2001-2023 Dynare Team % % This file is part of Dynare. % @@ -50,7 +50,11 @@ y = y(ivar,options_.drop+1:end)'; ME_present=0; if ~all(M_.H==0) - [observable_pos_requested_vars, index_subset, index_observables] = intersect(ivar, options_.varobs_id, 'stable'); + if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + [observable_pos_requested_vars, index_subset, index_observables] = intersect_stable(ivar, options_.varobs_id); + else + [observable_pos_requested_vars, index_subset, index_observables] = intersect(ivar, options_.varobs_id, 'stable'); + end if ~isempty(observable_pos_requested_vars) ME_present=1; i_ME = setdiff([1:size(M_.H,1)],find(diag(M_.H) == 0)); % find ME with 0 variance diff --git a/matlab/dynare_config.m b/matlab/dynare_config.m index 31e7dce80b30eb2b97cdadf94c7bd7e37d9bd7c6..2dd275572c7441adb13c1d1aa2e6bb654c9e6c60 100644 --- a/matlab/dynare_config.m +++ b/matlab/dynare_config.m @@ -122,6 +122,11 @@ if isoctave || matlab_ver_less_than('8.4') p{end+1} = '/missing/datetime'; end +% intersect with 'stable' flag is broken before Octave 8.4, bug #60347 +if isoctave && octave_ver_less_than('8.4') + p{end+1} = '/missing/intersect_stable'; +end + P = cellfun(@(c)[dynareroot(1:end-1) c], p, 'uni',false); % Get mex files folder(s) diff --git a/matlab/missing/intersect_stable/intersect_stable.m b/matlab/missing/intersect_stable/intersect_stable.m new file mode 100644 index 0000000000000000000000000000000000000000..155e1540103330ebda201b3bd18e85439dc753d1 --- /dev/null +++ b/matlab/missing/intersect_stable/intersect_stable.m @@ -0,0 +1,91 @@ +function [c, ia, ib] = intersect_stable(a, b) +% Crude implementation of intersect(…, 'stable'), which is missing before +% Octave 6.2 and buggy before 8.4 (#60347) + +% Copyright (C) 2019-2023 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see <http://www.gnu.org/licenses/>. + +if nargin ~= 2 + error('intersect_stable: needs exactly 2 input arguments'); +end + +if isnumeric (a) && isnumeric (b) + c = []; +elseif iscell (b) + c = {}; +else + c = ''; +end +ia = []; +ib = []; + +if isempty (a) || isempty (b) + return +else + isrowvec = isrow (a) && isrow (b); + + for i = 1:numel(a) + if iscellstr(c) + idx = strcmp(a(i), b); + else + idx = a(i) == b; + end + if any(idx) && ~ismember(a(i), c) + c = [c(:); a(i)]; + if nargout > 1 + ia = [ia, i]; + ib = [ib, find(idx)]; + end + end + end + + %% Adjust output orientation for MATLAB compatibility + if isrowvec + c = c.'; + end +end +end + +%!test +%! a = [3 4 1 5]; +%! b = [2 4 9 1 6]; +%! [c,ia,ib]=intersect_stable(a,b); +%! assert(c, [4 1]) +%! assert(ia, [2 3]) +%! assert(ib, [2 4]) +%! assert(a(ia), c) +%! assert(b(ib), c) + +%!test +%! a = [3 4 1 5]'; +%! b = [2 4 9 1 6]'; +%! [c,ia,ib]=intersect_stable(a,b); +%! assert(c, [4 1]') +%! assert(ia, [2 3]) +%! assert(ib, [2 4]) +%! assert(a(ia), c) +%! assert(b(ib), c) + +%!test +%! a = { 'defun', 'mapcar', 'let', 'eval-when'}; +%! b = { 'setf', 'let', 'list', 'cdr', 'defun'}; +%! [c,ia,ib]=intersect_stable(a,b); +%! assert(c, { 'defun', 'let' }) +%! assert(ia, [1 3]) +%! assert(ib, [5 2]) +%! assert(a(ia), c) +%! assert(b(ib), c) diff --git a/matlab/moments/check_measurement_error_requested_vars.m b/matlab/moments/check_measurement_error_requested_vars.m index 76bee009d90b1b135418bd15a58f90bea7320729..6f7419b1fd47a94f044f14d4732f7a2c08540e9e 100644 --- a/matlab/moments/check_measurement_error_requested_vars.m +++ b/matlab/moments/check_measurement_error_requested_vars.m @@ -38,7 +38,11 @@ observable_pos_requested_vars=[]; ME_present=false; if ~all(diag(M_.H)==0) - [observable_pos_requested_vars,index_subset,index_observables]=intersect(ivar,options_.varobs_id,'stable'); + if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + [observable_pos_requested_vars,index_subset,index_observables]=intersect_stable(ivar,options_.varobs_id); + else + [observable_pos_requested_vars,index_subset,index_observables]=intersect(ivar,options_.varobs_id,'stable'); + end if ~isempty(observable_pos_requested_vars) ME_present=true; end diff --git a/matlab/moments/display_unconditional_variance_decomposition.m b/matlab/moments/display_unconditional_variance_decomposition.m index df547d02cf12d4083605c385c3905d20f8ca921a..f07ecb91b672d3fb788da1bef51530ba1c79574a 100644 --- a/matlab/moments/display_unconditional_variance_decomposition.m +++ b/matlab/moments/display_unconditional_variance_decomposition.m @@ -45,7 +45,11 @@ if M_.exo_nbr > 1 lh = cellofchararraymaxlength(labels)+2; dyntable(options_, title, headers, labels, 100*oo_.gamma_y{options_.ar+2}(stationary_vars,:), lh, 8, 2); if ME_present - [stationary_observables, pos_index_subset] = intersect(index_subset, stationary_vars, 'stable'); + if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + [stationary_observables, pos_index_subset] = intersect_stable(index_subset, stationary_vars); + else + [stationary_observables, pos_index_subset] = intersect(index_subset, stationary_vars, 'stable'); + end headers_ME = vertcat(headers, 'ME'); labels=get_labels_transformed_vars(M_.endo_names,ivar(stationary_observables),options_,false); dyntable(options_, [title,' WITH MEASUREMENT ERROR'], headers_ME, labels, ... diff --git a/matlab/posterior_analysis.m b/matlab/posterior_analysis.m index 3b523c0a7c392bda8dbfacea7d3cb63c13bd9ff9..2bc14e27c8f1d5ad0243bc38fa0a53c4396b0f0b 100644 --- a/matlab/posterior_analysis.m +++ b/matlab/posterior_analysis.m @@ -66,7 +66,11 @@ switch type M_.exo_names,arg2,vartan,arg1,options_.mh_conf_sig,oo_,options_); if ~all(diag(M_.H)==0) if strmatch(arg1,options_.varobs,'exact') - [observable_name_requested_vars,index_subset,index_observables]=intersect(vartan,options_.varobs,'stable'); + if isoctave && octave_ver_less_than('8.4') %Octave bug #60347 + observable_name_requested_vars=intersect_stable(vartan,options_.varobs); + else + observable_name_requested_vars=intersect(vartan,options_.varobs,'stable'); + end oo_ = variance_decomposition_ME_mc_analysis(SampleSize,'posterior',M_.dname,M_.fname,... [M_.exo_names;'ME'],arg2,observable_name_requested_vars,arg1,options_.mh_conf_sig,oo_,options_); end