1function q = mtimes(o, p) % --*-- Unitary tests --*--
2
3% Overloads the mtimes (*) operator for dseries objects.
4%
5% INPUTS
6% - o [dseries]           T observations and N variables.
7% - p [dseries,double]    scalar, vector or dseries object.
8%
9% OUTPUTS
10% - q [dseries]           T observations and N variables.
11
12% Copyright (C) 2013-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::mtimes: Second input argument must be a dseries object!')
32    end
33    q = copy(p);
34    q.data = bsxfun(@times, o, p.data);
35    for i=1:vobs(q)
36        if isscalar(o)
37            if isempty(p.ops{i})
38                q.ops(i) = {sprintf('mtimes(%s, %s)', num2str(o), p.name{i})};
39            else
40                q.ops(i) = {sprintf('mtimes(%s, %s)', num2str(o), p.ops{i})};
41            end
42        elseif isrow(o)
43            if isempty(p.ops{i})
44                q.ops(i) = {sprintf('mtimes(%s, %s)', num2str(o(i)), p.name{i})};
45            else
46                q.ops(i) = {sprintf('mtimes(%s, %s)', num2str(o(i)), p.ops{i})};
47            end
48        else
49            if isempty(p.ops{i})
50                q.ops(i) = {sprintf('mtimes(%s, %s)', matrix2string(o), p.name{i})};
51            else
52                q.ops(i) = {sprintf('mtimes(%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::mtimes: First input argument must be a dseries object!')
62    end
63    q = copy(o);
64    q.data = bsxfun(@times, o.data, p);
65    for i=1:vobs(q)
66        if isscalar(p)
67            if isempty(q.ops{i})
68                q.ops(i) = {sprintf('mtimes(%s, %s)', q.name{i}, num2str(p))};
69            else
70                q.ops(i) = {sprintf('mtimes(%s, %s)', q.ops{i}, num2str(p))};
71            end
72        elseif isrow(p)
73            if isempty(q.ops{i})
74                q.ops(i) = {sprintf('mtimes(%s, %s)', q.name{i}, num2str(p(i)))};
75            else
76                q.ops(i) = {sprintf('mtimes(%s, %s)', q.ops{i}, num2str(p(i)))};
77            end
78        else
79            if isempty(q.ops{i})
80                q.ops(i) = {sprintf('mtimes(%s, %s)', q.name{i}, matrix2string(p))};
81            else
82                q.ops(i) = {sprintf('mtimes(%s, %s)', q.ops{i}, matrix2string(p))};
83            end
84        end
85    end
86    return
87end
88
89if isdseries(o) && isdseries(p)
90    % Element by element multiplication of two dseries object
91    if ~isequal(vobs(o), vobs(p)) && ~(isequal(vobs(o),1) || isequal(vobs(p),1))
92        error(['dseries::times: Cannot multiply ' inputname(1) ' and ' inputname(2) ' (wrong number of variables)!'])
93    else
94        if vobs(o)>vobs(p)
95            idB = 1:vobs(o);
96            idC = ones(1:vobs(o));
97        elseif vobs(o)<vobs(p)
98            idB = ones(1,vobs(p));
99            idC = 1:vobs(p);
100        else
101            idB = 1:vobs(o);
102            idC = 1:vobs(p);
103        end
104    end
105    if ~isequal(frequency(o),frequency(p))
106        error(['dseries::times: Cannot multiply ' inputname(1) ' and ' inputname(2) ' (frequencies are different)!'])
107    end
108    if ~isequal(nobs(o), nobs(p)) || ~isequal(firstdate(o),firstdate(p))
109        [o, p] = align(o, p);
110    end
111    if vobs(o)>=vobs(p)
112        q = copy(o);
113    else
114        q = dseries(zeros(size(p.data)), p.firstdate);
115    end
116    for i=1:vobs(q)
117        if isempty(o.ops{idB(i)})
118            if isempty(p.ops{idC(i)})
119                q.ops(i) = {sprintf('mtimes(%s, %s)', o.name{idB(i)}, p.name{idC(i)})};
120            else
121                q.ops(i) = {sprintf('mtimes(%s, %s)', o.name{idB(i)}, p.ops{idC(i)})};
122            end
123        else
124            if isempty(p.ops{idC(i)})
125                q.ops(i) = {sprintf('mtimes(%s, %s)', o.ops{idB(i)}, p.name{idC(i)})};
126            else
127                q.ops(i) = {sprintf('mtimes(%s, %s)', o.ops{idB(i)}, p.ops{idC(i)})};
128            end
129        end
130    end
131    q.data = bsxfun(@times, o.data, p.data);
132else
133    error()
134end
135
136%@test:1
137%$ % Define a datasets.
138%$ A = rand(10,2); B = randn(10,1);
139%$
140%$ % Define names
141%$ A_name = {'A1';'A2'}; B_name = {'B1'};
142%$
143%$
144%$ % Instantiate a time series object.
145%$ try
146%$    ts1 = dseries(A,[],A_name,[]);
147%$    ts2 = dseries(B,[],B_name,[]);
148%$    ts3 = ts1*ts2;
149%$    t = 1;
150%$ catch
151%$    t = 0;
152%$ end
153%$
154%$ if t(1)
155%$    t(2) = dassert(ts3.vobs,2);
156%$    t(3) = dassert(ts3.nobs,10);
157%$    t(4) = dassert(ts3.data,[A(:,1).*B, A(:,2).*B],1e-15);
158%$    t(5) = dassert(ts3.name,{'A1';'A2'});
159%$    t(6) = dassert(ts3.ops,{'mtimes(A1, B1)';'mtimes(A2, B1)'});
160%$ end
161%$ T = all(t);
162%@eof:1
163
164%@test:2
165%$ % Define a datasets.
166%$ A = rand(10,2); B = pi;
167%$
168%$ % Define names
169%$ A_name = {'A1';'A2'};
170%$
171%$
172%$ % Instantiate a time series object.
173%$ try
174%$    ts1 = dseries(A,[],A_name,[]);
175%$    ts2 = ts1*B;
176%$    t = 1;
177%$ catch
178%$    t = 0;
179%$ end
180%$
181%$ if t(1)
182%$    t(2) = dassert(ts2.vobs,2);
183%$    t(3) = dassert(ts2.nobs,10);
184%$    t(4) = dassert(ts2.data,A*B,1e-15);
185%$ end
186%$ T = all(t);
187%@eof:2
188
189%@test:3
190%$ % Define a datasets.
191%$ A = rand(10,2); B = pi;
192%$
193%$ % Define names
194%$ A_name = {'A1';'A2'};
195%$
196%$
197%$ % Instantiate a time series object.
198%$ try
199%$    ts1 = dseries(A,[],A_name,[]);
200%$    ts2 = B*ts1;
201%$    t = 1;
202%$ catch
203%$    t = 0;
204%$ end
205%$
206%$ if t(1)
207%$    t(2) = dassert(ts2.vobs,2);
208%$    t(3) = dassert(ts2.nobs,10);
209%$    t(4) = dassert(ts2.data,A*B,1e-15);
210%$ end
211%$ T = all(t);
212%@eof:3
213
214%@test:4
215%$ % Define a datasets.
216%$ A = rand(10,2); B = A(1,:);
217%$
218%$ % Define names
219%$ A_name = {'A1';'A2'};
220%$
221%$
222%$ % Instantiate a time series object.
223%$ try
224%$    ts1 = dseries(A,[],A_name,[]);
225%$    ts2 = B*ts1;
226%$    t = 1;
227%$ catch
228%$    t = 0;
229%$ end
230%$
231%$ if t(1)
232%$    t(2) = dassert(ts2.vobs,2);
233%$    t(3) = dassert(ts2.nobs,10);
234%$    t(4) = dassert(ts2.data,bsxfun(@times,A,B),1e-15);
235%$ end
236%$ T = all(t);
237%@eof:4
238