Implement broadcasting for operations (+,-,* and /) between dseries and scalar or vectors. Efficiency and cosmetic changes.

time-shift
Stéphane Adjemian (Charybdis) 2014-01-15 18:22:32 +01:00
parent 3534c68be6
commit 117f338eff
4 changed files with 133 additions and 116 deletions

View File

@ -23,7 +23,7 @@ function A = minus(B,C) % --*-- Unitary tests --*--
%! @end deftypefn
%@eod:
% Copyright (C) 2012-2013 Dynare Team
% Copyright (C) 2012-2014, Dynare Team
%
% This file is part of Dynare.
%
@ -40,38 +40,22 @@ function A = minus(B,C) % --*-- Unitary tests --*--
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if isnumeric(B) && isreal(B) && isequal(length(B),1) && isdseries(C)
A = dseries();
A.freq = C.freq;
A.init = C.init;
A.dates = C.dates;
A.nobs = C.nobs;
A.vobs = C.vobs;
A.name = cell(A.vobs,1);
A.tex = cell(A.vobs,1);
for i=1:A.vobs
A.name(i) = {['minus(' num2str(B) ',' C.name{i} ')']};
A.tex(i) = {['(' num2str(B) '-' C.tex{i} ')']};
if isnumeric(B) && (isscalar(B) || isvector(B))
if ~isdseries(C)
error('dseries::minus: Second input argument must be a dseries object!')
end
A.data = bsxfun(@minus, B, C.data);
A = C;
A.data = bsxfun(@minus,C.data,B);
return;
end
if isnumeric(C) && isreal(C) && isequal(length(C),1) && isdseries(B)
A = dseries();
A.freq = B.freq;
A.init = B.init;
A.dates = B.dates;
A.nobs = B.nobs;
A.vobs = B.vobs;
A.name = cell(A.vobs,1);
A.tex = cell(A.vobs,1);
for i=1:A.vobs
A.name(i) = {['minus(' B.name{i} ',' num2str(C) ')']};
A.tex(i) = {['(' B.tex{i} '-' num2str(C) ')']};
if isnumeric(C) && (isscalar(C) || isvector(C))
if ~isdseries(B)
error('dseries::minus: First input argument must be a dseries object!')
end
A.data = bsxfun(@minus, B.data, C);
return;
A = B;
A.data = bsxfun(@minus,B.data,C);
return
end
if ~isequal(B.vobs,C.vobs) && ~(isequal(B.vobs,1) || isequal(C.vobs,1))

View File

@ -23,7 +23,7 @@ function A = mrdivide(B,C) % --*-- Unitary tests --*--
%! @end deftypefn
%@eod:
% Copyright (C) 2012-2013 Dynare Team
% Copyright (C) 2012-2014 Dynare Team
%
% This file is part of Dynare.
%
@ -39,6 +39,24 @@ function A = mrdivide(B,C) % --*-- Unitary tests --*--
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if isnumeric(B) && (isscalar(B) || isvector(B))
if ~isdseries(C)
error('dseries::mrdivide: Second input argument must be a dseries object!')
end
A = C;
A.data = bsxfun(@rdivide,B,C.data);
return;
end
if isnumeric(C) && (isscalar(C) || isvector(C))
if ~isdseries(B)
error('dseries::mrdivide: First input argument must be a dseries object!')
end
A = B;
A.data = bsxfun(@rdivide,B.data,C);
return
end
if isdseries(B) && isdseries(C)
% Element by element divisions of two dseries object
@ -75,36 +93,6 @@ if isdseries(B) && isdseries(C)
A.tex(i) = {['(' B.tex{idB(i)} '/' C.tex{idC(i)} ')']};
end
A.data = bsxfun(@rdivide,B.data,C.data);
elseif isnumeric(C) && isreal(C) && isequal(length(C),1) && isdseries(B)
% division of a dseries object by a real scalar.
A = dseries();
A.freq = B.freq;
A.dates = B.dates;
A.init = B.init;
A.nobs = B.nobs;
A.vobs = B.vobs;
A.name = cell(A.vobs,1);
A.tex = cell(A.vobs,1);
for i=1:A.vobs
A.name(i) = {['divide(' B.name{i} ',' num2str(C) ')']};
A.tex(i) = {['(' B.tex{i} '/' num2str(C) ')']};
end
A.data = B.data/C;
elseif isnumeric(B) && isreal(B) && isequal(length(B),1) && isdseries(C)
% division of a real scalar by a dseries object.
A = dseries();
A.freq = C.freq;
A.dates = C.dates;
A.init = C.init;
A.nobs = C.nobs;
A.vobs = C.vobs;
A.name = cell(A.vobs,1);
A.tex = cell(A.vobs,1);
for i=1:A.vobs
A.name(i) = {['divide(' num2str(B) ',' C.name{i} ')']};
A.tex(i) = {['(' num2str(B) '/' C.tex{i} ')']};
end
A.data = B./C.data;
else
error()
end

