如何在可选字符串输入中使用MATLAB的inputParser?该文件说“使用验证功能”,但目前还不清楚如何做到这一点
我有一个MATLAB文件,其中包含一个顶级函数。该函数又包含两个嵌套函数,即mysum
和myprod
,它们的功能和参数相同,除了一个在内部使用@sum
,而另一个在内部使用@prod
。我的目标是创建一个包装函数,用于处理mysum
和myprod
中的所有验证和输入解析。这个功能被称为applyFunc
。如何在可选字符串输入中使用MATLAB的inputParser?该文件说“使用验证功能”,但目前还不清楚如何做到这一点
这里是棘手的地方。 mysum
和myprod
有两种形式:
-
mysum(v)
回报sum(v, 1)
。 -
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'
说法是没有(如在s
和p
分配)通过,代码工作正常,但如果我不通过它,我得到这个错误:
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',''}
)中的匹配字符串,而不是布尔值,指示它是否通过验证。相反,使用strcmp
和any
:
@(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;
问题不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
要求验证功能要么返回一个布尔值,要么失败时抛出错误。
你见过R2014a预发布发行说明吗?现在似乎是一个空的字符串匹配。就好像MathWorks读取SO一样。 :) – chappjc
我还没有看到预售,但这是个好消息。感谢您让我们知道..出于好奇,预售中是否有重大变化? HG2图形也许? – Amro
HG2不是默认设置。当你在命令行上点击向上键时,会出现一个令人讨厌的新弹出命令历史记录。 MEX设置现在更容易,但是使用单独的C和C++配置(前面我看到质量混乱)。 “flipud”,“fliplr”和“rot90”命令现在可用于多维数组,但语法已更改。一些新的测试功能,例如'issymmetric','isdiag'等。 – chappjc
+1使用'strcmp'解决了这个问题。我个人不喜欢“可选参数”,我宁愿使用名称值参数参数:'p.addParameter('imag',false,@(x)validateattributes(x,{'logical'},{'标量'}))'。那么'p.Result.imag'可能是真或假。 – Amro
这是在代码中稍后清理比较的好方法。它可能是具有逻辑值的参数值参数。 – chappjc
@chappjc感谢您的帮助。我真的很喜欢使用名称 - 值对而不是可选参数,所以我可能会将它用于新代码。不幸的是,我现在正在使用的代码是不允许更改的API的遗留问题。 –