Added new function from.
Allows the follwing syntax FROM d1 TO d2 DO y(t)=f(y(t-1),e(t),e(t+1),e(t-1)) where d1 and d2 are @dates objects (d1<d2), y is a @dseries object defined over d1-1:d2, and e is a @dseries object defined over d1-1:d2+1.time-shift
parent
1958a7b5df
commit
4dad18b222
|
@ -63,6 +63,7 @@ addpath([dynareroot '/utilities/tests/'])
|
|||
addpath([dynareroot '/utilities/dates/'])
|
||||
addpath([dynareroot '/utilities/dataset/'])
|
||||
addpath([dynareroot '/utilities/general/'])
|
||||
addpath([dynareroot '/utilities/dseries/'])
|
||||
addpath([dynareroot '/reports/'])
|
||||
|
||||
% For functions that exist only under some Octave versions
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
function from(varargin)
|
||||
|
||||
% 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 ~(ismember('to',varargin) && ismember('do',varargin))
|
||||
error('This command must be followed by TO and DO keywords (in that order).')
|
||||
end
|
||||
|
||||
to_id = strmatch('to',varargin);
|
||||
do_id = strmatch('do',varargin);
|
||||
|
||||
if do_id<to_id
|
||||
error(sprintf('Wrong syntax! The TO keyword must preceed the DO keyword.\nThe correct syntax is:\n\n from d1 to d2 do SOMETHING\n\n where d1<d2 are dates objects, and SOMETHING is a recursive expression involving dseries objects.'))
|
||||
end
|
||||
|
||||
if ~isdate(varargin{1})
|
||||
error('Wrong syntax! The FROM statement must be followed by a dates object')
|
||||
end
|
||||
|
||||
if ~isequal(to_id,2)
|
||||
error('Wrong syntax! The first dates object must be immediately followed by the TO keyword.')
|
||||
end
|
||||
|
||||
if ~isdate(varargin{3})
|
||||
error('Wrong syntax! The TO keyword must be followed by a second dates object')
|
||||
end
|
||||
|
||||
d1 = dates(varargin{1});
|
||||
d2 = dates(varargin{3});
|
||||
|
||||
if d1>d2
|
||||
error('The first date must preceed the second one!')
|
||||
end
|
||||
|
||||
if ~isequal(do_id,4)
|
||||
error('Wrong syntax! The second dates object must be immediately followed by the DO keyword.')
|
||||
end
|
||||
|
||||
% Build the recursive expression.
|
||||
EXPRESSION = [];
|
||||
for i=5:nargin
|
||||
EXPRESSION = [EXPRESSION, varargin{i}];
|
||||
end
|
||||
|
||||
% Get all the variables involved in the recusive expression.
|
||||
variables = regexpi(EXPRESSION, '\w*\(t\)|\w*\(t\-\d\)|\w*\(t\+\d\)','match');
|
||||
|
||||
% Remove the time indices.
|
||||
for i=1:length(variables)
|
||||
start = regexpi(variables{i},'\(t\)|\(t\-\d\)|\(t\+\d\)');
|
||||
variables(i) = {variables{i}(1:start-1)};
|
||||
end
|
||||
|
||||
% Remove duplicates.
|
||||
variables = unique(variables);
|
||||
|
||||
% Test that all the involved variables are available dseries objects.
|
||||
for i=1:length(variables)
|
||||
try
|
||||
var = evalin('caller',variables{i});
|
||||
catch
|
||||
error(['Variable ' variables{i} ' is unknown!'])
|
||||
end
|
||||
if ~isdseries(var)
|
||||
error(['Variable ' variables{i} ' is not a dseries object!'])
|
||||
else
|
||||
eval(sprintf('%s = var;',variables{i}));
|
||||
end
|
||||
end
|
||||
|
||||
% Check that the recursion is assigning something to a variable
|
||||
equal_id = strfind(EXPRESSION,'=');
|
||||
if isempty(equal_id)
|
||||
error('The expression following the DO keyword must be an assignment (missing equal symbol)!')
|
||||
end
|
||||
if isequal(length(equal_id),1)
|
||||
assignedvariablename = regexpi(EXPRESSION(1:equal_id-1), '\w*\(t\)|\w*\(t\-\d\)|\w*\(t\+\d\)','match');
|
||||
if isempty(assignedvariablename)
|
||||
error('The expression following the DO keyword must be an assignment (missing variable before the equal symbol)!')
|
||||
end
|
||||
if length(assignedvariablename)>1
|
||||
error('No more than one variable can be assigned!')
|
||||
end
|
||||
assignedvariablename = assignedvariablename{1}(1:regexpi(assignedvariablename{1},'\(t\)|\(t\-\d\)|\(t\+\d\)')-1);
|
||||
eval(sprintf('wrongtype = ~isdseries(%s);',assignedvariablename))
|
||||
if wrongtype
|
||||
error('The assigned variable must be a dseries object!')
|
||||
end
|
||||
else
|
||||
error('Not yet implemented! Only one assignment is allowed in the FROM-TO-DO statement.')
|
||||
end
|
||||
|
||||
% Transform the indexed variables after the assignment symbol: X(t-1) -> X(t-1).data
|
||||
expression = EXPRESSION(equal_id+1:end);
|
||||
expression = regexprep(expression,'\w*\(t\)|\w*\(t\-\d\)|\w*\(t\+\d\)','$0.data');
|
||||
EXPRESSION = [EXPRESSION(1:equal_id),expression];
|
||||
|
||||
% Run the recursion!
|
||||
eval(sprintf('t=dates(''%s''); while t<=dates(''%s''), %s; t = t+1; end',char(d1),char(d2),EXPRESSION))
|
||||
|
||||
% Put assigned variable back in the caller workspace...
|
||||
eval(sprintf('assignin(''caller'', assignedvariablename, %s)',assignedvariablename));
|
Loading…
Reference in New Issue