View File

@ -23,7 +23,7 @@ function A = mtimes(B,C) % --*-- Unitary tests --*--
%! @end deftypefn
%@eod:
% Copyright (C) 2012-2013 Dynare Team
% Copyright (C) 2012-2014 Dynare Team
%
% This file is part of Dynare.
%
@ -40,6 +40,24 @@ function A = mtimes(B,C) % --*-- Unitary tests --*--
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if isnumeric(B) && (isscalar(B) || isvector(B))
if ~isdseries(C)
error('dseries::mtimes: Second input argument must be a dseries object!')
end
A = C;
A.data = bsxfun(@times,C.data,B);
return;
end
if isnumeric(C) && (isscalar(C) || isvector(C))
if ~isdseries(B)
error('dseries::mtimes: First input argument must be a dseries object!')
end
A = B;
A.data = bsxfun(@times,B.data,C);
return
end
if isdseries(B) && isdseries(C)
% Element by element multiplication of two dseries object
if ~isequal(B.vobs,C.vobs) && ~(isequal(B.vobs,1) || isequal(C.vobs,1))
@ -75,36 +93,6 @@ if isdseries(B) && isdseries(C)
A.tex(i) = {['(' B.tex{idB(i)} '*' C.tex{idC(i)} ')']};
end
A.data = bsxfun(@times,B.data,C.data);
elseif isnumeric(C) && isreal(C) && isequal(length(C),1) && isdseries(B)
% Multiplication of a dseries object by a real scalar.
A = dseries();
A.freq = B.freq;
A.init = B.init;
A.dates = B.dates;
A.nobs = B.nobs;
A.vobs = B.vobs;
A.name = cell(A.vobs,1);
A.tex = cell(A.vobs,1);
for i=1:A.vobs
A.name(i) = {['multiply(' B.name{i} ',' num2str(C) ')']};
A.tex(i) = {['(' B.tex{i} '*' num2str(C) ')']};
end
A.data = B.data*C;
elseif isnumeric(B) && isreal(B) && isequal(length(B),1) && isdseries(C)
% Multiplication of a dseries object by a real scalar.
A = dseries();
A.freq = C.freq;
A.init = C.init;
A.dates = C.dates;
A.nobs = C.nobs;
A.vobs = C.vobs;
A.name = cell(A.vobs,1);
A.tex = cell(A.vobs,1);
for i=1:A.vobs
A.name(i) = {['multiply(' num2str(B) ',' C.name{i} ')']};
A.tex(i) = {['(' num2str(B) '*' C.tex{i} ')']};
end
A.data = C.data*B;
else
error()
end
@ -157,7 +145,6 @@ end
%$ t(2) = dyn_assert(ts2.vobs,2);
%$ t(3) = dyn_assert(ts2.nobs,10);
%$ t(4) = dyn_assert(ts2.data,A*B,1e-15);
%$ t(5) = dyn_assert(ts2.name,{['multiply(A1,' num2str(pi) ')'];['multiply(A2,' num2str(pi) ')']});
%$ end
%$ T = all(t);
%@eof:2
@ -183,7 +170,31 @@ end
%$ t(2) = dyn_assert(ts2.vobs,2);
%$ t(3) = dyn_assert(ts2.nobs,10);
%$ t(4) = dyn_assert(ts2.data,A*B,1e-15);
%$ t(5) = dyn_assert(ts2.name,{['multiply(' num2str(pi) ',A1)'];['multiply(' num2str(pi) ',A2)']});
%$ end
%$ T = all(t);
%@eof:3
%@test:4
%$ % Define a datasets.
%$ A = rand(10,2); B = A(1,:);
%$
%$ % Define names
%$ A_name = {'A1';'A2'};
%$
%$
%$ % Instantiate a time series object.
%$ try
%$ ts1 = dseries(A,[],A_name,[]);
%$ ts2 = B*ts1;
%$ t = 1;
%$ catch
%$ t = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dyn_assert(ts2.vobs,2);
%$ t(3) = dyn_assert(ts2.nobs,10);
%$ t(4) = dyn_assert(ts2.data,bsxfun(@times,A,B),1e-15);
%$ end
%$ T = all(t);
%@eof:4

