如何根据已经给定的必需参数使用inputParser验证参数

时间:2016-04-27 12:07:48

标签: matlab

我有两个必需的输入,称为分布,以及两个可选的参数值对:​​ grainCount - 整数值和< strong> radius - 双值。 分布必须采用1x4向量,分布可以是&#39;统一&#39;或者&#39; hex&#39;。到现在为止,没有问题。 grainCount 仅在分发设置为“统一”时才有意义。同样,如果分布设置为&#39; hex&#39;,则半径有意义。我想要做的是如果 radius 提供了统一的&#39;则要发出警告。 发布 grainCount 随附<&lt; hex;&#39;的分布即可。我正在考虑将验证函数创建为嵌套函数,以便它可以看到 inputParser 对象并可以提取已经给出的分布值。问题是只能看到给定属性的名称,而不能看到它的设定值(即“均匀”或“十六进制”)。我该怎么解决?我更喜欢使用 inputParser 类的解决方案,因为它很强大。以下是附加代码。我用createRVE([0 1 1 2], 'hex', 'nGrain',3)称呼它。

function out = createRVE(domain, distribution, varargin)
%% Process inputs
% Provide the callback functions for the input processing
validDistribution = {'uniform', 'hex'};
validateDistribution = @(x) any(validatestring(x, validDistribution));
    function TF = validateDomain(domain)
        TF = false;
        if ~isnumeric(domain)
            error('domain must have numeric type.');
        elseif ~(isequal(size(domain),[1 4]) || isequal(size(domain),[4 1]))
            error('domain must have the size 1x4 or 4x1.');
        else
            TF = true;
        end
    end

    function TF = validateGrainCount(nGrain)
        TF = false;
        if ~isnumeric(nGrain)
            error('nGrain must have numeric type.');
        elseif ~isscalar(nGrain)
            error('nGrain must be a scalar.');
        else
            TF = true;
        end
        % Check if the distribution is 'uniform'
        % pseudocode: if p.distribution has value 'hex'
        %                warning('nGrain is defined only for uniform distribution.');
        %             end
        % How can I obtain that the distribution is 'hex' or not?
    end

% Parse the inputs with the inputParser class
p = inputParser;
% Two required inputs: the tesselated domain and the distribution of seeds
addRequired(p, 'domain', @validateDomain);
addRequired(p, 'distribution', validateDistribution);
% Add parameter name-value pairs
addParameter(p, 'nGrain', 10, @validateGrainCount)
% Parse it
parse(p, domain, distribution, varargin{:});
end

1 个答案:

答案 0 :(得分:1)

不幸的是,inputParser类不足以解决这个问题。您可以使用inputParser单独检查每个输入,但您必须自己进行更复杂的处理。如下所示:

function out = createRVE(domain, distribution, varargin)
    inputs = parseInputs(domain, distribution, varargin{:});

    % rest of the function

end

function inputs = parseInputs(domain, distribution, varargin)
    VALID_DISTRIBUTION = {'uniform', 'hex'};
    parser = inputParser();
    parser.addRequired('domain', @(x) isnumeric(x) && isvector(x) && numel(x) == 4);
    parser.addRequired('distribution', @(x) ismember(x, VALID_DISTRIBUTION));
    % Here, we add the optional parameters with defaults set to NaN
    % That way we can check whether they were set
    parser.addParameter('grainCount', NaN, @(x) isscalar(x) && floor(x) == ceil(x));
    parser.addParameter('radius', NaN, @(x) isscalar(x) && isa(x, 'double'));
    parser.parse(domain, distribution, varargin{:})
    inputs = parser.Results;
    if ~isnan(inputs.radius) && strcmp(inputs.distribution, 'uniform')
        warning('radius is defined only for a hex distribution');
    end
    if ~isnan(inputs.grainCount) && strcmp(inputs.distribution, 'hex')
        warning('grainCount is defined only for a uniform distribution');
    end
end