1function o = cumprod_(varargin) % --*-- Unitary tests --*-- 2 3% Overloads matlab's cumprod function for dseries objects. 4% 5% INPUTS 6% - o dseries object [mandatory]. 7% - d dates object [optional] 8% - v dseries object with one observation [optional] 9% 10% OUTPUTS 11% - o dseries object. 12 13% Copyright (C) 2014-2017 Dynare Team 14% 15% This file is part of Dynare. 16% 17% Dynare is free software: you can redistribute it and/or modify 18% it under the terms of the GNU General Public License as published by 19% the Free Software Foundation, either version 3 of the License, or 20% (at your option) any later version. 21% 22% Dynare is distributed in the hope that it will be useful, 23% but WITHOUT ANY WARRANTY; without even the implied warranty of 24% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25% GNU General Public License for more details. 26% 27% You should have received a copy of the GNU General Public License 28% along with Dynare. If not, see <http://www.gnu.org/licenses/>. 29 30% Get the firt observation number where all the variables are observed (ie without NaNs) 31idx = find(all(~isnan(varargin{1}.data), 2),1); 32if isempty(idx) 33 idx = 0; 34end 35 36% Is the first period where variables are observed common? 37common_first_period_witout_nan = true; 38if ~idx 39 if any(~isnan(varargin{1}.data(:))) 40 common_first_period_witout_nan = false; 41 end 42else 43 if idx>1 44 if any(any(~isnan(varargin{1}.data(1:idx-1,:)))) 45 common_first_period_witout_nan = false; 46 end 47 end 48end 49 50switch nargin 51 case 1 52 % Initialize the output. 53 o = varargin{1}; 54 % Perform the cumulated sum 55 if isequal(idx, 1) 56 o.data = cumprod(o.data); 57 else 58 if common_first_period_witout_nan 59 o.data(idx:end,:) = cumprod(o.data(idx:end,:)); 60 else 61 o.data = cumprodnan(o.data); 62 end 63 end 64 for i=1:vobs(o) 65 if isempty(o.ops{i}) 66 o.ops(i) = {['cumprod(' o.name{i} ')']}; 67 else 68 o.ops(i) = {['cumprod(' o.ops{i} ')']}; 69 end 70 end 71 case 2 72 if isdseries(varargin{2}) 73 if ~isequal(vobs(varargin{1}), vobs(varargin{2})) 74 error('dseries::cumprod: First and second input arguments must be dseries objects with the same number of variables!') 75 end 76 if ~isequal(varargin{1}.name, varargin{2}.name) 77 warning('dseries::cumprod: First and second input arguments must be dseries objects do not have the same variables!') 78 end 79 if ~isequal(nobs(varargin{2}),1) 80 error('dseries::cumprod: Second input argument must be a dseries object with only one observation!') 81 end 82 o = cumprod_(varargin{1}); 83 o.data = bsxfun(@rdivide, o.data, o.data(1,:)); 84 o.data = bsxfun(@times, o.data, varargin{2}.data); 85 elseif isdates(varargin{2}) 86 o = cumprod_(varargin{1}); 87 t = find(o.dates==varargin{2}); 88 if isempty(t) 89 if varargin{2}==(firstdate(o)-1) 90 return 91 else 92 error(['dseries::cumprod: date ' date2string(varargin{2}) ' is not in the sample!']) 93 end 94 end 95 o.data = bsxfun(@rdivide, o.data, o.data(t,:)); 96 else 97 error('dseries::cumprod: Second input argument must be a dseries object or a dates object!') 98 end 99 case 3 100 if ~isdates(varargin{2}) 101 error('dseries::cumprod: Second input argument must be a dates object!') 102 end 103 if ~isdseries(varargin{3}) 104 error('dseries::cumprod: Third input argument must be a dseries object!') 105 end 106 if ~isequal(vobs(varargin{1}), vobs(varargin{3})) 107 error('dseries::cumprod: First and third input arguments must be dseries objects with the same number of variables!') 108 end 109 if ~isequal(varargin{1}.name, varargin{3}.name) 110 warning('dseries::cumprod: First and third input arguments must be dseries objects do not have the same variables!') 111 end 112 if ~isequal(nobs(varargin{3}),1) 113 error('dseries::cumprod: Third input argument must be a dseries object with only one observation!') 114 end 115 o = cumprod_(varargin{1}); 116 t = find(o.dates==varargin{2}); 117 if isempty(t) 118 if varargin{2}==(firstdate(o)-1) 119 o.data = bsxfun(@times, o.data, varargin{3}.data); 120 return 121 else 122 error(['dseries::cumprod: date ' date2string(varargin{2}) ' is not in the sample!']) 123 end 124 end 125 o.data = bsxfun(@rdivide, o.data, o.data(t,:)); 126 o.data = bsxfun(@times, o.data, varargin{3}.data); 127 otherwise 128 error('dseries::cumprod: Wrong number of input arguments!') 129end 130 131%@test:1 132%$ % Define a data set. 133%$ A = 2*ones(4,1); 134%$ 135%$ % Define names 136%$ A_name = {'A1'}; 137%$ 138%$ % Instantiate a time series object. 139%$ ts = dseries(A,[],A_name,[]); 140%$ 141%$ % Call the tested method. 142%$ try 143%$ ts.cumprod_(); 144%$ t(1) = 1; 145%$ catch 146%$ t(1) = 0; 147%$ end 148%$ 149%$ if t(1) 150%$ t(2) = isequal(ts.data, cumprod(A)); 151%$ t(3) = isequal(ts.name{1}, 'A1'); 152%$ t(4) = isequal(ts.ops{1}, 'cumprod(A1)'); 153%$ end 154%$ 155%$ T = all(t); 156%@eof:1 157 158%@test:2 159%$ % Define a data set. 160%$ A = 2*ones(4,1); 161%$ 162%$ % Define names 163%$ A_name = {'A1'}; 164%$ 165%$ % Instantiate a time series object. 166%$ ts = dseries(A,[],A_name,[]); 167%$ 168%$ % Call the tested method. 169%$ try 170%$ cumprod_(ts); 171%$ t(1) = 1; 172%$ catch 173%$ t(1) = 0; 174%$ end 175%$ 176%$ if t(1) 177%$ t(2) = isequal(ts.data, cumprod(A)); 178%$ t(3) = isequal(ts.name{1},'A1'); 179%$ t(4) = isequal(ts.ops{1}, 'cumprod(A1)'); 180%$ end 181%$ 182%$ T = all(t); 183%@eof:2 184 185 186%@test:3 187%$ % Define a data set. 188%$ A = 2*ones(7,1); 189%$ 190%$ % Define names 191%$ A_name = {'A1'}; 192%$ 193%$ % Instantiate a time series object. 194%$ ts = dseries(A,[],A_name,[]); 195%$ 196%$ % Call the tested method. 197%$ try 198%$ ts.cumprod_(dates('3Y')); 199%$ t(1) = 1; 200%$ catch 201%$ t(1) = 0; 202%$ end 203%$ 204%$ % Expected results. 205%$ ds = dseries([.25; .5; 1; 2; 4; 8; 16], [], A_name, []); 206%$ 207%$ % Check the results. 208%$ t(1) = dassert(ts.data, ds.data); 209%$ T = all(t); 210%@eof:3 211 212%@test:4 213%$ % Define a data set. 214%$ A = 2*ones(7,1); 215%$ 216%$ % Define names 217%$ A_name = {'A1'}; 218%$ 219%$ % Instantiate a time series object. 220%$ ts1 = dseries(A, [], A_name, []); 221%$ ts2 = dseries(pi, [], A_name, []); 222%$ 223%$ % Call the tested method. 224%$ try 225%$ ts3 = ts1.cumprod_(dates('3Y'), ts2); 226%$ t(1) = 1; 227%$ catch 228%$ t(1) = 0; 229%$ end 230%$ 231%$ % Expected results. 232%$ ts4 = dseries([.25; .5; 1; 2; 4; 8; 16]*pi, [], A_name, []); 233%$ 234%$ % Check the results. 235%$ if t(1) 236%$ t(2) = dassert(ts3.data,ts4.data); 237%$ t(3) = dassert(ts1.data,ts4.data); 238%$ end 239%$ T = all(t); 240%@eof:4 241 242%@test:5 243%$ % Define a data set. 244%$ A = 2*ones(7,1); 245%$ 246%$ % Define names 247%$ A_name = {'A1'}; 248%$ 249%$ % Instantiate a time series object. 250%$ ts1 = dseries(A, [], A_name, []); 251%$ ts2 = dseries(pi, [], A_name, []); 252%$ 253%$ % Call the tested method. 254%$ try 255%$ ts3 = ts1.cumprod_(dates('3Y'),ts2); 256%$ t(1) = 1; 257%$ catch 258%$ t(1) = 0; 259%$ end 260%$ 261%$ % Expected results. 262%$ ts4 = dseries([.25; .5; 1; 2; 4; 8; 16]*pi, [], A_name, []); 263%$ 264%$ % Check the results. 265%$ if t(1) 266%$ t(2) = dassert(ts3.data, ts4.data); 267%$ t(3) = dassert(ts1.data, ts4.data); 268%$ end 269%$ T = all(t); 270%@eof:5 271 272%@test:6 273%$ % Define a data set. 274%$ A = [NaN, NaN; 1 NaN; 1 1; 1 1; 1 NaN]; 275%$ 276%$ % Instantiate a time series object. 277%$ ts0 = dseries(A); 278%$ 279%$ % Call the tested method. 280%$ try 281%$ ts0.cumprod_(); 282%$ t(1) = 1; 283%$ catch 284%$ t(1) = 0; 285%$ end 286%$ 287%$ % Check the results. 288%$ if t(1) 289%$ t(2) = dassert(ts0.data, A); 290%$ end 291%$ T = all(t); 292%@eof:6