Verified Commit ba42996f authored by Stéphane Adjemian's avatar Stéphane Adjemian

Merged dates class history in dseries project.

parents 3711864b f25def5a
......@@ -3,7 +3,6 @@ variables:
TERM: linux
before_script:
- git clone https://git.dynare.org/Dynare/dates
- git clone https://git.dynare.org/Dynare/m-unit-tests
testsuite_matlab:
......
> Copyright (C) 2014 Dynare Team
> Copyright (C) 2014-2018 Dynare Team
>
> The dseries Matlab/Octave class is 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.
>
......
......@@ -3,12 +3,25 @@ MATLAB=`which matlab`
all: check-octave check-matlab
check-octave:
@cd tests ;\
$(OCTAVE) --no-init-file --silent --no-history --eval "addpath ../m-unit-tests/src; addpath ../dates/src; runalltests" && [ ! -f ./failed ] && [ -f ./pass ]
check-octave: check-octave-dseries check-octave-dates
check-matlab:
@$(MATLAB) -nosplash -nodisplay -r "addpath m-unit-tests/src; addpath dates/src; cd tests; runalltests; quit" && [ ! -f ./tests/failed ] && [ -f ./tests/pass ]
check-matlab: check-matlab-dseries check-matlab-dates
check-octave-dseries:
@cd tests/dseries ;\
$(OCTAVE) --no-init-file --silent --no-history --eval "addpath([pwd() '/../../m-unit-tests/src']); runalltests" && [ ! -f ./failed ] && [ -f ./pass ]
check-octave-dates:
@cd tests/dates ;\
$(OCTAVE) --no-init-file --silent --no-history --eval "addpath([pwd() '/../../m-unit-tests/src']); runalltests" && [ ! -f ./failed ] && [ -f ./pass ]
check-matlab-dseries:
@$(MATLAB) -nosplash -nodisplay -r "addpath m-unit-tests/src; cd tests/dseries; runalltests; quit" && [ ! -f ./tests/failed ] && [ -f ./tests/pass ]
check-matlab-dates:
@$(MATLAB) -nosplash -nodisplay -r "addpath m-unit-tests/src; cd tests/dates; runalltests; quit" && [ ! -f ./tests/failed ] && [ -f ./tests/pass ]
check-clean:
rm -f tests/*_test_*.m tests/*.csv tests/*.xls tests/*.xlsx tests/*.mat tests/failed tests/datafile_for_test
rm -f tests/dseries/*_test_*.m tests/dseries/*.csv tests/dseries/*.xls tests/dseries/*.xlsx tests/dseries/*.mat tests/dseries/failed tests/dseries/datafile_for_test
rm -f tests/dates/*_test_*.m tests/dates/*.csv tests/dates/*.xls tests/dates/*.xlsx tests/dates/*.mat tests/dates/failed tests/dates/datafile_for_test
expected_str_1 = sprintf('toto is an empty dates object.\n');
expected_str_2 = sprintf('toto = <dates: 1950Q1, 1950Q2>\n');
expected_str_3 = sprintf('toto = <dates: 1950Q1, 1950Q2, ..., 1950Q4, 1951Q1>\n');
expected_str_4 = sprintf('toto = <dates: 1950Q1, 1950Q2, 1950Q3, 1950Q4, 1951Q1>\n');
function o = append(o, d) % --*-- Unitary tests --*--
% append method for dates class.
%
% INPUTS
% - o [dates]
% - a [dates or string] dates object with one element or string that can be interpreted as a date.
%
% OUTPUTS
% - o [dates] dates object containing dates defined in o and d.
% Copyright (C) 2012-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 dates 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 isa(d, 'dates')
if ~isequal(length(d), 1)
error('dates:append:ArgCheck','Input argument %s has to be a dates object with one element.', inputname(2))
end
if isempty(d)
return
end
elseif isdate(d)
d = dates(d);
end
if ~isequal(o.freq, d.freq)
error('dates:append:ArgCheck','dates must have common frequency!')
end
o = copy(o);
o.append_(d);
%@test:1
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009Q2';
%$
%$ % Define expected results.
%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4];
%$ e.freq = 4;
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3,B2,B1);
%$ try
%$ d.append(dates(B5));
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ % Check the results.
%$ if t(1)
%$ t(2) = dassert(d.time,e.time);
%$ t(3) = dassert(d.freq,e.freq);
%$ end
%$ T = all(t);
%@eof:1
%@test:2
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009q2';
%$
%$ % Define expected results.
%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
%$ f.time = [1945 3; 1950 1; 1950 2; 1953 4];
%$ e.freq = 4;
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3,B2,B1);
%$ try
%$ c = d.append(B5);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ % Check the results.
%$ if t(1)
%$ t(2) = dassert(d.time,f.time);
%$ t(3) = dassert(c.time,e.time);
%$ t(4) = dassert(c.freq,e.freq);
%$ t(5) = dassert(d.freq,e.freq);
%$ end
%$ T = all(t);
%@eof:2
%@test:3
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009q2';
%$
%$ % Define expected results.
%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
%$ f.time = [1945 3; 1950 1; 1950 2; 1953 4];
%$ e.freq = 4;
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3,B2,B1);
%$ try
%$ c = append(d, B5);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ % Check the results.
%$ if t(1)
%$ t(2) = dassert(d.time,f.time);
%$ t(3) = dassert(c.time,e.time);
%$ t(4) = dassert(c.freq,e.freq);
%$ t(5) = dassert(d.freq,e.freq);
%$ end
%$ T = all(t);
%@eof:3
function o = append_(o, d) % --*-- Unitary tests --*--
% append method for dates class (in place modification).
%
% INPUTS
% - o [dates]
% - a [dates or string] dates object with one element or string that can be interpreted as a date.
%
% OUTPUTS
% - o [dates] dates object containing dates defined in o and d.
% Copyright (C) 2012-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 dates 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 isa(d, 'dates')
if ~isequal(length(d), 1)
error('dates:append_:ArgCheck','Input argument %s has to be a dates object with one element.', inputname(2))
end
if isempty(d)
return
end
elseif isdate(d)
d = dates(d);
end
if ~isequal(o.freq, d.freq)
error('dates:append_:ArgCheck','dates must have common frequency!')
end
o.time = [o.time; d.time];
%@test:1
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009Q2';
%$
%$ % Define expected results.
%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
%$ e.freq = 4;
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3,B2,B1);
%$ try
%$ d.append_(dates(B5));
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ % Check the results.
%$ if t(1)
%$ t(2) = dassert(d.time,e.time);
%$ t(3) = dassert(d.freq,e.freq);
%$ end
%$ T = all(t);
%@eof:1
%@test:2
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009Q2';
%$
%$ % Define expected results.
%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
%$ e.freq = 4;
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3,B2,B1);
%$ try
%$ d.append_(B5);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ % Check the results.
%$ if t(1)
%$ t(2) = dassert(d.time,e.time);
%$ t(3) = dassert(d.freq,e.freq);
%$ end
%$ T = all(t);
%@eof:2
%@test:3
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009Q2';
%$
%$ % Define expected results.
%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
%$ e.freq = 4;
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3,B2,B1);
%$ try
%$ c = d.append_(B5);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ % Check the results.
%$ if t(1)
%$ t(2) = dassert(d.time,e.time);
%$ t(3) = dassert(c.time,e.time);
%$ t(4) = dassert(d.freq,e.freq);
%$ t(5) = dassert(c.freq,e.freq);
%$ end
%$ T = all(t);
%@eof:3
%@test:4
%$ % Define some dates
%$ B1 = '1953Q4';
%$ B2 = '1950Q2';
%$ B3 = '1950Q1';
%$ B4 = '1945Q3';
%$ B5 = '2009Q2';
%$
%$ % Call the tested routine.
%$ d = dates(B4,B3);
%$ e = dates(B1,B2,B5);
%$ try
%$ d.append_(e);
%$ t(1) = false;
%$ catch
%$ t(1) = true;
%$ end
%$
%$ T = all(t);
%@eof:4
%@test:5
%$ % Define some dates
%$ B = '1950Q2';
%$
%$ % Call the tested routine.
%$ d = dates(B);
%$ try
%$ d.append_('1950Q3');
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(d.time, [1950 2; 1950 3]);
%$ end
%$
%$ T = all(t);
%@eof:5
%@test:6
%$ % Define some dates
%$ B = '1950Q2';
%$
%$ % Call the tested routine.
%$ d = dates(B);
%$ try
%$ d.append_('1950Z3');
%$ t(1) = false;
%$ catch
%$ t(1) = true;
%$ end
%$
%$ T = all(t);
%@eof:6
function s = char(o) % --*-- Unitary tests --*--
% Given a one element dates object, returns a string with the formatted date.
%
% INPUTS
% - o [dates]
%
% OUTPUTS
% - s [string]
% Copyright (C) 2014-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 dates 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 length(o)>1
error('dates:char:ArgCheck', 'The input argument must be a dates object with one element!')
end
s = date2string(o.time, o.freq);
%@test:1
%$ % Define a dates object
%$ o = dates('1950Q1');
%$
%$ % Call the tested routine.
%$ try
%$ str = char(o);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(str,'1950Q1');
%$ end
%$ T = all(t);
%@eof:1
%@test:2
%$ % Define a dates object
%$ o = dates('1950M1');
%$
%$ % Call the tested routine.
%$ try
%$ str = char(o);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(str,'1950M1');
%$ end
%$ T = all(t);
%@eof:2
%@test:3
%$ % Define a dates object
%$ o = dates('1950W50');
%$
%$ % Call the tested routine.
%$ try
%$ str = char(o);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(str,'1950W50');
%$ end
%$ T = all(t);
%@eof:3
%@test:4
%$ % Define a dates object
%$ o = dates('1950Y');
%$
%$ % Call the tested routine.
%$ try
%$ str = char(o);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(str,'1950Y');
%$ end
%$ T = all(t);
%@eof:4
%@test:5
%$ % Define a dates object
%$ o = dates('1950A');
%$
%$ % Call the tested routine.
%$ try
%$ str = char(o);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(str,'1950Y');
%$ end
%$ T = all(t);
%@eof:5
function q = colon(varargin) % --*-- Unitary tests --*--
% Overloads the colon operator (:). This method can be used to create ranges of dates.
%
% INPUTS
% o o [dates] Initial date.
% o d [integer] Number of periods between each date (default value, if nargin==2, is one)
% o p [dates] Terminal date.
%
% OUTPUTS
% o q [dates] Object with length(p-o) elements (if d==1).
%
% REMARKS
% 1. p must be greater than o if d>0.
% 2. p and q are dates objects with one element.
% Copyright (C) 2013-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 dates 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/>.
% Check the input arguments.
if isequal(nargin,2)
o = varargin{1};
p = varargin{2};
d = 1;
if ~(isa(o,'dates') && isa(p,'dates') && isequal(o.length(),1) && isequal(p.length(),1))
error('dates:colon:ArgCheck','In an expression like A:B, A and B must be one element dates objects!')
end
elseif isequal(nargin,3)
o = varargin{1};
p = varargin{3};
d = varargin{2};
if ~(isa(o,'dates') && isa(p,'dates') && isequal(o.length(),1) && isequal(o.length(),1) && isscalar(d) && isint(d))
error('dates:colon:ArgCheck','In an expression like A:d:B, A and B must be one element dates objects and d a scalar integer!')
end
if isequal(d,0)
error('dates:colon:ArgCheck','In an expression like A:d:B, d (the incremental number of periods) must nonzero!')
end
else
error('dates:colon:ArgCheck','See the manual for the colon (:) operator and dates objects.')
end
if ~isequal(o.freq, p.freq)
error('dates:colon:ArgCheck','dates::colon: Input arguments %s and %s must have common frequency!', inputname(1), inputname(2))
end
if o>p && d>0
error('dates:colon:ArgCheck','First date must preceed the second one!')
end
if p>o && d<0
error('dates:colon:ArgCheck','Second date must preceed the first one!')
end
% Initialize the output argument.
q = dates();
% Compute the number of elements in the returned dates object.
n = (p-o)+1; % The number of elements in q dates object if d==1.
m = n;
if d>1 % Correction of the number of elements (if d is not equal to one).
m = length(1:d:n);
end
% Set the frequency in q
q.freq = o.freq;
if isequal(q.freq, 1)
% Yearly
q.time = NaN(m,2);
q.time(:,1) = o.time(1)+transpose(0:d:n-1);
q.time(:,2) = 1;
else
% Weekly, Monthly, Quaterly
q.time = NaN(n,2);
initperiods = min(q.freq-o.time(2)+1,n);
q.time(1:initperiods,1) = o.time(1);
q.time(1:initperiods,2) = transpose(o.time(2)-1+(1:initperiods));
if n>initperiods
l = n-initperiods;
if l<=q.freq
q.time(initperiods+(1:l),1) = o.time(1)+1;
q.time(initperiods+(1:l),2) = transpose(1:l);
else
k = fix(l/o.freq);
r = rem(l,o.freq);
q.time(initperiods+(1:q.freq*k),2) = repmat(transpose(1:q.freq),k,1);
q.time(initperiods+(1:q.freq*k),1) = kron(o.time(1)+transpose(1:k),ones(q.freq,1));
if r>0
q.time(initperiods+q.freq*k+(1:r),1) = q.time(initperiods+q.freq*k,1)+1;
q.time(initperiods+q.freq*k+(1:r),2) = transpose(1:r);
end
end
end
if d>1
q.time = q.time(1:d:n,:);
end
end
%@test:1
%$ % Define two dates
%$ date_1 = '1950Q2';
%$ date_2 = '1951Q4';
%$
%$ % Define expected results.
%$ e.freq = 4;
%$ e.time = [1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4];
%$
%$ % Call the tested routine.
%$ d1 = dates(date_1);
%$ d2 = dates(date_2);
%$ d3 = d1:d2;
%$
%$ % Check the results.
%$ t(1) = dassert(d3.time,e.time);
%$ t(2) = dassert(d3.freq,e.freq);
%$ T = all(t);
%@eof:1
%@test:2
%$ % Define expected results.
%$ e.freq = 4;
%$ e.time = [1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4];
%$
%$ % Call the tested routine.
%$ d = dates('1950Q2'):dates('1951Q4');
%$
%$ % Check the results.
%$ t(1) = dassert(d.time,e.time);
%$ t(2) = dassert(d.freq,e.freq);
%$ T = all(t);
%@eof:2
%@test:3
%$ % Define expected results.
%$ e.freq = 4;
%$ e.time = [1950 2; 1950 4; 1951 2; 1951 4];
%$
%$ % Call the tested routine.
%$ d = dates('1950Q2'):2:dates('1951Q4');
%$
%$ % Check the results.
%$ t(1) = dassert(d.time,e.time);
%$ t(2) = dassert(d.freq,e.freq);
%$ T = all(t);
%@eof:3
%$ @test:3
%$ % Create an empty dates object for quaterly data
%$ qq = dates('Q');
%$
%$ % Define expected results.
%$ e.freq = 4;
%$ e.time = [1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4];
%$
%$ % Call the tested routine.
%$ d = qq(1950,2):qq(1951,4);
%$
%$ % Check the results.
%$ t(1) = dassert(d.time,e.time);
%$ t(2) = dassert(d.freq,e.freq);
%$ T = all(t);
%$ @eof:3
%$ @test:4
%$ % Create an empty dates object for quaterly data
%$ qq = dates('Q');
%$
%$ % Define expected results.
%$ e.freq = 4;
%$ e.time = [1950 1; 1950 2; 1950 3];
%$
%$ % Call the tested routine.
%$ d = qq(1950,1):qq(1950,3);
%$
%$ % Check the results.
%$ t(1) = dassert(d.time,e.time);
%$ t(2) = dassert(d.freq,e.freq);
%$ T = all(t);
%$ @eof:4
function p = copy(o) % --*-- Unitary tests --*--
% Do a copy of a dates object.
%
% INPUTS
% - o [dates]
%
% OUTPUTS
% - p [dates]
% Copyright (C) 2014-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 dates 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/>.
p = dates();
p.freq = o.freq;
p.time = o.time;
%@test:1
%$ % Define a dates object
%$ o = dates('1945Q3','1944Q4');
%$ q = dates('1945Q3','1944Q4');
%$
%$ % Call the tested routine.
%$ try
%$ p = copy(o);