在我的代码中,我使用特定的方式来定义测试函数:在单元格中,存储了布尔类型的测试('< =','> =','=='...)。之后我想对特定值应用测试。我存储测试类型的原因是我的代码特有的,允许我编写代码而不需要事先了解测试类型。另一种方法是使用例如switch
来指定每个布尔测试的测试,但是我想避免它的那一刻。
MWE
a{1}=[1 2 3 4];
a{2}=[5 1 4 6];
typeTest{1}='<=';
typeTest{2}='<';
%create function
funCheck=@(x,y)eval([num2str(x),y,'0']);
%works
funCheck(1,'<')
%apply on cell (does not work due to the array in a)
cellfun(funCheck,a,typeTest)
使用此语法,无法同时使用eval
和向量表达式...
答案 0 :(得分:3)
现在在MATLAB中避免使用eval
实际上非常简单。如果你将typeTest
定义为一组函数句柄而不是字符串,那么你就是99%:
a{1}=[1 2 3 4];
a{2}=[5 1 4 6];
typeTest{1}=@le; % <=
typeTest{2}=@lt; % <
%create function
funCheck=@(x,y)y(x,0);
%works
funCheck(1,typeTest{1})
%apply on cell
cellfun(funCheck,a,typeTest,'UniformOutput',false)
请注意,我在'UniformOutput',false
的参数中添加了cellfun
。这将创建一个单元格数组作为输出,其中每个单元格是a
中其中一个元素和typeTest
中相应元素的结果。也就是说,TypeTest{1}
检查{1},a{2}
检查TypeTest{2}
。
我实际上会创建一个包含所有实际测试的数组,如下所示:
checks = { @(x)x<=3 , @(x)x>4 };
现在您对运算符和右操作数进行编码。这使您可以灵活地创建其他类型的支票:@(x)var(x)<1e-3
,@(x)max(diff(x))<1
等。
要将每个检查应用于每个数据阵列,您需要使用bsxfun
。我尝试了以下语句,但它在Octave 3.0.0中无法正常工作(我认为这可能是一个错误):
bsxfun( @(fun,data){fun{1}(data{1})}, checks(:)', a(:) )
这将生成一个2x2(检查次数的数据数组)单元格数组。
上述有效的替代方案是:
cellfun( @(fun,data)fun(data), ...
repmat(checks(:)',numel(a),1), ...
repmat(a(:),1,numel(checks)), ...
'UniformOutput',false)