如何在可选字符串输入中使用MATLAB的inputParser?该文件说“使用验证功能”,但目前还不清楚如何做到这一点

问题描述:

我有一个MATLAB文件,其中包含一个顶级函数​​。该函数又包含两个嵌套函数,即mysummyprod,它们的功能和参数相同,除了一个在内部使用@sum,而另一个在内部使用@prod。我的目标是创建一个包装函数,用于处理mysummyprod中的所有验证和输入解析。这个功能被称为applyFunc如何在可选字符串输入中使用MATLAB的inputParser?该文件说“使用验证功能”,但目前还不清楚如何做到这一点

这里是棘手的地方。 mysummyprod有两种形式:

  1. mysum(v)回报sum(v, 1)
  2. mysum(v, 'imag')sum(v, 1) + 1i返回

输入的任何其它的组合应引发错误。

我在使用inputParser解析输入的各种组合时遇到问题,特别是可选的字符串输入。下面的代码:

function sandbox() 
%% Data 
v = [1 4; 3 3]; 

%% Calculations 
s = mysum(v); 
si = mysum(v, 'imag'); 
p = myprod(v); 
pi = myprod(v, 'imag'); 

%% Accuracy tests 
assert(isequal(s, [4 7])) 
assert(isequal(si, [4+1i 7+1i])) 
assert(isequal(p, [3 12])) 
assert(isequal(pi, [3+1i 12+1i])) 

    function x = mysum(varargin) 
     x = applyFunc(@sum, varargin{:}); 
    end 

    function x = myprod(varargin) 
     x = applyFunc(@prod, varargin{:}); 
    end 
end 

function x = applyFunc(func, varargin) 

p = inputParser(); 
p.addRequired('func', @(x) validateattributes(x, {'function_handle'}, {'scalar'})); 
p.addRequired('v', @(x) validateattributes(x, {'double'}, {}, 'applyFunc:msg', 'v')); 
p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''})); % THIS LINE IS THE PROBLEM 
p.parse(func, varargin{:}); 

f = p.Results.func; 
v = p.Results.v; 
strflag = p.Results.imag; 

x = f(v); 
if ~isempty(strflag) 
    validatestring(strflag, {'imag'}); 
    x = x + 1i; 
end 
end 

是造成该问题的行这一个(如标注在上面的代码中):

p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''})); 

为inputParser文档说:

For optional string inputs, specify a validation function. Without a validation function, the input parser interprets valid string inputs as invalid parameter names and throws an error.

不幸的是,我不知道如何做到这一点。有什么简单的我失踪或什么?如果'imag'说法是没有(如在sp分配)通过,代码工作正常,但如果我不通过它,我得到这个错误:

Error using sandbox>applyFunc (line 32) 
The value of 'imag' is invalid. It must satisfy the function: 
@(x)validatestring(x,{'imag',''}). 
Error in sandbox/mysum (line 18) 
     x = applyFunc(@sum, varargin{:}); 
Error in sandbox (line 7) 
si = mysum(v, 'imag'); 

任何帮助吗?

问题是validatestring返回单元格参数({'imag',''})中的匹配字符串,而不是布尔值,指示它是否通过验证。相反,使用strcmpany

@(x) any(strcmp(x,{'imag', ''})) 

而且,与validatestring,如果输入的字符串不匹配或者'imag'''(其实只是'imag'因为空字符串只在R2014a +匹配),它会抛出一个错误,而不是返回false以便inputParser可以返回相应的错误。

另一种很好的方式来解决这个问题是要改变的applyFunc语法完全让,而不是只'imag'作为一个可选的字符串输入参数,使用Parameter-Value'imag'作为参数和经过验证的布尔值作为输入。

评价通过荷银建议的输入定义:

p.addParameter('imag', false, @(x)validateattributes(x, {'logical'}, {'scalar'})) 

用法:

mysum(x,'imag',true) 
mysum(x)    % default is equivalent to mysum(x,'imag',false) 

这将简化的代码的其余部分与p.Result.imag是一个logical标量。我建议:

x = f(v) + p.Result.imag*1i; 
+3

+1使用'strcmp'解决了这个问题。我个人不喜欢“可选参数”,我宁愿使用名称值参数参数:'p.addParameter('imag',false,@(x)validateattributes(x,{'logical'},{'标量'}))'。那么'p.Result.imag'可能是真或假。 – Amro

+0

这是在代码中稍后清理比较的好方法。它可能是具有逻辑值的参数值参数。 – chappjc

+0

@chappjc感谢您的帮助。我真的很喜欢使用名称 - 值对而不是可选参数,所以我可能会将它用于新代码。不幸的是,我现在正在使用的代码是不允许更改的API的遗留问题。 –

问题不inputParser,我认为这个问题是validatestring

1)首先,它不匹配空字符串:

>> x = '' 
x = 
    '' 

>> validatestring(x, {'imag',''}) 
Expected input to match one of these strings: 

imag, 

The input did not match any of the valid strings. 
Caused by: 
    Error using validatestring>checkString (line 85) 
    Expected input to be a row vector. 

2)其次,如果匹配成功,它返回解析字符串(从有效的选择之一),而不是真/假。 inputParser要求验证功能要么返回一个布尔值,要么失败时抛出错误。

+0

你见过R2014a预发布发行说明吗?现在似乎是一个空的字符串匹配。就好像MathWorks读取SO一样。 :) – chappjc

+0

我还没有看到预售,但这是个好消息。感谢您让我们知道..出于好奇,预售中是否有重大变化? HG2图形也许? – Amro

+0

HG2不是默认设置。当你在命令行上点击向上键时,会出现一个令人讨厌的新弹出命令历史记录。 MEX设置现在更容易,但是使用单独的C和C++配置(前面我看到质量混乱)。 “flipud”,“fliplr”和“rot90”命令现在可用于多维数组,但语法已更改。一些新的测试功能,例如'issymmetric','isdiag'等。 – chappjc