Commit e42b7347 authored by Stéphane Adjemian's avatar Stéphane Adjemian

Initial commit (Copy from Dynare repository).

parents
> Copyright (C) 2014 Dynare Team
>
> The dseries Matlab/Octave class is licensed under GNU GPL as published by
> the Free Software Foundation, either version 3 of the License, or (at
> your option) any later version.
>
> This code 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.
> A copy of the GNU General Public License is available here
> <http://www.gnu.org/licenses/>.
function A = abs(B) % --*-- Unitary tests --*--
%@info:
%! @deftypefn {Function File} {@var{A} =} abs (@var{B})
%! @anchor{@dseries/uminus}
%! @sp 1
%! Overloads the abs method for the Dynare time series class (@ref{dseries}).
%! @sp 2
%! @strong{Inputs}
%! @sp 1
%! @table @ @var
%! @item B
%! Dynare time series object instantiated by @ref{dseries}.
%! @end table
%! @sp 1
%! @strong{Outputs}
%! @sp 1
%! @table @ @var
%! @item A
%! Dynare time series object.
%! @end deftypefn
%@eod:
% Copyright (C) 2013 Dynare Team
%
% 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/>.
A = dseries();
A.data = abs(B.data);
A.dates = B.dates;
A.name = cell(vobs(A), 1);
A.tex = cell(vobs(A), 1);
for i = 1:vobs(A)
A.name(i) = {[ 'abs(' B.name{i} ')']};
A.tex(i) = {[ '|' B.tex{i} '|']};
end
%@test:1
%$ % Define a datasets.
%$ A = randn(10,2);
%$
%$ % Define names
%$ A_name = {'A1';'A2'};
%$ A_tex = {'A_1';'A_2'};
%$ t = zeros(6,1);
%$
%$ % Instantiate a time series object and compute the absolute value.
%$ try
%$ ts1 = dseries(A,[],A_name,A_tex);
%$ ts2 = abs(ts1);
%$ t(1) = 1;
%$ catch
%$ t = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(ts2.vobs,2);
%$ t(3) = dassert(ts2.nobs,10);
%$ t(4) = dassert(ts2.data,abs(A),1e-15);
%$ t(5) = dassert(ts2.name,{'abs(A1)';'abs(A2)'});
%$ t(6) = dassert(ts2.tex,{'|A_1|';'|A_2|'});
%$ end
%$ T = all(t);
%@eof:1
%@test:2
%$ % Define a datasets.
%$ A = randn(10,2);
%$
%$ % Define names
%$ A_name = {'A1';'A2'};
%$ A_tex = {'A_1';'A_2'};
%$ t = zeros(6,1);
%$
%$ % Instantiate a time series object and compute the absolute value.
%$ try
%$ ts1 = dseries(A,[],A_name,A_tex);
%$ ts2 = ts1.abs();
%$ t(1) = 1;
%$ catch
%$ t = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(ts2.vobs,2);
%$ t(3) = dassert(ts2.nobs,10);
%$ t(4) = dassert(ts2.data,abs(A),1e-15);
%$ t(5) = dassert(ts2.name,{'abs(A1)';'abs(A2)'});
%$ t(6) = dassert(ts2.tex,{'|A_1|';'|A_2|'});
%$ end
%$ T = all(t);
%@eof:2
\ No newline at end of file
function [a,b] = align(a, b) % --*-- Unitary tests --*--
%@info:
%! @deftypefn {Function File} {[@var{a}, @var{b}] =} align (@var{a}, @var{b})
%! @anchor{dseries/align}
%! @sp 1
%! If dseries objects @var{a} and @var{b} are defined on different time ranges, extend @var{a} and/or
%! @var{b} with NaNs so that they are defined on the same time range.
%! @sp 2
%! @strong{Inputs}
%! @sp 1
%! @table @ @var
%! @item a
%! Object instantiated by @ref{dseries}.
%! @item b
%! Object instantiated by @ref{dseries}.
%! @end table
%! @sp 2
%! @strong{Outputs}
%! @sp 1
%! @table @ @var
%! @item a
%! Object instantiated by @ref{dseries}.
%! @item b
%! Object instantiated by @ref{dseries}.
%! @end table
%! @end deftypefn
%@eod:
% Copyright (C) 2013 Dynare Team
%
% 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 ~isequal(frequency(a),frequency(b))
error(['dseries::align: ''' inputname(1) ''' and ''' inputname(2) ''' dseries objects must have common frequencies!'])
end
init = min(firstdate(a),firstdate(b));
last = max(lastdate(a),lastdate(b));
if isempty(intersect(a.dates,b.dates))
error(['dseries::align: ''' inputname(1) ''' and ''' inputname(2) ''' dseries object must have at least one common date!'])
end
a_init = init;
b_init = init;
a_last = last;
b_last = last;
if firstdate(b)>init
n = firstdate(b)-init;
b.data = [NaN(n, vobs(b)); b.data];
b_init = init;
end
if firstdate(a)>init
n = firstdate(a)-init;
a.data = [NaN(n, vobs(a)); a.data];
a_init = init;
end
if lastdate(b)<last
n = last-lastdate(b);
b.data = [b.data; NaN(n, vobs(b))];
end
if lastdate(a)<last
n = last-lastdate(a);
a.data = [a.data; NaN(n, vobs(a))];
end
a.dates = a_init:a_init+(nobs(a)-1);
b.dates = b_init:b_init+(nobs(b)-1);
%@test:1
%$ % Define a datasets.
%$ A = rand(8,3); B = rand(7,2);
%$
%$ % Define names
%$ A_name = {'A1';'A2';'A3'};
%$ B_name = {'B1';'B2'};
%$
%$ % Define initial dates
%$ A_init = '1990Q1';
%$ B_init = '1989Q2';
%$
%$ % Instantiate two dseries objects
%$ ts1 = dseries(A,A_init,A_name);
%$ ts2 = dseries(B,B_init,B_name);
%$
%$ try
%$ [ts1, ts2] = align(ts1, ts2);
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(ts1.nobs,ts2.nobs);
%$ t(3) = dassert(ts1.init,ts2.init);
%$ t(4) = dassert(ts1.data,[NaN(3,3); A], 1e-15);
%$ t(5) = dassert(ts2.data,[B; NaN(4,2)], 1e-15);
%$ end
%$ T = all(t);
%@eof:1
%@test:2
%$ % Define a datasets.
%$ A = rand(8,3); B = rand(7,2);
%$
%$ % Define names
%$ A_name = {'A1';'A2';'A3'};
%$ B_name = {'B1';'B2'};
%$
%$ % Define initial dates
%$ A_init = '1990Q1';
%$ B_init = '1990Q1';
%$
%$ % Instantiate two dseries objects
%$ ts1 = dseries(A,A_init,A_name);
%$ ts2 = dseries(B,B_init,B_name);
%$
%$ try
%$ [ts1, ts2] = align(ts1, ts2);
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(ts1.nobs,ts2.nobs);
%$ t(3) = dassert(ts1.init,ts2.init);
%$ t(4) = dassert(ts1.data,A, 1e-15);
%$ t(5) = dassert(ts2.data,[B; NaN(1,2)], 1e-15);
%$ end
%$ T = all(t);
%@eof:2
%@test:3
%$ % Define a datasets.
%$ A = rand(8,3); B = rand(7,2);
%$
%$ % Define names
%$ A_name = {'A1';'A2';'A3'};
%$ B_name = {'B1';'B2'};
%$
%$ % Define initial dates
%$ A_init = '1990Q1';
%$ B_init = '1990Q1';
%$
%$ % Instantiate two dseries objects
%$ ts1 = dseries(A,A_init,A_name);
%$ ts2 = dseries(B,B_init,B_name);
%$
%$ try
%$ [ts2, ts1] = align(ts2, ts1);
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(ts1.nobs,ts2.nobs);
%$ t(3) = dassert(ts1.init,ts2.init);
%$ t(4) = dassert(ts1.data,A, 1e-15);
%$ t(5) = dassert(ts2.data,[B; NaN(1,2)], 1e-15);
%$ end
%$ T = all(t);
%@eof:3
\ No newline at end of file
function ts = baxter_king_filter(ts, high_frequency, low_frequency, K) % --*-- Unitary tests --*--
% ts = baxter_king_filter(ts, high_frequency, low_frequency, K)
%
% Implementation of Baxter and King (1999) band pass filter for dseries objects. The code is adapted from
% the one provided by Baxter and King. This filter isolates business cycle fluctuations with a period of length
% ranging between high_frequency to low_frequency (quarters).
%
% INPUTS
% o ts dseries object.
% o high_frequency positive scalar, period length (default value is 6).
% o low_frequency positive scalar, period length (default value is 32).
% o K positive scalar integer, truncation parameter (default value is 12).
%
% OUTPUTS
% o ts dseries object.
%
% REMARKS
% This filter use a (symmetric) moving average smoother, so that K observations at the beginning and at the end of the
% sample are lost in the computation of the filter.
% Copyright (C) 2013 Dynare Team
%
% 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 nargin<4 || isempty(truncature)
K = 12;
if nargin<3 || isempty(low_frequency)
% Set default number of periods corresponding to the lowest frequency.
low_frequency = 32;
if nargin<2 || isempty(high_frequency)
% Set default number of periods corresponding to the highest frequency.
high_frequency = 6;
if nargin<1
error('dseries::baxter_king_filter: I need at least one argument')
end
else
if high_frequency<2
error('dseries::baxter_king_filter: Second argument must be greater than 2!')
end
if high_frequency>low_frequency
error('dseries::baxter_king_filter: Second argument must be smaller than the third argument!')
end
end
end
end
% translate periods into frequencies.
hf=2.0*pi/high_frequency;
lf=2.0*pi/low_frequency;
% Set weights for the band-pass filter's lag polynomial.
weights = zeros(K+1,1); lpowers = transpose(1:K);
weights(2:K+1) = (sin(lpowers*hf)-sin(lpowers*lf))./(lpowers*pi);
weights(1) = (hf-lf)/pi;
% Set the constraint on the sum of weights.
if low_frequency>1000
% => low pass filter.
sum_of_weights_constraint = 1.0;
else
sum_of_weights_constraint = 0.0;
end
% Compute the sum of weights.
sum_of_weights = weights(1) + 2*sum(weights(2:K+1));
% Correct the weights.
weights = weights + (sum_of_weights_constraint - sum_of_weights)/(2*K+1);
% Weights are symmetric!
weights = [flipud(weights(2:K+1)); weights];
tmp = zeros(size(ts.data));
% Filtering step.
for t = K+1:nobs(ts)-K
tmp(t,:) = weights'*ts.data(t-K:t+K,:);
end
% Update dseries object.
ts.data = tmp(K+1:end-K,:);
init = firstdate(ts)+K;
ts.dates = init:init+(nobs(ts)-1);
%@test:1
%$ plot_flag = 0;
%$
%$ % Create a dataset.
%$ e = .2*randn(200,1);
%$ u = randn(200,1);
%$ stochastic_trend = cumsum(e);
%$ deterministic_trend = .1*transpose(1:200);
%$ x = zeros(200,1);
%$ for i=2:200
%$ x(i) = .75*x(i-1) + e(i);
%$ end
%$ y = x + stochastic_trend + deterministic_trend;
%$
%$ % Test the routine.
%$ try
%$ ts = dseries(y,'1950Q1');
%$ ts = ts.baxter_king_filter();
%$ xx = dseries(x,'1950Q1');
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(ts.freq,4);
%$ t(3) = dassert(ts.init.freq,4);
%$ t(4) = dassert(ts.init.time,[1953, 1]);
%$ t(5) = dassert(ts.vobs,1);
%$ t(6) = dassert(ts.nobs,176);
%$ end
%$
%$ % Show results
%$ if plot_flag
%$ plot(xx(ts.dates).data,'-k');
%$ hold on
%$ plot(ts.data,'--r');
%$ hold off
%$ axis tight
%$ id = get(gca,'XTick');
%$ set(gca,'XTickLabel',strings(ts.dates(id)));
%$ legend({'Stationary component of y', 'Filtered y'})
%$ print('-depsc2','../doc/dynare.plots/BaxterKingFilter.eps')
%$ system('convert -density 300 ../doc/dynare.plots/BaxterKingFilter.eps ../doc/dynare.plots/BaxterKingFilter.png');
%$ system('convert -density 300 ../doc/dynare.plots/BaxterKingFilter.eps ../doc/dynare.plots/BaxterKingFilter.pdf');
%$ system('convert -density 300 ../doc/dynare.plots/BaxterKingFilter.eps ../doc/dynare.plots/BaxterKingFilter.jpg');
%$ end
%$
%$ T = all(t);
%@eof:1
\ No newline at end of file
function vs = chain(ts,us) % --*-- Unitary tests --*--
% Copyright (C) 2014 Dynare Team
%
% 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 vobs(ts)-vobs(us)
error(['dseries::chain: dseries objects ' inputname(1) ' and ' inputname(2) ' must have the same number of variables!'])
end
if frequency(ts)-frequency(us)
error(['dseries::chain: dseries objects ' inputname(1) ' and ' inputname(2) ' must have common frequencies!'])
end
if lastdate(ts)<firstdate(us)
error(['dseries::chain: The last date in ' inputname(1) ' (' date2string(ts.dates(end)) ') must not preceed the first date in ' inputname(2) ' (' date2string(us.dates(1)) ')!'])
end
tdx = find(sum(bsxfun(@eq,us.dates.time,ts.dates.time(end,:)),2)==2);
GrowthFactor = us.data(tdx+1:end,:)./us.data(tdx:end-1,:);
CumulatedGrowthFactors = cumprod(GrowthFactor);
vs = ts;
vs.data = [vs.data; bsxfun(@times,CumulatedGrowthFactors,vs.data(end,:))];
vs.dates = firstdate(vs):firstdate(vs)+nobs(vs);
%@test:1
%$ try
%$ ts = dseries([1; 2; 3; 4],dates('1950Q1')) ;
%$ us = dseries([3; 4; 5; 6],dates('1950Q3')) ;
%$ vs = chain(ts,us);
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = dassert(vs.freq,4);
%$ t(3) = dassert(vs.init.freq,4);
%$ t(4) = dassert(vs.init.time,[1950, 1]);
%$ t(5) = dassert(ts.vobs,1);
%$ t(6) = dassert(vs.nobs,6);
%$ t(7) = isequal(vs.data,transpose(1:6));
%$ end
%$
%$ T = all(t);
%@eof:1
\ No newline at end of file
function [error_flag,message] = check(A)
% Copyright (C) 2013 Dynare Team
%
% 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/>.
error_flag = 0;
[n,m] = size(A.data);
if ~isequal(m, vobs(A));
error_flag = 1;
if nargout>1
message = ['dseries: Wrong number of variables in dseries object ''' inputname(1) '''!'];
end
return
end
if ~isequal(n,nobs(A));
error_flag = 1;
if nargout>1
message = ['dseries: Wrong number of observations in dseries object ''' inputname(1) '''!'];
end
return
end
if ~isequal(m,numel(A.name));
error_flag = 1;
if nargout>1
message = ['dseries: Wrong number of variable names in dseries object ''' inputname(1) '''!'];
end
return
end
if ~isequal(m,numel(A.tex));
error_flag = 1;
if nargout>1
message = ['dseries: Wrong number of variable tex names in dseries object ''' inputname(1) '''!'];
end
return
end
if ~isequal(numel(A.name),numel(A.tex));
error_flag = 1;
if nargout>1
message = ['dseries: The number of variable tex names has to be equal to the number of variable names in dseries object ''' inputname(1) '''!'];
end
return
end
if ~isequal(numel(unique(A.name)),numel(A.name));
error_flag = 1;
if nargout>1
message = ['dseries: The variable names in dseries object ''' inputname(1) ''' are not unique!'];
end
return
end
if ~isequal(numel(unique(A.tex)),numel(A.tex));
error_flag = 1;
if nargout>1
message = ['dseries: The variable tex names in dseries object ''' inputname(1) ''' are not unique!'];
end
return
end
if ~isequal(A.dates,firstdate(A):firstdate(A)+nobs(A))
error_flag = 1;
if nargout>1
message = ['dseries: Wrong definition of the dates member in dseries object ''' inputname(1) '''!'];
end
return
end
\ No newline at end of file
function B = cumprod(varargin) % --*-- Unitary tests --*--
% Overloads matlab's cumprod function for dseries objects.
%
% INPUTS
% o A dseries object [mandatory].
% o d dates object [optional]
% o v dseries object with one observation [optional]
%
% OUTPUTS
% o B dseries object.
% Copyright (C) 2014 Dynare Team
%
% 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/>.
% Get indices of the columns without NaNs
idx = find(~any(isnan(varargin{1}.data)));
if isempty(idx)
error('dseries::cumprod: All the variables have NaNs. The cumulated product cannot be computed!')
end
if ~isequal(idx(:),transpose(1:vobs(varargin{1})))
warning('dseries::cumprod: The cumulated product is not computed for some variables because they have NaNs!')
end
switch nargin
case 1
% Initialize the output.
B = varargin{1};
% Perform the cumulated sum
B.data(:,idx) = cumprod(B.data(:,idx));
% Change the name of the variables
for i=1:vobs(B)
B.name(i) = {['cumprod(' B.name{i} ')']};
B.tex(i) = {['\prod_t ' B.tex{i}]};
end
case 2
if isdseries(varargin{2})
if ~isequal(vobs(varargin{1}), vobs(varargin{2}))
error('dseries::cumprod: First and second input arguments must be dseries objects with the same number of variables!')
end
if ~isequal(varargin{1}.name, varargin{2}.name)
warning('dseries::cumprod: First and second input arguments must be dseries objects do not have the same variables!')
end
if ~isequal(nobs(varargin{2}),1)
error('dseries::cumprod: Second input argument must be a dseries object with only one observation!')
end
B = cumprod(varargin{1});
B.data = bsxfun(@rdivide,B.data,B.data(1,:));
B.data = bsxfun(@times,B.data,varargin{2}.data);
elseif isdates(varargin{2})
B = cumprod(varargin{1});
t = find(B.dates==varargin{2});
if isempty(t)
if varargin{2}==(firstdate(B)-1)
return
else
error(['dseries::cumprod: date ' date2string(varargin{2}) ' is not in the sample!'])
end
end
B.data = bsxfun(@rdivide,B.data,B.data(t,:));
else
error('dseries::cumprod: Second input argument must be a dseries object or a dates object!')
end
case 3
if ~isdates(varargin{2})
error('dseries::cumprod: Second input argument must be a dates object!')
end
if ~isdseries(varargin{3})
error('dseries::cumprod: Third input argument must be a dseries object!')
end
if ~isequal(vobs(varargin{1}), vobs(varargin{3}))
error('dseries::cumprod: First and third input arguments must be dseries objects with the same number of variables!')
end
if ~isequal(varargin{1}.name, varargin{3}.name)
warning('dseries::cumprod: First and third input arguments must be dseries objects do not have the same variables!')
end
if