1function r = subsref(o, S) % --*-- Unitary tests --*-- 2 3% Overloads the subsref method for dseries class. 4% 5% INPUTS 6% - o [dseries] Time series object instantiated by dseries. 7% - S [struct] Matlab's structure array S with two fields, type and subs. The type field is 8% a string containing '()', '{}', or '.', where '()' specifies integer 9% subscripts, '{}' specifies cell array subscripts, and '.' specifies 10% subscripted structure fields. The subs field is a cell array or a string 11% containing the actual subscripts (see matlab's documentation). 12% 13% OUTPUTS 14% - r [dseries] Depending on the calling sequence `r` is a transformation of `o` obtained 15% by applying a public method on `o`, or a dseries object built by extracting 16% a variable from `o`, or a dseries object containing a subsample. 17 18% Copyright (C) 2011-2019 Dynare Team 19% 20% This file is part of Dynare. 21% 22% Dynare is free software: you can redistribute it and/or modify 23% it under the terms of the GNU General Public License as published by 24% the Free Software Foundation, either version 3 of the License, or 25% (at your option) any later version. 26% 27% Dynare is distributed in the hope that it will be useful, 28% but WITHOUT ANY WARRANTY; without even the implied warranty of 29% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30% GNU General Public License for more details. 31% 32% You should have received a copy of the GNU General Public License 33% along with Dynare. If not, see <http://www.gnu.org/licenses/>. 34 35switch S(1).type 36 case '.' 37 switch S(1).subs 38 case {'data','name','tex','dates','ops', 'tags'} % Public members. 39 if length(S)>1 && isequal(S(2).type,'()') && isempty(S(2).subs) 40 error(['dseries::subsref: ' S(1).subs ' is not a method but a member!']) 41 end 42 r = builtin('subsref', o, S(1)); 43 case 'nobs' 44 % Returns the number of observations. 45 r = rows(o.data); 46 case 'vobs' 47 % Returns the number of variables. 48 r = columns(o.data); 49 case 'init' 50 % Returns a dates object (first date). 51 r = o.dates(1); 52 case 'last' 53 % Returns a dates object (last date). 54 r = o.dates(end); 55 case 'freq' 56 % Returns an integer characterizing the data frequency (1, 4, 12 or 52) 57 r = o.dates.freq; 58 case 'length' 59 error(['dseries::subsref: we do not support the length operator on ' ... 60 'dseries. Please use ''nobs'' or ''vobs''']); 61 case 'save' 62 % Save dseries object on disk (default is a mat file). 63 r = NaN; 64 if isequal(length(S),2) 65 if strcmp(S(2).type,'()') 66 if isempty(S(2).subs) 67 save(o); 68 else 69 if isempty(S(2).subs{1}) 70 save(o,'',S(2).subs{2}); 71 else 72 save(o,S(2).subs{:}); 73 end 74 end 75 S = shiftS(S,1); 76 else 77 error('dseries::subsref: Wrong syntax.') 78 end 79 elseif isequal(length(S),1) 80 save(o); 81 else 82 error('dseries::subsref: Call to save method must come in last position!') 83 end 84 case 'struct' 85 r = dseries2struct(o); 86 case 'initialize' 87 r = NaN; 88 initialize(o); 89 case {'baxter_king_filter', 'baxter_king_filter_', ... 90 'cumsum','cumsum_', ... 91 'insert', ... 92 'pop','pop_', ... 93 'cumprod','cumprod_', ... 94 'remove','remove_', ... 95 'onesidedhptrend','onesidedhptrend_', ... 96 'onesidedhpcycle','onesidedhpcycle_', ... 97 'lag','lag_', ... 98 'lead','lead_', ... 99 'hptrend','hptrend_', ... 100 'hpcycle','hpcycle_', ... 101 'chain','chain_', ... 102 'backcast','backcast_', ... 103 'detrend','detrend_', ... 104 'exist', ... 105 'mean', ... 106 'nanmean', ... 107 'std', ... 108 'center','center_', ... 109 'log','log_', ... 110 'exp','exp_', ... 111 'ygrowth','ygrowth_', ... 112 'qgrowth','qgrowth_', ... 113 'mgrowth','mgrowth_', ... 114 'ydiff','ydiff_', ... 115 'qdiff','qdiff_', ... 116 'diff', 'diff_', ... 117 'mdiff','mdiff_', ... 118 'abs','abs_', ... 119 'isnan', ... 120 'isinf', ... 121 'isreal', ... 122 'firstdate', ... 123 'lastdate', ... 124 'firstobservedperiod', ... 125 'lastobservedperiod', ... 126 'lineartrend', ... 127 'resetops', 'resettags', ... 128 'subsample'} 129 if length(S)>1 && isequal(S(2).type,'()') 130 if isempty(S(2).subs) 131 r = feval(S(1).subs,o); 132 S = shiftS(S,1); 133 else 134 r = feval(S(1).subs,o,S(2).subs{:}); 135 S = shiftS(S,1); 136 end 137 else 138 r = feval(S(1).subs,o); 139 end 140 case 'size' 141 if isequal(length(S),2) && strcmp(S(2).type,'()') 142 if isempty(S(2).subs) 143 [x,y] = size(o); 144 r = [x, y]; 145 else 146 r = size(o,S(2).subs{1}); 147 end 148 S = shiftS(S,1); 149 elseif isequal(length(S),1) 150 [x,y] = size(o); 151 r = [x, y]; 152 else 153 error('dseries::subsref: Call to size method must come in last position!') 154 end 155 case {'set_names','rename','rename_','tex_rename','tex_rename_', 'tag'} 156 r = feval(S(1).subs,o,S(2).subs{:}); 157 S = shiftS(S,1); 158 case {'disp'} 159 feval(S(1).subs,o); 160 return 161 otherwise % Extract a sub-object by selecting one variable. 162 ndx = find(strcmp(S(1).subs,o.name)); 163 if ~isempty(ndx) 164 r = dseries(); 165 r.data = o.data(:,ndx); 166 r.name = o.name(ndx); 167 r.tex = o.tex(ndx); 168 r.dates = o.dates; 169 r.ops = o.ops(ndx); 170 tagnames = fieldnames(o.tags); 171 for i=1:length(tagnames) 172 r.tags.(tagnames{i}) = o.tags.(tagnames{i})(ndx); 173 end 174 else 175 error('dseries::subsref: Unknown public method, public member or variable!') 176 end 177 end 178 case '()' 179 if ischar(S(1).subs{1}) && ~isdate(S(1).subs{1}) 180 % If ts is an empty dseries object, populate this object by reading data in a file. 181 if isempty(o) 182 if exist(S(1).subs{1}, 'file') 183 r = dseries(S(1).subs{1}); 184 else 185 error('dseries::subsref: Cannot find file %s', S(1).subs{1}) 186 end 187 else 188 error('dseries::subsref: dseries object is not empty!') 189 end 190 elseif isscalar(S(1).subs{1}) && isint(S(1).subs{1}) 191 % Input is also interpreted as a backward/forward operator 192 if S(1).subs{1}>0 193 r = lead(o, S(1).subs{1}); 194 elseif S(1).subs{1}<0 195 r = lag(o, -S(1).subs{1}); 196 else 197 % Do nothing. 198 r = o; 199 end 200 elseif isdates(S(1).subs{1}) || isdate(S(1).subs{1}) 201 % Select observation(s) with date(s) 202 if isdate(S(1).subs{1}) 203 Dates = dates(S(1).subs{1}); 204 else 205 Dates = S(1).subs{1}; 206 end 207 % Test if Dates is out of bounds 208 if min(Dates)<min(o.dates) 209 error(['dseries::subsref: Indices are out of bounds! Subsample cannot start before ' date2string(o.dates(1)) '.']) 210 end 211 if max(Dates)>max(o.dates) 212 error(['dseries::subsref: Indices are out of bounds! Subsample cannot end after ' date2string(o.dates(end)) '.']) 213 end 214 % Extract a subsample using a dates object 215 [~,tdx] = intersect(o.dates.time,Dates.time,'rows'); 216 r = copy(o); 217 r.data = r.data(tdx,:); 218 r.dates = r.dates(tdx); 219 elseif isnumeric(S(1).subs{1}) && isequal(ndims(S(1).subs{1}), 2) 220 if isempty(o) 221 % Populate an empty dseries object. 222 if isempty(o.dates) 223 r = copy(o); 224 r.dates = dates('1Y'):dates('1Y')+(rows(S(1).subs{1})-1); 225 r.data = S(1).subs{1}; 226 r.name = default_name(columns(r.data)); 227 r.tex = name2tex(r.name); 228 r.ops = cell(length(r.name), 1); 229 else 230 r = copy(o); 231 r.dates = r.dates:r.dates+(rows(S(1).subs{1})-1); 232 r.data = S(1).subs{1}; 233 r.name = default_name(columns(r.data)); 234 r.tex = name2tex(r.name); 235 r.ops = cell(length(r.name), 1); 236 end 237 else 238 error('dseries::subsref: It is not possible to populate a non empty dseries object!'); 239 end 240 else 241 error('dseries::subsref: I have no idea of what you are trying to do!') 242 end 243 case '{}' 244 if iscellofchar(S(1).subs) 245 r = extract(o,S(1).subs{:}); 246 elseif isequal(length(S(1).subs),1) && all(isint(S(1).subs{1})) 247 idx = S(1).subs{1}; 248 if max(idx)>size(o.data,2) || min(idx)<1 249 error('dseries::subsref: Indices are out of bounds!') 250 end 251 r = dseries(); 252 r.data = o.data(:,idx); 253 r.name = o.name(idx); 254 r.tex = o.tex(idx); 255 r.dates = o.dates; 256 r.ops = o.ops(idx); 257 tagnames = fieldnames(o.tags); 258 for i=1:length(tagnames) 259 r.tags.(tagnames{i}) = o.tags.(tagnames{i})(idx); 260 end 261 else 262 error('dseries::subsref: What the Hell are you tryin'' to do?!') 263 end 264 otherwise 265 error('dseries::subsref: What the Hell are you doin'' here?!') 266end 267 268S = shiftS(S,1); 269if ~isempty(S) 270 r = subsref(r, S); 271end 272 273return 274 275%@test:1 276 % Define a data set. 277 A = [transpose(1:10),2*transpose(1:10)]; 278 279 % Define names 280 A_name = {'A1';'A2'}; 281 282 % Instantiate a time series object. 283 ts1 = dseries(A,[],A_name,[]); 284 285 % Call the tested method. 286 a = ts1(ts1.dates(2:9)); 287 288 % Expected results. 289 e.data = [transpose(2:9),2*transpose(2:9)]; 290 e.nobs = 8; 291 e.vobs = 2; 292 e.name = {'A1';'A2'}; 293 e.freq = 1; 294 e.init = dates(1,2); 295 296 % Check the results. 297 t(1) = dassert(a.data,e.data); 298 t(2) = dassert(a.nobs,e.nobs); 299 t(3) = dassert(a.vobs,e.vobs); 300 t(4) = dassert(a.freq,e.freq); 301 t(5) = dassert(a.init,e.init); 302 T = all(t); 303%@eof:1 304 305%@test:2 306 % Define a data set. 307 A = [transpose(1:10),2*transpose(1:10)]; 308 309 % Define names 310 A_name = {'A1';'A2'}; 311 312 % Instantiate a time series object. 313 ts1 = dseries(A,[],A_name,[]); 314 315 % Call the tested method. 316 a = ts1.A1; 317 318 % Expected results. 319 e.data = transpose(1:10); 320 e.nobs = 10; 321 e.vobs = 1; 322 e.name = {'A1'}; 323 e.freq = 1; 324 e.init = dates(1,1); 325 326 % Check the results. 327 t(1) = dassert(a.data,e.data); 328 t(2) = dassert(a.init,e.init); 329 t(3) = dassert(a.nobs,e.nobs); 330 t(4) = dassert(a.vobs,e.vobs); 331 t(5) = dassert(a.freq,e.freq); 332 T = all(t); 333%@eof:2 334 335%@test:3 336 % Define a data set. 337 A = [transpose(1:10),2*transpose(1:10)]; 338 339 % Define names 340 A_name = {'A1';'A2'}; 341 342 % Instantiate a time series object. 343 ts1 = dseries(A,[],A_name,[]); 344 345 % Call the tested method. 346 a = ts1.log; 347 348 % Expected results. 349 e.data = log(A); 350 e.nobs = 10; 351 e.vobs = 2; 352 e.name = {'A1';'A2'}; 353 e.freq = 1; 354 e.init = dates(1,1); 355 356 % Check the results. 357 t(1) = dassert(a.data,e.data); 358 t(2) = dassert(a.nobs,e.nobs); 359 t(3) = dassert(a.vobs,e.vobs); 360 t(4) = dassert(a.freq,e.freq); 361 t(5) = dassert(a.init,e.init); 362 T = all(t); 363%@eof:3 364 365%@test:4 366 % Create an empty dseries object. 367 dataset = dseries(); 368 369 t = zeros(5,1); 370 371 try 372 dseries_src_root = strrep(which('initialize_dseries_class'),'initialize_dseries_class.m',''); 373 A = dseries([ dseries_src_root '../tests/data/dynseries_test_data.csv' ]); 374 t(1) = 1; 375 catch 376 t = 0; 377 end 378 379 % Check the results. 380 if length(t)>1 381 t(2) = dassert(A.nobs,4); 382 t(3) = dassert(A.vobs,4); 383 t(4) = dassert(A.freq,4); 384 t(5) = dassert(A.init,dates('1990Q1')); 385 end 386 T = all(t); 387%@eof:4 388 389%@test:5 390 % Define a data set. 391 A = [transpose(1:10),2*transpose(1:10),3*transpose(1:10)]; 392 393 % Define names 394 A_name = {'A1';'A2';'B1'}; 395 396 % Instantiate a time series object. 397 ts1 = dseries(A,[],A_name,[]); 398 399 % Call the tested method. 400 a = ts1{'A1','B1'}; 401 402 % Expected results. 403 e.data = A(:,[1,3]); 404 e.nobs = 10; 405 e.vobs = 2; 406 e.name = {'A1';'B1'}; 407 e.freq = 1; 408 e.init = dates(1,1); 409 410 t(1) = dassert(e.data,a.data); 411 t(2) = dassert(e.nobs,a.nobs); 412 t(3) = dassert(e.vobs,a.vobs); 413 t(4) = dassert(e.name,a.name); 414 t(5) = dassert(e.init,a.init); 415 T = all(t); 416%@eof:5 417 418%@test:6 419 % Define a data set. 420 A = rand(10,24); 421 422 % Define names 423 A_name = {'GDP_1';'GDP_2';'GDP_3'; 'GDP_4'; 'GDP_5'; 'GDP_6'; 'GDP_7'; 'GDP_8'; 'GDP_9'; 'GDP_10'; 'GDP_11'; 'GDP_12'; 'HICP_1';'HICP_2';'HICP_3'; 'HICP_4'; 'HICP_5'; 'HICP_6'; 'HICP_7'; 'HICP_8'; 'HICP_9'; 'HICP_10'; 'HICP_11'; 'HICP_12';}; 424 425 % Instantiate a time series object. 426 ts1 = dseries(A,[],A_name,[]); 427 428 % Call the tested method. 429 try 430 a = ts1{'[GDP_[0-9]]'}; 431 t(1) = 1; 432 catch 433 t(1) = 0; 434 end 435 try 436 b = ts1{'[[A-Z]*_1]'}; 437 t(2) = 1; 438 catch 439 t(2) = 0; 440 end 441 try 442 warning off all 443 c = ts1{'[A-Z]_1'}; 444 warning on all 445 t(3) = 0; 446 catch 447 t(3) = 1; 448 end 449 450 % Expected results. 451 e1.data = A(:,1:9); 452 e1.nobs = 10; 453 e1.vobs = 9; 454 e1.name = {'GDP_1';'GDP_2';'GDP_3'; 'GDP_4'; 'GDP_5'; 'GDP_6'; 'GDP_7'; 'GDP_8'; 'GDP_9'}; 455 e1.freq = 1; 456 e1.init = dates(1,1); 457 e2.data = A(:,[1 13]); 458 e2.nobs = 10; 459 e2.vobs = 2; 460 e2.name = {'GDP_1';'HICP_1'}; 461 e2.freq = 1; 462 e2.init = dates(1,1); 463 464 % Check results. 465 t(4) = dassert(e1.data,a.data); 466 t(5) = dassert(e1.nobs,a.nobs); 467 t(6) = dassert(e1.vobs,a.vobs); 468 t(7) = dassert(e1.name,a.name); 469 t(8) = dassert(e1.init,a.init); 470 t(9) = dassert(e2.data,b.data); 471 t(10) = dassert(e2.nobs,b.nobs); 472 t(11) = dassert(e2.vobs,b.vobs); 473 t(12) = dassert(e2.name,b.name); 474 t(13) = dassert(e2.init,b.init); 475 T = all(t); 476%@eof:6 477 478%@test:7 479 % Define a data set. 480 A = [transpose(1:10),2*transpose(1:10)]; 481 482 % Define names 483 A_name = {'A1';'A2'}; 484 485 % Instantiate a time series object. 486 try 487 ts1 = dseries(A,[],A_name,[]); 488 ts1.save('ts1'); 489 t = 1; 490 catch 491 t = 0; 492 end 493 494 delete('ts1.mat'); 495 496 T = all(t); 497%@eof:7 498 499%@test:8 500 % Define a data set. 501 A = [transpose(1:10),2*transpose(1:10)]; 502 503 % Define names 504 A_name = {'A1';'A2'}; 505 506 % Instantiate a time series object. 507 try 508 ts1 = dseries(A,[],A_name,[]); 509 ts1.save('test_generated_data_file','m'); 510 delete('test_generated_data_file.m'); 511 t = 1; 512 catch 513 t = 0; 514 end 515 516 T = all(t); 517%@eof:8 518 519%@test:9 520 % Define a data set. 521 A = [transpose(1:60),2*transpose(1:60),3*transpose(1:60)]; 522 523 % Define names 524 A_name = {'A1';'A2';'B1'}; 525 526 % Instantiate a time series object. 527 ts1 = dseries(A,'1971Q1',A_name,[]); 528 529 % Define the range of a subsample. 530 range = dates('1971Q2'):dates('1971Q4'); 531 % Call the tested method. 532 a = ts1(range); 533 534 % Expected results. 535 e.data = A(2:4,:); 536 e.nobs = 3; 537 e.vobs = 3; 538 e.name = {'A1';'A2';'B1'}; 539 e.freq = 4; 540 e.init = dates('1971Q2'); 541 542 t(1) = dassert(e.data,a.data); 543 t(2) = dassert(e.nobs,a.nobs); 544 t(3) = dassert(e.vobs,a.vobs); 545 t(4) = dassert(e.name,a.name); 546 t(5) = dassert(e.init,a.init); 547 T = all(t); 548%@eof:9 549 550%@test:10 551 % Define a data set. 552 A = [transpose(1:60),2*transpose(1:60),3*transpose(1:60)]; 553 554 % Define names 555 A_name = {'A1';'A2';'B1'}; 556 557 % Instantiate a time series object. 558 ts1 = dseries(A,'1971Q1',A_name,[]); 559 560 % Test the size method. 561 B = ts1.size(); 562 C = ts1.size(1); 563 D = ts1.size(2); 564 E = ts1.size; 565 566 t(1) = dassert(B,[60, 3]); 567 t(2) = dassert(E,[60, 3]); 568 t(3) = dassert(C,60); 569 t(4) = dassert(D,3); 570 T = all(t); 571%@eof:10 572 573%@test:11 574 % Define a data set. 575 A = [transpose(1:60),2*transpose(1:60),3*transpose(1:60)]; 576 577 % Define names 578 A_name = {'A1';'A2';'B1'}; 579 580 % Instantiate a time series object. 581 ts1 = dseries(A,'1971Q1',A_name,[]); 582 583 % Test the size method. 584 B = ts1{1}; 585 C = ts1{[1,3]}; 586 D = ts1{'A1'}; 587 588 t(1) = dassert(B.name{1},'A1'); 589 t(2) = dassert(B.data,A(:,1)); 590 t(3) = dassert(C.name{1},'A1'); 591 t(4) = dassert(C.data(:,1),A(:,1)); 592 t(5) = dassert(C.name{2},'B1'); 593 t(6) = dassert(C.data(:,2),A(:,3)); 594 t(7) = dassert(D.name{1},'A1'); 595 t(8) = dassert(D.data,A(:,1)); 596 T = all(t); 597%@eof:11 598 599%@test:12 600 % Define a data set. 601 A = [transpose(1:10),2*transpose(1:10)]; 602 603 % Define names 604 A_name = {'A1';'A2'}; 605 606 % Instantiate a time series object. 607 try 608 ts1 = dseries(A,[],A_name,[]); 609 ts1.save(); 610 t = 1; 611 catch 612 t = 0; 613 end 614 615 delete('dynare_series.mat') 616 617 T = all(t); 618%@eof:12 619 620%@test:13 621 try 622 data = transpose(0:1:50); 623 ts = dseries(data,'1950Q1'); 624 a = ts.lag; 625 b = ts.lead; 626 c = ts(-1); 627 d = ts(1); 628 t(1) = 1; 629 catch 630 t(1) = 0; 631 end 632 633 if t(1)>1 634 t(2) = (a==c); 635 t(3) = (b==d); 636 end 637 638 T = all(t); 639%@eof:13 640 641%@test:14 642 try 643 ds = dseries(transpose(1:5)); 644 ts = ds(ds.dates(2:3)); 645 t(1) = 1; 646 catch 647 t(1) = 0; 648 end 649 650 if t(1)>1 651 t(2) = isdseries(ts); 652 t(3) = isequal(ts.data,ds.data(2:3)); 653 end 654 655 T = all(t); 656%@eof:14 657 658%@test:15 659 try 660 ds = dseries(transpose(1:5)); 661 ts = ds(ds.dates(2:6)); 662 t(1) = 0; 663 catch 664 t(1) = 1; 665 end 666 667 T = all(t); 668%@eof:15 669 670%@test:16 671 try 672 ds = dseries(transpose(1:5)); 673 ts = ds(dates('1Y'):dates('6Y')); 674 t(1) = 0; 675 catch 676 t(1) = 1; 677 end 678 679 T = all(t); 680%@eof:16 681 682%@test:17 683 try 684 ds = dseries(transpose(1:5)); 685 ts = ds(dates('-2Y'):dates('4Y')); 686 t(1) = 0; 687 catch 688 t(1) = 1; 689 end 690 691 T = all(t); 692%@eof:17 693 694%@test:18 695 try 696 tseries = dseries(); 697 ts = tseries(ones(10,1)); 698 t(1) = true; 699 catch 700 t(1) = false; 701 end 702 703 if t(1) 704 t(2) = ts.dates(1)==dates('1Y'); 705 t(3) = ts.dates(10)==dates('10Y'); 706 end 707 708 T = all(t); 709%@eof:18 710 711%@test:19 712 try 713 tseries = dseries(dates('2000Q1')); 714 ts = tseries(ones(5,1)); 715 t(1) = true; 716 catch 717 t(1) = false; 718 end 719 720 if t(1) 721 t(2) = ts.dates(1)==dates('2000Q1'); 722 t(3) = ts.dates(5)==dates('2001Q1'); 723 end 724 725 T = all(t); 726%@eof:19 727