MATLAB:使用inputParser和varargin

Dan*_*hoa 4 matlab

我有一个函数,我想通过参数传递varargin,并使用它inputParser来确保输入是理智的.有些论据是必需的,有些则不是.这是一个例子:

function myFunc(varargin)
    p = inputParser;
    p.addRequired(...
            'numStates', ...
                @(x) validateattributes(x, {'numeric'}, ...
                {'scalar', 'integer', 'positive'}));
        p.addRequired(...
            'numInps', ...
                @(x) validateattributes(x, {'numeric'}, ...
                {'scalar', 'integer', 'positive'}));
        p.addRequired(...
            'numOuts', ...
                @(x) validateattributes(x, {'numeric'}, ...
                {'scalar', 'integer', 'positive'}));
        p.addRequired(...
            'X0', ...
                @(x) validateattributes(x, {'numeric'}, ...
                {'vector'}));
        p.addOptional(...
            'freq', 10, ...
                @(x) validateattributes(x, {'numeric'}, ...
                {'scalar', 'integer', 'positive'}));
        p.addOptional(...
            'SimulinkVariables', struct(), ...
                @(x) isa(x, 'struct'));

    p.parse(varargin{:});

    %# do stuff with variables
end
Run Code Online (Sandbox Code Playgroud)

我希望能够传递如下参数; 只要有必要的那一对,那么哪一对传入就没关系.所以示例调用可能是:

myFunc('numStates', 4, 'numInps', 2, 'numOUts', 3, 'X0', [4;0]);
Run Code Online (Sandbox Code Playgroud)

显然,这种语法是非法的; parse()期望它中的第一个参数是必需的值,但它们不应该被明确命名,即,如:

function myFunc(numStates, numInps, numOuts, X0, varargin)
    ...
    p.parse(numStates, numInps, numOuts, X0, varargin{:});

end
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法可以做到我想要的,即第一个功能?我想最简单的事情就是做一些事情来重新排序元素varargin和踢出参数名称,但这并不是非常优雅.

dum*_*ter 7

我能想到的最优雅的解决方案是子类inputParser.所以你可以做这样的事情(另存为myInputParser.m):

classdef myInputParser < inputParser
    properties
        required = {};
    end

    methods
        function obj = myInputParser
            obj = obj@inputParser;
        end

        function addRequired(obj, argname, validator)
            obj.required = {obj.required{:}, argname};
            obj.addOptional(argname, [], validator);
        end

        function parse(obj, varargin)
            params_input = varargin(1:2:end);
            for i=1:length(obj.required)
                if isempty(strmatch(obj.required{i}, params_input))
                    error(sprintf('Required named parameter %s was not passed to function', obj.required{i}));
                end
            end
            parse@inputParser(obj, varargin{:});
        end

    end
end
Run Code Online (Sandbox Code Playgroud)

然后改变

    p = inputParser;
Run Code Online (Sandbox Code Playgroud)

    p = myInputParser;
Run Code Online (Sandbox Code Playgroud)

然后你的代码将按你的意愿工作.

请注意,这可能无法正确处理所有边缘情况,并且我没有对它进行过广泛的测试,但它确实适用于您的示例用例.


yuk*_*yuk 5

在InputParser中,您只能添加ParameterName - ParameterValueaddParamValue.这些论点应该是可选的.

作为一种解决方法,您可以添加所有参数,addParamValue并将其[]用作必需参数的默认值.

然后,您可以执行以下操作之一:

  • validateattributes函数中为必需参数添加'非空' (但是在这种情况下,错误消息不会说这是必需的参数,但它必须是非空的)
  • 或者使用您自己的错误消息添加单独的检查(带ifassert)所需的参数不应为空.

您不限于使用[].默认值可以是任何不适合特定参数的值,并且易于检查.