diff --git a/LICENSE.md b/LICENSE.md index ea80a3567d9969b1b0b8a3d911588a43f6aecc53..aa82a217eabf46a7184a61bbe38889edad2a82dd 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ > Copyright (C) 2014-2018 Dynare Team > -> The dseries and dates Matlab/Octave classes are licensed under GNU GPL as published by +> The dseries and dates MATLAB/Octave classes are licensed under GNU GPL as published by > the Free Software Foundation, either version 3 of the License, or (at > your option) any later version. > diff --git a/README.md b/README.md index 3b63ee4f3e75304ea4b91b7032117e33c3921f10..ddcd26165b782f83d240b82af032b9d2047c5877 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [](https://git.dynare.org/Dynare/dseries/commits/master) -This Matlab/Octave toolbox comes with two classes: +This MATLAB/Octave toolbox comes with two classes: - `@dates` which is used to handle dates. - `@dseries` which is used to handle time series data. @@ -8,7 +8,7 @@ This Matlab/Octave toolbox comes with two classes: The package is a dependence of [Dynare](https=//git.dynare.org/Dynare/dynare), but can also be used as a standalone package without Dynare. The package is -compatible with Matlab 2008a and following versions, and (almost +compatible with MATLAB 2008a and following versions, and (almost compatible with) the latest Octave version. ## Installation @@ -25,30 +25,24 @@ or downloading a zip archive: ## Usage -Add the `dseries/src` folder to the Matlab/Octave path, and run the following command (on Matlab/Octave) prompt: +Add the `dseries/src` folder to the MATLAB/Octave path, and run the following command (on MATLAB/Octave) prompt: >> dseries().initialize() which, depending on your system, will add the necessary subfolders to -the Matlab/Octave path. Also, if -[X13-ARIMA-SEATS](https://www.census.gov/srd/www/x13as/) is not -installed in your system (on debian it is possible to install it with -the `apt-get`) you will need (only the first time) to install the -binary. Scripts are available to install (or update) this -dependency. From the Matlab/Octave prompt: +the MATLAB/Octave path. - >> cd dseries/externals/x13 - >> installx13() - -and run the configuration again: - - >> dseries.initialize() - -You should not see the warning related to the missing `x13as` -binary. You are then ready to go. A full documentation will come soon, +You are then ready to go. A full documentation will come soon, but you can already obtain a general idea by looking into the Dynare reference manual. +Note that [X13-ARIMA-SEATS](https://www.census.gov/srd/www/x13as/) is required +for accessing all the features of the toolbox. On Windows and macOS, an +X13-ARIMA-SEATS binary is included in standalone dseries packages and in Dynare +packages. On Debian and Ubuntu it is possible to install X13-ARIMA-SEATS with +`apt install x13as` (on Debian, you must have the non-free archive area listed +in package sources). + ## Examples ### Instantiate a dseries object from an array diff --git a/externals/x13/.gitignore b/externals/x13/.gitignore deleted file mode 100644 index f81d555c74335b574e6c34574e772b5134ab4a4c..0000000000000000000000000000000000000000 --- a/externals/x13/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -x13.zip -linux/* -windows/* -*~ diff --git a/externals/x13/installx13.m b/externals/x13/installx13.m deleted file mode 100644 index 09c49a4f4a77b6ffc842bae207cc305bd251093f..0000000000000000000000000000000000000000 --- a/externals/x13/installx13.m +++ /dev/null @@ -1,50 +0,0 @@ -function installx13() - -% Installs CENSUS X13 binaries (Windows and Linux). - -% Copyright (C) 2017-2018 Dynare Team -% -% This code 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 dseries submodule 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 ~exist('x13.zip','file') - if ( ~isoctave() && verLessThan('matlab', 'R2014b') ) - websave('x13.zip', 'https://www.dynare.org/x13/x13.zip'); - else - urlwrite('https://www.dynare.org/x13/x13.zip', 'x13.zip'); - end - unzip('x13.zip'); - if ismac() - if exist('./osx', 'dir') - rmdir('osx', 's') - end - mkdir osx; - movefile('binaries/osx/*','./osx'); - elseif isunix() - if exist('./linux', 'dir') - rmdir('linux', 's') - end - mkdir linux; - movefile('binaries/linux/*','./linux'); - elseif ispc() - if exist('./windows', 'dir') - rmdir('windows', 's') - end - mkdir windows; - movefile('binaries/windows/*','./windows'); - else - error('X13 is not available for the current platform!') - end - rmdir('binaries', 's'); -end diff --git a/externals/x13/uninstallx13.m b/externals/x13/uninstallx13.m deleted file mode 100644 index 2e2c04cfbcd11f87ce65cb493eee77ca12f80f14..0000000000000000000000000000000000000000 --- a/externals/x13/uninstallx13.m +++ /dev/null @@ -1,35 +0,0 @@ -function uninstallx13() - -% Uninstalls CENSUS X13 binaries (Windows, OSX and Linux). - -% Copyright (C) 2017 Dynare Team -% -% This code 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 dseries submodule 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 exist('x13.zip','file') - delete('x13.zip') -end - -if exist('linux','dir') - rmdir('linux', 's') -end - -if exist('windows','dir') - rmdir('windows', 's') -end - -if exist('osx','dir') - rmdir('osx', 's') -end \ No newline at end of file diff --git a/externals/x13/updatex13.m b/externals/x13/updatex13.m deleted file mode 100644 index adf312642e175095cae78aad356807ea524b21c8..0000000000000000000000000000000000000000 --- a/externals/x13/updatex13.m +++ /dev/null @@ -1,29 +0,0 @@ -function updatex13() - -% Uninstalls CENSUS X13 binaries (Windows, OSX and Linux). - -% Copyright (C) 2017 Dynare Team -% -% This code 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 dseries submodule 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 exist('x13.zip','file') - delete('x13.zip') -end - -if exist('./binaries', 'dir') - rmdir('binaries', 's'); -end - -installx13(); \ No newline at end of file diff --git a/src/@dseries/extract.m b/src/@dseries/extract.m index 07aa80424ad7633968223230e9819f0252673847..f7b4094dd14d59aac34020c1fe92f89a50a6d750 100644 --- a/src/@dseries/extract.m +++ b/src/@dseries/extract.m @@ -64,7 +64,7 @@ for i=1:nargin-1 end % Check that square brackets in regular expressions if useregularexpression && ~usewildcardparameter && ~isequal(length(idBracket.open),length(idBracket.open)) - error('dseries::extract: (Matlab/Octave''s regular expressions) Check opening and closing square brackets!') + error('dseries::extract: (MATLAB/Octave''s regular expressions) Check opening and closing square brackets!') end % Loops and regular expressions are not compatible if useregularexpression && useimplicitloops diff --git a/src/@dseries/merge.m b/src/@dseries/merge.m index 59ce92e231ae82eee3573dbaa642bef84b359b8f..f62979e2c3d35698609d508650687c33119fd289 100644 --- a/src/@dseries/merge.m +++ b/src/@dseries/merge.m @@ -12,7 +12,7 @@ function q = merge(o, p) % --*-- Unitary tests --*-- % REMARKS % If dseries objects o and p have common variables, the variables in p take precedence. -% Copyright (C) 2013-2017 Dynare Team +% Copyright © 2013-2019 Dynare Team % % This file is part of Dynare. % @@ -45,6 +45,8 @@ q = dseries(); [q.name, IBC, ~] = unique([o.name; p.name], 'last'); +[list_of_common_variables, iO, iP] = intersect(o.name, p.name); + tex = [o.tex; p.tex]; q.tex = tex(IBC); @@ -79,16 +81,25 @@ elseif firstdate(o) >= firstdate(p) diff = firstdate(o) - firstdate(p); q_nobs = max(nobs(o) + diff, nobs(p)); q.data = NaN(q_nobs, vobs(q)); - Z1 = [NaN(diff, vobs(o));o.data]; + Z1 = [NaN(diff, vobs(o)); o.data]; if nobs(q) > nobs(o) + diff Z1 = [Z1; NaN(nobs(q)-(nobs(o) + diff), vobs(o))]; - end; + end Z2 = p.data; if nobs(q) > nobs(p) Z2 = [Z2; NaN(nobs(q) - nobs(p), vobs(p))]; - end; + end Z = [Z1 Z2]; q.data = Z(:,IBC); + if ~isempty(list_of_common_variables) + for i=1:length(iP) + jO = iO(i); + jP = iP(i); + jQ = find(strcmp(o.name{jO}, q.name)); + id = isnan(q.data(:,jQ)) & ~isnan(Z1(:,jO)) & isnan(Z2(:,jP)); + q.data(id, jQ) = Z1(id,jO); + end + end q_init = firstdate(p); else diff = firstdate(p) - firstdate(o); @@ -101,9 +112,18 @@ else Z2 = o.data; if nobs(q) > nobs(o) Z2 = [Z2; NaN(nobs(q) - nobs(o), vobs(o))]; - end; + end Z = [Z2 Z1]; q.data = Z(:,IBC); + if ~isempty(list_of_common_variables) + for i=1:length(iP) + jO = iO(i); + jP = iP(i); + jQ = find(strcmp(o.name{jO}, q.name)); + id = isnan(q.data(:,jQ)) & isnan(Z1(:,jP)) & ~isnan(Z2(:,jO)); + q.data(id, jQ) = Z2(id,jO); + end + end q_init = firstdate(o); end @@ -126,9 +146,9 @@ q.dates = q_init:q_init+(nobs(q)-1); %$ ts2.tag('type'); %$ ts2.tag('type', 'A1', 'Flow'); %$ ts3 = merge(ts1,ts2); -%$ t(1) = 1; +%$ t(1) = true; %$ catch -%$ t = 0; +%$ t = false; %$ end %$ %$ if t(1) @@ -157,9 +177,9 @@ q.dates = q_init:q_init+(nobs(q)-1); %$ ts2.tag('t2'); %$ ts2.tag('t2', 'B1', 1); %$ ts3 = merge(ts1,ts2); -%$ t(1) = 1; +%$ t(1) = true; %$ catch -%$ t = 0; +%$ t = false; %$ end %$ %$ if length(t)>1 @@ -171,3 +191,25 @@ q.dates = q_init:q_init+(nobs(q)-1); %$ end %$ T = all(t); %@eof:2 + +%@test:3 +%$ % Define two dseries objects. +%$ y = dseries(ones(4,1),'1989Q1', 'u'); +%$ z = dseries(ones(4,1),'1990Q1', 'u'); +%$ +%$ % Merge the two objects. +%$ try +%$ x = merge(y, z); +%$ t(1) = true; +%$ catch +%$ t = false; +%$ end +%$ +%$ if t(1) +%$ t(2) = dassert(x.vobs,1); +%$ t(3) = dassert(x.name{1},'u'); +%$ t(4) = dassert(x.data, ones(8,1)); +%$ t(5) = all(x.dates==dates('1989Q1'):dates('1990Q4')); +%$ end +%$ T = all(t); +%@eof:3 \ No newline at end of file diff --git a/src/@dseries/plot.m b/src/@dseries/plot.m index ed063de456405c2e4821a5165fdbb3504e705f56..f822e77870e799e1354922ddd51fadfba34ba41f 100644 --- a/src/@dseries/plot.m +++ b/src/@dseries/plot.m @@ -23,7 +23,6 @@ function h = plot(o, varargin) if isequal(nargin,1) ndseries = 1; nvariables = vobs(o); - nobservations = nobs(o); else if isdseries(varargin{1}) ndseries = 2; @@ -41,7 +40,6 @@ else else ndseries = 1; nvariables = vobs(o); - nobservations = nobs(o); end end @@ -50,7 +48,7 @@ switch ndseries if isequal(nvariables,1) hh = plot(o.data,varargin{:}); else - if length(varargin) + if ~isempty(varargin) message = sprintf('dseries::plot: dseries object %s has %d>1 variables but you passed additional arguments to the plot function.\n These additional arguments won''t ne interpreted. Use the Matlab/Octave set command and the plot\n handle instead if you wish to modify the properties of the plotted time series.',inputname(1),nvariables); warning(message) end diff --git a/src/@dseries/subsasgn.m b/src/@dseries/subsasgn.m index e66505bff681717f6c2850f95fe7d0cde6233d90..778fc756f13b5771bb7dd70e44c5f605d27640d8 100644 --- a/src/@dseries/subsasgn.m +++ b/src/@dseries/subsasgn.m @@ -45,7 +45,7 @@ switch length(S) idBracket.open = strfind(element, '['); idBracket.close = strfind(element, ']'); if ~isequal(length(idBracket.open),length(idBracket.open)) - error('dseries::subsasgn: (Matlab/Octave''s regular expressions) Check opening and closing square brackets!') + error('dseries::subsasgn: (MATLAB/Octave''s regular expressions) Check opening and closing square brackets!') end % Loops and regular expressions are not compatible if length(idArobase) && length(idBracket.open) diff --git a/src/initialize_dseries_class.m b/src/initialize_dseries_class.m index b041008f21e41fd3225cf9de273e20713d81fb02..f3a318033846436b3eaa6fe55cd9540cae420fba 100644 --- a/src/initialize_dseries_class.m +++ b/src/initialize_dseries_class.m @@ -18,28 +18,6 @@ function initialize_dseries_class() % Get the path to the dseries toolbox. dseries_src_root = strrep(which('initialize_dseries_class'),'initialize_dseries_class.m',''); -% Check that the x13 binary is available -nox13 = false; -if ismac() - if ~exist([dseries_src_root '../externals/x13/osx/64/x13as'], 'file') - nox13 = true; - end -elseif isunix() - [status, ~] = system('which x13as'); - if status && ~(exist([dseries_src_root '../externals/x13/linux/64/x13as'], 'file') && exist([dseries_src_root '../externals/x13/linux/32/x13as'], 'file')) - nox13 = true; - end -elseif ispc() - if ~(exist([dseries_src_root '../externals/x13/windows/64/x13as.exe'], 'file') && exist([dseries_src_root '../externals/x13/windows/32/x13as.exe'], 'file')) - nox13 = true; - end -else - error('Unsupported platform.') -end -if nox13 - warning('X13 binary is not available.\nIf you are under Debian or Ubuntu, you can install it through your package manager, with ''apt install x13as''.\nOtherwise, you can install it manually by running\nthe function installx13() available in:\n\n\t%s\n', [dseries_src_root(1:end-4), 'externals' filesep() 'x13']); -end - % Set the subfolders to be added in the path. p = {'read'; ... 'utilities/is'; ... @@ -52,12 +30,8 @@ p = {'read'; ... 'utilities/print'; ... 'utilities/variables'; ... 'utilities/cumulate'; ... - 'utilities/struct'}; - -% Add /utilities/x13' if x13 binary is available. -if ~nox13 - p{end+1} = 'utilities/x13'; -end + 'utilities/struct'; ... + 'utilities/x13'}; % Add missing routines if dynare is not in the path if ~exist('isint','file') @@ -136,4 +110,10 @@ end P = cellfun(@(c)[dseries_src_root c], p, 'uni', false); addpath(P{:}); +% If X13 binary is not available, display a warning, and remove the x13 +% subdirectory from the path +if isempty(select_x13_binary(true)) + rmpath([dseries_src_root 'utilities/x13']); +end + assignin('caller', 'dseries_src_root', dseries_src_root); diff --git a/src/utilities/is/is64bit.m b/src/utilities/is/is64bit.m index c1b688bb53939077b43178d63481080b0b59a0ee..62a38b1a50dbbd65af98df77c9ee2be3c9554d4c 100644 --- a/src/utilities/is/is64bit.m +++ b/src/utilities/is/is64bit.m @@ -1,8 +1,11 @@ function b = is64bit() -% Returns true iff Matlab 64bit version is used. +% Returns true iff operating system is 64-bit +% +% The test logic is the same as in dynare.m when selecting the preprocessor +% flavour. -% Copyright (C) 2017 Dynare Team +% Copyright (C) 2017-2019 Dynare Team % % This code is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by @@ -17,5 +20,10 @@ function b = is64bit() % You should have received a copy of the GNU General Public License % along with Dynare. If not, see <http://www.gnu.org/licenses/>. -[~, maxsize] = computer(); -b = (maxsize > 2^31); \ No newline at end of file +if ispc + arch = getenv('PROCESSOR_ARCHITECTURE'); +else + [~, arch] = system('uname -m'); +end + +b = ~isempty(strfind(arch, '64')); diff --git a/src/utilities/x13/select_x13_binary.m b/src/utilities/x13/select_x13_binary.m index 9725cd715b420f27d2baedc124eca5d41e97aec9..b7b3257eae52fe8194b98cd7d4e5f539515d4f4a 100644 --- a/src/utilities/x13/select_x13_binary.m +++ b/src/utilities/x13/select_x13_binary.m @@ -1,6 +1,10 @@ -function x13_binary = select_x13_binary() +function x13_binary = select_x13_binary(warn_only) -% Copyright (C) 2017 Dynare Team +% Returns the path to the X13 binary. If no X13 binary can be found, raises an +% error (unless warn_only=true, in which case it returns an empty string and +% displays a warning). + +% Copyright (C) 2017-2019 Dynare Team % % This code is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by @@ -15,26 +19,31 @@ function x13_binary = select_x13_binary() % 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 < 1 + warn_only = false; +end + dseries_src_root = strrep(which('initialize_dseries_class'),'initialize_dseries_class.m',''); dseries_x13_root = sprintf('%s%s%s%s%s%s%s', dseries_src_root, '..', filesep(), 'externals', filesep(), 'x13', filesep()); if ismac() - x13_binary = sprintf('%s%s%s', dseries_x13_root, 'osx', filesep()); + x13_binary = sprintf('%s%s%s', dseries_x13_root, 'macOS', filesep()); if is64bit() x13_binary = sprintf('%s%s%s%s', x13_binary, '64', filesep(), 'x13as'); else x13_binary = sprintf('%s%s%s%s', x13_binary, '32', filesep(), 'x13as'); end elseif isunix() - [status, x13_binary] = system('which x13as'); - if ~status - x13_binary = deblank(x13_binary); + x13_binary = sprintf('%s%s%s', dseries_x13_root, 'linux', filesep()); + if is64bit() + x13_binary = sprintf('%s%s%s%s', x13_binary, '64', filesep(), 'x13as'); else - x13_binary = sprintf('%s%s%s', dseries_x13_root, 'linux', filesep()); - if is64bit() - x13_binary = sprintf('%s%s%s%s', x13_binary, '64', filesep(), 'x13as'); - else - x13_binary = sprintf('%s%s%s%s', x13_binary, '32', filesep(), 'x13as'); + x13_binary = sprintf('%s%s%s%s', x13_binary, '32', filesep(), 'x13as'); + end + if ~exist(x13_binary, 'file') + [status, x13_binary] = system('which x13as'); + if ~status + x13_binary = deblank(x13_binary); end end elseif ispc() @@ -45,5 +54,14 @@ elseif ispc() x13_binary = sprintf('%s%s%s%s', x13_binary, '32', filesep(), 'x13as.exe'); end else - error('X13 binary is not available for this plateform') -end \ No newline at end of file + error('Unsupported platform') +end + +if ~exist(x13_binary, 'file') + if warn_only + warning('X13 binary is not available.\nIf you are under Debian or Ubuntu, you can install it through your package manager, with ''apt install x13as''.\nIf you are under Windows or macOS, this probably means that you did not install the dseries toolbox through an official package.\n'); + x13_binary = ''; + else + error('Can''t find X13 binary'); + end +end