function Formula = CheckAndConvert(Input) % converts from MathML in-fix to MATLAB functions % Filename : CheckAndConvert.m % Description : converts from MathML in-fix to MATLAB functions % Author(s) : SBML Team % Organization: University of Hertfordshire STRC % Created : 2004-12-13 % Revision : $Id: CheckAndConvert.m 8704 2009-01-04 02:26:05Z mhucka $ % $HeadURL: https://sbml.svn.sourceforge.net/svnroot/sbml/trunk/libsbml/src/bindings/matlab/CheckAndConvert.m $ % % Copyright 2003 California Institute of Technology, the Japan Science % and Technology Corporation, and the University of Hertfordshire % % This library is free software; you can redistribute it and/or modify it % under the terms of the GNU Lesser General Public License as published % by the Free Software Foundation; either version 2.1 of the License, or % any later version. % % This library 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. The software and % documentation provided hereunder is on an "as is" basis, and the % California Institute of Technology, the Japan Science and Technology % Corporation, and the University of Hertfordshire have no obligations to % provide maintenance, support, updates, enhancements or modifications. In % no event shall the California Institute of Technology, the Japan Science % and Technology Corporation or the University of Hertfordshire be liable % to any party for direct, indirect, special, incidental or consequential % damages, including lost profits, arising out of the use of this software % and its documentation, even if the California Institute of Technology % and/or Japan Science and Technology Corporation and/or University of % Hertfordshire have been advised of the possibility of such damage. See % the GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with this library; if not, write to the Free Software Foundation, % Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. % % The original code contained here was initially developed by: % % Sarah Keating % Science and Technology Research Centre % University of Hertfordshire % Hatfield, AL10 9AB % United Kingdom % % http://www.sbml.org % mailto:sbml-team@caltech.edu % % Contributor(s): Formula = strrep(Input, 'arccosh', 'acosh'); Formula = strrep(Formula, 'arccot', 'acot'); Formula = strrep(Formula, 'arccoth', 'acoth'); Formula = strrep(Formula, 'arccsc', 'acsc'); Formula = strrep(Formula, 'arccsch', 'acsch'); Formula = strrep(Formula, 'arcsec', 'asec'); Formula = strrep(Formula, 'arcsech', 'asech'); Formula = strrep(Formula, 'arcsinh', 'asinh'); Formula = strrep(Formula, 'arctanh', 'atanh'); Formula = strrep(Formula, 'exponentiale', 'exp(1)'); Formula = strrep(Formula, 'geq', 'ge'); Formula = strrep(Formula, 'leq', 'le'); Formula = strrep(Formula, 'pow', 'power'); % any logical expressions can only have two arguments Formula = SortLogicals(Formula); % log(2,x) must become log2(x) Formula = strrep(Formula, 'log(2,', 'log2('); % root(n,x) must become nthroot(x,n) Index = strfind(Formula, 'root('); for i = 1:length(Index) % create a subformula root(n,x) SubFunction = ''; j = 1; nFunctions=0; %number of functions in expression closedFunctions=0; %number of closed functions while(nFunctions==0 || nFunctions~=closedFunctions) SubFormula(j) = Formula(Index(i)+j-1); if(strcmp(SubFormula(j),')')) closedFunctions=closedFunctions+1; end; if(strcmp(SubFormula(j),'(')) nFunctions=nFunctions+1; end; j = j+1; end; j = 6; n = ''; while(~strcmp(SubFormula(j), ',')) n = strcat(n, SubFormula(j)); j = j+1; end; j = j+1; x = SubFormula(j:length(SubFormula)-1); ReplaceFormula = regexprep(SubFormula, n, x, 'once'); ReplaceFormula = regexprep(ReplaceFormula,regexptranslate('escape',x),n,2); ReplaceFormula = regexprep(ReplaceFormula, 'root', 'nthroot', 'once'); Formula = strrep(Formula, SubFormula, ReplaceFormula); Index = strfind(Formula, 'root('); end; % log(n,x) must become (log(x)/log(n)) % but log(x) must be left alone LogTypes = IsItLogBase(Formula); Index = strfind(Formula, 'log('); for i = 1:length(Index) if (LogTypes(i) == 1) % create a subformula log(n,x) SubFormula = ''; j = 1; while(~strcmp(Formula(Index(i)+j-1), ')')) SubFormula(j) = Formula(Index(i)+j-1); j = j+1; end; SubFormula = strcat(SubFormula, ')'); j = 5; n = ''; while(~strcmp(SubFormula(j), ',')) n = strcat(n, SubFormula(j)); j = j+1; end; j = j+1; x = ''; while(~strcmp(SubFormula(j), ')')) x = strcat(x, SubFormula(j)); j = j+1; end; ReplaceFormula = sprintf('(log(%s)/log(%s))', x, n); Formula = strrep(Formula, SubFormula, ReplaceFormula); Index = Index + 7; end; end; function y = IsItLogBase(Formula) % returns an array of 0/1 indicating whether each occurence of log is % a log(n,x) or a log(x) % e.g. Formula = 'log(2,3) + log(6)' % IsItLogBase returns y = [1,0] y = 0; % find log LogIndex = strfind(Formula, 'log('); if (isempty(LogIndex)) return; else OpenBracket = strfind(Formula, '('); Comma = strfind(Formula, ','); CloseBracket = strfind(Formula, ')'); for i = 1:length(LogIndex) if (isempty(Comma)) % no commas so no logbase formulas y(i) = 0; else % find the opening bracket Open = find(ismember(OpenBracket, LogIndex(i)+3) == 1); % find closing bracket Close = find(CloseBracket > LogIndex(i)+3, 1); % is there a comma between Greater = find(Comma > OpenBracket(Open)); Less = find(Comma < CloseBracket(Close)); if (isempty(Greater) || isempty(Less)) y(i) = 0; else Equal = find(Greater == Less); if (isempty(Equal)) y(i) = 0; else y(i) = 1; end; end; end; end; end; function Formula = CorrectFormula(OriginalFormula, LogicalExpression) % CorrectFormula takes an OriginalFormula (as a char array) % and a Logical Expression (as a char array with following '(') % and returns the formula written so that the logical expression only takes 2 arguments % % ************************************************************************************* % % EXAMPLE: y = CorrectFormula('and(A,B,C)', 'and(') % % y = 'and(and(A,B), C)' % % find all opening brackets, closing brackets and commas contained % within the original formula OpeningBracketIndex = find((ismember(OriginalFormula, '(')) == 1); ClosingBracketIndex = find((ismember(OriginalFormula, ')')) == 1); CommaIndex = find((ismember(OriginalFormula, ',')) == 1); % check that tha number of brackets matches if (length(OpeningBracketIndex) ~= length(ClosingBracketIndex)) error('Bracket mismatch'); end; % find the commas that are between the arguments of the logical expression % not those that may be part of the argument % in the OpeningBracketIndex the first element refers to the opening % bracket of the expression and the last element of ClosingBracketIndex % refers to the the closing bracket of the expression % commas between other pairs of brackets do not need to be considered % e.g. 'and(gt(d,e),lt(2,e),gt(f,d))' % | | % relevant commas for i = 1:length(CommaIndex) for j = 2:length(OpeningBracketIndex) if ((CommaIndex(i) > OpeningBracketIndex(j)) && (CommaIndex(i) < ClosingBracketIndex(j-1))) CommaIndex(i) = 0; end; end; end; NonZeros = find(CommaIndex ~= 0); % if there is only one relevant comma % implies only two arguments % MATLAB can deal with the OriginalFormula if (length(NonZeros) == 1) Formula = OriginalFormula; return; end; % get elements that represent the arguments of the logical expression % as an array of character arrays % e.g. first element is between opening barcket and first relevant comma % next elements are between relevant commas % last element is between last relevant comma and closing bracket j = OpeningBracketIndex(1); ElementNumber = 1; for i = 1:length(NonZeros) element = ''; j = j+1; while (j <= CommaIndex(NonZeros(i)) - 1) element = strcat(element, OriginalFormula(j)); j = j + 1; end; Elements{ElementNumber} = element; ElementNumber = ElementNumber + 1; end; element = ''; j = j+1; while (j < ClosingBracketIndex(length(ClosingBracketIndex)) - 1) element = strcat(element, OriginalFormula(j)); j = j + 1; end; Elements{ElementNumber} = element; % iteratively replace the first two arguments with the logical expression applied to % the first two arguments % e.g. OriginalFormula = 'and(a,b,c,d)' % becomes 'and(and(a,b),c,d)' % which becomes 'and(and(and(a,b),c),d)' Formula = OriginalFormula; if (length(Elements) > 2) for i = 2:length(Elements)-1 Find = strcat(Elements{i-1}, ',', Elements{i}); Replace = strcat(LogicalExpression, Find, ')'); Formula = strrep(Formula, Find, Replace); Elements{i} = Replace; end; end; function Arguments = CheckLogical(Formula, LogicalExpression) % CheckLogical takes a Formula (as a character array) % and a LogicalExpression (as a char array) % and returns an array of character strings % representing the application of the logical expression within the formula % % NOTE the logical expression is followed by an '(' to prevent confusion % with other character strings within the formula % % ****************************************************************** % EXAMPLE: y = CheckLogical('piecewise(and(A,B,C), 0.2, 1)' , 'and(') % % y = 'and(A,B,C)' % % EXAMPLE: y = CheckLogical('or(and(A,B), and(A,B,C))', 'and(') % % y = 'and(A,B)' 'and(A,B,C)' % find the starting indices of all occurences of the logical expression Start = strfind(Formula, LogicalExpression); % if not found; no arguments - return if (isempty(Start)) Arguments = {}; return; end; for j = 1:length(Start) % each occurence of the logical expression Stop = 0; flag = 0; i = Start(j); output = ''; for i = Start(j):Start(j)+length(LogicalExpression) output = strcat(output, Formula(i)); end; i = i + 1; while ((Stop == 0) && (i <= length(Formula))) c = Formula(i); if (strcmp(c, '(')) flag = flag + 1; output = strcat(output, c); elseif (strcmp(c, ')')) if (flag > 0) output = strcat(output, c); flag = flag - 1; else output = strcat(output, c); Stop = 1; end; else output = strcat(output, c); end; i = i + 1; end; Arguments{j} = output; end; function y = SortLogicals(Formula) % SortLogicals takes a formula as a char array % and returns the formula with and logical expressions applied to only two arguments Formula = LoseWhiteSpace(Formula); Find = CheckLogical(Formula, 'and('); for i = 1:length(Find) Replace = CorrectFormula(Find{i}, 'and('); Formula = strrep(Formula, Find{i}, Replace); end; Find = CheckLogical(Formula, 'xor('); for i = 1:length(Find) Replace = CorrectFormula(Find{i}, 'xor('); Formula = strrep(Formula, Find{i}, Replace); end; Find = CheckLogical(Formula, 'or('); for i = 1:length(Find) Replace = CorrectFormula(Find{i}, 'or('); Formula = strrep(Formula, Find{i}, Replace); end; y = Formula; %********************************************************************** % LoseWhiteSpace(charArray) takes an array of characters % and returns the array with any white space removed % %********************************************************************** function y = LoseWhiteSpace(charArray) % LoseWhiteSpace(charArray) takes an array of characters % and returns the array with any white space removed % %---------------------------------------------------------------- % EXAMPLE: % y = LoseWhiteSpace(' exa mp le') % y = 'example' % %------------------------------------------------------------ % check input is an array of characters if (~ischar(charArray)) error('LoseWhiteSpace(input)\n%s', 'input must be an array of characters'); end; %------------------------------------------------------------- % get the length of the array NoChars = length(charArray); %------------------------------------------------------------- % create an array that indicates whether the elements of charArray are % spaces % e.g. WSpace = isspace(' v b') = [1, 1, 0, 1, 0] % and determine how many WSpace = isspace(charArray); NoSpaces = sum(WSpace); %----------------------------------------------------------- % rewrite the array to leaving out any spaces % remove any numbers from the array of symbols if (NoSpaces > 0) NewArrayCount = 1; for i = 1:NoChars if (~isspace(charArray(i))) y(NewArrayCount) = charArray(i); NewArrayCount = NewArrayCount + 1; end; end; else y = charArray; end;