From 4dad18b22251f52c15a6648a372bac1b84c73e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Scylla=29?= Date: Fri, 2 May 2014 12:30:34 +0200 Subject: [PATCH] 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. + +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_idd2 + 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)); \ No newline at end of file