在Matlab中验证两个相关输入的最佳实践

在Matlab中验证两个相关输入的最佳实践,matlab,validation,input,Matlab,Validation,Input,我有一个问题,关于在具有多个输入的Matlab函数中输入验证的最佳实践。这有点哲学。我在论坛上四处看了看,还没有看到对此的全面讨论。我关心验证条件涉及两个或更多输入变量的情况。这里有一个例子 假设我写了一个有两个输入的函数,a和b。我知道输入必须满足条件 a>0和b>0 如果我想验证这些输入,我通常会编写这样一个函数(仅用于说明,函数的功能并不重要): 但是现在假设a和b是数组,我还需要检查它们是否大小相同: all(大小(a)=大小(b))==true 有没有办法用输入解析器来处理这种情况?如

我有一个问题,关于在具有多个输入的Matlab函数中输入验证的最佳实践。这有点哲学。我在论坛上四处看了看,还没有看到对此的全面讨论。我关心验证条件涉及两个或更多输入变量的情况。这里有一个例子

假设我写了一个有两个输入的函数,a和b。我知道输入必须满足条件

a>0
b>0

如果我想验证这些输入,我通常会编写这样一个函数(仅用于说明,函数的功能并不重要):

但是现在假设a和b是数组,我还需要检查它们是否大小相同:

all(大小(a)=大小(b))==true

有没有办法用输入解析器来处理这种情况?如果没有,最好的解决方法是什么

我能想出四个解决方案,但我不知道哪一个是最好的

1) 我是否应该将a和b合并到一个输入单元格数组变量
sumInput
,格式为
{a,b}
,并为单元格数组编写一个自定义验证函数?这很好,但我不知道这样把输入数据集中在一起是否总是一种好的做法。在这里,能够编写
myLogSum(a,b)
而不是
myLogSum(sumInput)
似乎很自然

2) 或者在这种情况下,我是否应该在函数中写入输入验证的这一部分,即修改上述代码,如下所示:

% My function
function [result] = myLogSum(a,b)

% Create an input parser
p = inputParser;
% Add required inputs with validation
isPositive = @(x) all(x>0);
addRequired(p, 'a', isPositive);
addRequired(p, 'b', isPositive);
% Parse the inputs
parse(p,a,b);

% Check that the input arrays have the same size
if ~all(size(a)==size(b))
   message = 'The arrays a and b must have the same size.';
   error(message);
end

% Calculate the log sum
result = log(a) + log(b);

end
这也很好,但这使得验证有点不均匀和不美观,因为现在输入a和b以不同的方式和不同的原因验证了两次

3) 我是否应该放弃输入解析器,编写自己的验证函数,如下所示:

但我非常喜欢输入解析器,因为它是一种管理选项的简洁方法

4) 当程序到达最后一行
result=log(a)+log(b)
且数组大小不匹配时,我可以让Matlab自己处理错误。但不知何故,我觉得从长远来看,这是在自找麻烦

如果您有Matlab方面的经验,请告诉我当两个输入相关时,您认为什么是最稳健和全面的验证策略


Ben

没有什么可以阻止您调用一次
parse
,然后添加新输入并再次调用
parse
——此时您可以在验证函数中使用以前解析的值。
validateattributes
函数在这里用于构建具有多个条件的验证函数。例如:

% My function
function [result] = myLogSum(a,b)

% Create an input parser
p = inputParser;
% Add required inputs with validation
addRequired(p, 'a', @(x) validateattributes(x, {'numeric'}, {'>', 0}));
% Check the first input was valid
p.parse(a);
addRequired(p, 'b', @(x) validateattributes(x, {'numeric'}, {'>', 0, 'size', size(a)}));
% Parse the inputs
p.parse(a,b);

% Calculate the log sum
result = log(a) + log(b);

end
validateattributes
还会为您生成合理的解释性错误消息:

>> myLogSum(30, 40)

ans =

    7.0901

>> myLogSum([30 20], 40)
Error using myLogSum (line 12)
The value of 'b' is invalid. Expected input to be of size 1x2 when it is
actually size 1x1.

>> myLogSum([30 20], [40 1])

ans =

    7.0901    2.9957

>> myLogSum([30 20], [40 -1])
Error using myLogSum (line 12)
The value of 'b' is invalid. Expected input to be an array with all of the
values > 0.

作为一个轶事:我最终为我的代码编写了我自己的“parse_input”函数,它还提供了默认值等。如果您做得正确(不像我那样),您可以创建一个相对通用的函数,但确实您最终修改了每个函数的代码片段。。。这是一个不错的选择,但如果您这样做了,请为输入解析器编写单元测试@AnderBiguri这也是我所做的,但出于另一个原因,我根本不知道输入解析器。在我的大项目中,我能够以类的形式编写一个通用解析器,它有更多的类,而且几乎所有的类都使用它。携带默认值和处理无序列表并不难。我还没想到这是可能的。这在回顾中很明显。我认为这是我首选的解决方案。它是自洽的,相对优雅,可以统一应用于所有函数。非常感谢。同样,在输入已经添加到解析器之后,是否可以添加验证条件?某些验证条件可能取决于先前验证的成功与否。
>> myLogSum(30, 40)

ans =

    7.0901

>> myLogSum([30 20], 40)
Error using myLogSum (line 12)
The value of 'b' is invalid. Expected input to be of size 1x2 when it is
actually size 1x1.

>> myLogSum([30 20], [40 1])

ans =

    7.0901    2.9957

>> myLogSum([30 20], [40 -1])
Error using myLogSum (line 12)
The value of 'b' is invalid. Expected input to be an array with all of the
values > 0.