1function q = plus(o, p) % --*-- Unitary tests --*--
2
3% Overloads the plus (+) operator for dseries objects.
4%
5% INPUTS
6% - o [dseries, real]
7% - p [dseries, real]
8%
9% OUTPUTS
10% - q [dseries]
11
12% Copyright (C) 2011-2017 Dynare Team
13%
14% This file is part of Dynare.
15%
16% Dynare is free software: you can redistribute it and/or modify
17% it under the terms of the GNU General Public License as published by
18% the Free Software Foundation, either version 3 of the License, or
19% (at your option) any later version.
20%
21% Dynare is distributed in the hope that it will be useful,
22% but WITHOUT ANY WARRANTY; without even the implied warranty of
23% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24% GNU General Public License for more details.
25%
26% You should have received a copy of the GNU General Public License
27% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
28
29if isnumeric(o) && (isscalar(o) ||  isvector(o))
30    if ~isdseries(p)
31        error('dseries::plus: Second input argument must be a dseries object!')
32    end
33    q = copy(p);
34    q.data = bsxfun(@plus, o, p.data);
35    for i=1:vobs(q)
36        if isscalar(o)
37            if isempty(p.ops{i})
38                q.ops(i) = {sprintf('plus(%s, %s)', num2str(o), p.name{i})};
39            else
40                q.ops(i) = {sprintf('plus(%s, %s)', num2str(o), p.ops{i})};
41            end
42        elseif isrow(o)
43            if isempty(p.ops{i})
44                q.ops(i) = {sprintf('plus(%s, %s)', num2str(o(i)), p.name{i})};
45            else
46                q.ops(i) = {sprintf('plus(%s, %s)', num2str(o(i)), p.ops{i})};
47            end
48        else
49            if isempty(p.ops{i})
50                q.ops(i) = {sprintf('plus(%s, %s)', matrix2string(o), p.name{i})};
51            else
52                q.ops(i) = {sprintf('plus(%s, %s)', matrix2string(o), p.ops{i})};
53            end
54        end
55    end
56    return
57end
58
59if isnumeric(p) && (isscalar(p) || isvector(p))
60    if ~isdseries(o)
61        error('dseries::plus: First input argument must be a dseries object!')
62    end
63    q = copy(o);
64    q.data = bsxfun(@plus,o.data,p);
65    for i=1:vobs(q)
66        if isscalar(p)
67            if isempty(q.ops{i})
68                q.ops(i) = {sprintf('plus(%s, %s)', q.name{i}, num2str(p))};
69            else
70                q.ops(i) = {sprintf('plus(%s, %s)', q.ops{i}, num2str(p))};
71            end
72        elseif isrow(p)
73            if isempty(q.ops{i})
74                q.ops(i) = {sprintf('plus(%s, %s)', q.name{i}, num2str(p(i)))};
75            else
76                q.ops(i) = {sprintf('plus(%s, %s)', q.ops{i}, num2str(p(i)))};
77            end
78        else
79            if isempty(q.ops{i})
80                q.ops(i) = {sprintf('plus(%s, %s)', q.name{i}, matrix2string(p))};
81            else
82                q.ops(i) = {sprintf('plus(%s, %s)', q.ops{i}, matrix2string(p))};
83            end
84        end
85    end
86    return
87end
88
89if isdseries(o) && isdseries(p)
90    if isempty(o)
91        q = copy(p);
92        return
93    end
94    if isempty(p)
95        q = copy(o);
96        return
97    end
98    if ~isequal(vobs(o), vobs(p)) && ~(isequal(vobs(o), 1) || isequal(vobs(p), 1))
99        error(['dseries::plus: Cannot add ' inputname(1) ' and ' inputname(2) ' (wrong number of variables)!'])
100    else
101        if vobs(o)>vobs(p)
102            ido = 1:vobs(o);
103            idp = ones(1,vobs(o));
104        elseif vobs(o)<vobs(p)
105            ido = ones(1,vobs(p));
106            idp = 1:vobs(p);
107        else
108            ido = 1:vobs(o);
109            idp = ido;
110        end
111    end
112
113    if ~isequal(frequency(o),frequency(p))
114        error(['dseries::plus: Cannot add ' inputname(1) ' and ' inputname(2) ' (frequencies are different)!'])
115    end
116
117    if ~isequal(nobs(o), nobs(p)) || ~isequal(firstdate(o),firstdate(p))
118        [o, p] = align(o, p);
119    end
120    if vobs(o)>=vobs(p)
121        q = copy(o);
122    else
123        q = dseries(zeros(size(p.data)), p.firstdate);
124    end
125    for i=1:vobs(q)
126        if isempty(o.ops{ido(i)})
127            if isempty(p.ops{idp(i)})
128                q.ops(i) = {sprintf('plus(%s, %s)', o.name{ido(i)}, p.name{idp(i)})};
129            else
130                q.ops(i) = {sprintf('plus(%s, %s)', o.name{ido(i)}, p.ops{idp(i)})};
131            end
132        else
133            if isempty(p.ops{idp(i)})
134                q.ops(i) = {sprintf('plus(%s, %s)', o.ops{ido(i)}, p.name{idp(i)})};
135            else
136                q.ops(i) = {sprintf('plus(%s, %s)', o.ops{ido(i)}, p.ops{idp(i)})};
137            end
138        end
139    end
140    q.data = bsxfun(@plus,o.data,p.data);
141else
142    error()
143end
144
145%@test:1
146%$ % Define a datasets.
147%$ A = rand(10,2); B = randn(10,1);
148%$
149%$ % Define names
150%$ A_name = {'A1';'A2'}; B_name = {'B1'};
151%$
152%$ % Instantiate a time series object.
153%$ try
154%$    ts1 = dseries(A,[],A_name,[]);
155%$    ts2 = dseries(B,[],B_name,[]);
156%$    ts3 = ts1+ts2;
157%$    t(1) = true;
158%$ catch
159%$    t = false;
160%$ end
161%$
162%$ if length(t)>1
163%$    t(2) = dassert(ts3.vobs,2);
164%$    t(3) = dassert(ts3.nobs,10);
165%$    t(4) = dassert(ts3.data,[A(:,1)+B, A(:,2)+B],1e-15);
166%$    t(5) = dassert(ts3.name,{'A1';'A2'});
167%$    t(6) = dassert(ts3.name,{'plus(A1, B1)';'plus(A2, B1)'});
168%$ end
169%$ T = all(t);
170%@eof:1
171
172%@test:2
173%$ % Define a datasets.
174%$ A = rand(10,2); B = randn(10,1);
175%$
176%$ % Define names
177%$ A_name = {'A1';'A2'}; B_name = {'B1'};
178%$
179%$ % Instantiate a time series object.
180%$ try
181%$    ts1 = dseries(A,[],A_name,[]);
182%$    ts2 = dseries(B,[],B_name,[]);
183%$    ts3 = ts1+ts2;
184%$    ts4 = ts3+ts1;
185%$    t(1) = true;
186%$ catch
187%$    t = false;
188%$ end
189%$
190%$ if length(t)>1
191%$    t(2) = dassert(ts4.vobs,2);
192%$    t(3) = dassert(ts4.nobs,10);
193%$    t(4) = dassert(ts4.data,[A(:,1)+B, A(:,2)+B]+A,1e-15);
194%$    t(5) = dassert(ts4.name,{'A1';'A2'});
195%$    t(6) = dassert(ts4.name,{'plus(plus(A1, B1), A1)';'plus(plus(A2, B1), A2)'});
196%$ end
197%$ T = all(t);
198%@eof:2
199
200
201%@test:3
202%$ % Define a datasets.
203%$ A = rand(10,2); B = randn(5,1);
204%$
205%$ % Define names
206%$ A_name = {'A1';'A2'}; B_name = {'B1'};
207%$
208%$ % Instantiate a time series object.
209%$ try
210%$    ts1 = dseries(A,[],A_name,[]);
211%$    ts2 = dseries(B,[],B_name,[]);
212%$    ts3 = ts1+ts2;
213%$    t(1) = true;
214%$ catch
215%$    t = false;
216%$ end
217%$
218%$ if length(t)>1
219%$    t(2) = dassert(ts3.vobs,2);
220%$    t(3) = dassert(ts3.nobs,10);
221%$    t(4) = dassert(ts3.data,[A(1:5,1)+B(1:5), A(1:5,2)+B(1:5) ; NaN(5,2)],1e-15);
222%$ end
223%$ T = all(t);
224%@eof:3
225
226%@test:4
227%$ try
228%$     ts = dseries(transpose(1:5),'1950q1',{'Output'}, {'Y_t'});
229%$     us = dseries(transpose(1:5),'1949q4',{'Consumption'}, {'C_t'});
230%$     vs = ts+us;
231%$     t(1) = true;
232%$ catch
233%$     t = false;
234%$ end
235%$
236%$ if length(t)>1
237%$     t(2) = dassert(ts.freq,4);
238%$     t(3) = dassert(us.freq,4);
239%$     t(4) = dassert(ts.init.time,[1950, 1]);
240%$     t(5) = dassert(us.init.time,[1949, 4]);
241%$     t(6) = dassert(vs.init.time,[1949, 4]);
242%$     t(7) = dassert(vs.nobs,6);
243%$ end
244%$
245%$ T = all(t);
246%@eof:4
247
248%@test:5
249%$ try
250%$     ts = dseries(transpose(1:5),'1950q1',{'Output'}, {'Y_t'});
251%$     us = dseries(transpose(1:7),'1950q1',{'Consumption'}, {'C_t'});
252%$     vs = ts+us;
253%$     t(1) = true;
254%$ catch
255%$     t = false;
256%$ end
257%$
258%$ if length(t)>1
259%$     t(2) = dassert(ts.freq,4);
260%$     t(3) = dassert(us.freq,4);
261%$     t(4) = dassert(ts.init.time,[1950, 1]);
262%$     t(5) = dassert(us.init.time,[1950, 1]);
263%$     t(6) = dassert(vs.init.time,[1950, 1]);
264%$     t(7) = dassert(vs.nobs,7);
265%$ end
266%$
267%$ T = all(t);
268%@eof:5
269
270%@test:6
271%$ try
272%$     ts = dseries(transpose(1:5),'1950q1',{'Output'}, {'Y_t'});
273%$     us = dseries(transpose(1:7),'1950q1',{'Consumption'}, {'C_t'});
274%$     vs = ts+us('1950q1').data;
275%$     t(1) = true;
276%$ catch
277%$     t = false;
278%$ end
279%$
280%$ if length(t)>1
281%$     t(2) = dassert(ts.freq,4);
282%$     t(3) = dassert(us.freq,4);
283%$     t(4) = dassert(ts.init.time,[1950, 1]);
284%$     t(5) = dassert(us.init.time,[1950, 1]);
285%$     t(6) = dassert(vs.init.time,[1950, 1]);
286%$     t(7) = dassert(vs.nobs,5);
287%$     t(8) = dassert(vs.data,ts.data+1);
288%$ end
289%$
290%$ T = all(t);
291%@eof:6
292
293%@test:7
294%$ try
295%$     ts = dseries([transpose(1:5), transpose(1:5)],'1950q1');
296%$     us = dseries([transpose(1:7),2*transpose(1:7)],'1950q1');
297%$     vs = ts+us('1950q1').data;
298%$     t(1) = true;
299%$ catch
300%$     t = false;
301%$ end
302%$
303%$ if length(t)>1
304%$     t(2) = dassert(ts.freq,4);
305%$     t(3) = dassert(us.freq,4);
306%$     t(4) = dassert(ts.init.time,[1950, 1]);
307%$     t(5) = dassert(us.init.time,[1950, 1]);
308%$     t(6) = dassert(vs.init.time,[1950, 1]);
309%$     t(7) = dassert(vs.nobs,5);
310%$     t(8) = dassert(vs.data,bsxfun(@plus,ts.data,[1, 2]));
311%$ end
312%$
313%$ T = all(t);
314%@eof:7
315
316%@test:8
317%$ ts1 = dseries(ones(3,1));
318%$ ts2 = ts1+1;
319%$ ts3 = 1+ts1;
320%$ t(1) = isequal(ts2.data, 2*ones(3,1));
321%$ t(2) = isequal(ts3.data, 2*ones(3,1));
322%$ T = all(t);
323%@eof:8
324
325%@test:9
326%$ ts1 = dseries(ones(3,2));
327%$ ts2 = ts1+1;
328%$ ts3 = 1+ts1;
329%$ t(1) = isequal(ts2.data, 2*ones(3,2));
330%$ t(2) = isequal(ts3.data, 2*ones(3,2));
331%$ T = all(t);
332%@eof:9
333
334%@test:10
335%$ ts1 = dseries(ones(3,2));
336%$ ts2 = ts1+ones(3,1);
337%$ ts3 = ones(3,1)+ts1;
338%$ t(1) = isequal(ts2.data, 2*ones(3,2));
339%$ t(2) = isequal(ts3.data, 2*ones(3,2));
340%$ T = all(t);
341%@eof:10
342
343%@test:11
344%$ ts1 = dseries(ones(3,2));
345%$ ts2 = ts1+ones(1,2);
346%$ ts3 = ones(1,2)+ts1;
347%$ t(1) = isequal(ts2.data, 2*ones(3,2));
348%$ t(2) = isequal(ts3.data, 2*ones(3,2));
349%$ T = all(t);
350%@eof:11
351