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

Use classdef (new class interface).

parent 6e43ba36
function ts = dseries(varargin) % --*-- Unitary tests --*-- classdef dseries<handle % --*-- Unitary tests --*--
%@info: % Class for time series.
%! @deftypefn {Function File} {@var{ts} =} dseries (@var{a},@var{b},@var{c},@var{d})
%! @anchor{dseries}
%! @sp 1
%! Constructor for the Dynare time series class.
%! @sp 2
%! @strong{Inputs}
%! @sp 2
%! If @code{nargin==0} then an empty dseries object is created. The object can be populated with data subsequently using the overloaded subsref method.
%! @sp 2
%! If @code{nargin==1} and if the input argument is a @ref{dates} object, then a dseries object without data is created. This object can be populated with the overload subsref method.
%! @sp 2
%! If @code{nargin==1} and if the input argument is a string for the name of a csv, m or mat file containing data, then a dseries object is created from these data.
%! @sp 2
%! If @code{nargin>1}:
%! @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*1 cell array of strings or N*q array of strings. Names of the N time series.
%! @item d
%! N*1 cell array of strings or N*p array of characters. TeX names of the N time series.
%! @end table
%! @sp 2
%! @strong{Outputs}
%! @sp 1
%! @table @ @var
%! @item ts
%! Dynare time series object.
%! @end table
%! @sp 2
%! @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
%! Cell array of strings, names of the variables.
%! @item tex
%! Cell array of strings, 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 init
%! @ref{dates} object, initial date of the dataset.
%! @end table
%! @end deftypefn
%@eod:
% Copyright (C) 2011-2013 Dynare Team % Copyright (C) 2013-2015 Dynare Team
% %
% This file is part of Dynare. % This code is free software: you can redistribute it and/or modify
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by % it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or % the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version. % (at your option) any later version.
% %
% Dynare is distributed in the hope that it will be useful, % Dynare dates submodule is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of % but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details. % GNU General Public License for more details.
...@@ -76,39 +17,61 @@ function ts = dseries(varargin) % --*-- Unitary tests --*-- ...@@ -76,39 +17,61 @@ function ts = dseries(varargin) % --*-- Unitary tests --*--
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>. % along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if nargin>0 && ischar(varargin{1}) && isequal(varargin{1},'initialize') properties
ts = struct; data = []; % Array of data (a column per variable, a row per observation)
ts.data = []; name = {}; % Names of the variables.
ts.name = {}; tex = {}; % TeX names of the variables.
ts.tex = {}; dates = dates(); % Dates associated to the observations.
ts.dates = dates(); end
ts = class(ts,'dseries');
assignin('base','emptydseriesobject',ts);
return
end
ts = evalin('base','emptydseriesobject');
switch nargin methods
function o = dseries(varargin)
% Constructor for the dseries class
%
% INPUTS
%
% - If no input arguments, the constructore returns an empty dseries object.
%
% - If only one input argument is provided, the behaviour of the constructor depends on the type of the argument:
% + varargin{1} [dates] Constructor will return a dseries object without data. The dseries object can be populated later using dseries' methods.
% + varargin{1} [char] The name of a csv, m, mat or xlsx file containing data. A dseries object is created from these data.
% + varargin{1} [double] A T*N array of data. A dseries object is created from the array (T observations, N variables).
%
% - If only one two, three or four arguments are provided, we must have:
% + varargin{1} [double] A T*N array of data.
% + varargin{2} [dates, char] A single element dates object or a string representing a date, the initial date of the database.
% + varargin{3} [cell] A N*1 cell of char or a N*q array of char, the names of the variables.
% + varargin{4} [cell] A N*1 cell of char or a N*q array of char, the TeX names of the variables.
%
% OUTPUTS
% - o [dseries]
switch nargin
case 0 case 0
% Create an empty dseries object. % Return empty object.
o.data = [];
o.name = {};
o.tex = {};
o.dates = dates();
return return
case 1 case 1
if isdates(varargin{1}) if isdates(varargin{1})
switch length(varargin{1}) switch length(varargin{1})
case 0 case 0
error(['dseries::dseries: Input (identified as a dates object) must be non empty!']) error('dseries:WrongInputArguments', 'Input (identified as a dates object) must be non empty!');
case 1 case 1
% Create an empty dseries object with an initial date. % Create an empty dseries object with an initial date.
ts.dates = varargin{1}; o.data = [];
o.name = {};
o.tex = {};
o.dates = varargin{1};
otherwise otherwise
error('dseries::dseries: Input (identified as a dates object) must have a unique element!') error('dseries:WrongInputArguments', 'Input (identified as a dates object) must have a unique element!');
end end
return return
elseif ischar(varargin{1}) elseif ischar(varargin{1})
% Create a dseries object loading data in a file (*.csv, *.m, *.mat). % Create a dseries object loading data in a file (*.csv, *.m, *.mat).
if isempty(varargin{1}) if isempty(varargin{1})
error('dseries:: Wrong calling sequence! Input argument cannot be an empty string.') error('dseries:WrongInputArguments', 'Input argument cannot be an empty string!')
elseif check_file_extension(varargin{1},'m') elseif check_file_extension(varargin{1},'m')
[freq,init,data,varlist,tex] = load_m_file_data(varargin{1}); [freq,init,data,varlist,tex] = load_m_file_data(varargin{1});
elseif check_file_extension(varargin{1},'mat') elseif check_file_extension(varargin{1},'mat')
...@@ -130,33 +93,33 @@ switch nargin ...@@ -130,33 +93,33 @@ switch nargin
[freq,init,data,varlist] = load_xls_file_data(varargin{1}, sheet, range); [freq,init,data,varlist] = load_xls_file_data(varargin{1}, sheet, range);
tex = []; tex = [];
else else
error(['dseries:: I''m not able to load data from ' varargin{1} '!']) error('dseries:WrongInputArguments', 'I''m not able to load data from %s!', varargin{1});
end end
ts.data = data; o.data = data;
ts.name = varlist; o.name = varlist;
ts.dates = init:init+(nobs(ts)-1); o.dates = init:init+(nobs(o)-1);
if isempty(tex) if isempty(tex)
ts.tex = name2tex(varlist); o.tex = name2tex(varlist);
else else
ts.tex = tex; o.tex = tex;
end end
elseif isnumeric(varargin{1}) && isequal(ndims(varargin{1}),2) elseif isnumeric(varargin{1}) && isequal(ndims(varargin{1}),2)
ts.data = varargin{1}; o.data = varargin{1};
ts.name = default_name(vobs(ts)); o.name = default_name(vobs(o));
ts.tex = name2tex(ts.name); o.tex = name2tex(o.name);
ts.dates = dates(1,1):dates(1,1)+(nobs(ts)-1); o.dates = dates(1,1):dates(1,1)+(nobs(o)-1);
end end
case {2,3,4} case {2,3,4}
if isequal(nargin,2) && ischar(varargin{1}) && isdates(varargin{2}) if isequal(nargin,2) && ischar(varargin{1}) && isdates(varargin{2})
% Instantiate dseries object with a data file and force the initial date to be as given by the second input argument. % Instantiate dseries object with a data file and force the initial date to be as given by the second input argument.
ds = dseries(varargin{1}); p = dseries(varargin{1});
ts = dseries(ds.data, varargin{2}, ds.name, ds.tex); o = dseries(p.data, varargin{2}, p.name, p.tex);
return return
end end
if isequal(nargin,2) && ischar(varargin{1}) && ischar(varargin{2}) && isdate(varargin{2}) if isequal(nargin,2) && ischar(varargin{1}) && ischar(varargin{2}) && isdate(varargin{2})
% Instantiate dseries object with a data file and force the initial date to be as given by the second input argument. % Instantiate dseries object with a data file and force the initial date to be as given by the second input argument.
ds = dseries(varargin{1}); p = dseries(varargin{1});
ts = dseries(ds.data, dates(varargin{2}), ds.name, ds.tex); o = dseries(p.data, dates(varargin{2}), p.name, p.tex);
return return
end end
a = varargin{1}; a = varargin{1};
...@@ -178,7 +141,7 @@ switch nargin ...@@ -178,7 +141,7 @@ switch nargin
end end
end end
% Get data, number of observations and number of variables. % Get data, number of observations and number of variables.
ts.data = a; o.data = a;
% Get the first date and set the frequency. % Get the first date and set the frequency.
if isempty(b) if isempty(b)
init = dates(1,1); init = dates(1,1);
...@@ -190,55 +153,53 @@ switch nargin ...@@ -190,55 +153,53 @@ switch nargin
init = dates([num2str(b) 'Y']); init = dates([num2str(b) 'Y']);
elseif isdates(b) % Range of dates elseif isdates(b) % Range of dates
init = b(1); init = b(1);
if nobs(ts)>1 && ~isequal(b.ndat,nobs(ts)) if nobs(o)>1 && ~isequal(b.ndat(),nobs(o))
message = 'dseries::dseries: If second input is a range, its number of elements must match '; error('dseries:WrongInputArguments', ['If second input is a range, its number ' ...
message = char(message, ' the number of rows in the first input, unless the first input'); 'of elements must match\nthe number of rows in the ' ...
message = char(message, ' has only one row.'); 'first input, unless the first input\nhas only one row.']);
skipline() elseif isequal(nobs(o), 1)
disp(message); o.data = repmat(o.data,b.ndat(),1);
error(' ');
elseif isequal(nobs(ts), 1)
ts.data = repmat(ts.data,b.ndat,1);
end end
ts.dates = b; o.dates = b;
elseif (isnumeric(b) && isint(b)) % Range of yearly dates. elseif (isnumeric(b) && isint(b)) % Range of yearly dates.
message = 'dseries::dseries: Not implemented! If you need to define a range of years'; error('dseries:WrongInputArguments', ['Not implemented! If you need to define ' ...
message = char(message, ' you have to pass a dates object as the second input argument.'); 'a range of years, you have to pass a dates object as the ' ...
disp(message) 'second input argument']);
error(' ')
else else
error('dseries::dseries: Wrong calling sequence!'); error('dseries:WrongInputArguments', 'Wrong calling sequence! Please check the manual.');
end end
% Get the names of the variables. % Get the names of the variables.
if ~isempty(c) if ~isempty(c)
if vobs(ts)==length(c) if vobs(o)==length(c)
for i=1:vobs(ts) for i=1:vobs(o)
ts.name = vertcat(ts.name, c(i)); o.name = vertcat(o.name, c(i));
end end
else else
error('dseries::dseries: The number of declared names does not match the number of variables!') error('dseries:WrongInputArguments', 'The number of declared names does not match the number of variables!')
end end
else else
ts.name = default_name(vobs(ts)); o.name = default_name(vobs(o));
end end
if ~isempty(d) if ~isempty(d)
if vobs(ts)==length(d) if vobs(o)==length(d)
for i=1:vobs(ts) for i=1:vobs(o)
ts.tex = vertcat(ts.tex, d(i)); o.tex = vertcat(o.tex, d(i));
end end
else else
error('dseries::dseries: The number of declared tex names does not match the number of variables!') error('dseries:WrongInputArguments', 'The number of declared tex names does not match the number of variables!')
end end
else else
ts.tex = name2tex(ts.name); o.tex = name2tex(o.name);
end end
otherwise otherwise
error('dseries::dseries: Can''t instantiate the class, wrong calling sequence!') error('dseries:WrongInputArguments', 'Wrong calling sequence! Please check the manual.')
end end
if isempty(o.dates)
if isempty(ts.dates) o.dates = init:init+(nobs(o)-1);
ts.dates = init:init+(nobs(ts)-1); end
end end % dseries
end % methods
end % classdef
%@test:1 %@test:1
%$ % Test if we can instantiate an empty dseries object. %$ % Test if we can instantiate an empty dseries object.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment