Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
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.
%$ A = [transpose(1:7),2*transpose(1:7)];
%$ B = [transpose(5:9),2*transpose(5:9)];
%$
%$ % 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];
%$ e.freq = 4;
%$ e.name = char('A1','A2','B1','B2');
%$ e.data = [ A, [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:4
function ts = log(ts)
% Apply the logarithm function to a Dynare time series object.
%@info:
%! @deftypefn {Function File} {@var{ts} =} log(@var{ts})
%! @anchor{log}
%! Apply the logarithm 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::log: Input argument has to be a Dynare time series object!')
end
if any(ts.data<eps)
error('dynSeries::log: Input argument has to be strictly positive!')
end
ts.data = log(ts.data);
\ No newline at end of file
function ts = set_time(ts)
%@info:
%! @deftypefn {Function File} {@var{ts} =} set_time(@var{ts})
%! @anchor{dynSeries}
%! @sp 1
%! Fill the time field of a Dynare time series object instantiated by @ref{dynSeries}.
%! @sp 2
%! @strong{Inputs}
%! @sp 2
%! @table @ @var
%! @item ts
%! Dynare time series object, instantiated by @ref{dynSeries}.
%! @end table
%! @sp 2
%! @strong{Outputs}
%! @sp 1
%! @table @ @var
%! @item t
%! Dynare time series object.
%! @end table
%! @sp 2
%! @strong{This function is called by:}
%! @table @ @ref
%! @item dynSeries
%! @item horzcat
%! @end table
%! @sp 2
%! @strong{This function calls:}
%!
%! @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.time = zeros(ts.nobs,2);
ts.time(1,:) = ts.init;
for obs=2:ts.nobs
if ts.time(obs-1,2)<ts.freq
ts.time(obs,1) = ts.time(obs-1,1);
ts.time(obs,2) = ts.time(obs-1,2)+1;
else
ts.time(obs,1) = ts.time(obs-1,1)+1;
ts.time(obs,2) = 1;
end
end
\ No newline at end of file
function B = subsasgn(A, S, B)
B = builtin('subsasgn', A, S, B);
\ No newline at end of file
function B = subsref(A, S)
B = builtin('subsref', A, S);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment