Commit 237744fe authored by Stéphane Adjemian's avatar Stéphane Adjemian Committed by Stéphane Adjemian
Browse files

Added dynare class for time series.

parent 467c60c5
function ts = dynSeries(a,b,c,d)
%@info:
%! @deftypefn {Function File} {@var{ts} =} dynSeries (@var{a},@var{b},@var{c},@var{d})
%! @anchor{dynSeries}
%! @sp 1
%! Constructor for the Dynare time series class.
%! @sp 2
%! @strong{Inputs}
%! @sp 1
%! @table @ @var
%! @item a
%! T*1 vector or T*N matrix of data.
%! @item b
%! Initial date. For Quaterly, Monthly or Weekly data, b must be a string. For yearly data or if the frequence is not
%! defined b must be an integer.
%! @item c
%! N*q array of characters. Names of the N time series.
%! @item d
%! N*p array of characters. TeX names of the N time series.
%! @end table
%! @sp 1
%! @strong{Outputs}
%! @sp 1
%! @table @ @var
%! @item ts
%! Dynare time series object.
%! @end table
%! @sp 1
%! @strong{Properties}
%! @sp 1
%! The constructor defines the following properties:
%! @sp 1
%! @table @ @var
%! @item data
%! Array of doubles (nobs*vobs).
%! @item nobs
%! Scalar integer, the number of observations.
%! @item vobs
%! Scalar integer, the number of variables.
%! @item name
%! Array of chars (nvobs*n), names of the variables.
%! @item tex
%! Array of chars (nvobs*n), tex names of the variables.
%! @item freq
%! Scalar integer, the frequency of the time series. @var{freq} is equal to 1 if data are on a yearly basis or if
%! frequency is unspecified. @var{freq} is equal to 4 if data are on a quaterly basis. @var{freq} is equal to
%! 12 if data are on a monthly basis. @var{freq} is equal to 52 if data are on a weekly basis.
%! @item time
%! Array of integers (nobs*2). The first column defines the years associated to each observation. The second column,
%! depending on the frequency, indicates the week, month or quarter numbers. For yearly data or unspecified frequency
%! the second column is filled by ones.
%! @item init
%! Row vector of integers (1*2) indicating the year and the week, month or quarter of the first observation. @var{init}
%! is the first row of @var{time}.
%! @item last
%! Row vector of integers (1*2) indicating the year and the week, month or quarter of the last observation. @var{init}
%! is the first row of @var{time}.
%! @end table
%! @sp 1
%! @strong{This function is called by:}
%! @sp 2
%! @strong{This function calls:}
%! @ref{set_time}
%!
%! @end deftypefn
%@eod:
% Copyright (C) 2011 Dynare Team
% stephane DOT adjemian AT univ DASH lemans DOT fr
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
ts = struct;
ts.data = [];
ts.nobs = 0;
ts.vobs = 0;
ts.name = [];
ts.tex = [];
ts.freq = [];
ts.time = [];
ts.init = [];
ts.last = [];
ts = class(ts,'dynSeries');
switch nargin
case 0
return
case {2,4}
if nargin==2
c = [];
d = [];
end
% Get data, number of observations and number of variables.
ts.data = a;
ts.nobs = size(a,1);
ts.vobs = size(a,2);
% Get the first date and set the frequency.
if ~isempty(b)
if ischar(b)% Weekly, Monthly or Quaterly data.
quaterly = findstr('Q',b);
monthly = findstr('M',b);
weekly = findstr('W',b);
if ~isempty(quaterly)
ts.freq = 4;
ts.init = [str2num(b(1:quaterly-1)) str2num(b(quaterly+1:end))];
ts = set_time(ts);
ts.last = ts.time(end,:);
end
if ~isempty(monthly)
ts.freq = 12;
ts.init = [str2num(b(1:monthly-1)) str2num(b(monthly+1:end))];
ts = set_time(ts);
ts.last = ts.time(end,:);
end
if ~isempty(weekly)
ts.freq = 52;
ts.init = [str2num(b(1:weekly-1)) str2num(b(weekly+1:end))];
ts = set_time(ts);
ts.last = ts.time(end,:);
end
if isempty(quaterly) && isempty(monthly) && isempty(weekly)
error('dynSeries:: Using a string as a second input argument, I can only handle weekly (W), monthly (M) or quaterly (Q) data!');
end
else% If b is not a string then yearly data are assumed.
ts.init = [b 1];
ts.freq = 1;
ts = set_time(ts);
ts.last = ts.time(end,:);
end
else% If b is empty.
ts.init = 1;
ts.last = ts.nobs;
ts.freq = 1;
ts = set_time(ts);
ts.last = ts.time(end,:);
end
% Get the names of the variables.
if ~isempty(c)
if ts.vobs==size(c,1)
ts.name = c;
else
error('dynSeries:: The number of declared names does not match the number of variables!')
end
else
for i=1:ts.vobs
ts.name = char(ts.name,'--NA--');
end
end
if ~isempty(d)
if ts.vobs==size(d,1)
ts.tex = d;
else
error('dynSeries:: The number of declared tex names does not match the number of variables!')
end
else
for i=1:ts.vobs
ts.tex = char(ts.tex,'--NA--');
end
end
otherwise
error('dynSeries:: Can''t instantiate the class, wrong calling sequence!')
end
%@test:1
%$ addpath ../matlab
%$ % Define a data set.
%$ A = transpose(1:10);
%$
%$ % Define initial date
%$ B1 = 1950;
%$ B2 = '1950Q2';
%$ B3 = '1950M10';
%$ B4 = '1950W50';
%$
%$ % Define expected results.
%$ e1.Time = transpose([1950 1951 1952 1953 1954 1955 1956 1957 1958 1959]);
%$ e1.freq = 1;
%$ e2.Time = char('1950Q2','1950Q3','1950Q4','1951Q1','1951Q2','1951Q3','1951Q4','1952Q1','1952Q2','1952Q3');
%$ e2.freq = 4;
%$ e3.Time = char('1950M10','1950M11','1950M12','1951M1','1951M2','1951M3','1951M4','1951M5','1951M6','1951M7');
%$ e3.freq = 12;
%$ e4.Time = char('1950W50','1950W51','1950W52','1951W1','1951W2','1951W3','1951W4','1951W5','1951W6','1951W7');
%$ e4.freq = 52;
%$
%$ % Call the tested routine.
%$ ts1 = dynSeries(A,B1);
%$ ts2 = dynSeries(A,B2);
%$ ts3 = dynSeries(A,B3);
%$ ts4 = dynSeries(A,B4);
%$
%$ % Check the results.
%$ t(1) = dyn_assert(getTime(ts1),e1.Time);
%$ t(2) = dyn_assert(getTime(ts2),e2.Time);
%$ t(3) = dyn_assert(getTime(ts3),e3.Time);
%$ t(4) = dyn_assert(getTime(ts4),e4.Time);
%$ t(5) = dyn_assert(ts1.freq,e1.freq);
%$ t(6) = dyn_assert(ts2.freq,e2.freq);
%$ t(7) = dyn_assert(ts3.freq,e3.freq);
%$ t(8) = dyn_assert(ts4.freq,e4.freq);
%$ T = all(t);
%@eof:1
function ts = exp(ts)
% Apply the exponential function to a Dynare time series object.
%@info:
%! @deftypefn {Function File} {@var{ts} =} log(@var{ts})
%! @anchor{exp}
%! Apply the exponential function to a Dynare time series object.
%!
%! @strong{Inputs}
%! @table @var
%! @item ts
%! Dynare time series object, instantiated by @ref{dynSeries}
%! @end table
%!
%! @strong{Outputs}
%! @table @var
%! @item ts
%! Dynare time series object with transformed data field.
%! @end table
%!
%! @strong{This function is called by:}
%! None.
%!
%! @strong{This function calls:}
%! None.
%!
%! @end deftypefn
%@eod:
% Copyright (C) 2011 Dynare Team
% stephane DOT adjemian AT univ DASH lemans DOT fr
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if ~isa(ts,'dynSeries')
error('dynSeries::exp: Input argument has to be a Dynare time series object!')
end
ts.data = exp(ts.data);
\ No newline at end of file
function name = getName(ts,i)
name = deblank(ts.name(i,:));
\ No newline at end of file
function texname = getTexName(ts,i)
texname = ['$' deblank(ts.tex(i,:)) '$'];
\ No newline at end of file
function time = getTime(ts)
if ts.freq==1
time = ts.time(:,1);
return
end
time = [];
switch ts.freq
case 4
for i=1:ts.nobs
time = char(time,[num2str(ts.time(i,1)) 'Q' num2str(ts.time(i,2))]);
end
case 12
for i=1:ts.nobs
time = char(time,[num2str(ts.time(i,1)) 'M' num2str(ts.time(i,2))]);
end
case 52
for i=1:ts.nobs
time = char(time,[num2str(ts.time(i,1)) 'W' num2str(ts.time(i,2))]);
end
otherwise
error('dynSeries::getTime: Unknown type of frequency!')
end
time = time(2:end,:);
\ No newline at end of file
function i = getVarIndex(ts,name)
switch size(name,1)
case 0
error('dynSeries::getVarIndex: Second input argument is empty!');
case 1
i = strmatch(deblank(name),ts.name,'exact');
if isempty(i)
i = 0;
end
otherwise
i = NaN(size(name,1))
for j = 1:size(name,1)
i(j) = strmatch(deblank(name(j,:)),ts.name,'exact');
if isempty(i)
i(j) = 0;
end
end
end
\ No newline at end of file
function a = horzcat(b,c)
%@info:
%! @deftypefn {Function file} {@var{a} =} horzcat (@var{b},@var{c})
%! @anchor{horzcat}
%! @sp 1
%! Method of the dynSeries class.
%! @sp 1
%! Merge two Dynare time series class. This method overloads the horizontal concatenation operator, so that
%! two time series objects can be merged using the following syntax
%!
%! a = [b, c];
%! @sp 2
%! @strong{Inputs}
%! @sp 1
%! @table @ @var
%! @item b
%! Dynare time series object, instantiated by @ref{dynSeries}.
%! @item c
%! Dynare time series object, instantiated by @ref{dynSeries}.
%! @end table
%! @sp 2
%! @strong{Outputs}
%! @sp 1
%! @table @var
%! @item a
%! Dynare time series object.
%! @end table
%! @sp 2
%! @strong{This function is called by:}
%! @ref{descriptive_statistics}
%!
%! @strong{This function calls:}
%! @ref{dynSeries}
%!
%! @strong{Remark 1.} It is assumed that the two time series objects have the same frequencies. The two time series objects can cover
%! different time ranges.
%!
%! @end deftypefn
%@eod:
% Copyright (C) 2011 Dynare Team
% stephane DOT adjemian AT univ DASH lemans DOT fr
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if ~isa(b,'dynSeries')
error('dynSeries::horzcat: First input argument has to be a Dynare time series object!')
end
if ~isa(c,'dynSeries')
error('dynSeries::horzcat: Second input argument has to be a Dynare time series object!')
end
if b.freq ~= c.freq
error('dynSeries::horzcat: Two time series objects must have common frequency!')
else
a = dynSeries();
a.freq = b.freq;
end
d_nobs_flag = 0;
if b.nobs ~= c.nobs
% error('dynSeries::horzcat: Two time series objects must have the same number of observations!')
d_nobs_flag = 1;
else
a.nobs = b.nobs;
end
d_init_flag = 0;
if isequal(b.init,c.init)
a.init = b.init;
else
% error('dynSeries:: Two time series objects must have common initial date!')
% set a.init equal to min(b.init,c.init)
if b.init(1)<c.init(1)
d_init_flag = 1;
a.init = b.init;
elseif b.init(1)==c.init(1)
if b.init(2)<c.init(2)
d_init_flag = 1;
a.init = b.init;
else
d_init_flag = 2;
a.init = c.init;
end
else
d_init_flag = 2;
a.init = c.init;
end
end
d_last_flag = 0;
if isequal(b.last,c.last)
a.last = b.last;
else
% error('dynSeries:: Two time series objects must have common initial date!')
% set a.last equal to max(b.last,c.last)
if b.last(1)<c.last(1)
d_last_flag = 2;
a.last = c.last;
elseif b.last(1)==c.last(1)
if b.last(2)<c.last(2)
d_last_flag = 2;
a.last = c.last;
else
d_last_flag = 1;
a.last = b.last;
end
else
d_last_flag = 1;
a.last = b.last;
end
end
a.vobs = b.vobs+c.vobs;
a.name = char(b.name,c.name);
a.tex = char(b.tex,c.tex);
if ~( d_nobs_flag(1) || d_init_flag(1) || d_last_flag(1) )
a.time = b.time;
a.data = [b.data,c.data];
else
[junk,ib] = setdiff(b.time,c.time,'rows');
[junk,ic] = setdiff(c.time,b.time,'rows');
[junk,jb,jc] = intersect(b.time,c.time,'rows');
a.time = [b.time(ib,:); b.time(jb,:); c.time(ic,:)];
a.time = sortrows(a.time,[1 2]);
a.nobs = rows(a.time);
a.data = NaN(a.nobs,a.vobs);
[junk,ia,ib] = intersect(a.time,b.time,'rows');
a.data(ia,1:b.vobs) = b.data;
[junk,ia,ic] = intersect(a.time,c.time,'rows');
a.data(ia,b.vobs+(1:c.vobs)) = c.data;
end
%@test:1
%$ addpath ../matlab
%$ % Define a data set.
%$ A = [transpose(1:10),2*transpose(1:10)];
%$ B = [transpose(1:10),2*transpose(1:10)];
%$
%$ % Define names
%$ A_name = char('A1','A2');
%$ B_name = char('B1','B2');
%$
%$ % Define expected results.
%$ e.time = [transpose(1:10), ones(10,1)];
%$ e.freq = 1;
%$ e.name = char('A1','A2','B1','B2');
%$ e.data = [A,B];
%$
%$ % Instantiate two time series objects.
%$ ts1 = dynSeries(A,[],A_name,[]);
%$ ts2 = dynSeries(B,[],B_name,[]);
%$
%$ % Call the tested method.
%$ ts3 = [ts1,ts2];
%$
%$ % Check the results.
%$ t(1) = dyn_assert(ts3.time,e.time);
%$ t(2) = dyn_assert(ts3.freq,e.freq);
%$ t(3) = dyn_assert(ts3.data,e.data);
%$ t(4) = dyn_assert(ts3.name,e.name);
%$ T = all(t);
%@eof:1
%@test:2
%$ addpath ../matlab
%$ % Define a data set.
%$ A = [transpose(1:10),2*transpose(1:10)];
%$ B = [transpose(5:12),2*transpose(5:12)];
%$
%$ % Define names
%$ A_name = char('A1','A2');
%$ B_name = char('B1','B2');
%$
%$ % Define initial date
%$ A_init = 2001;
%$ B_init = 2005;
%$
%$ % Define expected results.
%$ e.time = [transpose(2000+(1:12)), ones(12,1)];
%$ e.freq = 1;
%$ e.name = char('A1','A2','B1','B2');
%$ e.data = [ [A; NaN(2,2)], [NaN(4,2); B]];
%$
%$ % Instantiate two time series objects.
%$ ts1 = dynSeries(A,A_init,A_name,[]);
%$ ts2 = dynSeries(B,B_init,B_name,[]);
%$
%$ % Call the tested method.
%$ ts3 = [ts1,ts2];
%$
%$ % Check the results.
%$ t(1) = dyn_assert(ts3.time,e.time);
%$ t(2) = dyn_assert(ts3.freq,e.freq);
%$ t(3) = dyn_assert(ts3.data,e.data);
%$ t(4) = dyn_assert(ts3.name,e.name);
%$ T = all(t);
%@eof:2
%@test:3
%$ addpath ../matlab
%$ % Define a data set.
%$ A = [transpose(1:7),2*transpose(1:7)];
%$ B = [transpose(5:11),2*transpose(5:11)];
%$
%$ % Define names
%$ A_name = char('A1','A2');
%$ B_name = char('B1','B2');
%$
%$ % Define initial date
%$ A_init = '1950Q1';
%$ B_init = '1950Q3';
%$
%$ % Define expected results.
%$ e.time = [ 1950, 1; 1950, 2; 1950, 3; 1950, 4; 1951, 1; 1951, 2; 1951, 3; 1951, 4; 1952, 1];
%$ e.freq = 4;
%$ e.name = char('A1','A2','B1','B2');
%$ e.data = [ [A; NaN(2,2)], [NaN(2,2); B]];
%$
%$ % Instantiate two time series objects.
%$ ts1 = dynSeries(A,A_init,A_name,[]);
%$ ts2 = dynSeries(B,B_init,B_name,[]);
%$
%$ % Call the tested method.
%$ ts3 = [ts1,ts2];
%$
%$ % Check the results.
%$ t(1) = dyn_assert(ts3.time,e.time);
%$ t(2) = dyn_assert(ts3.freq,e.freq);
%$ t(3) = dyn_assert(ts3.data,e.data);
%$ t(4) = dyn_assert(ts3.name,e.name);
%$ T = all(t);
%@eof:3
%@test:4
%$ addpath ../matlab
%$ % Define a data set.