Validate
This class contains methods to validate data according to class type, length, and definiteness.
SYNTAX [valid_flag value] = Validate.SCALAR(in,'PropertyName',Propertyvalue,...); [valid_flag value] = Validate.ARRAY(in,'PropertyName',Propertyvalue,...);
INPUTS in : Input object that is to be validated
PROPERTIES type {double} : The required class type of the input object. Cell ( true | {false} ) : Specifies if cell arrays are permitted in which case the properties are applied to all elements of the cell array. MinVal {-inf} MaxVal {inf} MinLen {0} MaxLen {inf}
EXAMPLES
[valid_flag value] = Validate.ARRAY(in);
==> array of doubles (empty permitted) [valid_flag value] = Validate.ARRAY(in,'Cell',true);
==> array of doubles (cell array of array of doubles permitted) [valid_flag value] = Validate.ARRAY(in,'type','int');
==> array of integer values [valid_flag value] = Validate.SCALAR(in,'minLen',1);
==> scalar double (empty not permitted) [valid_flag value] = Validate.SCALAR(in,'type','Name','Cell',true);
==> scalar Name object (cell array of scalar Name objects permitted) [valid_flag value] = Validate.ARRAY(in,'minLen',1,'minVal',eps);
==> array of positive definite doubles with at least one element. [valid_flag value] = Validate.SCALAR(in,'maxVal',0);
==> scalar negative semidefinite double. [valid_flag value] = Validate.ARRAY(in,'type','int','minLen',3','maxLen',3,'minVal',0,'maxVal',255);
==> 3-element array of integers between 0 and 255.Contents
classdef Validate < hgsetget
% This class is a static class that provides input validation services. % URL : $URL: $ % Log : $Id: Validate.html,v 1.1 2008/07/23 12:51:20 jberg Exp $ % Copyright (c) 2008 The MathWorks, Inc.
Class Properties
properties ( SetAccess = 'public', GetAccess = 'public' ) Cell; % default Cell Permitted; maxLen; % default Max Length; maxVal; % default Max Value; minLen; % default Min Length; minVal; % default Min Value; Type; % default Type; end properties ( SetAccess = 'private', GetAccess = 'private', Constant = true ) % Default properties CELL_PERMITTED = false; % default Cell Permitted; MAX_LEN = inf; % default Max Length; MAX_VAL = inf; % default Max Value; MIN_LEN = 0; % default Min Length; MIN_VAL = -inf; % default Min Value; TYPE = 'double'; % default Type; end methods function obj = Validate(varargin) end end methods (Static = true)
Public STATIC Helper Methods
function [valid_flag out] = SCALAR(varargin) varargin(end+1) = {'MaxLen'}; varargin(end+1) = {1}; [valid_flag out] = Validate.GENERIC(varargin{:}); end function [valid_flag out] = ARRAY(varargin) [valid_flag out] = Validate.GENERIC(varargin{:}); end function [valid_flag out] = GENERIC(varargin) in = varargin{1}; [type,cell_permitted,min_val,max_val,min_len,max_len] = ... Validate.assemble_vargs(varargin{2:end}); % Because there are different ways to represent logical values, we % must first convert valid values to logical before checking type. if strcmpi(type,'logical') in = Validate.Convert2Logical(in); end % Check size valid_flag = Validate.check_size(in,min_len,max_len,cell_permitted); % Is input empty? If valid_flag = true, then empty must be % acceptable. if valid_flag && ~isempty(in) % Check type valid_flag = Validate.check_type(in,type,cell_permitted,min_len); % Some types require further validation if valid_flag && isnumeric(in) % Check val valid_flag = Validate.check_val(in,min_val,max_val,cell_permitted); end if valid_flag && strcmpi(type,'int') valid_flag = Validate.check_int(in,cell_permitted); end end if valid_flag % Passed all hurdles, send back input out = in; else out = NaN; warning('%s.GENERIC could not interpret input as a valid %s',... mfilename,type) %#ok<WNTAG> end end function in = Convert2Logical(in) % Here, we want to allow other representations of true and false if iscell(in) in(cellfun(@(x) x==1,in)) = {true}; in(cellfun(@(x) strcmpi(x,'true'),in)) = {true}; in(cellfun(@(x) strcmpi(x,'t'),in)) = {true}; in(cellfun(@(x) strcmpi(x,'yes'),in)) = {true}; in(cellfun(@(x) strcmpi(x,'y'),in)) = {true}; in(cellfun(@(x) strcmpi(x,'on'),in)) = {true}; in(cellfun(@(x) x==0,in)) = {false}; in(cellfun(@(x) strcmpi(x,'false'),in)) = {false}; in(cellfun(@(x) strcmpi(x,'f'),in)) = {false}; in(cellfun(@(x) strcmpi(x,'no'),in)) = {false}; in(cellfun(@(x) strcmpi(x,'n'),in)) = {false}; in(cellfun(@(x) strcmpi(x,'off'),in)) = {false}; else true_idx = false(size(in)); false_idx = false(size(in)); nonlogical_idx = true(size(in)); true_idx(arrayfun(@(x) x==1,in)) = true; true_idx(arrayfun(@(x) strcmp(x,'true'),in)) = true; true_idx(arrayfun(@(x) strcmp(x,'t'),in)) = true; true_idx(arrayfun(@(x) strcmp(x,'yes'),in)) = true; true_idx(arrayfun(@(x) strcmp(x,'y'),in)) = true; true_idx(arrayfun(@(x) strcmp(x,'on'),in)) = true; false_idx(arrayfun(@(x) x==0,in)) = true; false_idx(arrayfun(@(x) strcmp(x,'false'),in)) = true; false_idx(arrayfun(@(x) strcmp(x,'f'),in)) = true; false_idx(arrayfun(@(x) strcmp(x,'no'),in)) = true; false_idx(arrayfun(@(x) strcmp(x,'n'),in)) = true; false_idx(arrayfun(@(x) strcmp(x,'off'),in)) = true; in = true_idx; in(false_idx) = false; nonlogical_idx(true_idx) = false; nonlogical_idx(false_idx) = false; if any(any(nonlogical_idx)) in = double(in); end end end function [type,Cell,MinVal,MaxVal,MinLen,MaxLen] = assemble_vargs(varargin) % Input Properties in_prop = {'type','Cell','MinVal','MaxVal','MinLen','MaxLen'}; % Retrieve default properties in_val{1} = Validate.TYPE; in_val{2} = Validate.CELL_PERMITTED; in_val{3} = Validate.MIN_VAL; in_val{4} = Validate.MAX_VAL; in_val{5} = Validate.MIN_LEN; in_val{6} = Validate.MAX_LEN; % Override the default properties according to varargin propertyArgIn = varargin; while length(propertyArgIn) >= 2, prop = propertyArgIn{1}; val = propertyArgIn{2}; idx = strmatch(lower(prop),lower(in_prop),'exact'); if isempty(idx) warning('%s.%s not sure how to handle property %s',... mfilename,'assemble_vargs',prop) %#ok<WNTAG> else in_val{idx} = val; %#ok<AGROW> end propertyArgIn = propertyArgIn(3:end); end [type,Cell,MinVal,MaxVal,MinLen,MaxLen] = deal(... in_val{1},in_val{2},in_val{3},in_val{4},in_val{5},in_val{6}); end function valid_flag = check_type(in,type,cell_permitted,min_len) valid_flag = false; % Use min_len to determine if empty is acceptable if isempty(in) && min_len == 0 valid_flag = true; else is_cell = iscell(in); if is_cell if cell_permitted valid_flag = all(all(cell2mat(cellfun(@(x) isa(x,type),in,'uniformoutput',false)))); else return; end end if isa(in,type) valid_flag = true; end end end function valid_flag = check_size(in,min_limit,max_limit,cell_permitted) valid_flag = false; is_cell = iscell(in); if isempty(in) the_lengths = 0; elseif is_cell if cell_permitted % size limits pertain to cell elements the_lengths = cell2mat(cellfun(@(x) length(x(:)),in,'uniformoutput',false)); else return; end else the_lengths = length(in(:)); end if (min(min(the_lengths)) >= min_limit) && (max(max(the_lengths)) <= max_limit) valid_flag = true; end end function valid_flag = check_val(in,min_limit,max_limit,cell_permitted) valid_flag = false; is_cell = iscell(in); if is_cell if cell_permitted % value limits pertain to cell elements the_mins = min(min(cell2mat(cellfun(@(x) min(min(x)),in,'uniformoutput',false)))); the_maxs = max(max(cell2mat(cellfun(@(x) max(max(x)),in,'uniformoutput',false)))); else return; end else the_mins = min(min(in)); the_maxs = max(max(in)); end if isempty(in) || ((min(the_mins) >= min_limit) && (max(the_maxs) <= max_limit)) valid_flag = true; end end function valid_flag = check_int(in,cell_permitted) valid_flag = false; is_cell = iscell(in); if is_cell if cell_permitted % values pertain to cell elements is_int = call2mat(cellfun(@(x) round(x)==x,in,'uniformoutput',false)); else return; end else is_int = round(in)==in; end if all(all(is_int)) valid_flag = true; end end
end
end