subsref.m 7.89 KB
Newer Older
Stéphane Adjemian's avatar
Stéphane Adjemian committed
1
2
3
4
function B = subsref(A,S)

%@info:
%! @deftypefn {Function File} {@var{us} =} subsref (@var{ts},S)
5
%! @anchor{@dynDate/subsref}
Stéphane Adjemian's avatar
Stéphane Adjemian committed
6
%! @sp 1
7
%! Overloads the subsref method for the Dynare dates class (@ref{dynDate}).
Stéphane Adjemian's avatar
Stéphane Adjemian committed
8
9
10
11
12
%! @sp 2
%! @strong{Inputs}
%! @sp 1
%! @table @ @var
%! @item A
13
%! Dynare date object instantiated by @ref{dynDate}.
Stéphane Adjemian's avatar
Stéphane Adjemian committed
14
15
16
17
18
19
20
21
22
23
%! @item S
%! Matlab's structure array S with two fields, type and subs. The type field is string containing '()', '@{@}', or '.', where '()' specifies
%! integer subscripts, '@{@}' specifies cell array subscripts, and '.' specifies subscripted structure fields. The subs field is a cell array
%! or a string containing the actual subscripts (see matlab's documentation).
%! @end table
%! @sp 1
%! @strong{Outputs}
%! @sp 1
%! @table @ @var
%! @item B
24
%! A matlab object (public member of the @ref{dynDate} object).
Stéphane Adjemian's avatar
Stéphane Adjemian committed
25
26
27
28
29
30
31
32
33
34
%! @end table
%! @sp 2
%! @strong{This function is called by:}
%! @sp 2
%! @strong{This function calls:}
%! @sp2
%!
%! @end deftypefn
%@eod:

Sébastien Villemot's avatar
Sébastien Villemot committed
35
% Copyright (C) 2011-2013 Dynare Team
Stéphane Adjemian's avatar
Stéphane Adjemian committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
%
% 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/>.

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
switch S(1).type
  case '.'
    switch S(1).subs
      case 'format'
        B = format(A);
      case {'time', 'freq'}
        B = builtin('subsref', A, S(1));
      otherwise
        error('dynDate::subsref: Unknown public member of method!')
    end
  case '()'
    switch length(S(1).subs)
      case 1
        if ischar(S(1).subs{1})
            if numel(S(1).subs{1})==1 && isempty(strmatch(S(1).subs{1},{'W','M','Q','Y'},'exact'))
                error(['dynDate::subsref: To set the frequency, the input argument of dynDate object ''' inputname(1) ''' should be ''W'', ''M'', ''Q'' or ''Y''.'])
68
            end
69
70
71
72
73
74
75
            % Set the frequency (if numel==1) of an empty dynDate object or set the date (if numel>1).
            B = dynDate(S(1).subs{1});
        elseif isnumeric(S(1).subs{1}) && isscalar(S(1).subs{1}) && isint(S(1).subs{1})
            if (~isnan(A.freq) && A.freq==1) || isnan(A.freq)
                B = dynDate(S(1).subs{1});
            else
                error(['dynDate::subsref: dynDate object ''' inputname(1) ''' was not instantiated for years.'])
76
            end
77
78
        else
            error('dynDate::subsref: Something is wrong in your syntax!')
79
        end
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
      case 2% Populate an empty dynDate object
        if isnan(A.freq)
            error(['dynDate::subsref: I cannot interpret the two inputs of dynDate object ''' inputname(1) ''' because frequency is not set.'])
        else
            tmp = [];
            switch A.freq
              case 4
                % Quaterly data
                if isint(S(1).subs{2}) && isint(S(1).subs{1}) && S(1).subs{2}<5 && S(1).subs{2}>0
                    tmp = [int2str(S(1).subs{1}), 'Q' int2str(S(1).subs{2})];
                else
                    if ~isint(S(1).subs{2}) || ~(S(1).subs{2}<5 && S(1).subs{2}>0)
                        error(['dynDate::subsref: The second input argument of dynDate object ''' inputname(1) ''' (' num2str(S(1).subs{2})  ') should be a positive integer less than or equal to 4.'])
                    end
                    if ~isint(S(1).subs{2})
                        error(['dynDate::subsref: The first input argument of dynDate object ''' inputname(1) ''' (' num2str(S(1).subs{1})  ') should be an integer.'])
                    end
                end
              case 12
                % Monthly data
                if isint(S(1).subs{2}) && isint(S(1).subs{1}) && S(1).subs{2}<13 && S(1).subs{2}>0
                    tmp = [num2str(S(1).subs{1}), 'M' num2str(S(1).subs{2})];
                else
                    if ~isint(S(1).subs{2}) || ~(S(1).subs{2}<13 && S(1).subs{2}>0)
                        error(['dynDate::subsref: The second input argument of dynDate object ''' inputname(1) ''' (' num2str(S(1).subs{2})  ') should be a positive integer less than or equal to 12.'])
                    end
                    if ~isint(S(1).subs{2})
                        error(['dynDate::subsref: The first input argument of dynDate object ''' inputname(1) ''' (' num2str(S(1).subs{1})  ') should be an integer.'])
                    end
                end
              case 52
                % Weekly data
                if isint(S(1).subs{2}) && isint(S(1).subs{1}) && S(1).subs{2}<53 && S(1).subs{2}>0
                    tmp = [num2str(S(1).subs{1}), 'W' num2str(S(1).subs{2})];
                else
                    if ~isint(S(1).subs{2}) || ~(S(1).subs{2}<53 && S(1).subs{2}>0)
                        error(['dynDate::subsref: The second input argument of dynDate object ''' inputname(1) ''' (' num2str(S(1).subs{2})  ') should be a positive integer less than or equal to 52.'])
                    end
                    if ~isint(S(1).subs{2})
                        error(['dynDate::subsref: The first input argument of dynDate object ''' inputname(1) ''' (' num2str(S(1).subs{1})  ') should be an integer.'])
                    end                    
                end
              case 1
                % Yearly data
                error('dynDate::subsref: Frequency is set for years. You should not provide more than one integer input argument (to set the year)!')
              otherwise
                error('dynDate::subsref: Unknown frequency!')
            end
            if ~isempty(tmp)
                B = dynDate(tmp);
            end
131
        end
132
133
      otherwise
        error(['dynDate::subsref: dynDate object ''' inputname(1) ''' cannot have more than two inputs.'])
134
    end
135
136
  otherwise
    error('dynDate::subsref: Something is wrong in your syntax!')
137
138
end

139
140
141
S = shiftS(S);
if ~isempty(S)
    B = subsref(B, S);
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
end

%@test:1
%$ t = zeros(3,1);
%$
%$ % Instantiate an empty dynDate object
%$ a = dynDate();
%$ if all(isnan(a.time)) && isnan(a.freq)
%$     t(1) = 1;
%$ end
%$
%$ % Populate the empty dynDate object
%$ try
%$     a = a('1950Q1');
%$     if isequal(a.time,[1950 1]) && isequal(a.freq,4)
%$         t(2) = 1;
%$     end
%$ catch
%$     % Nothing to do here...
%$ end
%$
%$ % "Overwrite" a dynDate object
%$ try
%$     a = a('1945Q3');
%$     if isequal(a.time,[1945 3]) && isequal(a.freq,4)
%$         t(3) = 1;
%$     end
%$ catch
%$     % Nothing to do here...
%$ end
%$
%$ % Check the results.
%$ T = all(t);
%@eof:1

%@test:2
%$ % Instantiate a dynDate object
%$ a = dynDate('1938Q4');
%$
%$ % Try to access a non existent (or forbidden) property
%$ try
%$     a.Time;
%$     t = 0;
%$ catch
%$     t = 1;
%$ end
%$
%$ T = all(t);
%@eof:2

192
193
%@test:3
%$ % Try more complex call to overloaded subsref
194
%$ t = zeros(3,1);
195
%$ try
196
%$     a = dynDate('M');
197
198
%$     time = a('1973M1').time;
%$     t(1) = 1;
199
200
%$     t(2) = dyn_assert(time,[1973,1]);
%$     t(3) = dyn_assert(a.freq,12);
201
202
203
204
205
%$ catch
%$     % Nothing to do here.
%$ end
%$
%$ T = all(t);
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
%@eof:3

%@test:4
%$ t = NaN(3,1);
%$ % Instantiate an empty object for quaterly date
%$ qq = dynDate('Q');
%$ % Populate this object
%$ a = qq(1938,4);
%$ try
%$    a = dynDate(1938,11);
%$    t(3) = 0;
%$ catch
%$    t(3) = 1;
%$ end
%$
%$ % Check the results
%$ t(1) = dyn_assert(a.freq,4);
%$ t(2) = dyn_assert(a.time,[1938,4]);
%$ T = all(t);
225
226
227
228
229
230
231
232
233
234
235
236
237
%@eof:4

%@test:5
%$ t = NaN(2,1);
%$ % Instantiate an empty object for quaterly date
%$ qq = dynDate('Q');
%$ % Populate this object and get the time member
%$ time = qq(1938,4).time;
%$ 
%$ % Check the results
%$ t(1) = dyn_assert(qq.freq,4);
%$ t(2) = dyn_assert(time,[1938,4]);
%$ T = all(t);
Sébastien Villemot's avatar
Sébastien Villemot committed
238
%@eof:5