View File

@ -23,7 +23,7 @@ function A = plus(B,C) % --*-- Unitary tests --*--
%! @end deftypefn
%@eod:
% Copyright (C) 2011-2013 Dynare Team
% Copyright (C) 2011-2014 Dynare Team
%
% This file is part of Dynare.
%
@ -40,37 +40,21 @@ function A = plus(B,C) % --*-- Unitary tests --*--
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if isnumeric(B) && isscalar(B)
if isnumeric(B) && (isscalar(B) || isvector(B))
if ~isdseries(C)
error('dseries::plus: Second input argument must be a dseries object!')
end
b(1:size(C)) = B;
BB = dseries(b, C.dates(1));
BB.freq = C.freq;
BB.dates = C.dates;
BB.nobs = C.nobs;
BB.vobs = C.vobs;
BB.name = cell(BB.vobs,1);
BB.tex = cell(BB.vobs,1);
BB.name(1) = {num2str(B)};
A = BB + C;
A = C;
A.data = bsxfun(@plus,C.data,B);
return;
end
if isnumeric(C) && isscalar(C)
if isnumeric(C) && (isscalar(C) || isvector(C))
if ~isdseries(B)
error('dseries::plus: First input argument must be a dseries object!')
end
c(1:size(C)) = C;
CC = dseries(C, B.dates(1));
CC.freq = B.freq;
CC.dates = B.dates;
CC.nobs = B.nobs;
CC.vobs = B.vobs;
CC.name = cell(CC.vobs,1);
CC.tex = cell(CC.vobs,1);
CC.name(1) = {num2str(C)};
A = B + CC;
A = B;
A.data = bsxfun(@plus,B.data,C);
return
end
@ -254,4 +238,54 @@ A.dates = A.init:A.init+(A.nobs-1);
%$ end
%$
%$ T = all(t);
%@eof:5
%@eof:5
%@test:6
%$ t = zeros(8,1);
%$
%$ try
%$ ts = dseries(transpose(1:5),'1950q1',{'Output'}, {'Y_t'});
%$ us = dseries(transpose(1:7),'1950q1',{'Consumption'}, {'C_t'});
%$ vs = ts+us('1950q1').data;
%$ t(1) = 1;
%$ catch
%$ t = 0;
%$ end
%$
%$ if length(t)>1
%$ t(2) = dyn_assert(ts.freq,4);
%$ t(3) = dyn_assert(us.freq,4);
%$ t(4) = dyn_assert(ts.init.time,[1950, 1]);
%$ t(5) = dyn_assert(us.init.time,[1950, 1]);
%$ t(6) = dyn_assert(vs.init.time,[1950, 1]);
%$ t(7) = dyn_assert(vs.nobs,5);
%$ t(8) = dyn_assert(vs.data,ts.data+1);
%$ end
%$
%$ T = all(t);
%@eof:6
%@test:7
%$ t = zeros(8,1);
%$
%$ try
%$ ts = dseries([transpose(1:5), transpose(1:5)],'1950q1');
%$ us = dseries([transpose(1:7),2*transpose(1:7)],'1950q1');
%$ vs = ts+us('1950q1').data;
%$ t(1) = 1;
%$ catch
%$ t = 0;
%$ end
%$
%$ if length(t)>1
%$ t(2) = dyn_assert(ts.freq,4);
%$ t(3) = dyn_assert(us.freq,4);
%$ t(4) = dyn_assert(ts.init.time,[1950, 1]);
%$ t(5) = dyn_assert(us.init.time,[1950, 1]);
%$ t(6) = dyn_assert(vs.init.time,[1950, 1]);
%$ t(7) = dyn_assert(vs.nobs,5);
%$ t(8) = dyn_assert(vs.data,bsxfun(@plus,ts.data,[1, 2]));
%$ end
%$
%$ T = all(t);
%@eof:7