2013-09-05 11:34:19 +02:00
function B = subsref ( A,S) % --*-- Unitary tests --*--
2011-10-20 14:03:58 +02:00
2013-10-15 15:36:21 +02:00
% Overload the subsref method for dates objects.
2013-10-15 15:06:32 +02:00
%
% INPUTS
2013-10-15 15:36:21 +02:00
% o A dates object.
2013-10-15 15:06:32 +02:00
% o S matlab's structure.
%
% OUTPUTS
2013-10-15 15:36:21 +02:00
% o B dates object.
2013-10-15 15:06:32 +02:00
%
% REMARKS
% See the matlab's documentation about the subsref method.
2011-10-20 14:03:58 +02:00
2013-02-05 12:49:41 +01:00
% Copyright (C) 2011-2013 Dynare Team
2011-10-20 14:03:58 +02:00
%
% 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/>.
2013-03-13 23:52:40 +01:00
switch S ( 1 ) . type
case ' .'
2011-10-20 15:02:58 +02:00
switch S ( 1 ) . subs
2013-03-13 23:52:40 +01:00
case { ' time' , ' freq' , ' ndat' } % Access public members.
2013-09-02 23:33:13 +02:00
if length ( S ) > 1 && isequal ( S ( 2 ) . type , ' ()' ) && isempty ( S ( 2 ) . subs )
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: ' S ( 1 ) . subs ' is not a method but a member!' ] )
2013-09-02 23:33:13 +02:00
end
2011-10-20 15:02:58 +02:00
B = builtin ( ' subsref' , A , S ( 1 ) ) ;
2013-11-04 18:26:45 +01:00
case { ' sort' , ' unique' , ' double' , ' isempty' , ' length' } % Public methods (without arguments)
2013-03-13 23:52:40 +01:00
B = feval ( S ( 1 ) . subs , A ) ;
2013-09-02 23:33:13 +02:00
if length ( S ) > 1 && isequal ( S ( 2 ) . type , ' ()' ) && isempty ( S ( 2 ) . subs )
S = shiftS ( S ) ;
end
2013-03-13 23:52:40 +01:00
case { ' append' , ' pop' } % Public methods (with arguments).
if isequal ( S ( 2 ) . type , ' ()' )
B = feval ( S ( 1 ) . subs , A , S ( 2 ) . subs { : } ) ;
S = shiftS ( S ) ;
2011-10-20 15:02:58 +02:00
else
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Something is wrong in your syntax!' )
2011-10-20 15:02:58 +02:00
end
otherwise
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Unknown public member or method!' )
2011-10-20 15:02:58 +02:00
end
2013-03-13 23:52:40 +01:00
case ' ()'
2013-10-15 15:06:32 +02:00
if isempty ( A )
if isempty ( A . freq )
2013-10-15 15:36:21 +02:00
% Populate an empty dates object with time member (freq is not specified). Needs two or three inputs. First input is an integer
2013-10-15 15:06:32 +02:00
% scalar specifying the frequency. Second input is either the time member (a n*2 array of integers) or a column vector with n
% elements (the first column of the time member --> years). If the the second input is a row vector and if A.freq~=1 a third input
% is necessary. The third input is n*1 vector of integers between 1 and A.freq (second column of the time member --> subperiods).
2013-10-15 15:36:21 +02:00
B = dates ( ) ;
2013-10-15 15:06:32 +02:00
% First input is the frequency.
if isfreq ( S ( 1 ) . subs { 1 } )
if ischar ( S ( 1 ) . subs { 1 } )
B . freq = string2freq ( S ( 1 ) . subs { 1 } ) ;
else
B . freq = S ( 1 ) . subs { 1 } ;
end
else
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: First input must be a frequency!' )
2013-10-15 15:06:32 +02:00
end
if isequal ( length ( S ( 1 ) . subs ) , 2 )
% If two inputs are provided, the second input must be a n*2 array except if frequency is annual.
[ n , m ] = size ( S ( 1 ) . subs { 2 } ) ;
if m > 2
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Second input argument array cannot have more than two columns!' )
2013-10-15 15:06:32 +02:00
end
if ~ isequal ( m , 2 ) && ~ isequal ( B . freq , 1 )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Second argument has to be a n*2 array for non annual frequency!' )
2013-10-15 15:06:32 +02:00
end
if ~ all ( all ( S ( 1 ) . subs { 2 } ) )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Second argument has be an array of intergers!' )
2013-10-15 15:06:32 +02:00
end
if m > 1 && ~ issubperiod ( S ( 1 ) . subs { 2 } ( : , 2 ) , B . freq )
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: Elements in the second column of the first input argument are not legal subperiods (should be integers betwwen 1 and ' num2str ( B . freq ) ' )!' ] )
2013-10-15 15:06:32 +02:00
end
if isequal ( m , 2 )
B . time = S ( 1 ) . subs { 2 } ;
elseif isequal ( m , 1 )
B . time = [ S ( 1 ) . subs { 2 } , ones ( n , 1 ) ] ;
else
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: This is a bug!' ] )
2013-10-15 15:06:32 +02:00
end
B . ndat = rows ( B . time ) ;
elseif isequal ( length ( S ( 1 ) . subs ) , 3 )
% If three inputs are provided, the second and third inputs are column verctors of integers (years and subperiods).
if ~ iscolumn ( S ( 1 ) . subs { 2 } ) && ~ all ( isint ( S ( 1 ) . subs { 2 } ) )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Second input argument must be a column vector of integers!' )
2013-10-15 15:06:32 +02:00
end
n1 = size ( S ( 1 ) . subs { 2 } , 1 ) ;
if ~ iscolumn ( S ( 1 ) . subs { 3 } ) && ~ issubperiod ( S ( 1 ) . subs { 3 } , B . freq )
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: Third input argument must be a column vector of subperiods (integers between 1 and ' num2str ( B . freq ) ' )!' ] )
2013-10-15 15:06:32 +02:00
end
n2 = size ( S ( 1 ) . subs { 3 } , 1 ) ;
if ~ isequal ( n1 , n2 )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Second and third input arguments must have the same number of elements!' )
2013-10-15 15:06:32 +02:00
end
B . time = [ S ( 1 ) . subs { 2 } , S ( 1 ) . subs { 3 } ] ;
B . ndat = rows ( B . time ) ;
else
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Wrong calling sequence!' )
2013-10-15 15:06:32 +02:00
end
else
2013-10-15 15:36:21 +02:00
% Populate an empty dates object with time member (freq is already specified).
2013-10-15 15:06:32 +02:00
% Needs one (time) or two (first and second columns of time for years and subperiods) inputs.
B = A ;
if isequal ( length ( S ( 1 ) . subs ) , 2 )
if ~ iscolumn ( S ( 1 ) . subs { 1 } ) && ~ all ( isint ( S ( 1 ) . subs { 1 } ) )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: First argument has to be a column vector of integers!' )
2013-10-15 15:06:32 +02:00
end
n1 = size ( S ( 1 ) . subs { 1 } , 1 ) ;
if ~ iscolumn ( S ( 1 ) . subs { 2 } ) && ~ issubperiod ( S ( 1 ) . subs { 2 } , B . freq )
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: Second argument has to be a column vector of subperiods (integers between 1 and ' num2str ( B . freq ) ' )!' ] )
2013-10-15 15:06:32 +02:00
end
n2 = size ( S ( 1 ) . subs { 2 } , 1 ) ;
if ~ isequal ( n2 , n1 )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: First and second argument must have the same number of rows!' )
2013-10-15 15:06:32 +02:00
end
B . time = [ S ( 1 ) . subs { 1 } , S ( 1 ) . subs { 2 } ] ;
B . ndat = rows ( B . time ) ;
elseif isequal ( length ( S ( 1 ) . subs ) , 1 )
[ n , m ] = size ( S ( 1 ) . subs { 1 } ) ;
if ~ isequal ( m , 2 ) && ~ isequal ( B . freq , 1 )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: First argument has to be a n*2 array!' )
2013-10-15 15:06:32 +02:00
end
if ~ all ( isint ( S ( 1 ) . subs { 1 } ( : , 1 ) ) )
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: First column of the first argument has to be a column vector of integers!' )
2013-10-15 15:06:32 +02:00
end
if m > 1 && issubperiod ( S ( 1 ) . subs { 1 } ( : , 1 ) , B . freq )
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: The second column of the first input argument has to be a column vector of subperiods (integers between 1 and ' num2str ( B . freq ) ' )!' ] )
2013-10-15 15:06:32 +02:00
end
if isequal ( m , 2 )
B . time = S ( 1 ) . subs { 1 } ;
elseif isequal ( m , 1 ) && isequal ( B . freq , 1 )
B . time = [ S ( 1 ) . subs { 1 } , ones ( n , 1 ) ] ;
else
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: This is a bug!' ] )
2013-10-15 15:06:32 +02:00
end
B . ndat = rows ( B . time ) ;
else
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Wrong number of inputs!' )
2013-10-15 15:06:32 +02:00
end
end
2013-03-13 19:22:18 +01:00
else
2013-10-15 15:36:21 +02:00
% dates object A is not empty. We extract some dates
2013-10-15 15:06:32 +02:00
if isvector ( S ( 1 ) . subs { 1 } ) && all ( isint ( S ( 1 ) . subs { 1 } ) ) && all ( S ( 1 ) . subs { 1 } > 0 ) && all ( S ( 1 ) . subs { 1 } < = A . ndat )
2013-10-15 15:36:21 +02:00
B = dates ( ) ;
2013-10-15 15:06:32 +02:00
B . freq = A . freq ;
B . time = A . time ( S ( 1 ) . subs { 1 } , : ) ;
B . ndat = rows ( B . time ) ;
else
2013-10-15 15:36:21 +02:00
error ( [ ' dates::subsref: indices has to be a vector of positive integers less than or equal to ' int2str ( A . ndat ) ' !' ] )
2013-10-15 15:06:32 +02:00
end
2013-01-13 10:24:16 +01:00
end
2013-03-13 23:52:40 +01:00
otherwise
2013-10-15 15:36:21 +02:00
error ( ' dates::subsref: Something is wrong in your syntax!' )
2013-03-13 22:10:26 +01:00
end
2013-03-13 23:52:40 +01:00
S = shiftS ( S ) ;
if ~ isempty ( S )
B = subsref ( B , S ) ;
end
2013-03-13 22:10:26 +01:00
%@test:1
2013-10-15 15:36:21 +02:00
%$ % Define a dates object
%$ B = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
2013-03-13 22:10:26 +01:00
%$
2013-10-15 15:36:21 +02:00
%$ % Try to extract a sub-dates object.
2013-03-13 22:10:26 +01:00
%$ d = B(2:3);
%$
2013-10-15 15:36:21 +02:00
%$ if isa(d,'dates')
2013-03-13 22:10:26 +01:00
%$ t(1) = 1;
%$ else
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dyn_assert(d.freq,B.freq);
%$ t(3) = dyn_assert(d.time,[1950 2; 1950 3]);
%$ t(4) = dyn_assert(d.ndat,2);
%$ end
%$ T = all(t);
2013-03-13 23:52:40 +01:00
%@eof:1
2013-10-15 15:06:32 +02:00
%@test:2
2013-10-15 15:36:21 +02:00
%$ % Define a dates object
%$ B = dates('1950Q1'):dates('1960Q3');
2013-03-13 23:52:40 +01:00
%$
2013-10-15 15:36:21 +02:00
%$ % Try to extract a sub-dates object and apply a method
2013-03-13 23:52:40 +01:00
%$
%$ d = B(2:3).sort ;
%$
2013-10-15 15:36:21 +02:00
%$ if isa(d,'dates')
2013-03-13 23:52:40 +01:00
%$ t(1) = 1;
%$ else
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dyn_assert(d.freq,B.freq);
%$ t(3) = dyn_assert(d.time,[1950 2; 1950 3]);
%$ t(4) = dyn_assert(d.ndat,2);
%$ end
%$ T = all(t);
2013-10-15 15:06:32 +02:00
%@eof:2
2013-09-02 23:33:13 +02:00
2013-10-15 15:06:32 +02:00
%@test:3
2013-10-15 15:36:21 +02:00
%$ % Define a dates object
%$ B = dates('1950Q1'):dates('1960Q3');
2013-09-02 23:33:13 +02:00
%$
2013-10-15 15:36:21 +02:00
%$ % Try to extract a sub-dates object and apply a method
2013-09-02 23:33:13 +02:00
%$
%$ d = B(2:3).sort() ;
%$
2013-10-15 15:36:21 +02:00
%$ if isa(d,'dates')
2013-09-02 23:33:13 +02:00
%$ t(1) = 1;
%$ else
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dyn_assert(d.freq,B.freq);
%$ t(3) = dyn_assert(d.time,[1950 2; 1950 3]);
%$ t(4) = dyn_assert(d.ndat,2);
%$ end
%$ T = all(t);
2013-10-15 15:06:32 +02:00
%@eof:3
2013-10-11 10:20:08 +02:00
%@test:4
2013-10-15 15:36:21 +02:00
%$ % Define a dates object
%$ B = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
2013-10-11 10:20:08 +02:00
%$
2013-10-15 15:36:21 +02:00
%$ % Try to extract a sub-dates object.
2013-10-11 10:20:08 +02:00
%$ d = B(2);
%$
2013-10-15 15:36:21 +02:00
%$ if isa(d,'dates')
2013-10-11 10:20:08 +02:00
%$ t(1) = 1;
%$ else
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dyn_assert(d.freq,B.freq);
%$ t(3) = dyn_assert(d.time,[1950 2]);
%$ t(4) = dyn_assert(d.ndat,1);
%$ end
%$ T = all(t);
%@eof:4
2013-10-15 15:06:32 +02:00
%@test:5
2013-10-15 15:36:21 +02:00
%$ % Define an empty dates object with quaterly frequency.
%$ qq = dates('Q');
2013-10-15 15:06:32 +02:00
%$
%$ % Define a ranges of dates using qq.
%$ try
%$ r1 = qq(1950,1):qq([1950, 3]);
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$ if t(1)
%$ try
%$ r2 = qq([1950, 1; 1950, 2; 1950, 3]);
%$ t(2) = 1;
%$ catch
%$ t(2) = 0;
%$ end
%$ end
%$ if t(1) && t(2)
%$ try
%$ r3 = qq(1950*ones(3,1), transpose(1:3));
%$ t(3) = 1;
%$ catch
%$ t(3) = 0;
%$ end
%$ end
%$
%$ if t(1) && t(2) && t(3)
%$ t(4) = dyn_assert(isequal(r1,r2),1);
%$ t(5) = dyn_assert(isequal(r1,r3),1);
%$ end
%$ T = all(t);
%@eof:5
%@test:6
2013-10-15 15:36:21 +02:00
%$ % Define an empty dates object with quaterly frequency.
%$ date = dates();
2013-10-15 15:06:32 +02:00
%$
%$ % Define a ranges of dates using qq.
%$ try
%$ r1 = date(4,1950,1):date(4,[1950, 3]);
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$ if t(1)
%$ try
%$ r2 = date(4,[1950, 1; 1950, 2; 1950, 3]);
%$ t(2) = 1;
%$ catch
%$ t(2) = 0;
%$ end
%$ end
%$ if t(1) && t(2)
%$ try
%$ r3 = date(4,1950*ones(3,1), transpose(1:3));
%$ t(3) = 1;
%$ catch
%$ t(3) = 0;
%$ end
%$ end
%$
%$ if t(1) && t(2) && t(3)
%$ t(4) = dyn_assert(isequal(r1,r2),1);
%$ t(5) = dyn_assert(isequal(r1,r3),1);
%$ end
%$ T = all(t);
%@eof:6