% processAlgorithmParameters
%
% Usage: [exitFlag exitMsg structOfReadParameters] = processAlgorithmParameters (algorithmParametersString, cellOfDefaultParameters)
%
% Abstract: This function process the algorithm parameters string entered
% by the user, checking if the user defined values are right (right data
% type, right value range) and setting up the parameters non-defined by the
% user to default values.
%
% Arguments:
% o In:
% algorithmParametersString: String of algorithm parameters defined
% by the user. The syntax of this string consist of paramaters separated
% by commas. Each parameter is defined as:
% paramaterName = parameterValue
%
% For several parameters:
%
% parameter1Name = parameter1Value (, parameter2Name = parameter2Value, ...)
%
% The number of white spaces is not checked.
%
% cellOfDefaultParameters:(numberOfDefaultParameters x 4): Cell array of
% strings which consist of as many rows as default parameters and four
% columns, where the first one are the parameter names of each parameter,
% the second one is the default-value of each parameter, the third one is
% the data type of each parameter, and the fourth one is the valid range of
% values of each parameter.
% The valid strings for the data type are:
% - 'boolean'
% - 'integer'
% - 'numeric'
% - 'string'
% The valid range is not defined for 'boolean' data type. For data types
% 'integer' and 'numeric', the valid range is defined as a string with
% this syntax:
%
% typeOfLowerLimit lower limit , upper limit typeOfUpperLimit
%
% where typeOfLowerLimit can be some or ( or [ , depending on the set of
% valid values is open or closed, respectively; and
% where typeOfUpperLimit can be some or ) or ] , depending on the set of
% valid values is open or closed, respectively;
%
% For data types 'string', the valid range is defined as cell array of
% strings, where each string is a valid value for the paramater.
%
% o Out:
% . exitFlag: If exitFlag = 0, the processing of the algorithm parameters
% string was succesful. If exitFlag = -1, the processing of the algorithm
% parameters string was failed.
%
% exitMsg: Exit Message.
%
% . cellOfReadParameters: Cell array of strings which consist of as many
% rows as algorithm parameters and two columns, where the first one are
% the parameter names of each parameter, and the second one are the
% parameter values of each parameter.
%
function [exitFlag exitMsg structOfReadParameters] = processAlgorithmParameters (algorithmParametersString, cellOfDefaultParameters)
exitFlag = 0;
exitMsg = 'Succesful processing';
[numberOfDefaultParameters numberOfFields] = size(cellOfDefaultParameters);
structOfReadParameters = struct();
%%% check default values are good
if (length (unique (cellOfDefaultParameters(:,1))) ~= length (cellOfDefaultParameters(:,1)))
exitFlag = -1; exitMsg = 'Some default parameter name is repeated'; return
end
%1) First, we create the default parameters and assign them to varargout and check them.
for i=1:numberOfDefaultParameters,
paramNameAsString = cellOfDefaultParameters{i,1};
paramValueAsString = cellOfDefaultParameters{i,2};
[exitFlagOfValidate exitMsgOfValidate paramValueValidated] = ...
validateParamaterValue(paramValueAsString,cellOfDefaultParameters{i,3}, cellOfDefaultParameters{i,4});
if exitFlagOfValidate == -1,
exitFlag = -1; exitMsg = 'Error on validating the Default Parameters'; return
end
structOfReadParameters = setfield (structOfReadParameters , paramNameAsString , paramValueValidated);
end
%2) We check the algorithmParametersString and assign the user-defined
%parameter to the varargout{:}
algorithmParametersTokens = regexp(algorithmParametersString, '([^,]*)', 'tokens');
numberOfUserDefinedParameters = numel(algorithmParametersTokens);
for i=1:numberOfUserDefinedParameters,
pairParamNameParamValue = regexp(cell2mat(algorithmParametersTokens{i}), '([^=]*)', 'tokens');
if not(numel(pairParamNameParamValue)==2),
exitFlag = -1;
exitMsg = 'Bad syntax of "Algorithm Parameters"';
varargout =cell(1,numberOfDefaultParameters);
return
end
paramNameAsString=strtrim(cell2mat(pairParamNameParamValue{1}));
paramValueAsString=strtrim(cell2mat(pairParamNameParamValue{2}));
parameterIndex = find (strcmp(paramNameAsString, cellOfDefaultParameters(:,1)) == 1);
if isempty(parameterIndex),
exitFlag = -1; exitMsg = 'Some entered Parameter Name is not valid';
return
end
% We check the user defined parameter values for the user defined data
% type and range of the parameter
[exitFlagOfValidate exitMsgOfValidate paramValueValidated] = ...
validateParamaterValue(paramValueAsString,cellOfDefaultParameters{parameterIndex,3},cellOfDefaultParameters{parameterIndex,4});
if exitFlagOfValidate == -1,
exitFlag = -1; exitMsg = 'Error on validating the User-Defined Parameters'; return
end
structOfReadParameters = setfield (structOfReadParameters , paramNameAsString , paramValueValidated);
end
end
%%%This fuction validates a parameter value,checking if the value belongs
%%%to the valid range and the right data type.
%The input arguments (parameterValueAsString, dataTypeOfParameter,
%validRangeOfParameter) are strings.
%The output argument paramValueValidated is the validate value of the
%parameter.
%The output argument exitFlag is "-1" if the validation failed (otherwise,
%"0"), and the exitMsg is a string with a message about the validation
%result.
function [exitFlag exitMsg paramValueValidated] = validateParamaterValue(parameterValueAsString, dataTypeOfParameter, validRangeOfParameter)
exitFlag = 0;
exitMsg = 'Valid Parameter Value' ;
%Only if the data type of the parameter is numeric 'integer' or
%'numeric', we check the "validRangeOfParameter"
if (strcmp(dataTypeOfParameter, 'integer')) | (strcmp(dataTypeOfParameter, 'numeric')) ,
validRangeOfParameterTokens = regexp(validRangeOfParameter, '([^,]*)', 'tokens');
if not(numel(validRangeOfParameterTokens)==2),
exitFlag = -1;
exitMsg = 'Bad syntax of "validRangeOfParameter"';
paramValueValidated = [];
return
end
typeOfLimit=cell(1,2);
limit=zeros(1,2);
for i=1:2,
typeOfLimit(i) = regexp(cell2mat(validRangeOfParameterTokens{i}) , '[ \[ \] ( ) ]*', 'match');
limit(i)=str2num(cell2mat(regexp(cell2mat(validRangeOfParameterTokens{i}) , '[^ \[ \] ( ) ]*', 'match')));
end
end
%Now we check the parameterValue for the user-defined data type and the
%user-defined range of values
dataTypeOfParameter;
switch dataTypeOfParameter
case 'boolean',
paramValueValidated = str2num(parameterValueAsString);
if numel(intersect(paramValueValidated, [0 1]))==0,
exitFlag = -1;
exitMsg = 'Not Valid Boolean Parameter Value';
paramValueValidated = [];
return
end
case 'integer',
paramValueValidated = str2num(parameterValueAsString);
if not(isnumeric(paramValueValidated)) | (paramValueValidated ~= round(paramValueValidated)),
exitFlag = -1;
exitMsg = 'Not Valid Integer Parameter Value';
paramValueValidated = [];
return
end
%we check the lower limit
switch typeOfLimit{1}
case '('
if paramValueValidated <= limit(1),
exitFlag = -1;
exitMsg = 'Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
case '['
if paramValueValidated < limit(1),
exitFlag = -1;
exitMsg = 'Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
otherwise
exitFlag = -1;
exitMsg = 'Bad syntax of "validRangeOfParameter"';
paramValueValidated = [];
return
end
%we check the upper limit
switch typeOfLimit{2}
case ')'
if paramValueValidated >= limit(2),
exitFlag = -1;
exitMsg = 'Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
case ']'
if paramValueValidated > limit(2),
exitFlag = -1;
exitMsg = 'Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
otherwise
exitFlag = -1;
exitMsg = 'Bad syntax of "validRangeOfParameter"';
paramValueValidated = [];
return
end
case 'numeric',
paramValueValidated = str2num(parameterValueAsString);
if not(isnumeric(paramValueValidated)),
exitFlag = -1;
exitMsg = 'Not Valid Non-Integer Parameter Value';
paramValueValidated = [];
return
end
%we check the lower limit
switch typeOfLimit{1}
case '('
if paramValueValidated <= limit(1),
exitFlag = -1;
exitMsg = 'Non-Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
case '['
if paramValueValidated < limit(1),
exitFlag = -1;
exitMsg = 'Non-Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
otherwise
exitFlag = -1;
exitMsg = 'Bad syntax of "validRangeOfParameter"';
paramValueValidated = [];
return
end
%we check the upper limit
switch typeOfLimit{2}
case ')'
if paramValueValidated >= limit(2),
exitFlag = -1;
exitMsg = 'Non-Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
case ']'
if paramValueValidated > limit(2),
exitFlag = -1;
exitMsg = 'Non-Integer Parameter Value Out Of Range';
paramValueValidated = [];
return
end
otherwise
exitFlag = -1;
exitMsg = 'Bad syntax of "validRangeOfParameter"';
paramValueValidated = [];
return
end
case 'string',
paramValueValidated = parameterValueAsString;
if not(ischar(parameterValueAsString))
exitFlag = -1;
exitMsg = 'Not Valid String Parameter Value';
paramValueValidated = [];
return
end
if not(isempty(validRangeOfParameter)),
%%% "check validRangeOfParameter" are good
numNotRepeatedElementsInValidRange = length(unique(validRangeOfParameter));
numElementsInValidRange = length(validRangeOfParameter);
if (numNotRepeatedElementsInValidRange ~= numElementsInValidRange)
exitFlag = -1;
exitMsg = 'Some possible string as parameter value is repeated';
paramValueValidated = [];
return
end
%% check the value range of strings
if sum (strcmp(parameterValueAsString, validRangeOfParameter)) == 0,
exitFlag = -1;
exitMsg = 'Parameter Value is not a valid string';
paramValueValidated = [];
return
end
end
end
end