From 08ea66057ce9c6ed68dcb58073467b998695398c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 12 Jun 2014 15:15:04 +0200 Subject: [PATCH] Automagically increase the number of observations in the assigned variable if needed. So that the following is possible y = dseries([0],'1990Q1','y'); e = dseries(randn(1000,1),'1990Q1','e'); from 1990Q2 to 2239Q4 do y(t) = .5*y(t-1) + e(t) - .5*e(t-1)*y(t-1) +.1*y(t-1)^2 Initially y has only one observation (which is mandatory because y depends on its first lag), the routine extends the number of observations so that y.dates(end)==2239Q4 Note that the exogenous variables are not adjusted, they must be defined (leads/lags included) between the first and last dates of the from-to-do syntax. --- matlab/utilities/dseries/from.m | 100 +++++++++++++++++++------------- 1 file changed, 59 insertions(+), 41 deletions(-) diff --git a/matlab/utilities/dseries/from.m b/matlab/utilities/dseries/from.m index ebac2e940..9351a02e3 100644 --- a/matlab/utilities/dseries/from.m +++ b/matlab/utilities/dseries/from.m @@ -86,6 +86,17 @@ end % Build the recursive expression. EXPRESSION = char([varargin{5:end}]); +% Check that the expression is an assignment +equal_id = strfind(EXPRESSION,'='); +if isempty(equal_id) + error('dseries::from: Wrong syntax! The expression following the DO keyword must be an assignment (missing equal symbol).') +end + +% Issue ann error message if the user attempts to do more than one assignment. +if ~isequal(length(equal_id),1) + error('dseries::from: Not yet implemented! Only one assignment is allowed in the FROM-TO-DO statement.') +end + % Get all the variables involved in the recursive expression. variables = unique(regexpi(EXPRESSION, '\w*\(t\)|\w*\(t\-\d\)|\w*\(t\+\d\)|\w*\.\w*\(t\)|\w*\.\w*\(t\-\d\)|\w*\.\w*\(t\+\d\)','match')); @@ -221,54 +232,50 @@ for i=1:number_of_variables error(msg) end if d2>var.dates(end)-leadlagtable{i,4} - msg = sprintf('dseries::from: Last date of the loop (%s) is inconsistent with %s''s range!\n',char(d2),current_variable); - msg = [msg, sprintf(' Last date should be less than or equal to %s.',char(var.dates(end)-leadlagtable{i,4}))]; - error(msg) + % The first variable should be the assigned variable (will be tested later) + if ~isassignedvariable(leadlagtable{i,1},EXPRESSION) + msg = sprintf('dseries::from: Last date of the loop (%s) is inconsistent with %s''s range!\n',char(d2),current_variable); + msg = [msg, sprintf(' Last date should be less than or equal to %s.',char(var.dates(end)-leadlagtable{i,4}))]; + error(msg) + else + var = [var; dseries(NaN((d2-var.dates(end)),1),var.dates(end)+1:d2,var.name)]; + end end eval(sprintf('%s = var;',current_variable)); end end -% Check that the recursion is assigning something to a variable -equal_id = strfind(EXPRESSION,'='); -if isempty(equal_id) - error('dseries::from: Wrong syntax! The expression following the DO keyword must be an assignment (missing equal symbol).') +% Get the name of the assigned variable (with time index) +assignedvariablename = regexpi(EXPRESSION(1:equal_id-1), '\w*\(t\)|\w*\(t\-\d\)|\w*\(t\+\d\)|\w*\.\w*\(t\)|\w*\.\w*\(t\-\d\)|\w*\.\w*\(t\+\d\)','match'); +if isempty(assignedvariablename) + error('dseries::from: Wrong syntax! The expression following the DO keyword must be an assignment (missing variable before the equal symbol).') end -if isequal(length(equal_id),1) - % Get the name of the assigned variable (with time index) - assignedvariablename = regexpi(EXPRESSION(1:equal_id-1), '\w*\(t\)|\w*\(t\-\d\)|\w*\(t\+\d\)|\w*\.\w*\(t\)|\w*\.\w*\(t\-\d\)|\w*\.\w*\(t\+\d\)','match'); - if isempty(assignedvariablename) - error('dseries::from: Wrong syntax! The expression following the DO keyword must be an assignment (missing variable before the equal symbol).') +if length(assignedvariablename)>1 + error('dseries::from: No more than one variable can be assigned!') +end +% Check if the model is static +start = regexpi(assignedvariablename{1},'\(t\)|\(t\-\d\)|\(t\+\d\)'); +index = assignedvariablename{1}(start:end); +assignedvariablename = assignedvariablename{1}(1:start-1); +indva = strmatch(assignedvariablename, leadlagtable(:,1)); +dynamicmodel = ~isempty(regexpi(EXPRESSION(equal_id:end), ... + sprintf('%s\\(t\\)|%s\\(t\\-\\d\\)|%s\\(t\\+\\d\\)',assignedvariablename,assignedvariablename,assignedvariablename),'match')); +% Check that the dynamic model for the endogenous variable is not forward looking. +if dynamicmodel + indum = index2num(index); + if indum1 - error('dseries::from: No more than one variable can be assigned!') +end +% Check that the assigned variable does not depend on itself (the assigned variable can depend on its past level but not on the current level). +if dynamicmodel + tmp = regexpi(EXPRESSION(equal_id+1:end), ... + sprintf('%s\\(t\\)|%s\\(t\\-\\d\\)|%s\\(t\\+\\d\\)',assignedvariablename,assignedvariablename,assignedvariablename),'match'); + tmp = cellfun(@extractindex, tmp); + tmp = cellfun(@index2num, tmp); + if ~all(tmp(:)